sqlinsight-pro/src/SQLInsight.Agent/Program.cs
Claude 3121b598f9
Some checks are pending
CI / Build og unit tests (push) Waiting to run
CI / Integration (mcr.microsoft.com/mssql/server:2017-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2019-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2022-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2025-latest) (push) Blocked by required conditions
Fase 3: signed updates of rule packs and the application
Rule packs (support dates and newest CU per release) are published in a
signed feed and hot-loaded without a restart; the verified pack is
reloaded at startup. New versions are announced (Notify) or downloaded
and staged by the unprivileged agent (Automatic), and installed by a
privileged apply-update task that re-verifies signature and hash in an
admin-only folder, keeps appsettings/web.config, health-checks the
services and rolls back on failure. Stable and preview channels,
manifest expiry and rollback protection, https or folder/share feeds
for offline sites. Vendor tool gains rulepack and publish; the Hub can
serve the feed; the web UI gets a System page with update, rule pack,
license and exactly what is sent to the Hub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E3EExwndy8Z22EK2Qpt6BK
2026-09-29 09:19:41 +00:00

73 lines
3.2 KiB
C#

using Microsoft.Extensions.Options;
using SQLInsight.Agent;
using SQLInsight.Agent.Monitoring;
using SQLInsight.Agent.Updates;
using SQLInsight.Connectivity;
using SQLInsight.Notifications;
using SQLInsight.Repository;
using SQLInsight.Rules;
using SQLInsight.Rules.Engine;
if (UpdateCommands.Handles(args))
{
return await UpdateCommands.RunAsync(args);
}
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddWindowsService(o => o.ServiceName = "SQLInsight Agent");
builder.Services.AddSystemd();
builder.Services.Configure<AgentOptions>(builder.Configuration.GetSection(AgentOptions.SectionName));
builder.Services.AddSingleton(TimeProvider.System);
builder.Services.AddSingleton<ISqlConnectionFactory, SqlConnectionFactory>();
builder.Services.Configure<UpdateOptions>(builder.Configuration.GetSection(UpdateOptions.SectionName));
builder.Services.AddSingleton(sp => UpdateService.LoadKnowledge(
sp.GetRequiredService<IOptions<UpdateOptions>>().Value, sp.GetRequiredService<ILoggerFactory>().CreateLogger<UpdateService>()));
builder.Services.AddSingleton(sp => new RuleEngine(BuiltInRules.Create(sp.GetRequiredService<SQLInsight.Rules.Lifecycle.RuleKnowledge>())));
builder.Services.AddSingleton(sp =>
{
var connectionString = sp.GetRequiredService<IOptions<AgentOptions>>().Value.Repository.ConnectionString;
if (string.IsNullOrWhiteSpace(connectionString))
{
throw new InvalidOperationException(
"SQLInsight:Repository:ConnectionString mangler. Angiv forbindelsen til repository-databasen (SQL Server 2016+, ikke en af de overvågede instanser).");
}
return new InsightRepository(connectionString);
});
builder.Services.Configure<NotificationOptions>(builder.Configuration.GetSection(NotificationOptions.SectionName));
builder.Services.AddHttpClient("notifications", c => c.Timeout = TimeSpan.FromSeconds(15));
builder.Services.AddSingleton(sp =>
{
var options = sp.GetRequiredService<IOptions<NotificationOptions>>().Value;
var http = sp.GetRequiredService<IHttpClientFactory>();
var channels = new List<INotificationChannel>();
if (options.Email.Enabled)
{
channels.Add(new EmailChannel(options.Email));
}
if (options.Teams.Enabled)
{
channels.Add(new TeamsChannel(options.Teams, http.CreateClient("notifications")));
}
if (options.Webhook.Enabled)
{
channels.Add(new WebhookChannel(options.Webhook, http.CreateClient("notifications")));
}
return new NotificationDispatcher(channels, options, sp.GetRequiredService<TimeProvider>(), sp.GetRequiredService<ILogger<NotificationDispatcher>>());
});
builder.Services.Configure<SQLInsight.Agent.Hub.HubOptions>(builder.Configuration.GetSection(SQLInsight.Agent.Hub.HubOptions.SectionName));
builder.Services.AddHttpClient("hub", c => c.Timeout = TimeSpan.FromSeconds(30));
builder.Services.AddSingleton<SQLInsight.Agent.Hub.HubOutbox>();
builder.Services.AddHostedService<SQLInsight.Agent.Hub.HubSyncService>();
builder.Services.AddHttpClient("updates", c => c.Timeout = TimeSpan.FromMinutes(10));
builder.Services.AddHostedService<UpdateService>();
builder.Services.AddHostedService<MonitoringService>();
var host = builder.Build();
await host.RunAsync();
return 0;