chore: initial project import
This commit is contained in:
commit
26620707a0
347 files changed
+56172
No files matched your search
@@ -0,0 +1,92 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using Fleet.Core;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Fleet.Server;
|
||||
|
||||
public static class FleetEnrollmentEndpoints
|
||||
{
|
||||
private const int MaxBodyBytes = 64 * 1024;
|
||||
|
||||
/// <summary>注册端点:<c>POST {path}</c>,使用加入令牌认证。需要在 DI 中注册 <see cref="FleetEnrollmentService"/>。</summary>
|
||||
public static IEndpointRouteBuilder MapFleetEnrollment(this IEndpointRouteBuilder app, string path)
|
||||
{
|
||||
app.MapPost(path, HandleAsync)
|
||||
.WithName("fleet_enroll")
|
||||
.WithTags("agent")
|
||||
.WithSummary("Enroll a node with a join token")
|
||||
.DisableAntiforgery();
|
||||
return app;
|
||||
}
|
||||
|
||||
private static async Task<IResult> HandleAsync(HttpContext http, FleetEnrollmentService service)
|
||||
{
|
||||
EnrollRequest? request;
|
||||
try
|
||||
{
|
||||
request = await ReadBodyAsync(http, http.RequestAborted);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
request = null;
|
||||
}
|
||||
|
||||
if (request is null)
|
||||
{
|
||||
return Problem(StatusCodes.Status400BadRequest, FleetErrors.InvalidParams, "request body is not valid");
|
||||
}
|
||||
|
||||
Result<EnrollResponse> result = await service.EnrollAsync(request, http.Connection.RemoteIpAddress?.ToString(), http.RequestAborted);
|
||||
if (result.TryGet(out EnrollResponse? response, out FleetError? error))
|
||||
{
|
||||
return Results.Json(response, EnrollmentJsonContext.Default.EnrollResponse, statusCode: StatusCodes.Status201Created);
|
||||
}
|
||||
|
||||
int status = error.Code == FleetErrors.JoinTokenInvalid ? StatusCodes.Status401Unauthorized
|
||||
: error.Code == FleetErrors.JoinTokenExpired ? StatusCodes.Status410Gone
|
||||
: error.Code == FleetErrors.ProofInvalid ? StatusCodes.Status403Forbidden
|
||||
: error.Code == FleetErrors.NameConflict ? StatusCodes.Status409Conflict
|
||||
: error.Code == FleetErrors.InvalidParams ? StatusCodes.Status400BadRequest
|
||||
: StatusCodes.Status500InternalServerError;
|
||||
return Problem(status, error.Code, error.Message);
|
||||
}
|
||||
|
||||
private static async Task<EnrollRequest?> ReadBodyAsync(HttpContext http, CancellationToken ct)
|
||||
{
|
||||
if (http.Request.ContentLength > MaxBodyBytes)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using var buffer = new MemoryStream();
|
||||
byte[] chunk = new byte[4096];
|
||||
int read;
|
||||
while ((read = await http.Request.Body.ReadAsync(chunk, ct)) > 0)
|
||||
{
|
||||
buffer.Write(chunk, 0, read);
|
||||
if (buffer.Length > MaxBodyBytes)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return JsonSerializer.Deserialize(buffer.ToArray(), EnrollmentJsonContext.Default.EnrollRequest);
|
||||
}
|
||||
|
||||
private static IResult Problem(int status, ErrorCode code, string detail) =>
|
||||
Results.Json(
|
||||
new FleetProblem { Title = ((HttpStatusCode)status).ToString(), Status = status, Code = code.Value, Detail = detail },
|
||||
EnrollmentJsonContext.Default.FleetProblem,
|
||||
contentType: "application/problem+json",
|
||||
statusCode: status);
|
||||
}
|
||||
|
||||
public static class FleetEnrollmentServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddFleetEnrollment(this IServiceCollection services) =>
|
||||
services.AddSingleton<FleetEnrollmentService>();
|
||||
}
|
||||
Reference in new issue
Block a user