- /servere reads the overview in one query and says which paused servers and checks are left out of the active findings; admin notes use InstanceSetup.WhoMayChangeText as main. - The check form refuses a port, interval, timeout or limit that is not a number (Danish message) and clamps minutes before multiplying; an interval set to part of a minute through the API is shown and kept in seconds. - "Kør nu" is refused for a paused check (message, no button); ?koersel= shows that run. - A finding of a removed server or check does not link to a missing page and says why it is not active. - The forecast text uses the history the forecasts were computed from; the grant script text matches the new script (-WhatIf first, -WinRM, -EnableFirewall -AgentAddress, -Remove only what it added). - HTTP addresses are at most 2000 characters. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
92 lines
4.2 KiB
Text
92 lines
4.2 KiB
Text
@page "/syntetiske-tjek"
|
||
@using SQLInsight.Core.SyntheticChecks
|
||
@inject InsightRepository Repository
|
||
@inject Display Display
|
||
@inject Microsoft.Extensions.Options.IOptions<WebOptions> Options
|
||
|
||
<PageTitle>Syntetiske tjek · SQLInsight Pro</PageTitle>
|
||
|
||
<h1>Syntetiske tjek</h1>
|
||
<p class="lead">Agenten gør det, en bruger eller en applikation gør – forbinder til AOS-porten, henter en side, logger på SQL Server, slår et navn op, logger på Dynamics AX – med jævne mellemrum og med sin egen konto. Så opdages det, når en applikationsserver ikke svarer, selv om tjenesten kører.</p>
|
||
|
||
@if (Fjernet == 1)
|
||
{
|
||
<p class="notice ok" role="status">Tjekket er fjernet. Resultaterne er bevaret, indtil de udløber.</p>
|
||
}
|
||
@if (!string.IsNullOrEmpty(Fejl))
|
||
{
|
||
<p class="notice bad" role="alert">@Fejl</p>
|
||
}
|
||
@if (!_mayChange)
|
||
{
|
||
<p class="notice" role="note">Du kan se tjekkene, men kun administratorer kan tilføje og ændre dem. @InstanceSetup.WhoMayChangeText(Options.Value)</p>
|
||
}
|
||
|
||
<section class="card">
|
||
<div class="card-head"><h2>Tjek</h2><span class="muted">@_checks.Count(c => !c.Paused) aktive · <a href="@ServerSetup.ServersPage">Windows-servere</a></span></div>
|
||
@if (_checks.Count == 0)
|
||
{
|
||
<p class="empty">Der er ingen syntetiske tjek endnu.@(_mayChange ? " Tilføj det første nedenfor." : string.Empty)</p>
|
||
}
|
||
else
|
||
{
|
||
<table>
|
||
<thead><tr><th>Tjek</th><th>Type</th><th>Mål</th><th>Status</th><th class="num">Svartid</th><th>Seneste</th><th>Fund</th></tr></thead>
|
||
<tbody>
|
||
@foreach (var c in _checks)
|
||
{
|
||
var counts = _counts.GetValueOrDefault((FindingScope.Check, c.CheckId));
|
||
<tr>
|
||
<td><a href="@ServerSetup.CheckPage(c.CheckId)">@c.Name</a>@if (c.ServerName is { } server) { <div class="muted small">@server@(c.Settings.ServiceName is { } svc ? " · " + svc : string.Empty)</div> }</td>
|
||
<td>@SyntheticCheckKind.Display(c.Kind)</td>
|
||
<td class="mono small">@c.Settings.Target(c.Kind)</td>
|
||
<td><CheckStatus Check="c" /></td>
|
||
<td class="num">@(c.LastDurationMs is { } ms ? Display.Number(ms) + " ms" : "–")</td>
|
||
<td title="@c.LastMessage">@Display.Ago(c.LastRunAt)</td>
|
||
<td>
|
||
@if (counts is null || counts.Count == 0)
|
||
{
|
||
<SeverityBadge Severity="null" />
|
||
}
|
||
else
|
||
{
|
||
@foreach (var (severity, count) in counts.OrderByDescending(x => x.Key))
|
||
{
|
||
<SeverityBadge Severity="severity" Count="count" />
|
||
}
|
||
}
|
||
</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
}
|
||
</section>
|
||
|
||
@if (_mayChange)
|
||
{
|
||
<section class="panel" id="tilfoej">
|
||
<h2>Tilføj tjek</h2>
|
||
<p class="muted">Udfyld felterne for den valgte type; de andre ignoreres. Efter tilføjelsen kører agenten tjekket med det samme.</p>
|
||
<CheckForm Action="/syntetiske-tjek/tilfoej" Servers="_servers" SubmitText="Tilføj og kør tjekket" />
|
||
</section>
|
||
}
|
||
|
||
@code {
|
||
[CascadingParameter] private HttpContext? Http { get; set; }
|
||
[SupplyParameterFromQuery(Name = "fejl")] public string? Fejl { get; set; }
|
||
[SupplyParameterFromQuery(Name = "fjernet")] public int? Fjernet { get; set; }
|
||
|
||
private IReadOnlyList<SyntheticCheckRow> _checks = [];
|
||
private IReadOnlyList<WindowsServerRow> _servers = [];
|
||
private IReadOnlyDictionary<(string, int), IReadOnlyDictionary<Severity, int>> _counts = new Dictionary<(string, int), IReadOnlyDictionary<Severity, int>>();
|
||
private bool _mayChange;
|
||
|
||
protected override async Task OnInitializedAsync()
|
||
{
|
||
_checks = await Repository.GetSyntheticChecksAsync();
|
||
_servers = await Repository.GetWindowsServersAsync();
|
||
_counts = await Repository.GetServerFindingCountsAsync();
|
||
_mayChange = Http is not null && InstanceSetup.MayChange(Http.User, Options.Value);
|
||
}
|
||
}
|