using SQLInsight.Core.Servers; namespace SQLInsight.Servers; /// Opens read-only sessions to Windows servers, as the agent's own identity. public interface IWindowsServerSource { /// Connects to : WS-Man (WinRM) first, DCOM if that fails, or locally for the agent's own computer. /// The server could not be reached; the message says why (Danish). Task ConnectAsync(string host, CancellationToken cancellationToken); } /// /// One connection to a Windows server. Every method only reads: no method changes, starts or stops anything. Each /// throws with the exact reason when its area cannot be read. /// public interface IWindowsServerSession : IDisposable { /// "WS-Man", "DCOM" or "lokal". string Protocol { get; } /// Why the preferred protocol was not used (Danish), when it was not. string? ProtocolNote { get; } Task GetOperatingSystemAsync(CancellationToken cancellationToken); Task GetPerformanceAsync(DateTimeOffset now, CancellationToken cancellationToken); Task> GetDisksAsync(CancellationToken cancellationToken); Task> GetServicesAsync(CancellationToken cancellationToken); /// One service, or null when it does not exist (or cannot be seen). Task GetServiceAsync(string name, CancellationToken cancellationToken); /// Errors and critical events in the System and Application logs since , oldest first. Task GetEventsAsync(DateTimeOffset since, int max, CancellationToken cancellationToken); /// Scheduled tasks; run information only for the ones selects (at most ). Task GetTasksAsync(Func watch, int maxWatched, CancellationToken cancellationToken); } /// How the logs were read: "Event Log (RPC)" or "CIM (Win32_NTLogEvent)". /// More events than max: the rest is read next time. public sealed record ServerEventRead(IReadOnlyList Entries, string Method, bool Truncated, string? Note = null); /// Every task the agent could see. public sealed record ServerTaskRead(IReadOnlyList Watched, int Visible, string? Note = null); public enum ServerAccessProblem { /// The server does not answer (name, network, firewall, WinRM/RPC not running). Unreachable, /// The server answers, but the agent's account may not read this. AccessDenied, /// The server does not have it (an older Windows without the class or namespace). NotAvailable, /// The server did not answer in time. Timeout, /// The agent cannot do it at all (not on Windows). NotSupported, Other, } /// A Windows server or one of its areas could not be read. The message is Danish and says exactly why and what to do. public sealed class ServerAccessException : Exception { public ServerAccessException() { } public ServerAccessException(string message) : base(message) { } public ServerAccessException(string message, Exception innerException) : base(message, innerException) { } public ServerAccessException(ServerAccessProblem problem, string message, Exception? innerException = null) : base(message, innerException) { Problem = problem; } public ServerAccessProblem Problem { get; } = ServerAccessProblem.Other; /// The Windows error code (HRESULT) when there was one, for support. public uint? Code { get; init; } } /// For an agent that does not run on Windows: Windows servers cannot be read from Linux. public sealed class UnsupportedWindowsServerSource : IWindowsServerSource { public const string Reason = "Windows-servere kan kun overvåges, når SQLInsight Agent kører på Windows (CIM/WMI og hændelseslog er Windows-protokoller)."; public Task ConnectAsync(string host, CancellationToken cancellationToken) => throw new ServerAccessException(ServerAccessProblem.NotSupported, Reason); }