using System.Text.Json; using System.Text.Json.Serialization; namespace Fleet.Server; public sealed class EnrollRequest { [JsonPropertyName("join_token")] public string JoinToken { get; set; } = ""; [JsonPropertyName("name")] public string Name { get; set; } = ""; /// 身份公钥(SPKI,base64)。 [JsonPropertyName("pubkey")] public string PublicKey { get; set; } = ""; /// 面向对端节点的 TLS 证书指纹(SHA-256,base64)。 [JsonPropertyName("tls_spki")] public string TlsSpki { get; set; } = ""; /// /// 同一把 TLS 密钥的完整公钥(SPKI,base64),必须和 对得上。节点用这把密钥做对等面的签名认证 /// (和连服务端用的身份密钥是两把独立的密钥),对端要验签就需要完整的公钥,而不只是指纹。 /// [JsonPropertyName("tls_pubkey")] public string TlsPublicKey { get; set; } = ""; /// 持有证明:对 fleet|v1|enroll|{sha256_hex(join_token)}|{pubkey} 的签名(base64)。 [JsonPropertyName("proof")] public string Proof { get; set; } = ""; [JsonPropertyName("node_version")] public string NodeVersion { get; set; } = ""; [JsonPropertyName("meta")] public JsonElement? Meta { get; set; } } public sealed class EnrollResponse { [JsonPropertyName("node_id")] public string NodeId { get; set; } = ""; /// pending | active [JsonPropertyName("status")] public string Status { get; set; } = ""; } /// RFC 9457 problem+json,带 code 扩展字段。 public sealed class FleetProblem { [JsonPropertyName("type")] public string Type { get; set; } = "about:blank"; [JsonPropertyName("title")] public string Title { get; set; } = ""; [JsonPropertyName("status")] public int Status { get; set; } [JsonPropertyName("code")] public string Code { get; set; } = ""; [JsonPropertyName("detail")] public string? Detail { get; set; } } [JsonSourceGenerationOptions(DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] [JsonSerializable(typeof(EnrollRequest))] [JsonSerializable(typeof(EnrollResponse))] [JsonSerializable(typeof(FleetProblem))] internal sealed partial class EnrollmentJsonContext : JsonSerializerContext;