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
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
73 lines
3.2 KiB
C#
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;
|