62 lines
3.1 KiB
C#
62 lines
3.1 KiB
C#
using Fleet.Core;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Routing;
|
|
using MoShiro.Backend.Application;
|
|
using MoShiro.Protocol;
|
|
|
|
namespace MoShiro.Backend.Api;
|
|
|
|
/// <summary>线路开关:哪些(Probe,Agent)要连。自动连接的总开关是设置 <c>fleet.auto_link</c>;这里看每一对的结果,并且手动强制开、关或取消手动设置。</summary>
|
|
public static class LinkEndpoints
|
|
{
|
|
private const string Tag = "admin-links";
|
|
|
|
public static void Map(RouteGroupBuilder group)
|
|
{
|
|
group.MapGet("/links", ListAsync)
|
|
.Api("links_list", "Every probe/agent pair: whether it is linked, the manual override and whether it is connected", Tag).Returns<LinkMatrixDto>().ProducesProblems(401, 403)
|
|
.Requires(Capability.FleetRead);
|
|
group.MapPut("/links/{probe_id}/{agent_id}", SetAsync)
|
|
.Api("links_set", "Force a link on or off, or give it back to the automatic setting (enabled: null)", Tag).Returns<LinkDto>().ProducesProblems(400, 401, 403, 404)
|
|
.Requires(Capability.FleetWrite);
|
|
}
|
|
|
|
private static async Task<IResult> ListAsync(AgentService agents, ProbeService probes, LinkService links, CancellationToken ct)
|
|
{
|
|
LinkSnapshot snapshot = await links.SnapshotAsync(ct);
|
|
IReadOnlyList<AgentView> agentViews = await agents.ListAsync(ct);
|
|
var items = new List<LinkDto>();
|
|
foreach (ProbeView probe in (await probes.ListAsync(ct)).Where(p => !p.Revoked).OrderBy(p => p.Probe.Name, StringComparer.Ordinal))
|
|
{
|
|
foreach (AgentView agent in agentViews.OrderBy(a => a.Agent.Name, StringComparer.Ordinal))
|
|
{
|
|
items.Add(ToDto(snapshot, probe, agent));
|
|
}
|
|
}
|
|
|
|
return TypedResults.Json(new LinkMatrixDto(snapshot.Auto, items), ApiJsonContext.Default.LinkMatrixDto);
|
|
}
|
|
|
|
private static async Task<IResult> SetAsync(HttpContext http, AgentService agents, ProbeService probes, LinkService links, string probe_id, string agent_id, SetLinkRequest request, CancellationToken ct)
|
|
{
|
|
if (await probes.GetAsync(probe_id, ct) is not { Revoked: false } probe)
|
|
{
|
|
return Problems.Create(http, MoShiroErrors.ProbeNotFound, "probe not found");
|
|
}
|
|
|
|
if (await agents.GetAsync(new NodeId(agent_id), ct) is not { } agent)
|
|
{
|
|
return Problems.Create(http, MoShiroErrors.AgentNotFound, "agent not found");
|
|
}
|
|
|
|
await links.SetAsync(probe_id, agent_id, request.Enabled, ct);
|
|
await agents.AfterAgentSetChangedAsync(ct); // 重新下发:Probe 的 Agent 列表、Agent 允许的 Probe
|
|
return TypedResults.Json(ToDto(await links.SnapshotAsync(ct), probe, agent), ApiJsonContext.Default.LinkDto);
|
|
}
|
|
|
|
private static LinkDto ToDto(LinkSnapshot snapshot, ProbeView probe, AgentView agent) =>
|
|
new(probe.Probe.Id, probe.Probe.Name, agent.Agent.Id.Value, agent.Agent.Name, snapshot.IsLinked(probe.Probe.Id, agent.Agent.Id.Value), snapshot.OverrideOf(probe.Probe.Id, agent.Agent.Id.Value),
|
|
agent.Probes.Any(p => p.Id == probe.Probe.Id));
|
|
}
|