53 lines
2.2 KiB
C#
53 lines
2.2 KiB
C#
using System.Net.Http.Json;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Zcbot.WindowsNode;
|
|
|
|
internal static class EnrollmentClient
|
|
{
|
|
private static readonly string[] Capabilities = ["origin.plot@v1"];
|
|
|
|
internal static async Task EnrollAsync(
|
|
EnrollOptions options, NodeConfigStore store, CancellationToken cancellationToken)
|
|
{
|
|
if (store.Exists)
|
|
{
|
|
throw new NodeConfigurationException(
|
|
$"Node is already registered. Remove {store.ConfigPath} through the administrator recovery procedure before re-enrolling.");
|
|
}
|
|
|
|
var installId = Guid.NewGuid();
|
|
var request = new EnrollRequest(
|
|
options.EnrollmentCode,
|
|
options.NodeName,
|
|
installId,
|
|
Assembly.GetExecutingAssembly().GetName().Version?.ToString(3) ?? "0.1.0",
|
|
RuntimeInformation.OSDescription,
|
|
Capabilities);
|
|
|
|
using var client = new HttpClient { BaseAddress = options.ServerUrl, Timeout = TimeSpan.FromSeconds(30) };
|
|
using var response = await client.PostAsJsonAsync(
|
|
"v1/compute/nodes/enroll", request, cancellationToken);
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var detail = await response.Content.ReadAsStringAsync(cancellationToken);
|
|
throw new NodeConfigurationException(
|
|
$"Registration failed with HTTP {(int)response.StatusCode}: {Limit(detail, 300)}");
|
|
}
|
|
var enrolled = await response.Content.ReadFromJsonAsync<EnrollResponse>(cancellationToken)
|
|
?? throw new NodeConfigurationException("Registration response was empty.");
|
|
if (enrolled.NodeId == Guid.Empty || string.IsNullOrWhiteSpace(enrolled.NodeToken))
|
|
{
|
|
throw new NodeConfigurationException("Registration response did not contain a valid node identity.");
|
|
}
|
|
|
|
store.Save(new NodeConfig(
|
|
options.ServerUrl, enrolled.NodeId, installId, options.NodeName,
|
|
enrolled.NodeToken, Math.Clamp(enrolled.HeartbeatSeconds, 5, 300), Capabilities));
|
|
}
|
|
|
|
private static string Limit(string value, int maxLength) =>
|
|
value.Length <= maxLength ? value : value[..maxLength];
|
|
}
|