83 lines
3.0 KiB
C#
83 lines
3.0 KiB
C#
using ControlPlane.Core.Config;
|
|
using ControlPlane.Core.Interfaces;
|
|
using ControlPlane.Core.Services;
|
|
using ControlPlane.Worker;
|
|
using ControlPlane.Worker.Services;
|
|
using ControlPlane.Worker.Steps;
|
|
using Keycloak.AuthServices.Sdk;
|
|
using MassTransit;
|
|
using Npgsql;
|
|
|
|
var builder = Host.CreateApplicationBuilder(args);
|
|
|
|
builder.AddServiceDefaults();
|
|
|
|
// Centralized infrastructure options — domain, network, internal URLs, cert paths
|
|
builder.Services.Configure<ClarityInfraOptions>(
|
|
builder.Configuration.GetSection(ClarityInfraOptions.Section));
|
|
|
|
// Keycloak Admin SDK client
|
|
builder.Services.AddKeycloakAdminHttpClient(o =>
|
|
{
|
|
o.AuthServerUrl = builder.Configuration["Keycloak:AuthServerUrl"] ?? "http://localhost:8080";
|
|
o.Realm = builder.Configuration["Keycloak:Realm"] ?? "master";
|
|
o.Resource = builder.Configuration["Keycloak:Resource"] ?? "admin-cli";
|
|
});
|
|
|
|
// Custom admin client - handles realm creation, roles, role assignment (not in SDK)
|
|
builder.Services.AddSingleton<KeycloakAdminClient>();
|
|
|
|
// Named HttpClient for Gitea commit status API (self-signed cert + token auth)
|
|
builder.Services.AddHttpClient("gitea", (sp, client) =>
|
|
{
|
|
var cfg = sp.GetRequiredService<IConfiguration>();
|
|
client.BaseAddress = new Uri(cfg["Gitea:BaseUrl"] ?? "https://opc.clarity.test");
|
|
client.DefaultRequestHeaders.Authorization =
|
|
new System.Net.Http.Headers.AuthenticationHeaderValue("token", cfg["Gitea:Token"]);
|
|
}).ConfigurePrimaryHttpMessageHandler(() =>
|
|
new HttpClientHandler { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator });
|
|
|
|
// opcdb for build/release history tracking
|
|
var opcConnStr = builder.Configuration.GetConnectionString("opcdb");
|
|
builder.Services.AddSingleton(NpgsqlDataSource.Create(
|
|
!string.IsNullOrWhiteSpace(opcConnStr) ? opcConnStr : "Host=127.0.0.1;Port=5433;Database=opcdb;Username=postgres;Password=controlplane-dev"));
|
|
builder.Services.AddSingleton<BuildHistoryService>();
|
|
|
|
// Docker container manager for per-tenant Clarity.Server instances
|
|
builder.Services.AddSingleton<ClarityContainerService>();
|
|
|
|
// Tenant registry - persists provisioned tenant XML files to ClientAssets folder
|
|
builder.Services.AddSingleton<TenantRegistryService>();
|
|
|
|
// Saga steps in execution order — container launches LAST once all context is populated
|
|
builder.Services.AddSingleton<ISagaStep, KeycloakStep>();
|
|
builder.Services.AddSingleton<ISagaStep, VaultStep>();
|
|
builder.Services.AddSingleton<ISagaStep, MigrationStep>();
|
|
builder.Services.AddSingleton<ISagaStep, LaunchStep>();
|
|
builder.Services.AddSingleton<ISagaStep, HandoffStep>();
|
|
|
|
builder.Services.AddMassTransit(x =>
|
|
{
|
|
x.SetKebabCaseEndpointNameFormatter();
|
|
|
|
x.AddConsumer<ProvisioningConsumer>();
|
|
x.AddConsumer<BuildConsumer>();
|
|
|
|
x.UsingRabbitMq((ctx, cfg) =>
|
|
{
|
|
cfg.Host(builder.Configuration.GetConnectionString("rabbitmq"));
|
|
cfg.ConfigureEndpoints(ctx);
|
|
});
|
|
});
|
|
|
|
try
|
|
{
|
|
var host = builder.Build();
|
|
host.Run();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.Error.WriteLine($"FATAL WORKER CRASH: {ex}");
|
|
throw;
|
|
}
|