refactor (networking)
This commit is contained in:
parent
febc4d9488
commit
450a6f2796
153 changed files with 7834 additions and 8004 deletions
14
insight.sln
14
insight.sln
|
|
@ -31,12 +31,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Server", "src\Serve
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Updater", "src\Updater\Insight.Updater\Insight.Updater.csproj", "{4875D70F-A96B-4EBA-99BE-218886D29BEB}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Web.Assets", "src\Web\Insight.Web.Assets\Insight.Web.Assets.csproj", "{EBB8A2A8-453B-4867-A8E2-072530391DD0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Agent", "src\Agent\Insight.Agent\Insight.Agent.csproj", "{2A391CA2-F96B-4DB7-80AA-0668A5141640}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Agent.Assets", "src\Agent\Insight.Agent.Assets\Insight.Agent.Assets.csproj", "{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -71,18 +67,10 @@ Global
|
|||
{4875D70F-A96B-4EBA-99BE-218886D29BEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4875D70F-A96B-4EBA-99BE-218886D29BEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4875D70F-A96B-4EBA-99BE-218886D29BEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EBB8A2A8-453B-4867-A8E2-072530391DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EBB8A2A8-453B-4867-A8E2-072530391DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EBB8A2A8-453B-4867-A8E2-072530391DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EBB8A2A8-453B-4867-A8E2-072530391DD0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2A391CA2-F96B-4DB7-80AA-0668A5141640}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2A391CA2-F96B-4DB7-80AA-0668A5141640}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2A391CA2-F96B-4DB7-80AA-0668A5141640}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2A391CA2-F96B-4DB7-80AA-0668A5141640}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -95,9 +83,7 @@ Global
|
|||
{EF3188D7-338D-43DA-BF6B-D26E5BDAC3A6} = {35BA5DCB-BECC-4F51-8DD0-694C555D205A}
|
||||
{1E75F7E9-E6AA-44E7-A2F3-DB4CA85E0118} = {038C3821-E554-496D-B585-A3BC193B7913}
|
||||
{4875D70F-A96B-4EBA-99BE-218886D29BEB} = {F2D241DB-7692-46DB-8A6A-958B365DAAF8}
|
||||
{EBB8A2A8-453B-4867-A8E2-072530391DD0} = {3F000016-069D-477E-ACA3-F643880B57E8}
|
||||
{2A391CA2-F96B-4DB7-80AA-0668A5141640} = {140F73DD-29D3-4C44-809B-5B470880AA0D}
|
||||
{4C2B66EA-4EE1-47BF-BAEE-DDBAF6FCB324} = {140F73DD-29D3-4C44-809B-5B470880AA0D}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F376A326-7590-4E7E-AB9B-76CED8527AB0}
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
namespace Insight.Agent.Enums
|
||||
{
|
||||
public enum CategoryEnum
|
||||
{
|
||||
Network = 1,
|
||||
System = 2,
|
||||
Application = 3,
|
||||
Security = 4,
|
||||
Monitoring = 5,
|
||||
Task = 6,
|
||||
Printer = 7,
|
||||
RDP = 8
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
namespace Insight.Agent.Enums
|
||||
{
|
||||
public enum DispatchEnum
|
||||
{
|
||||
Pending = 1,
|
||||
Failure = 2,
|
||||
Success = 3,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
namespace Insight.Agent.Enums
|
||||
{
|
||||
public enum StatusEnum
|
||||
{
|
||||
Information = 1,
|
||||
Warning = 2,
|
||||
Error = 3
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AssemblyName>Insight.Agent.Assets</AssemblyName>
|
||||
<RootNamespace>Insight.Agent</RootNamespace>
|
||||
<Product>Insight</Product>
|
||||
<AssemblyVersion>2023.9.14.0</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Vaitr.Network" Version="2023.9.13" />
|
||||
<PackageReference Include="Vaitr.Snmp" Version="2023.3.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Core\Insight.Domain\Insight.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
using Insight.Agent.Messages;
|
||||
|
||||
namespace Insight.Agent.Interfaces
|
||||
{
|
||||
public partial interface IAgentMessageHandler<TSender>
|
||||
{
|
||||
ValueTask HandleAsync<TMessage>(TSender sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
using MemoryPack;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(120, typeof(Application))]
|
||||
[MemoryPackUnion(121, typeof(ApplicationList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Application : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Publisher { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Location { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Source { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Uninstall { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public DateTime? InstallDate { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public Architecture? Architecture { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class ApplicationList : List<Application>, IAgentMessage { }
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(1, typeof(Authentication))]
|
||||
[MemoryPackUnion(2, typeof(AuthenticationRequest))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Authentication : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public PlatformType? Platform { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public Guid Serial { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public Version? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Hostname { get; set; }
|
||||
|
||||
public enum PlatformType
|
||||
{
|
||||
Unknown = 0,
|
||||
Windows = 1,
|
||||
Unix = 2
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class AuthenticationRequest : IAgentMessage { }
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(2000, typeof(GetInventory))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class GetInventory : IAgentMessage { }
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(1000, typeof(ConsoleQuery))]
|
||||
[MemoryPackUnion(1001, typeof(ConsoleQueryRequest))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ConsoleQuery : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? HostId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Query { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Data { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Errors { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public bool IsString { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public bool IsArray { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool HadErrors { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ConsoleQueryRequest : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? HostId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Query { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(50, typeof(Drive))]
|
||||
[MemoryPackUnion(51, typeof(DriveList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Drive : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public string? InterfaceType { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public string? FirmwareRevision { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public string? PNPDeviceID { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public List<Volume>? Volumes { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class DriveList : List<Drive>, IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Volume : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public ulong? FreeSpace { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public string? FileSystem { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public bool? Compressed { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? Bootable { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? PrimaryPartition { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public bool? BootPartition { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public ulong? BlockSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public ulong? NumberOfBlocks { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public ulong? StartingOffset { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public DriveType? DriveType { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public string? ProviderName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(10, typeof(Event))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Event : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? Timestamp { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public StatusType? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Source { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Category { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public int? EventId { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Task { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Message { get; set; }
|
||||
|
||||
public enum StatusType
|
||||
{
|
||||
Unknown = 0,
|
||||
Information = 1,
|
||||
Warning = 2,
|
||||
Error = 3,
|
||||
Critical = 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackable]
|
||||
public partial interface IAgentMessage { }
|
||||
}
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
using MemoryPack;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(70, typeof(Interface))]
|
||||
[MemoryPackUnion(71, typeof(InterfaceList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Interface : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public Guid? Guid { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Mac { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Suffix { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool? Physical { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public NetworkInterfaceType? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public OperationalStatus? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public long? Speed { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public long? Ipv4Mtu { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public bool? Ipv4Dhcp { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public bool? Ipv4Forwarding { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public long? Ipv6Mtu { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public long? Sent { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public long? Received { get; set; }
|
||||
|
||||
[MemoryPackOrder(17)]
|
||||
public long? IncomingPacketsDiscarded { get; set; }
|
||||
|
||||
[MemoryPackOrder(18)]
|
||||
public long? IncomingPacketsWithErrors { get; set; }
|
||||
|
||||
[MemoryPackOrder(19)]
|
||||
public long? IncomingUnknownProtocolPackets { get; set; }
|
||||
|
||||
[MemoryPackOrder(20)]
|
||||
public long? OutgoingPacketsDiscarded { get; set; }
|
||||
|
||||
[MemoryPackOrder(21)]
|
||||
public long? OutgoingPacketsWithErrors { get; set; }
|
||||
|
||||
[MemoryPackOrder(22)]
|
||||
public List<Unicast>? Addresses { get; set; }
|
||||
|
||||
[MemoryPackOrder(23)]
|
||||
public List<IPAddress2>? Gateways { get; set; }
|
||||
|
||||
[MemoryPackOrder(24)]
|
||||
public List<IPAddress2>? Dns { get; set; }
|
||||
|
||||
[MemoryPackOrder(25)]
|
||||
public List<IPAddress2>? Dhcp { get; set; }
|
||||
|
||||
[MemoryPackOrder(26)]
|
||||
public List<Route>? Routes { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class InterfaceList : List<Interface>, IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Unicast : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public IPAddress2? IpAddress { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public IPAddress2? Ipv4Mask { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public long? AddressPreferredLifetime { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public long? AddressValidLifetime { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public long? DhcpLeaseLifetime { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public DuplicateAddressDetectionState? DuplicateAddressDetectionState { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public int? PrefixLength { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public PrefixOrigin? PrefixOrigin { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public SuffixOrigin? SuffixOrigin { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Route : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? InterfaceIndex { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public IPAddress2? Destination { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public IPAddress2? Gateway { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Mask { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public int? Metric { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class IPAddress2 : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public AddressFamily? AddressFamily { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Address { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public bool? IsIPv6Teredo { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public bool? IsIPv6SiteLocal { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public bool? IsIPv6Multicast { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public bool? IsIPv6LinkLocal { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public bool? IsIPv4MappedToIPv6 { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool? IsIPv6UniqueLocal { get; set; }
|
||||
|
||||
[MemoryPackConstructor]
|
||||
public IPAddress2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public IPAddress2(IPAddress address)
|
||||
{
|
||||
AddressFamily = address.AddressFamily;
|
||||
Address = address.ToString();
|
||||
IsIPv4MappedToIPv6 = address.IsIPv4MappedToIPv6;
|
||||
IsIPv6LinkLocal = address.IsIPv6LinkLocal;
|
||||
IsIPv6Multicast = address.IsIPv6Multicast;
|
||||
IsIPv6SiteLocal = address.IsIPv6SiteLocal;
|
||||
IsIPv6Teredo = address.IsIPv6Teredo;
|
||||
IsIPv6UniqueLocal = address.IsIPv6UniqueLocal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(0, typeof(Keepalive))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Keepalive : IAgentMessage { }
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(20, typeof(Mainboard))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Mainboard : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Model { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Serial { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? BiosManufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? BiosVersion { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public DateTime? BiosDate { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(40, typeof(Memory))]
|
||||
[MemoryPackUnion(41, typeof(MemoryList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Memory : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Tag { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Location { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Model { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Serial { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public ulong? Capacity { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public uint? Speed { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public uint? Voltage { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public uint? ConfiguredSpeed { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public uint? ConfiguredVoltage { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class MemoryList : List<Memory>, IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class MemoryMetric : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? Timestamp { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public float? MemoryAvailable { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public float? MemoryAvailablePercentage { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public float? MemoryUsed { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public float? MemoryUsagePercentage { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
using MemoryPack;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(90, typeof(OperationSystem))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class OperationSystem : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public Architecture? Architecture { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public bool? Virtual { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public DateTime? InstallDate { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(140, typeof(Printer))]
|
||||
[MemoryPackUnion(141, typeof(PrinterList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Printer : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Driver { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Port { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Location { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Comment { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class PrinterList : List<Printer>, IAgentMessage { }
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(30, typeof(Processor))]
|
||||
[MemoryPackUnion(31, typeof(ProcessorList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Processor : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Socket { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? DeviceId { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public uint? Cores { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public uint? LogicalCores { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public uint? CurrentSpeed { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public uint? MaxSpeed { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public uint? L1Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public uint? L2Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public uint? L3Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public bool? Virtualization { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class ProcessorList : List<Processor>, IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ProcessorMetric : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? Timestamp { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public float? ProcessorUsagePercentage { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(130, typeof(Service))]
|
||||
[MemoryPackUnion(131, typeof(ServiceList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Service : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? ProcessId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Display { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? PathName { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Account { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public bool? Delay { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public ServiceStatus? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public ServiceMode? StartMode { get; set; }
|
||||
|
||||
public enum ServiceStatus
|
||||
{
|
||||
Unknown = -1,
|
||||
Stopped = 1,
|
||||
StartPending = 2,
|
||||
StopPending = 3,
|
||||
Running = 4,
|
||||
ContinuePending = 5,
|
||||
PausePending = 6,
|
||||
Paused = 7
|
||||
}
|
||||
|
||||
public enum ServiceMode
|
||||
{
|
||||
Unknown = -1,
|
||||
Boot = 0,
|
||||
System = 1,
|
||||
Automatic = 2,
|
||||
Manual = 3,
|
||||
Disabled = 4
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class ServiceList : List<Service>, IAgentMessage { }
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(110, typeof(Session))]
|
||||
[MemoryPackUnion(111, typeof(SessionList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Session : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Sid { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? User { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Remote { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class SessionList : List<Session>, IAgentMessage { }
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(3, typeof(Status))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Status : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime Timestamp { get; } = DateTime.Now;
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public TimeSpan Uptime { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,302 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(160, typeof(StoragePool))]
|
||||
[MemoryPackUnion(161, typeof(StoragePoolList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class StoragePool : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? UniqueId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? FriendlyName { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public List<OperationalState>? States { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public HealthState? Health { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public RetireMissingPhysicalDisksEnum? RetireMissingPhysicalDisks { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Resiliency { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool? IsPrimordial { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public bool? IsReadOnly { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? IsClustered { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public ulong? AllocatedSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public ulong? SectorSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public List<PhysicalDisk>? PhysicalDisks { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public List<VirtualDisk>? VirtualDisks { get; set; }
|
||||
|
||||
public enum OperationalState
|
||||
{
|
||||
Unknown = 0,
|
||||
Other = 1,
|
||||
OK = 2,
|
||||
Degraded = 3,
|
||||
Stressed = 4,
|
||||
Predictive_Failure = 5,
|
||||
Error = 6,
|
||||
Non_Recoverable_Error = 7,
|
||||
Starting = 8,
|
||||
Stopping = 9,
|
||||
Stopped = 10,
|
||||
In_Service = 11,
|
||||
No_Contact = 12,
|
||||
Lost_Communication = 13,
|
||||
Aborted = 14,
|
||||
Dormant = 15,
|
||||
Supporting_Entity_In_Error = 16,
|
||||
Completed = 17,
|
||||
Power_Mode = 18,
|
||||
Relocating = 19
|
||||
}
|
||||
|
||||
public enum HealthState
|
||||
{
|
||||
Healthy = 0,
|
||||
Warning = 1,
|
||||
Unhealthy = 2,
|
||||
Unknown = 3
|
||||
}
|
||||
|
||||
public enum RetireMissingPhysicalDisksEnum
|
||||
{
|
||||
Auto = 1,
|
||||
Always = 2,
|
||||
Never = 3
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class StoragePoolList : List<StoragePool>, IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class PhysicalDisk : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? UniqueId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? DeviceId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? FriendlyName { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Model { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public ushort? MediaType { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public ushort? BusType { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public List<OperationalState>? States { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public HealthState? Health { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public List<SupportedUsagesEnum>? SupportedUsages { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public ushort? Usage { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public string? PhysicalLocation { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public string? FirmwareVersion { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public ulong? AllocatedSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public ulong? LogicalSectorSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(17)]
|
||||
public ulong? PhysicalSectorSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(18)]
|
||||
public ulong? VirtualDiskFootprint { get; set; }
|
||||
|
||||
public enum OperationalState
|
||||
{
|
||||
Unknown = 0,
|
||||
Other = 1,
|
||||
OK = 2,
|
||||
Degraded = 3,
|
||||
Stressed = 4,
|
||||
Predictive_Failure = 5,
|
||||
Error = 6,
|
||||
Non_Recoverable_Error = 7,
|
||||
Starting = 8,
|
||||
Stopping = 9,
|
||||
Stopped = 10,
|
||||
In_Service = 11,
|
||||
No_Contact = 12,
|
||||
Lost_Communication = 13,
|
||||
Aborted = 14,
|
||||
Dormant = 15,
|
||||
Supporting_Entity_In_Error = 16,
|
||||
Completed = 17,
|
||||
Power_Mode = 18,
|
||||
Relocating = 19
|
||||
}
|
||||
|
||||
public enum HealthState
|
||||
{
|
||||
Healthy = 0,
|
||||
Warning = 1,
|
||||
Unhealthy = 2,
|
||||
Unknown = 3
|
||||
}
|
||||
|
||||
public enum SupportedUsagesEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
Auto_Select = 1,
|
||||
Manual_Select = 2,
|
||||
Hot_Spare = 3,
|
||||
Retired = 4,
|
||||
Journal = 5
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class VirtualDisk : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? UniqueId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? FriendlyName { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public List<OperationalState>? States { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public HealthState? Health { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public AccessTypeEnum? AccessType { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public ProvisioningTypeEnum? ProvisioningType { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public ushort? PhysicalDiskRedundancy { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public string? ResiliencySettingName { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? Deduplication { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? IsSnapshot { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public ulong? AllocatedSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public ulong? FootprintOnPool { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public ulong? ReadCacheSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public ulong? WriteCacheSize { get; set; }
|
||||
|
||||
public enum OperationalState
|
||||
{
|
||||
Unknown = 0,
|
||||
Other = 1,
|
||||
OK = 2,
|
||||
Degraded = 3,
|
||||
Stressed = 4,
|
||||
Predictive_Failure = 5,
|
||||
Error = 6,
|
||||
Non_Recoverable_Error = 7,
|
||||
Starting = 8,
|
||||
Stopping = 9,
|
||||
Stopped = 10,
|
||||
In_Service = 11,
|
||||
No_Contact = 12,
|
||||
Lost_Communication = 13,
|
||||
Aborted = 14,
|
||||
Dormant = 15,
|
||||
Supporting_Entity_In_Error = 16,
|
||||
Completed = 17,
|
||||
Power_Mode = 18,
|
||||
Relocating = 19
|
||||
}
|
||||
|
||||
public enum HealthState
|
||||
{
|
||||
Healthy = 0,
|
||||
Warning = 1,
|
||||
Unhealthy = 2,
|
||||
Unknown = 3
|
||||
}
|
||||
|
||||
public enum AccessTypeEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
Readable = 1,
|
||||
Writeable = 2,
|
||||
Read_Write = 3,
|
||||
Write_Once = 4
|
||||
}
|
||||
|
||||
public enum ProvisioningTypeEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
Thin = 1,
|
||||
Fixed = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(80, typeof(SystemInfo))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class SystemInfo : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? LastBootUpTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public DateTime? LocalDateTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public uint? Processes { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? License { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(11, typeof(Trap))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Trap : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? Timestamp { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Endpoint { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Hostname { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Community { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public List<KeyValuePair<string, string?>>? Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(100, typeof(Update))]
|
||||
[MemoryPackUnion(101, typeof(UpdateList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Update : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public DateTime? Date { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? SupportUrl { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Hotfix { get; set; }
|
||||
|
||||
// if installed
|
||||
[MemoryPackOrder(6)]
|
||||
public OsUpdateResultCodeEnum? Result { get; set; }
|
||||
|
||||
// if pending
|
||||
[MemoryPackOrder(7)]
|
||||
public OsUpdateTypeEnum? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public decimal? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? IsDownloaded { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? CanRequestUserInput { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public OsUpdateRebootBehaviorEnum? RebootBehavior { get; set; }
|
||||
|
||||
public enum OsUpdateRebootBehaviorEnum
|
||||
{
|
||||
NeverReboots = 1,
|
||||
AlwaysRequiresReboot = 2,
|
||||
CanRequestReboot = 3
|
||||
}
|
||||
|
||||
public enum OsUpdateResultCodeEnum
|
||||
{
|
||||
NotStarted = 1,
|
||||
InProgress = 2,
|
||||
Succeeded = 3,
|
||||
SucceededWithErrors = 4,
|
||||
Failed = 5,
|
||||
Aborted = 6
|
||||
}
|
||||
|
||||
public enum OsUpdateTypeEnum
|
||||
{
|
||||
Software = 1,
|
||||
Driver = 2
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class UpdateList : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public List<Update>? Installed { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public List<Update>? Pending { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(150, typeof(User))]
|
||||
[MemoryPackUnion(151, typeof(UserList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class User : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Sid { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Domain { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? FullName { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public bool? LocalAccount { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool? Disabled { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public bool? Lockout { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? PasswordChangeable { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? PasswordExpires { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public bool? PasswordRequired { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public List<Group>? Groups { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class UserList : List<User>, IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Group : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Sid { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Domain { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public bool? LocalAccount { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(60, typeof(Videocard))]
|
||||
[MemoryPackUnion(61, typeof(VideocardList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Videocard : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? DeviceId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Model { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public ulong Memory { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public DateTime DriverDate { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? DriverVersion { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class VideocardList : List<Videocard>, IAgentMessage { }
|
||||
}
|
||||
|
|
@ -1,265 +0,0 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Agent.Messages
|
||||
{
|
||||
[MemoryPackUnion(170, typeof(VirtualMaschine))]
|
||||
[MemoryPackUnion(171, typeof(VirtualMaschineList))]
|
||||
public partial interface IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class VirtualMaschine : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public uint? ProcessId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Caption { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Notes { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public EnabledEnum? Enabled { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public EnabledDefaultEnum? EnabledDefault { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public HealthStatusEnum? HealthState { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public ulong? OnTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public uint? ReplicationMode { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public ReplicationStateEnum? ReplicationState { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public ReplicationHealthEnum? ReplicationHealth { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public string? ConfigurationVersion { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public IntegrationServicesVersionStateEnum? IntegrationServicesVersionState { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public uint? NumberOfProcessors { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public uint? ProcessorLoad { get; set; }
|
||||
|
||||
[MemoryPackOrder(17)]
|
||||
public int? MemoryAvailable { get; set; }
|
||||
|
||||
[MemoryPackOrder(18)]
|
||||
public ulong? MemoryUsage { get; set; }
|
||||
|
||||
[MemoryPackOrder(19)]
|
||||
public DateTime? InstallDate { get; set; }
|
||||
|
||||
[MemoryPackOrder(20)]
|
||||
public DateTime? TimeOfLastConfigurationChange { get; set; }
|
||||
|
||||
[MemoryPackOrder(21)]
|
||||
public DateTime? TimeOfLastStateChange { get; set; }
|
||||
|
||||
[MemoryPackOrder(22)]
|
||||
public DateTime? LastReplicationTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(23)]
|
||||
public string? GuestOperatingSystem { get; set; }
|
||||
|
||||
[MemoryPackOrder(24)]
|
||||
public List<VirtualMaschineConfiguration>? Configurations { get; set; }
|
||||
|
||||
public enum EnabledEnum
|
||||
{
|
||||
Unbekannt = 0,
|
||||
Andere = 1,
|
||||
Aktiviert = 2,
|
||||
Deaktiviert = 3,
|
||||
Herunterfahren = 4,
|
||||
Nicht_Verfügbar = 5,
|
||||
Aktiviert_Offline = 6,
|
||||
In_Test = 7,
|
||||
Latent = 8,
|
||||
Eingeschränkt = 9,
|
||||
Wird_gestartet = 10
|
||||
}
|
||||
|
||||
public enum EnabledDefaultEnum
|
||||
{
|
||||
Aktiviert = 2,
|
||||
Deaktiviert = 3,
|
||||
Aktiviert_Offline = 6
|
||||
}
|
||||
|
||||
public enum HealthStatusEnum
|
||||
{
|
||||
OK = 5,
|
||||
Hauptfehler = 20,
|
||||
Kritischer_Fehler = 25
|
||||
}
|
||||
|
||||
public enum ReplicationStateEnum
|
||||
{
|
||||
Deaktiviert = 0,
|
||||
Bereit = 1,
|
||||
Warten_auf_Erstreplikation = 2,
|
||||
Replikat = 3,
|
||||
Synchronisierte_Replication_abgeschlossen = 4,
|
||||
Wiederhergestellt = 5,
|
||||
Commit = 6,
|
||||
Angehalten = 7,
|
||||
Kritisch = 8,
|
||||
Warten_auf_die_Neusynchronisierung = 9,
|
||||
Resynchronisierung = 10,
|
||||
Resynchronisierung_angehalten = 11,
|
||||
Failover_in_Bearbeitung = 12,
|
||||
Failback_in_Fortschritt = 13,
|
||||
Failback_abgeschlossen = 14,
|
||||
Datenträgerupdate_in_Bearbeitung = 15,
|
||||
Datenträgeraktualisierung_kritisch = 16,
|
||||
Unbekannt = 17,
|
||||
Repurpose_Replikation_in_Bearbeitung = 18,
|
||||
Vorbereitet_für_die_Synchronisierungsreplikation = 19,
|
||||
Vorbereitet_für_die_Umgekehrte_Replikation_der_Gruppe = 20,
|
||||
Failover_in_Fortschritt = 21
|
||||
}
|
||||
|
||||
public enum ReplicationHealthEnum
|
||||
{
|
||||
OK = 1,
|
||||
Warnung = 2,
|
||||
Kritisch = 3
|
||||
}
|
||||
|
||||
public enum IntegrationServicesVersionStateEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
UpToDate = 1,
|
||||
Mismatch = 2
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class VirtualMaschineList : List<VirtualMaschine>, IAgentMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class VirtualMaschineConfiguration : IAgentMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? ParentId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Generation { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Architecture { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public AutomaticStartupActionEnum? AutomaticStartupAction { get; set; }
|
||||
//public DateTime? AutomaticStartupActionDelay { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public AutomaticShutdownActionEnum? AutomaticShutdownAction { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public AutomaticRecoveryActionEnum? AutomaticRecoveryAction { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? AutomaticSnapshotsEnabled { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public string? BaseBoardSerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public string? BIOSGUID { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public string? BIOSSerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public ushort[]? BootOrder { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public string? ConfigurationDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public string? ConfigurationFile { get; set; }
|
||||
|
||||
[MemoryPackOrder(17)]
|
||||
public string? GuestStateDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(18)]
|
||||
public string? GuestStateFile { get; set; }
|
||||
|
||||
[MemoryPackOrder(19)]
|
||||
public string? SnapshotDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(20)]
|
||||
public string? SuspendDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(21)]
|
||||
public string? SwapFileDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(22)]
|
||||
public bool? SecureBootEnabled { get; set; }
|
||||
|
||||
[MemoryPackOrder(23)]
|
||||
public bool? IsAutomaticSnapshot { get; set; }
|
||||
|
||||
[MemoryPackOrder(24)]
|
||||
public string[]? Notes { get; set; }
|
||||
|
||||
[MemoryPackOrder(25)]
|
||||
public List<VirtualMaschineConfiguration>? Childs { get; set; }
|
||||
|
||||
//public string[]? HostResource { get; set; }
|
||||
|
||||
public enum AutomaticStartupActionEnum
|
||||
{
|
||||
Nothing = 2,
|
||||
RestartIfLastStateActive = 3,
|
||||
Alway = 4
|
||||
}
|
||||
|
||||
public enum AutomaticShutdownActionEnum
|
||||
{
|
||||
Ausschalten = 2,
|
||||
Speichern = 3,
|
||||
Herunterfahren = 4
|
||||
}
|
||||
|
||||
public enum AutomaticRecoveryActionEnum
|
||||
{
|
||||
Keine = 2,
|
||||
Neustart = 3,
|
||||
Rollback = 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
<RootNamespace>Insight.Agent</RootNamespace>
|
||||
<Product>Insight</Product>
|
||||
<AssemblyName>agent</AssemblyName>
|
||||
<AssemblyVersion>2023.9.14.0</AssemblyVersion>
|
||||
<AssemblyVersion>2023.9.21.0</AssemblyVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
|
@ -27,10 +27,11 @@
|
|||
<PackageReference Include="System.Management" Version="7.0.2" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="7.0.1" />
|
||||
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.3.7" />
|
||||
<PackageReference Include="Vaitr.Snmp" Version="2023.3.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Insight.Agent.Assets\Insight.Agent.Assets.csproj" />
|
||||
<ProjectReference Include="..\..\Core\Insight.Domain\Insight.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,57 +1,56 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Vaitr.Network;
|
||||
|
||||
namespace Insight.Agent.Network
|
||||
namespace Insight.Agent.Network;
|
||||
|
||||
public class AgentSession : TcpSession<IMessage>
|
||||
{
|
||||
public class AgentSession : TcpSession<IAgentMessage>
|
||||
private readonly IEnumerable<IMessageHandler<AgentSession>> _handlers;
|
||||
|
||||
public AgentSession(IEnumerable<IMessageHandler<AgentSession>> handlers, ISerializer<IMessage> serializer, ILogger<AgentSession> logger) : base(serializer, logger)
|
||||
{
|
||||
private readonly IEnumerable<IAgentMessageHandler<AgentSession>> _handlers;
|
||||
_handlers = handlers;
|
||||
}
|
||||
|
||||
public AgentSession(IEnumerable<IAgentMessageHandler<AgentSession>> handlers, ISerializer<IAgentMessage> serializer, ILogger<AgentSession> logger) : base(serializer, logger)
|
||||
protected override ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) connected", RemoteEndPoint);
|
||||
return default;
|
||||
}
|
||||
|
||||
protected override ValueTask OnDisconnectedAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) disconnected", RemoteEndPoint);
|
||||
return default;
|
||||
}
|
||||
|
||||
protected override ValueTask OnSentAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
|
||||
{
|
||||
return base.OnSentAsync(context, cancellationToken);
|
||||
}
|
||||
|
||||
protected override async ValueTask OnReceivedAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
|
||||
{
|
||||
await base.OnReceivedAsync(context, cancellationToken);
|
||||
|
||||
foreach (var handler in _handlers)
|
||||
{
|
||||
_handlers = handlers;
|
||||
}
|
||||
|
||||
protected override ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) connected", RemoteEndPoint);
|
||||
return default;
|
||||
}
|
||||
|
||||
protected override ValueTask OnDisconnectedAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) disconnected", RemoteEndPoint);
|
||||
return default;
|
||||
}
|
||||
|
||||
protected override ValueTask OnSentAsync(IPacketContext<IAgentMessage> context, CancellationToken cancellationToken)
|
||||
{
|
||||
return base.OnSentAsync(context, cancellationToken);
|
||||
}
|
||||
|
||||
protected override async ValueTask OnReceivedAsync(IPacketContext<IAgentMessage> context, CancellationToken cancellationToken)
|
||||
{
|
||||
await base.OnReceivedAsync(context, cancellationToken);
|
||||
|
||||
foreach (var handler in _handlers)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
await handler.HandleAsync(this, context.Packet, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning("Agent ({ep?}) {ex}", RemoteEndPoint, ex.ToString());
|
||||
}
|
||||
await handler.HandleAsync(this, context.Packet, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning("Agent ({ep?}) {ex}", RemoteEndPoint, ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override ValueTask OnHeartbeatAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) Heartbeat", RemoteEndPoint);
|
||||
return default;
|
||||
}
|
||||
protected override ValueTask OnHeartbeatAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) Heartbeat", RemoteEndPoint);
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +1,38 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Agent.Models;
|
||||
using Insight.Agent.Models;
|
||||
using Insight.Agent.Services;
|
||||
using Insight.Domain.Constants;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
public class AuthenticationHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
public class AuthenticationHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is AuthenticationRequest)
|
||||
{
|
||||
if (message is AuthenticationRequest)
|
||||
Config? config = null;
|
||||
|
||||
try
|
||||
{
|
||||
Config? config = null;
|
||||
|
||||
try
|
||||
{
|
||||
config = await Configurator.ReadAsync<Config>(Configuration.DefaultConfig, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
if (config is null)
|
||||
{
|
||||
config = new Config { Serial = Guid.NewGuid() };
|
||||
await Configurator.WriteAsync(config, Configuration.DefaultConfig, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await sender.SendAsync(new Authentication
|
||||
{
|
||||
Serial = config.Serial ?? throw new InvalidDataException(nameof(config.Serial)),
|
||||
Version = Configuration.Version,
|
||||
Hostname = Configuration.Hostname
|
||||
}, cancellationToken);
|
||||
config = await Configurator.ReadAsync<Config>(Configuration.DefaultConfig, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
if (config is null)
|
||||
{
|
||||
config = new Config { Serial = Guid.NewGuid() };
|
||||
await Configurator.WriteAsync(config, Configuration.DefaultConfig, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await sender.SendAsync(new Authentication
|
||||
{
|
||||
Serial = config.Serial ?? throw new InvalidDataException(nameof(config.Serial)),
|
||||
Version = Configuration.Version,
|
||||
Hostname = Configuration.Hostname
|
||||
}, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Runspaces;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
public class ConsoleHandler : IAgentMessageHandler<AgentSession>
|
||||
public class ConsoleHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
if (message is ConsoleQueryRequest consoleQueryRequest)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,178 +1,178 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class DriveHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class DriveHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new DriveList();
|
||||
result.AddRange(GetDrives());
|
||||
var result = new DriveList();
|
||||
result.AddRange(GetDrives());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Drive> GetDrives()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select index, name, caption, model, manufacturer, serialNumber, size, status, interfacetype, firmwarerevision, deviceid, pnpdeviceid from win32_diskdrive")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_diskdrive");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var drives = new List<Drive>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var drive = new Drive();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
drive.Index = @object.GetValue<uint>(properties, "index");
|
||||
drive.Id = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
drive.Name = @object.GetValue<string>(properties, "model")?.Trim();
|
||||
drive.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
drive.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
drive.Size = @object.GetValue<ulong>(properties, "size");
|
||||
drive.Status = @object.GetValue<string>(properties, "status")?.Trim();
|
||||
drive.InterfaceType = @object.GetValue<string>(properties, "interfacetype")?.Trim();
|
||||
drive.FirmwareRevision = @object.GetValue<string>(properties, "firmwarerevision")?.Trim();
|
||||
drive.PNPDeviceID = @object.GetValue<string>(properties, "pnpdeviceid")?.Trim();
|
||||
drive.Volumes = new List<Volume>();
|
||||
|
||||
var diskpartition = @object.GetRelated("win32_diskpartition");
|
||||
using (diskpartition)
|
||||
{
|
||||
foreach (ManagementObject dp in diskpartition.Cast<ManagementObject>())
|
||||
{
|
||||
var volume = new Volume();
|
||||
var dpProperties = dp.GetPropertyHashes();
|
||||
|
||||
volume.NumberOfBlocks = dp.GetValue<ulong>(dpProperties, "numberofblocks");
|
||||
volume.BootPartition = dp.GetValue<bool>(dpProperties, "bootpartition");
|
||||
volume.PrimaryPartition = dp.GetValue<bool>(dpProperties, "primarypartition");
|
||||
volume.Size = dp.GetValue<ulong>(dpProperties, "size");
|
||||
volume.Index = dp.GetValue<uint>(dpProperties, "index");
|
||||
volume.Type = dp.GetValue<string>(dpProperties, "type")?.Trim();
|
||||
volume.Bootable = dp.GetValue<bool>(dpProperties, "bootable");
|
||||
volume.BlockSize = dp.GetValue<ulong>(dpProperties, "blocksize");
|
||||
volume.StartingOffset = dp.GetValue<ulong>(dpProperties, "startingoffset");
|
||||
|
||||
var logicaldisk = dp.GetRelated("win32_logicaldisk");
|
||||
using (logicaldisk)
|
||||
{
|
||||
foreach (ManagementObject ld in logicaldisk.Cast<ManagementObject>())
|
||||
{
|
||||
var ldProperties = ld.GetPropertyHashes();
|
||||
|
||||
volume.Id = ld.GetValue<string>(ldProperties, "deviceid")?.Trim();
|
||||
volume.Name = ld.GetValue<string>(ldProperties, "volumename")?.Trim();
|
||||
volume.SerialNumber = ld.GetValue<string>(ldProperties, "volumeserialnumber")?.Trim();
|
||||
volume.DriveType = (DriveType)ld.GetValue<uint>(ldProperties, "drivetype");
|
||||
volume.FileSystem = ld.GetValue<string>(ldProperties, "filesystem")?.Trim();
|
||||
volume.Compressed = ld.GetValue<bool>(ldProperties, "compressed");
|
||||
volume.Size = ld.GetValue<ulong>(ldProperties, "size");
|
||||
volume.FreeSpace = ld.GetValue<ulong>(ldProperties, "freespace");
|
||||
volume.ProviderName = ld.GetValue<string>(ldProperties, "providername")?.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
drive.Volumes.Add(volume);
|
||||
}
|
||||
}
|
||||
|
||||
drives.Add(drive);
|
||||
}
|
||||
}
|
||||
|
||||
return drives;
|
||||
}
|
||||
|
||||
private static List<Volume> GetVolumes()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select deviceid, volumename, volumeserialnumber, drivetype, filesystem, compressed, size, freeSpace, providername from win32_logicaldisk")
|
||||
};
|
||||
|
||||
// per device query
|
||||
// "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + driveDeviceId + "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition"
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_logicaldisk");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var volumes = new List<Volume>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var volume = new Volume();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
//volume.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
//volume.VolumeName = @object.GetValue<string>(properties, "volumename")?.Trim();
|
||||
//volume.VolumeSerialNumber = @object.GetValue<string>(properties, "volumeserialnumber")?.Trim();
|
||||
volume.DriveType = (DriveType)@object.GetValue<uint>(properties, "drivetype");
|
||||
volume.FileSystem = @object.GetValue<string>(properties, "filesystem")?.Trim();
|
||||
volume.Compressed = @object.GetValue<bool>(properties, "compressed");
|
||||
volume.Size = @object.GetValue<ulong>(properties, "size");
|
||||
volume.FreeSpace = @object.GetValue<ulong>(properties, "freespace");
|
||||
volume.ProviderName = @object.GetValue<string>(properties, "providername")?.Trim();
|
||||
|
||||
if (volume.Id is not null)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("associators of {win32_logicaldisk.deviceid='" + volume.Id + "'} where assocclass=win32_logicaldisktopartition");
|
||||
|
||||
if (searcher.TryGet(out var collection2))
|
||||
{
|
||||
using (collection2)
|
||||
{
|
||||
foreach (ManagementObject @object2 in collection2)
|
||||
{
|
||||
var properties2 = @object2.GetPropertyHashes();
|
||||
|
||||
volume.Index = @object2.GetValue<uint>(properties2, "index");
|
||||
//volume.DiskIndex = @object2.GetValue<uint>(properties2, "diskindex");
|
||||
volume.Type = @object2.GetValue<string>(properties2, "type")?.Trim();
|
||||
volume.Bootable = @object2.GetValue<bool>(properties2, "bootable");
|
||||
volume.PrimaryPartition = @object2.GetValue<bool>(properties2, "primarypartition");
|
||||
volume.BootPartition = @object2.GetValue<bool>(properties2, "bootpartition");
|
||||
volume.BlockSize = @object2.GetValue<ulong>(properties2, "blocksize");
|
||||
volume.NumberOfBlocks = @object2.GetValue<ulong>(properties2, "numberofblocks");
|
||||
volume.StartingOffset = @object2.GetValue<ulong>(properties2, "startingoffset");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volumes.Add(volume);
|
||||
}
|
||||
}
|
||||
|
||||
return volumes;
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Drive> GetDrives()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select index, name, caption, model, manufacturer, serialNumber, size, status, interfacetype, firmwarerevision, deviceid, pnpdeviceid from win32_diskdrive")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_diskdrive");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var drives = new List<Drive>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var drive = new Drive();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
drive.Index = @object.GetValue<uint>(properties, "index");
|
||||
drive.Id = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
drive.Name = @object.GetValue<string>(properties, "model")?.Trim();
|
||||
drive.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
drive.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
drive.Size = @object.GetValue<ulong>(properties, "size");
|
||||
drive.Status = @object.GetValue<string>(properties, "status")?.Trim();
|
||||
drive.InterfaceType = @object.GetValue<string>(properties, "interfacetype")?.Trim();
|
||||
drive.FirmwareRevision = @object.GetValue<string>(properties, "firmwarerevision")?.Trim();
|
||||
drive.PNPDeviceID = @object.GetValue<string>(properties, "pnpdeviceid")?.Trim();
|
||||
drive.Volumes = new List<Volume>();
|
||||
|
||||
var diskpartition = @object.GetRelated("win32_diskpartition");
|
||||
using (diskpartition)
|
||||
{
|
||||
foreach (ManagementObject dp in diskpartition.Cast<ManagementObject>())
|
||||
{
|
||||
var volume = new Volume();
|
||||
var dpProperties = dp.GetPropertyHashes();
|
||||
|
||||
volume.NumberOfBlocks = dp.GetValue<ulong>(dpProperties, "numberofblocks");
|
||||
volume.BootPartition = dp.GetValue<bool>(dpProperties, "bootpartition");
|
||||
volume.PrimaryPartition = dp.GetValue<bool>(dpProperties, "primarypartition");
|
||||
volume.Size = dp.GetValue<ulong>(dpProperties, "size");
|
||||
volume.Index = dp.GetValue<uint>(dpProperties, "index");
|
||||
volume.Type = dp.GetValue<string>(dpProperties, "type")?.Trim();
|
||||
volume.Bootable = dp.GetValue<bool>(dpProperties, "bootable");
|
||||
volume.BlockSize = dp.GetValue<ulong>(dpProperties, "blocksize");
|
||||
volume.StartingOffset = dp.GetValue<ulong>(dpProperties, "startingoffset");
|
||||
|
||||
var logicaldisk = dp.GetRelated("win32_logicaldisk");
|
||||
using (logicaldisk)
|
||||
{
|
||||
foreach (ManagementObject ld in logicaldisk.Cast<ManagementObject>())
|
||||
{
|
||||
var ldProperties = ld.GetPropertyHashes();
|
||||
|
||||
volume.Id = ld.GetValue<string>(ldProperties, "deviceid")?.Trim();
|
||||
volume.Name = ld.GetValue<string>(ldProperties, "volumename")?.Trim();
|
||||
volume.SerialNumber = ld.GetValue<string>(ldProperties, "volumeserialnumber")?.Trim();
|
||||
volume.DriveType = (DriveType)ld.GetValue<uint>(ldProperties, "drivetype");
|
||||
volume.FileSystem = ld.GetValue<string>(ldProperties, "filesystem")?.Trim();
|
||||
volume.Compressed = ld.GetValue<bool>(ldProperties, "compressed");
|
||||
volume.Size = ld.GetValue<ulong>(ldProperties, "size");
|
||||
volume.FreeSpace = ld.GetValue<ulong>(ldProperties, "freespace");
|
||||
volume.ProviderName = ld.GetValue<string>(ldProperties, "providername")?.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
drive.Volumes.Add(volume);
|
||||
}
|
||||
}
|
||||
|
||||
drives.Add(drive);
|
||||
}
|
||||
}
|
||||
|
||||
return drives;
|
||||
}
|
||||
|
||||
private static List<Volume> GetVolumes()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select deviceid, volumename, volumeserialnumber, drivetype, filesystem, compressed, size, freeSpace, providername from win32_logicaldisk")
|
||||
};
|
||||
|
||||
// per device query
|
||||
// "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + driveDeviceId + "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition"
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_logicaldisk");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var volumes = new List<Volume>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var volume = new Volume();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
//volume.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
//volume.VolumeName = @object.GetValue<string>(properties, "volumename")?.Trim();
|
||||
//volume.VolumeSerialNumber = @object.GetValue<string>(properties, "volumeserialnumber")?.Trim();
|
||||
volume.DriveType = (DriveType)@object.GetValue<uint>(properties, "drivetype");
|
||||
volume.FileSystem = @object.GetValue<string>(properties, "filesystem")?.Trim();
|
||||
volume.Compressed = @object.GetValue<bool>(properties, "compressed");
|
||||
volume.Size = @object.GetValue<ulong>(properties, "size");
|
||||
volume.FreeSpace = @object.GetValue<ulong>(properties, "freespace");
|
||||
volume.ProviderName = @object.GetValue<string>(properties, "providername")?.Trim();
|
||||
|
||||
if (volume.Id is not null)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("associators of {win32_logicaldisk.deviceid='" + volume.Id + "'} where assocclass=win32_logicaldisktopartition");
|
||||
|
||||
if (searcher.TryGet(out var collection2))
|
||||
{
|
||||
using (collection2)
|
||||
{
|
||||
foreach (ManagementObject @object2 in collection2)
|
||||
{
|
||||
var properties2 = @object2.GetPropertyHashes();
|
||||
|
||||
volume.Index = @object2.GetValue<uint>(properties2, "index");
|
||||
//volume.DiskIndex = @object2.GetValue<uint>(properties2, "diskindex");
|
||||
volume.Type = @object2.GetValue<string>(properties2, "type")?.Trim();
|
||||
volume.Bootable = @object2.GetValue<bool>(properties2, "bootable");
|
||||
volume.PrimaryPartition = @object2.GetValue<bool>(properties2, "primarypartition");
|
||||
volume.BootPartition = @object2.GetValue<bool>(properties2, "bootpartition");
|
||||
volume.BlockSize = @object2.GetValue<ulong>(properties2, "blocksize");
|
||||
volume.NumberOfBlocks = @object2.GetValue<ulong>(properties2, "numberofblocks");
|
||||
volume.StartingOffset = @object2.GetValue<ulong>(properties2, "startingoffset");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volumes.Add(volume);
|
||||
}
|
||||
}
|
||||
|
||||
return volumes;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,274 +1,274 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using Route = Insight.Agent.Messages.Route;
|
||||
using Route = Insight.Domain.Messages.Agent.Route;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class InterfaceHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new InterfaceList();
|
||||
result.AddRange(GetInterfaces());
|
||||
var result = new InterfaceList();
|
||||
result.AddRange(GetInterfaces());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Interface> GetInterfaces()
|
||||
{
|
||||
if (NetworkInterface.GetIsNetworkAvailable() is false) return null;
|
||||
if (NetworkInterface.GetAllNetworkInterfaces().Any() is false) return null;
|
||||
|
||||
var interfaces = new List<Interface>();
|
||||
|
||||
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
var ipProperties = ni.GetIPProperties();
|
||||
var ipStatistics = ni.GetIPStatistics();
|
||||
|
||||
var @interface = new Interface
|
||||
{
|
||||
Mac = ni.GetPhysicalAddress().ToString(),
|
||||
Name = ni.Name,
|
||||
Description = ni.Description,
|
||||
Type = ni.NetworkInterfaceType,
|
||||
Speed = ni.Speed,
|
||||
Status = ni.OperationalStatus,
|
||||
Suffix = ipProperties.DnsSuffix,
|
||||
Sent = ipStatistics.BytesSent,
|
||||
Received = ipStatistics.BytesReceived,
|
||||
IncomingPacketsDiscarded = ipStatistics.IncomingPacketsDiscarded,
|
||||
IncomingPacketsWithErrors = ipStatistics.IncomingPacketsWithErrors,
|
||||
IncomingUnknownProtocolPackets = ipStatistics.IncomingUnknownProtocolPackets,
|
||||
OutgoingPacketsDiscarded = ipStatistics.OutgoingPacketsDiscarded,
|
||||
OutgoingPacketsWithErrors = ipStatistics.OutgoingPacketsWithErrors
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var propertiesV4 = ipProperties.GetIPv4Properties();
|
||||
@interface.Index = uint.Parse(propertiesV4.Index.ToString());
|
||||
@interface.Ipv4Mtu = propertiesV4.Mtu;
|
||||
@interface.Ipv4Dhcp = propertiesV4.IsDhcpEnabled;
|
||||
@interface.Ipv4Forwarding = propertiesV4.IsForwardingEnabled;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
try
|
||||
{
|
||||
var propertiesV6 = ipProperties.GetIPv6Properties();
|
||||
@interface.Index = uint.Parse(propertiesV6.Index.ToString());
|
||||
@interface.Ipv6Mtu = propertiesV6.Mtu;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
@interface.Gateways = GetAddresses(ipProperties.GatewayAddresses);
|
||||
@interface.Addresses = GetAddresses(ipProperties.UnicastAddresses);
|
||||
@interface.Dns = GetAddresses(ipProperties.DnsAddresses);
|
||||
@interface.Dhcp = GetAddresses(ipProperties.DhcpServerAddresses);
|
||||
|
||||
if (@interface.Index.HasValue)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery($"select interfaceindex, guid, physicaladapter, manufacturer from win32_networkadapter where interfaceindex = {@interface.Index}")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery($"select * from win32_networkadapter where interfaceindex = {@interface.Index}");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
@interface.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
@interface.Guid = @object.GetValue<Guid>(properties, "guid");
|
||||
@interface.Physical = @object.GetValue<bool>(properties, "physicaladapter");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@interface.Routes = QueryInterfaceRoutes(@interface.Index.Value);
|
||||
}
|
||||
}
|
||||
|
||||
interfaces.Add(@interface);
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
private static List<Route> QueryInterfaceRoutes(uint interfaceIndex)
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\standardcimv2"),
|
||||
Query = new ObjectQuery($"select addressFamily, state, interfaceindex, routemetric, nexthop, destinationprefix from msft_netroute where interfaceindex = {interfaceIndex}")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery($"select * from msft_netroute where interfaceindex = {interfaceIndex}");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var routes = new List<Route>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (var @object in collection)
|
||||
{
|
||||
var route = new Route
|
||||
{
|
||||
InterfaceIndex = interfaceIndex
|
||||
};
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "routemetric", out var routemetric))
|
||||
{
|
||||
if (int.TryParse(routemetric?.ToString(), out var metric)) route.Metric = metric;
|
||||
}
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "nexthop", out var nexthop))
|
||||
{
|
||||
if (IPAddress.TryParse(nexthop?.ToString(), out var gateway)) route.Gateway = new IPAddress2(gateway);
|
||||
}
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "destinationprefix", out var destinationprefix))
|
||||
{
|
||||
var split = destinationprefix?.ToString()?.Split('/');
|
||||
var cidrData = split?[1];
|
||||
|
||||
if (IPAddress.TryParse(split?[0], out var destination))
|
||||
route.Destination = new IPAddress2(destination);
|
||||
|
||||
if (int.TryParse(cidrData, out var cidr))
|
||||
{
|
||||
var mask = ConvertCidr(cidr);
|
||||
route.Mask = mask;
|
||||
}
|
||||
}
|
||||
|
||||
routes.Add(route);
|
||||
}
|
||||
}
|
||||
|
||||
return routes;
|
||||
}
|
||||
|
||||
private static List<Unicast> GetAddresses(UnicastIPAddressInformationCollection unicastCollection)
|
||||
{
|
||||
var addresses = new List<Unicast>();
|
||||
|
||||
if (unicastCollection.Any() is false) return addresses;
|
||||
|
||||
foreach (var unicast in unicastCollection)
|
||||
{
|
||||
addresses.Add(new Unicast
|
||||
{
|
||||
IpAddress = new IPAddress2(unicast.Address),
|
||||
AddressPreferredLifetime = unicast.AddressPreferredLifetime,
|
||||
AddressValidLifetime = unicast.AddressValidLifetime,
|
||||
DuplicateAddressDetectionState = unicast.DuplicateAddressDetectionState,
|
||||
Ipv4Mask = new IPAddress2(unicast.IPv4Mask),
|
||||
PrefixLength = unicast.PrefixLength,
|
||||
PrefixOrigin = unicast.PrefixOrigin,
|
||||
SuffixOrigin = unicast.SuffixOrigin,
|
||||
DhcpLeaseLifetime = unicast.DhcpLeaseLifetime,
|
||||
});
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
private static List<IPAddress2> GetAddresses(IPAddressCollection addressCollection)
|
||||
{
|
||||
var addresses = new List<IPAddress2>();
|
||||
|
||||
if (addressCollection.Any() is false) return addresses;
|
||||
|
||||
foreach (var address in addressCollection)
|
||||
{
|
||||
addresses.Add(new IPAddress2(address));
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
private static List<IPAddress2> GetAddresses(GatewayIPAddressInformationCollection addressCollection)
|
||||
{
|
||||
var addresses = new List<IPAddress2>();
|
||||
|
||||
if (addressCollection.Any() is false) return addresses;
|
||||
|
||||
foreach (var address in addressCollection)
|
||||
{
|
||||
addresses.Add(new IPAddress2(address.Address));
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
private static string? ConvertCidr(int cidr)
|
||||
{
|
||||
return cidr switch
|
||||
{
|
||||
0 => "0.0.0.0",
|
||||
1 => "128.0.0.0",
|
||||
2 => "192.0.0.0",
|
||||
3 => "224.0.0.0",
|
||||
4 => "240.0.0.0",
|
||||
5 => "248.0.0.0",
|
||||
6 => "252.0.0.0",
|
||||
7 => "254.0.0.0",
|
||||
8 => "255.0.0.0",
|
||||
9 => "255.128.0.0",
|
||||
10 => "255.192.0.0",
|
||||
11 => "255.224.0.0",
|
||||
12 => "255.240.0.0",
|
||||
13 => "255.248.0.0",
|
||||
14 => "255.252.0.0",
|
||||
15 => "255.254.0.0",
|
||||
16 => "255.255.0.0",
|
||||
17 => "255.255.128.0",
|
||||
18 => "255.255.192.0",
|
||||
19 => "255.255.224.0",
|
||||
20 => "255.255.240.0",
|
||||
21 => "255.255.248.0",
|
||||
22 => "255.255.252.0",
|
||||
23 => "255.255.254.0",
|
||||
24 => "255.255.255.0",
|
||||
25 => "255.255.255.128",
|
||||
26 => "255.255.255.192",
|
||||
27 => "255.255.255.224",
|
||||
28 => "255.255.255.240",
|
||||
29 => "255.255.255.248",
|
||||
30 => "255.255.255.252",
|
||||
31 => "255.255.255.254",
|
||||
32 => "255.255.255.255",
|
||||
_ => null,
|
||||
};
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Interface> GetInterfaces()
|
||||
{
|
||||
if (NetworkInterface.GetIsNetworkAvailable() is false) return null;
|
||||
if (NetworkInterface.GetAllNetworkInterfaces().Any() is false) return null;
|
||||
|
||||
var interfaces = new List<Interface>();
|
||||
|
||||
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
var ipProperties = ni.GetIPProperties();
|
||||
var ipStatistics = ni.GetIPStatistics();
|
||||
|
||||
var @interface = new Interface
|
||||
{
|
||||
Mac = ni.GetPhysicalAddress().ToString(),
|
||||
Name = ni.Name,
|
||||
Description = ni.Description,
|
||||
Type = ni.NetworkInterfaceType,
|
||||
Speed = ni.Speed,
|
||||
Status = ni.OperationalStatus,
|
||||
Suffix = ipProperties.DnsSuffix,
|
||||
Sent = ipStatistics.BytesSent,
|
||||
Received = ipStatistics.BytesReceived,
|
||||
IncomingPacketsDiscarded = ipStatistics.IncomingPacketsDiscarded,
|
||||
IncomingPacketsWithErrors = ipStatistics.IncomingPacketsWithErrors,
|
||||
IncomingUnknownProtocolPackets = ipStatistics.IncomingUnknownProtocolPackets,
|
||||
OutgoingPacketsDiscarded = ipStatistics.OutgoingPacketsDiscarded,
|
||||
OutgoingPacketsWithErrors = ipStatistics.OutgoingPacketsWithErrors
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var propertiesV4 = ipProperties.GetIPv4Properties();
|
||||
@interface.Index = uint.Parse(propertiesV4.Index.ToString());
|
||||
@interface.Ipv4Mtu = propertiesV4.Mtu;
|
||||
@interface.Ipv4Dhcp = propertiesV4.IsDhcpEnabled;
|
||||
@interface.Ipv4Forwarding = propertiesV4.IsForwardingEnabled;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
try
|
||||
{
|
||||
var propertiesV6 = ipProperties.GetIPv6Properties();
|
||||
@interface.Index = uint.Parse(propertiesV6.Index.ToString());
|
||||
@interface.Ipv6Mtu = propertiesV6.Mtu;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
@interface.Gateways = GetAddresses(ipProperties.GatewayAddresses);
|
||||
@interface.Addresses = GetAddresses(ipProperties.UnicastAddresses);
|
||||
@interface.Dns = GetAddresses(ipProperties.DnsAddresses);
|
||||
@interface.Dhcp = GetAddresses(ipProperties.DhcpServerAddresses);
|
||||
|
||||
if (@interface.Index.HasValue)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery($"select interfaceindex, guid, physicaladapter, manufacturer from win32_networkadapter where interfaceindex = {@interface.Index}")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery($"select * from win32_networkadapter where interfaceindex = {@interface.Index}");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
@interface.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
@interface.Guid = @object.GetValue<Guid>(properties, "guid");
|
||||
@interface.Physical = @object.GetValue<bool>(properties, "physicaladapter");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@interface.Routes = QueryInterfaceRoutes(@interface.Index.Value);
|
||||
}
|
||||
}
|
||||
|
||||
interfaces.Add(@interface);
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
private static List<Route> QueryInterfaceRoutes(uint interfaceIndex)
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\standardcimv2"),
|
||||
Query = new ObjectQuery($"select addressFamily, state, interfaceindex, routemetric, nexthop, destinationprefix from msft_netroute where interfaceindex = {interfaceIndex}")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery($"select * from msft_netroute where interfaceindex = {interfaceIndex}");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var routes = new List<Route>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (var @object in collection)
|
||||
{
|
||||
var route = new Route
|
||||
{
|
||||
InterfaceIndex = interfaceIndex
|
||||
};
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "routemetric", out var routemetric))
|
||||
{
|
||||
if (int.TryParse(routemetric?.ToString(), out var metric)) route.Metric = metric;
|
||||
}
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "nexthop", out var nexthop))
|
||||
{
|
||||
if (IPAddress.TryParse(nexthop?.ToString(), out var gateway)) route.Gateway = new IPAddress2(gateway);
|
||||
}
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "destinationprefix", out var destinationprefix))
|
||||
{
|
||||
var split = destinationprefix?.ToString()?.Split('/');
|
||||
var cidrData = split?[1];
|
||||
|
||||
if (IPAddress.TryParse(split?[0], out var destination))
|
||||
route.Destination = new IPAddress2(destination);
|
||||
|
||||
if (int.TryParse(cidrData, out var cidr))
|
||||
{
|
||||
var mask = ConvertCidr(cidr);
|
||||
route.Mask = mask;
|
||||
}
|
||||
}
|
||||
|
||||
routes.Add(route);
|
||||
}
|
||||
}
|
||||
|
||||
return routes;
|
||||
}
|
||||
|
||||
private static List<Unicast> GetAddresses(UnicastIPAddressInformationCollection unicastCollection)
|
||||
{
|
||||
var addresses = new List<Unicast>();
|
||||
|
||||
if (unicastCollection.Any() is false) return addresses;
|
||||
|
||||
foreach (var unicast in unicastCollection)
|
||||
{
|
||||
addresses.Add(new Unicast
|
||||
{
|
||||
IpAddress = new IPAddress2(unicast.Address),
|
||||
AddressPreferredLifetime = unicast.AddressPreferredLifetime,
|
||||
AddressValidLifetime = unicast.AddressValidLifetime,
|
||||
DuplicateAddressDetectionState = unicast.DuplicateAddressDetectionState,
|
||||
Ipv4Mask = new IPAddress2(unicast.IPv4Mask),
|
||||
PrefixLength = unicast.PrefixLength,
|
||||
PrefixOrigin = unicast.PrefixOrigin,
|
||||
SuffixOrigin = unicast.SuffixOrigin,
|
||||
DhcpLeaseLifetime = unicast.DhcpLeaseLifetime,
|
||||
});
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
private static List<IPAddress2> GetAddresses(IPAddressCollection addressCollection)
|
||||
{
|
||||
var addresses = new List<IPAddress2>();
|
||||
|
||||
if (addressCollection.Any() is false) return addresses;
|
||||
|
||||
foreach (var address in addressCollection)
|
||||
{
|
||||
addresses.Add(new IPAddress2(address));
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
private static List<IPAddress2> GetAddresses(GatewayIPAddressInformationCollection addressCollection)
|
||||
{
|
||||
var addresses = new List<IPAddress2>();
|
||||
|
||||
if (addressCollection.Any() is false) return addresses;
|
||||
|
||||
foreach (var address in addressCollection)
|
||||
{
|
||||
addresses.Add(new IPAddress2(address.Address));
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
private static string? ConvertCidr(int cidr)
|
||||
{
|
||||
return cidr switch
|
||||
{
|
||||
0 => "0.0.0.0",
|
||||
1 => "128.0.0.0",
|
||||
2 => "192.0.0.0",
|
||||
3 => "224.0.0.0",
|
||||
4 => "240.0.0.0",
|
||||
5 => "248.0.0.0",
|
||||
6 => "252.0.0.0",
|
||||
7 => "254.0.0.0",
|
||||
8 => "255.0.0.0",
|
||||
9 => "255.128.0.0",
|
||||
10 => "255.192.0.0",
|
||||
11 => "255.224.0.0",
|
||||
12 => "255.240.0.0",
|
||||
13 => "255.248.0.0",
|
||||
14 => "255.252.0.0",
|
||||
15 => "255.254.0.0",
|
||||
16 => "255.255.0.0",
|
||||
17 => "255.255.128.0",
|
||||
18 => "255.255.192.0",
|
||||
19 => "255.255.224.0",
|
||||
20 => "255.255.240.0",
|
||||
21 => "255.255.248.0",
|
||||
22 => "255.255.252.0",
|
||||
23 => "255.255.254.0",
|
||||
24 => "255.255.255.0",
|
||||
25 => "255.255.255.128",
|
||||
26 => "255.255.255.192",
|
||||
27 => "255.255.255.224",
|
||||
28 => "255.255.255.240",
|
||||
29 => "255.255.255.248",
|
||||
30 => "255.255.255.252",
|
||||
31 => "255.255.255.254",
|
||||
32 => "255.255.255.255",
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,86 +1,86 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class MainboardHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class MainboardHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
await sender.SendAsync(GetMainboard(), cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static Mainboard GetMainboard()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select manufacturer, product, serialnumber from win32_baseboard")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_baseboard");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var mainboard = new Mainboard();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
mainboard.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
mainboard.Model = @object.GetValue<string>(properties, "product")?.Trim();
|
||||
mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
searcher.Query = new ObjectQuery("select manufacturer, serialnumber, smbiosbiosversion, releasedate from win32_bios");
|
||||
|
||||
if (searcher.TryGet(out var collection2) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_bios");
|
||||
|
||||
if (searcher.TryGet(out collection2) is false) return null;
|
||||
}
|
||||
|
||||
using (collection2)
|
||||
{
|
||||
foreach (ManagementObject @object in collection2.Cast<ManagementObject>())
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
mainboard.BiosManufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
mainboard.BiosVersion = @object.GetValue<string>(properties, "smbiosbiosversion")?.Trim();
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "releasedate", out var releasedate))
|
||||
{
|
||||
mainboard.BiosDate = ManagementDateTimeConverter.ToDateTime(releasedate?.ToString());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Logger.LogWarning(JsonSerializer.Serialize(mainboard, new JsonSerializerOptions
|
||||
//{
|
||||
// WriteIndented= true
|
||||
//}));
|
||||
|
||||
return mainboard;
|
||||
await sender.SendAsync(GetMainboard(), cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static Mainboard GetMainboard()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select manufacturer, product, serialnumber from win32_baseboard")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_baseboard");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var mainboard = new Mainboard();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
mainboard.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
mainboard.Model = @object.GetValue<string>(properties, "product")?.Trim();
|
||||
mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
searcher.Query = new ObjectQuery("select manufacturer, serialnumber, smbiosbiosversion, releasedate from win32_bios");
|
||||
|
||||
if (searcher.TryGet(out var collection2) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_bios");
|
||||
|
||||
if (searcher.TryGet(out collection2) is false) return null;
|
||||
}
|
||||
|
||||
using (collection2)
|
||||
{
|
||||
foreach (ManagementObject @object in collection2.Cast<ManagementObject>())
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
mainboard.BiosManufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
mainboard.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
mainboard.BiosVersion = @object.GetValue<string>(properties, "smbiosbiosversion")?.Trim();
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "releasedate", out var releasedate))
|
||||
{
|
||||
mainboard.BiosDate = ManagementDateTimeConverter.ToDateTime(releasedate?.ToString());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Logger.LogWarning(JsonSerializer.Serialize(mainboard, new JsonSerializerOptions
|
||||
//{
|
||||
// WriteIndented= true
|
||||
//}));
|
||||
|
||||
return mainboard;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +1,123 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class MemoryHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class MemoryHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new MemoryList();
|
||||
result.AddRange(GetMemory());
|
||||
var result = new MemoryList();
|
||||
result.AddRange(GetMemory());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
|
||||
private static List<Memory> GetMemory()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select tag, devicelocator, manufacturer, partnumber, serialnumber, capacity, speed, maxvoltage, configuredclockspeed, configuredvoltage from win32_physicalmemory")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_physicalmemory");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var memorysticks = new List<Memory>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
uint index = 0;
|
||||
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var @memory = new Memory();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
@memory.Index = index;
|
||||
@memory.Tag = @object.GetValue<string>(properties, "tag")?.Trim();
|
||||
@memory.Location = @object.GetValue<string>(properties, "devicelocator")?.Trim();
|
||||
@memory.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
@memory.Model = @object.GetValue<string>(properties, "partnumber")?.Trim();
|
||||
@memory.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
@memory.Capacity = @object.GetValue<ulong>(properties, "capacity");
|
||||
@memory.Speed = @object.GetValue<uint>(properties, "speed");
|
||||
@memory.Voltage = @object.GetValue<uint>(properties, "maxvoltage");
|
||||
@memory.ConfiguredSpeed = @object.GetValue<uint>(properties, "configuredclockspeed");
|
||||
@memory.ConfiguredVoltage = @object.GetValue<uint>(properties, "configuredvoltage");
|
||||
|
||||
memorysticks.Add(@memory);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return memorysticks;
|
||||
}
|
||||
|
||||
//private async ValueTask<Memory.Metric> GetMemoryMetricAsync(CancellationToken cancellationToken)
|
||||
//{
|
||||
// var metric = new Memory.Metric();
|
||||
|
||||
// using var searcher = new ManagementObjectSearcher
|
||||
// {
|
||||
// Scope = new ManagementScope(@"root\cimv2"),
|
||||
// Query = new ObjectQuery("select totalphysicalmemory from win32_computersystem")
|
||||
// };
|
||||
|
||||
// if (searcher.TryGet(out var collection) is false)
|
||||
// {
|
||||
// searcher.Query = new ObjectQuery("select * from win32_computersystem");
|
||||
|
||||
// if (searcher.TryGet(out collection) is false) return metric;
|
||||
// }
|
||||
|
||||
// ulong capacity = 0;
|
||||
|
||||
// using (collection)
|
||||
// {
|
||||
// foreach (var @object in collection)
|
||||
// {
|
||||
// var properties = @object.GetPropertyHashes();
|
||||
|
||||
// if (@object.TryGetValue(properties, "totalphysicalmemory", out capacity))
|
||||
// {
|
||||
// capacity = capacity / 1024 / 1024;
|
||||
// }
|
||||
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (MemoryAvailableCounter is null)
|
||||
// {
|
||||
// MemoryAvailableCounter = new PerformanceCounter
|
||||
// {
|
||||
// CategoryName = "Memory",
|
||||
// CounterName = "Available MBytes"
|
||||
// };
|
||||
|
||||
// metric.MemoryAvailable = MemoryAvailableCounter.NextValue();
|
||||
// await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
|
||||
// }
|
||||
|
||||
// metric.Timestamp = DateTime.Now;
|
||||
// metric.MemoryAvailable = MemoryAvailableCounter.NextValue();
|
||||
// metric.MemoryUsed = capacity - metric.MemoryAvailable;
|
||||
// metric.MemoryUsagePercentage = metric.MemoryUsed / capacity * 100;
|
||||
// metric.MemoryAvailablePercentage = 100 - metric.MemoryUsagePercentage;
|
||||
// return metric;
|
||||
//}
|
||||
}
|
||||
|
||||
private static List<Memory> GetMemory()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select tag, devicelocator, manufacturer, partnumber, serialnumber, capacity, speed, maxvoltage, configuredclockspeed, configuredvoltage from win32_physicalmemory")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_physicalmemory");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var memorysticks = new List<Memory>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
uint index = 0;
|
||||
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var @memory = new Memory();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
@memory.Index = index;
|
||||
@memory.Tag = @object.GetValue<string>(properties, "tag")?.Trim();
|
||||
@memory.Location = @object.GetValue<string>(properties, "devicelocator")?.Trim();
|
||||
@memory.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
@memory.Model = @object.GetValue<string>(properties, "partnumber")?.Trim();
|
||||
@memory.Serial = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
@memory.Capacity = @object.GetValue<ulong>(properties, "capacity");
|
||||
@memory.Speed = @object.GetValue<uint>(properties, "speed");
|
||||
@memory.Voltage = @object.GetValue<uint>(properties, "maxvoltage");
|
||||
@memory.ConfiguredSpeed = @object.GetValue<uint>(properties, "configuredclockspeed");
|
||||
@memory.ConfiguredVoltage = @object.GetValue<uint>(properties, "configuredvoltage");
|
||||
|
||||
memorysticks.Add(@memory);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return memorysticks;
|
||||
}
|
||||
|
||||
//private async ValueTask<Memory.Metric> GetMemoryMetricAsync(CancellationToken cancellationToken)
|
||||
//{
|
||||
// var metric = new Memory.Metric();
|
||||
|
||||
// using var searcher = new ManagementObjectSearcher
|
||||
// {
|
||||
// Scope = new ManagementScope(@"root\cimv2"),
|
||||
// Query = new ObjectQuery("select totalphysicalmemory from win32_computersystem")
|
||||
// };
|
||||
|
||||
// if (searcher.TryGet(out var collection) is false)
|
||||
// {
|
||||
// searcher.Query = new ObjectQuery("select * from win32_computersystem");
|
||||
|
||||
// if (searcher.TryGet(out collection) is false) return metric;
|
||||
// }
|
||||
|
||||
// ulong capacity = 0;
|
||||
|
||||
// using (collection)
|
||||
// {
|
||||
// foreach (var @object in collection)
|
||||
// {
|
||||
// var properties = @object.GetPropertyHashes();
|
||||
|
||||
// if (@object.TryGetValue(properties, "totalphysicalmemory", out capacity))
|
||||
// {
|
||||
// capacity = capacity / 1024 / 1024;
|
||||
// }
|
||||
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (MemoryAvailableCounter is null)
|
||||
// {
|
||||
// MemoryAvailableCounter = new PerformanceCounter
|
||||
// {
|
||||
// CategoryName = "Memory",
|
||||
// CounterName = "Available MBytes"
|
||||
// };
|
||||
|
||||
// metric.MemoryAvailable = MemoryAvailableCounter.NextValue();
|
||||
// await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
|
||||
// }
|
||||
|
||||
// metric.Timestamp = DateTime.Now;
|
||||
// metric.MemoryAvailable = MemoryAvailableCounter.NextValue();
|
||||
// metric.MemoryUsed = capacity - metric.MemoryAvailable;
|
||||
// metric.MemoryUsagePercentage = metric.MemoryUsed / capacity * 100;
|
||||
// metric.MemoryAvailablePercentage = 100 - metric.MemoryUsagePercentage;
|
||||
// return metric;
|
||||
//}
|
||||
}
|
||||
|
|
@ -1,91 +1,91 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Microsoft.Win32;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security.AccessControl;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class OperationSystemHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class OperationSystemHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
await sender.SendAsync(GetOperatingSystem(), cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static OperationSystem GetOperatingSystem()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select caption, version, serialnumber, osarchitecture, installdate from win32_operatingsystem")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_operatingsystem");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var os = new OperationSystem();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
os.Name = @object.GetValue<string>(properties, "caption")?.Trim();
|
||||
os.Version = @object.GetValue<string>(properties, "version")?.Trim();
|
||||
os.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
|
||||
if (@object.TryGetValue<string>(properties, "osarchitecture", out var architecture))
|
||||
{
|
||||
if (architecture is not null && architecture.ToLower().Contains("64")) os.Architecture = Architecture.X64;
|
||||
}
|
||||
else
|
||||
{
|
||||
os.Architecture = Architecture.X86;
|
||||
}
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "installdate", out var installdate))
|
||||
{
|
||||
os.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
using var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
|
||||
using var key = registry.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
|
||||
|
||||
if (key is not null && key?.GetValue("UBR")?.ToString() is string buildNumber)
|
||||
{
|
||||
os.Version = $"{os.Version}.{buildNumber}";
|
||||
}
|
||||
|
||||
searcher.Query = new ObjectQuery("select * from win32_portconnector");
|
||||
|
||||
if (searcher.TryGet(out var collection2) is false)
|
||||
{
|
||||
os.Virtual = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
os.Virtual = false;
|
||||
}
|
||||
|
||||
collection2.Dispose();
|
||||
|
||||
return os;
|
||||
await sender.SendAsync(GetOperatingSystem(), cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static OperationSystem GetOperatingSystem()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select caption, version, serialnumber, osarchitecture, installdate from win32_operatingsystem")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_operatingsystem");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var os = new OperationSystem();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
os.Name = @object.GetValue<string>(properties, "caption")?.Trim();
|
||||
os.Version = @object.GetValue<string>(properties, "version")?.Trim();
|
||||
os.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
|
||||
if (@object.TryGetValue<string>(properties, "osarchitecture", out var architecture))
|
||||
{
|
||||
if (architecture is not null && architecture.ToLower().Contains("64")) os.Architecture = Architecture.X64;
|
||||
}
|
||||
else
|
||||
{
|
||||
os.Architecture = Architecture.X86;
|
||||
}
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "installdate", out var installdate))
|
||||
{
|
||||
os.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
using var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
|
||||
using var key = registry.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
|
||||
|
||||
if (key is not null && key?.GetValue("UBR")?.ToString() is string buildNumber)
|
||||
{
|
||||
os.Version = $"{os.Version}.{buildNumber}";
|
||||
}
|
||||
|
||||
searcher.Query = new ObjectQuery("select * from win32_portconnector");
|
||||
|
||||
if (searcher.TryGet(out var collection2) is false)
|
||||
{
|
||||
os.Virtual = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
os.Virtual = false;
|
||||
}
|
||||
|
||||
collection2.Dispose();
|
||||
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +1,60 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class PrinterHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class PrinterHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new PrinterList();
|
||||
result.AddRange(GetPrinters());
|
||||
var result = new PrinterList();
|
||||
result.AddRange(GetPrinters());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Printer> GetPrinters()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select drivername, name, portname, location, comment from win32_printer")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_printer");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var printers = new List<Printer>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var printer = new Printer();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
printer.Driver = @object.GetValue<string>(properties, "drivername")?.Trim();
|
||||
printer.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
printer.Port = @object.GetValue<string>(properties, "portname")?.Trim();
|
||||
printer.Location = @object.GetValue<string>(properties, "location")?.Trim();
|
||||
printer.Comment = @object.GetValue<string>(properties, "comment")?.Trim();
|
||||
|
||||
printers.Add(printer);
|
||||
}
|
||||
}
|
||||
|
||||
return printers;
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Printer> GetPrinters()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select drivername, name, portname, location, comment from win32_printer")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_printer");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var printers = new List<Printer>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var printer = new Printer();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
printer.Driver = @object.GetValue<string>(properties, "drivername")?.Trim();
|
||||
printer.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
printer.Port = @object.GetValue<string>(properties, "portname")?.Trim();
|
||||
printer.Location = @object.GetValue<string>(properties, "location")?.Trim();
|
||||
printer.Comment = @object.GetValue<string>(properties, "comment")?.Trim();
|
||||
|
||||
printers.Add(printer);
|
||||
}
|
||||
}
|
||||
|
||||
return printers;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,143 +1,143 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class ProcessorHandler : IAgentMessageHandler<AgentSession>
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new ProcessorList();
|
||||
result.AddRange(GetProcessors());
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class ProcessorHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
var result = new ProcessorList();
|
||||
result.AddRange(GetProcessors());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Processor> GetProcessors()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select deviceid, name, manufacturer, socketdesignation, version, processorid, l2cachesize, l3cachesize, currentclockspeed, maxclockspeed, numberofcores, numberoflogicalprocessors, virtualizationfirmwareenabled from win32_processor")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_processor");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
private static List<Processor> GetProcessors()
|
||||
var processors = new List<Processor>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
uint index = 0;
|
||||
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select deviceid, name, manufacturer, socketdesignation, version, processorid, l2cachesize, l3cachesize, currentclockspeed, maxclockspeed, numberofcores, numberoflogicalprocessors, virtualizationfirmwareenabled from win32_processor")
|
||||
};
|
||||
var processor = new Processor();
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_processor");
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
processor.Index = index;
|
||||
processor.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
processor.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
processor.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
processor.Socket = @object.GetValue<string>(properties, "socketdesignation")?.Trim();
|
||||
processor.Version = @object.GetValue<string>(properties, "version")?.Trim();
|
||||
processor.SerialNumber = @object.GetValue<string>(properties, "processorid")?.Trim();
|
||||
processor.CurrentSpeed = @object.GetValue<uint>(properties, "currentclockspeed");
|
||||
processor.MaxSpeed = @object.GetValue<uint>(properties, "maxclockspeed");
|
||||
processor.Cores = @object.GetValue<uint>(properties, "numberofcores");
|
||||
processor.LogicalCores = @object.GetValue<uint>(properties, "numberoflogicalprocessors");
|
||||
processor.Virtualization = @object.GetValue<bool>(properties, "virtualizationfirmwareenabled");
|
||||
|
||||
var processors = new List<Processor>();
|
||||
searcher.Query = new ObjectQuery("select level, maxcachesize from win32_cachememory");
|
||||
|
||||
using (collection)
|
||||
{
|
||||
uint index = 0;
|
||||
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
if (searcher.TryGet(out var collection2) is false)
|
||||
{
|
||||
var processor = new Processor();
|
||||
searcher.Query = new ObjectQuery("select * from win32_cachememory");
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
if (searcher.TryGet(out collection2) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
processor.Index = index;
|
||||
processor.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
processor.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
processor.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
processor.Socket = @object.GetValue<string>(properties, "socketdesignation")?.Trim();
|
||||
processor.Version = @object.GetValue<string>(properties, "version")?.Trim();
|
||||
processor.SerialNumber = @object.GetValue<string>(properties, "processorid")?.Trim();
|
||||
processor.CurrentSpeed = @object.GetValue<uint>(properties, "currentclockspeed");
|
||||
processor.MaxSpeed = @object.GetValue<uint>(properties, "maxclockspeed");
|
||||
processor.Cores = @object.GetValue<uint>(properties, "numberofcores");
|
||||
processor.LogicalCores = @object.GetValue<uint>(properties, "numberoflogicalprocessors");
|
||||
processor.Virtualization = @object.GetValue<bool>(properties, "virtualizationfirmwareenabled");
|
||||
|
||||
searcher.Query = new ObjectQuery("select level, maxcachesize from win32_cachememory");
|
||||
|
||||
if (searcher.TryGet(out var collection2) is false)
|
||||
using (collection2)
|
||||
{
|
||||
foreach (ManagementObject @object2 in collection2.Cast<ManagementObject>())
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_cachememory");
|
||||
var properties2 = @object2.GetPropertyHashes();
|
||||
|
||||
if (searcher.TryGet(out collection2) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
ProcessorCacheLevelEnum? cacheLevel = null;
|
||||
|
||||
using (collection2)
|
||||
{
|
||||
foreach (ManagementObject @object2 in collection2.Cast<ManagementObject>())
|
||||
cacheLevel = (ProcessorCacheLevelEnum?)@object2.GetValue<ushort>(properties2, "level");
|
||||
|
||||
if (cacheLevel is null) continue;
|
||||
|
||||
var installedSize = @object2.GetValue<uint>(properties2, "maxcachesize");
|
||||
|
||||
switch (cacheLevel)
|
||||
{
|
||||
var properties2 = @object2.GetPropertyHashes();
|
||||
|
||||
ProcessorCacheLevelEnum? cacheLevel = null;
|
||||
|
||||
cacheLevel = (ProcessorCacheLevelEnum?)@object2.GetValue<ushort>(properties2, "level");
|
||||
|
||||
if (cacheLevel is null) continue;
|
||||
|
||||
var installedSize = @object2.GetValue<uint>(properties2, "maxcachesize");
|
||||
|
||||
switch (cacheLevel)
|
||||
{
|
||||
case ProcessorCacheLevelEnum.L1:
|
||||
{
|
||||
processor.L1Size = installedSize;
|
||||
break;
|
||||
}
|
||||
case ProcessorCacheLevelEnum.L2:
|
||||
{
|
||||
processor.L2Size = installedSize;
|
||||
break;
|
||||
}
|
||||
case ProcessorCacheLevelEnum.L3:
|
||||
{
|
||||
processor.L3Size = installedSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ProcessorCacheLevelEnum.L1:
|
||||
{
|
||||
processor.L1Size = installedSize;
|
||||
break;
|
||||
}
|
||||
case ProcessorCacheLevelEnum.L2:
|
||||
{
|
||||
processor.L2Size = installedSize;
|
||||
break;
|
||||
}
|
||||
case ProcessorCacheLevelEnum.L3:
|
||||
{
|
||||
processor.L3Size = installedSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processors.Add(processor);
|
||||
index++;
|
||||
}
|
||||
|
||||
processors.Add(processor);
|
||||
index++;
|
||||
}
|
||||
|
||||
return processors;
|
||||
}
|
||||
|
||||
private enum ProcessorCacheLevelEnum
|
||||
{
|
||||
L1 = 3,
|
||||
L2 = 4,
|
||||
L3 = 5,
|
||||
}
|
||||
|
||||
//private async ValueTask<Processor.Metric?> GetProcessorMetricAsync(CancellationToken cancellationToken)
|
||||
//{
|
||||
// var metric = new Processor.Metric();
|
||||
|
||||
// if (ProcessorTimeCounter is null)
|
||||
// {
|
||||
// ProcessorTimeCounter = new PerformanceCounter
|
||||
// {
|
||||
// CategoryName = "Processor",
|
||||
// CounterName = "% Processor Time",
|
||||
// InstanceName = "_Total"
|
||||
// };
|
||||
|
||||
// metric.ProcessorUsagePercentage = ProcessorTimeCounter.NextValue();
|
||||
// await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
|
||||
// }
|
||||
|
||||
// metric.Timestamp = DateTime.Now;
|
||||
// metric.ProcessorUsagePercentage = ProcessorTimeCounter?.NextValue();
|
||||
// return metric;
|
||||
//}
|
||||
return processors;
|
||||
}
|
||||
|
||||
private enum ProcessorCacheLevelEnum
|
||||
{
|
||||
L1 = 3,
|
||||
L2 = 4,
|
||||
L3 = 5,
|
||||
}
|
||||
|
||||
//private async ValueTask<Processor.Metric?> GetProcessorMetricAsync(CancellationToken cancellationToken)
|
||||
//{
|
||||
// var metric = new Processor.Metric();
|
||||
|
||||
// if (ProcessorTimeCounter is null)
|
||||
// {
|
||||
// ProcessorTimeCounter = new PerformanceCounter
|
||||
// {
|
||||
// CategoryName = "Processor",
|
||||
// CounterName = "% Processor Time",
|
||||
// InstanceName = "_Total"
|
||||
// };
|
||||
|
||||
// metric.ProcessorUsagePercentage = ProcessorTimeCounter.NextValue();
|
||||
// await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
|
||||
// }
|
||||
|
||||
// metric.Timestamp = DateTime.Now;
|
||||
// metric.ProcessorUsagePercentage = ProcessorTimeCounter?.NextValue();
|
||||
// return metric;
|
||||
//}
|
||||
}
|
||||
|
|
@ -1,118 +1,118 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class ServiceHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class ServiceHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new ServiceList();
|
||||
result.AddRange(GetServices());
|
||||
var result = new ServiceList();
|
||||
result.AddRange(GetServices());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Service> GetServices()
|
||||
{
|
||||
var services = new List<Service>();
|
||||
|
||||
var serviceControllers = ServiceController.GetServices()?.OrderBy(s => s.DisplayName)?.ToList();
|
||||
if (serviceControllers is null || serviceControllers.Any() is false) throw new InvalidOperationException("SERVICE Collection NULL");
|
||||
|
||||
foreach (var sc in serviceControllers)
|
||||
{
|
||||
var status = sc.Status switch
|
||||
{
|
||||
ServiceControllerStatus.Stopped => Service.ServiceStatus.Stopped,
|
||||
ServiceControllerStatus.StartPending => Service.ServiceStatus.StartPending,
|
||||
ServiceControllerStatus.StopPending => Service.ServiceStatus.StopPending,
|
||||
ServiceControllerStatus.Running => Service.ServiceStatus.Running,
|
||||
ServiceControllerStatus.ContinuePending => Service.ServiceStatus.ContinuePending,
|
||||
ServiceControllerStatus.PausePending => Service.ServiceStatus.PausePending,
|
||||
ServiceControllerStatus.Paused => Service.ServiceStatus.Paused,
|
||||
_ => Service.ServiceStatus.Unknown
|
||||
};
|
||||
|
||||
var mode = sc.StartType switch
|
||||
{
|
||||
ServiceStartMode.Boot => Service.ServiceMode.Boot,
|
||||
ServiceStartMode.System => Service.ServiceMode.System,
|
||||
ServiceStartMode.Automatic => Service.ServiceMode.Automatic,
|
||||
ServiceStartMode.Manual => Service.ServiceMode.Manual,
|
||||
ServiceStartMode.Disabled => Service.ServiceMode.Disabled,
|
||||
_ => Service.ServiceMode.Unknown,
|
||||
};
|
||||
|
||||
var service = new Service
|
||||
{
|
||||
Name = sc.ServiceName?.Trim(),
|
||||
Display = sc.DisplayName?.Trim(),
|
||||
Status = status,
|
||||
StartMode = mode
|
||||
};
|
||||
|
||||
services.Add(service);
|
||||
}
|
||||
|
||||
// additional infos
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("SELECT processid, name, description, pathname, startname, delayedautostart from win32_service")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_service");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var services2 = new List<Service>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var service2 = new Service();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
service2.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
service2.ProcessId = @object.GetValue<uint>(properties, "processid");
|
||||
service2.Description = @object.GetValue<string>(properties, "description")?.Trim();
|
||||
service2.PathName = @object.GetValue<string>(properties, "pathname")?.Trim();
|
||||
service2.Account = @object.GetValue<string>(properties, "startname")?.Trim();
|
||||
service2.Delay = @object.GetValue<bool>(properties, "delayedautostart");
|
||||
|
||||
services2.Add(service2);
|
||||
}
|
||||
}
|
||||
|
||||
if (services2.Any() is false) return services;
|
||||
|
||||
foreach (var svc in services)
|
||||
{
|
||||
var map = services2.Where(p => p.Name == svc.Name).FirstOrDefault();
|
||||
|
||||
if (map is null) continue;
|
||||
|
||||
svc.ProcessId = map.ProcessId;
|
||||
svc.Description = map.Description;
|
||||
svc.PathName = map.PathName;
|
||||
svc.Account = map.Account;
|
||||
svc.Delay = map.Delay;
|
||||
}
|
||||
|
||||
return services.OrderBy(x => x.Name).ToList();
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Service> GetServices()
|
||||
{
|
||||
var services = new List<Service>();
|
||||
|
||||
var serviceControllers = ServiceController.GetServices()?.OrderBy(s => s.DisplayName)?.ToList();
|
||||
if (serviceControllers is null || serviceControllers.Any() is false) throw new InvalidOperationException("SERVICE Collection NULL");
|
||||
|
||||
foreach (var sc in serviceControllers)
|
||||
{
|
||||
var status = sc.Status switch
|
||||
{
|
||||
ServiceControllerStatus.Stopped => Service.ServiceStatus.Stopped,
|
||||
ServiceControllerStatus.StartPending => Service.ServiceStatus.StartPending,
|
||||
ServiceControllerStatus.StopPending => Service.ServiceStatus.StopPending,
|
||||
ServiceControllerStatus.Running => Service.ServiceStatus.Running,
|
||||
ServiceControllerStatus.ContinuePending => Service.ServiceStatus.ContinuePending,
|
||||
ServiceControllerStatus.PausePending => Service.ServiceStatus.PausePending,
|
||||
ServiceControllerStatus.Paused => Service.ServiceStatus.Paused,
|
||||
_ => Service.ServiceStatus.Unknown
|
||||
};
|
||||
|
||||
var mode = sc.StartType switch
|
||||
{
|
||||
ServiceStartMode.Boot => Service.ServiceMode.Boot,
|
||||
ServiceStartMode.System => Service.ServiceMode.System,
|
||||
ServiceStartMode.Automatic => Service.ServiceMode.Automatic,
|
||||
ServiceStartMode.Manual => Service.ServiceMode.Manual,
|
||||
ServiceStartMode.Disabled => Service.ServiceMode.Disabled,
|
||||
_ => Service.ServiceMode.Unknown,
|
||||
};
|
||||
|
||||
var service = new Service
|
||||
{
|
||||
Name = sc.ServiceName?.Trim(),
|
||||
Display = sc.DisplayName?.Trim(),
|
||||
Status = status,
|
||||
StartMode = mode
|
||||
};
|
||||
|
||||
services.Add(service);
|
||||
}
|
||||
|
||||
// additional infos
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("SELECT processid, name, description, pathname, startname, delayedautostart from win32_service")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_service");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var services2 = new List<Service>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var service2 = new Service();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
service2.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
service2.ProcessId = @object.GetValue<uint>(properties, "processid");
|
||||
service2.Description = @object.GetValue<string>(properties, "description")?.Trim();
|
||||
service2.PathName = @object.GetValue<string>(properties, "pathname")?.Trim();
|
||||
service2.Account = @object.GetValue<string>(properties, "startname")?.Trim();
|
||||
service2.Delay = @object.GetValue<bool>(properties, "delayedautostart");
|
||||
|
||||
services2.Add(service2);
|
||||
}
|
||||
}
|
||||
|
||||
if (services2.Any() is false) return services;
|
||||
|
||||
foreach (var svc in services)
|
||||
{
|
||||
var map = services2.Where(p => p.Name == svc.Name).FirstOrDefault();
|
||||
|
||||
if (map is null) continue;
|
||||
|
||||
svc.ProcessId = map.ProcessId;
|
||||
svc.Description = map.Description;
|
||||
svc.PathName = map.PathName;
|
||||
svc.Account = map.Account;
|
||||
svc.Delay = map.Delay;
|
||||
}
|
||||
|
||||
return services.OrderBy(x => x.Name).ToList();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,252 +1,252 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class SessionHandler : IAgentMessageHandler<AgentSession>
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new SessionList();
|
||||
result.AddRange(GetSessions());
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class SessionHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
var result = new SessionList();
|
||||
result.AddRange(GetSessions());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Session> GetSessions()
|
||||
{
|
||||
var query = NativeMethods.GetSessions();
|
||||
|
||||
var sessions = new List<Session>();
|
||||
|
||||
foreach (var s in NativeMethods.GetSessions())
|
||||
{
|
||||
sessions.Add(new Session
|
||||
{
|
||||
Sid = s.SessionId.ToString(),
|
||||
User = s.Username,
|
||||
Type = s.Workstation,
|
||||
Status = s.State.ToString(),
|
||||
Remote = s.IPAddress
|
||||
});
|
||||
}
|
||||
|
||||
private static List<Session> GetSessions()
|
||||
return sessions;
|
||||
}
|
||||
|
||||
private static partial class NativeMethods
|
||||
{
|
||||
//public const int WTS_CURRENT_SESSION = -1;
|
||||
|
||||
[DllImport("wtsapi32.dll")]
|
||||
static extern int WTSEnumerateSessions(
|
||||
nint pServer,
|
||||
[MarshalAs(UnmanagedType.U4)] int iReserved,
|
||||
[MarshalAs(UnmanagedType.U4)] int iVersion,
|
||||
ref nint pSessionInfo,
|
||||
[MarshalAs(UnmanagedType.U4)] ref int iCount);
|
||||
|
||||
[DllImport("Wtsapi32.dll")]
|
||||
private static extern bool WTSQuerySessionInformation(
|
||||
nint pServer,
|
||||
int iSessionID,
|
||||
WTS_INFO_CLASS oInfoClass,
|
||||
out nint pBuffer,
|
||||
out uint iBytesReturned);
|
||||
|
||||
[DllImport("wtsapi32.dll")]
|
||||
static extern void WTSFreeMemory(
|
||||
nint pMemory);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WTS_CLIENT_ADDRESS
|
||||
{
|
||||
var query = NativeMethods.GetSessions();
|
||||
public int iAddressFamily;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
|
||||
public byte[] bAddress;
|
||||
}
|
||||
|
||||
var sessions = new List<Session>();
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WTS_SESSION_INFO
|
||||
{
|
||||
public int iSessionID;
|
||||
[MarshalAs(UnmanagedType.LPStr)]
|
||||
public string sWinsWorkstationName;
|
||||
public WTS_CONNECTSTATE_CLASS oState;
|
||||
}
|
||||
|
||||
foreach (var s in NativeMethods.GetSessions())
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WTS_CLIENT_DISPLAY
|
||||
{
|
||||
public int iHorizontalResolution;
|
||||
public int iVerticalResolution;
|
||||
//1 = The display uses 4 bits per pixel for a maximum of 16 colors.
|
||||
//2 = The display uses 8 bits per pixel for a maximum of 256 colors.
|
||||
//4 = The display uses 16 bits per pixel for a maximum of 2^16 colors.
|
||||
//8 = The display uses 3-byte RGB values for a maximum of 2^24 colors.
|
||||
//16 = The display uses 15 bits per pixel for a maximum of 2^15 colors.
|
||||
public int iColorDepth;
|
||||
}
|
||||
|
||||
public enum WTS_CONNECTSTATE_CLASS
|
||||
{
|
||||
WTSActive,
|
||||
WTSConnected,
|
||||
WTSConnectQuery,
|
||||
WTSShadow,
|
||||
WTSDisconnected,
|
||||
WTSIdle,
|
||||
WTSListen,
|
||||
WTSReset,
|
||||
WTSDown,
|
||||
WTSInit
|
||||
}
|
||||
|
||||
public enum WTS_INFO_CLASS
|
||||
{
|
||||
WTSInitialProgram,
|
||||
WTSApplicationName,
|
||||
WTSWorkingDirectory,
|
||||
WTSOEMId,
|
||||
WTSSessionId,
|
||||
WTSUserName,
|
||||
WTSWinStationName,
|
||||
WTSDomainName,
|
||||
WTSConnectState,
|
||||
WTSClientBuildNumber,
|
||||
WTSClientName,
|
||||
WTSClientDirectory,
|
||||
WTSClientProductId,
|
||||
WTSClientHardwareId,
|
||||
WTSClientAddress,
|
||||
WTSClientDisplay,
|
||||
WTSClientProtocolType,
|
||||
WTSIdleTime,
|
||||
WTSLogonTime,
|
||||
WTSIncomingBytes,
|
||||
WTSOutgoingBytes,
|
||||
WTSIncomingFrames,
|
||||
WTSOutgoingFrames,
|
||||
WTSClientInfo,
|
||||
WTSSessionInfo,
|
||||
WTSConfigInfo,
|
||||
WTSValidationInfo,
|
||||
WTSSessionAddressV4,
|
||||
WTSIsRemoteSession
|
||||
}
|
||||
|
||||
public class WTSSession
|
||||
{
|
||||
public int SessionId { get; set; }
|
||||
public WTS_CONNECTSTATE_CLASS State { get; set; }
|
||||
public string? Workstation { get; set; }
|
||||
public string? IPAddress { get; set; }
|
||||
public string? Username { get; set; }
|
||||
public int HorizontalResolution { get; set; }
|
||||
public int VerticalResolution { get; set; }
|
||||
public int ColorDepth { get; set; }
|
||||
public string? ClientApplicationDirectory { get; set; }
|
||||
}
|
||||
|
||||
public static IEnumerable<WTSSession> GetSessions()
|
||||
{
|
||||
var sessions = new List<WTSSession>();
|
||||
|
||||
var pServer = nint.Zero;
|
||||
var pSessionInfo = nint.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
sessions.Add(new Session
|
||||
var count = 0;
|
||||
var sessionCount = WTSEnumerateSessions(pServer, 0, 1, ref pSessionInfo, ref count);
|
||||
var dataSize = (long)Marshal.SizeOf(typeof(WTS_SESSION_INFO));
|
||||
var current = (long)pSessionInfo;
|
||||
|
||||
if (sessionCount <= 0)
|
||||
return sessions;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Sid = s.SessionId.ToString(),
|
||||
User = s.Username,
|
||||
Type = s.Workstation,
|
||||
Status = s.State.ToString(),
|
||||
Remote = s.IPAddress
|
||||
});
|
||||
if (Marshal.PtrToStructure((nint)current, typeof(WTS_SESSION_INFO)) is not object sessionStructure)
|
||||
continue;
|
||||
|
||||
var sessionInfo = (WTS_SESSION_INFO)sessionStructure;
|
||||
current += dataSize;
|
||||
|
||||
var session = new WTSSession
|
||||
{
|
||||
SessionId = sessionInfo.iSessionID,
|
||||
State = sessionInfo.oState,
|
||||
Workstation = sessionInfo.sWinsWorkstationName,
|
||||
};
|
||||
|
||||
var returned = (uint)0;
|
||||
|
||||
// get terminal user address
|
||||
var address = nint.Zero;
|
||||
var clientAddress = new WTS_CLIENT_ADDRESS();
|
||||
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientAddress, out address, out returned) == true)
|
||||
{
|
||||
if (Marshal.PtrToStructure(address, clientAddress.GetType()) is not object addressStructure)
|
||||
break;
|
||||
|
||||
clientAddress = (WTS_CLIENT_ADDRESS)addressStructure;
|
||||
session.IPAddress = clientAddress.bAddress[2] + "." + clientAddress.bAddress[3] + "." + clientAddress.bAddress[4] + "." + clientAddress.bAddress[5];
|
||||
}
|
||||
|
||||
// get terminal user name
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSUserName, out address, out returned) == true)
|
||||
{
|
||||
session.Username = Marshal.PtrToStringAnsi(address);
|
||||
}
|
||||
|
||||
// get terminal user domain name
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSDomainName, out address, out returned) == true)
|
||||
{
|
||||
session.Username = Marshal.PtrToStringAnsi(address) + @"\" + session.Username;
|
||||
}
|
||||
|
||||
// get terminal user display informations
|
||||
var clientDisplay = new WTS_CLIENT_DISPLAY();
|
||||
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDisplay, out address, out returned) == true)
|
||||
{
|
||||
if (Marshal.PtrToStructure(address, clientDisplay.GetType()) is not object displayStructure)
|
||||
break;
|
||||
|
||||
clientDisplay = (WTS_CLIENT_DISPLAY)displayStructure;
|
||||
session.HorizontalResolution = clientDisplay.iHorizontalResolution;
|
||||
session.VerticalResolution = clientDisplay.iVerticalResolution;
|
||||
session.ColorDepth = clientDisplay.iColorDepth;
|
||||
}
|
||||
|
||||
// get terminal user application directory
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDirectory, out address, out returned) == true)
|
||||
{
|
||||
session.ClientApplicationDirectory = Marshal.PtrToStringAnsi(address);
|
||||
}
|
||||
|
||||
sessions.Add(session);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
WTSFreeMemory(pSessionInfo);
|
||||
}
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
private static partial class NativeMethods
|
||||
{
|
||||
//public const int WTS_CURRENT_SESSION = -1;
|
||||
|
||||
[DllImport("wtsapi32.dll")]
|
||||
static extern int WTSEnumerateSessions(
|
||||
nint pServer,
|
||||
[MarshalAs(UnmanagedType.U4)] int iReserved,
|
||||
[MarshalAs(UnmanagedType.U4)] int iVersion,
|
||||
ref nint pSessionInfo,
|
||||
[MarshalAs(UnmanagedType.U4)] ref int iCount);
|
||||
|
||||
[DllImport("Wtsapi32.dll")]
|
||||
private static extern bool WTSQuerySessionInformation(
|
||||
nint pServer,
|
||||
int iSessionID,
|
||||
WTS_INFO_CLASS oInfoClass,
|
||||
out nint pBuffer,
|
||||
out uint iBytesReturned);
|
||||
|
||||
[DllImport("wtsapi32.dll")]
|
||||
static extern void WTSFreeMemory(
|
||||
nint pMemory);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WTS_CLIENT_ADDRESS
|
||||
{
|
||||
public int iAddressFamily;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
|
||||
public byte[] bAddress;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WTS_SESSION_INFO
|
||||
{
|
||||
public int iSessionID;
|
||||
[MarshalAs(UnmanagedType.LPStr)]
|
||||
public string sWinsWorkstationName;
|
||||
public WTS_CONNECTSTATE_CLASS oState;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WTS_CLIENT_DISPLAY
|
||||
{
|
||||
public int iHorizontalResolution;
|
||||
public int iVerticalResolution;
|
||||
//1 = The display uses 4 bits per pixel for a maximum of 16 colors.
|
||||
//2 = The display uses 8 bits per pixel for a maximum of 256 colors.
|
||||
//4 = The display uses 16 bits per pixel for a maximum of 2^16 colors.
|
||||
//8 = The display uses 3-byte RGB values for a maximum of 2^24 colors.
|
||||
//16 = The display uses 15 bits per pixel for a maximum of 2^15 colors.
|
||||
public int iColorDepth;
|
||||
}
|
||||
|
||||
public enum WTS_CONNECTSTATE_CLASS
|
||||
{
|
||||
WTSActive,
|
||||
WTSConnected,
|
||||
WTSConnectQuery,
|
||||
WTSShadow,
|
||||
WTSDisconnected,
|
||||
WTSIdle,
|
||||
WTSListen,
|
||||
WTSReset,
|
||||
WTSDown,
|
||||
WTSInit
|
||||
}
|
||||
|
||||
public enum WTS_INFO_CLASS
|
||||
{
|
||||
WTSInitialProgram,
|
||||
WTSApplicationName,
|
||||
WTSWorkingDirectory,
|
||||
WTSOEMId,
|
||||
WTSSessionId,
|
||||
WTSUserName,
|
||||
WTSWinStationName,
|
||||
WTSDomainName,
|
||||
WTSConnectState,
|
||||
WTSClientBuildNumber,
|
||||
WTSClientName,
|
||||
WTSClientDirectory,
|
||||
WTSClientProductId,
|
||||
WTSClientHardwareId,
|
||||
WTSClientAddress,
|
||||
WTSClientDisplay,
|
||||
WTSClientProtocolType,
|
||||
WTSIdleTime,
|
||||
WTSLogonTime,
|
||||
WTSIncomingBytes,
|
||||
WTSOutgoingBytes,
|
||||
WTSIncomingFrames,
|
||||
WTSOutgoingFrames,
|
||||
WTSClientInfo,
|
||||
WTSSessionInfo,
|
||||
WTSConfigInfo,
|
||||
WTSValidationInfo,
|
||||
WTSSessionAddressV4,
|
||||
WTSIsRemoteSession
|
||||
}
|
||||
|
||||
public class WTSSession
|
||||
{
|
||||
public int SessionId { get; set; }
|
||||
public WTS_CONNECTSTATE_CLASS State { get; set; }
|
||||
public string? Workstation { get; set; }
|
||||
public string? IPAddress { get; set; }
|
||||
public string? Username { get; set; }
|
||||
public int HorizontalResolution { get; set; }
|
||||
public int VerticalResolution { get; set; }
|
||||
public int ColorDepth { get; set; }
|
||||
public string? ClientApplicationDirectory { get; set; }
|
||||
}
|
||||
|
||||
public static IEnumerable<WTSSession> GetSessions()
|
||||
{
|
||||
var sessions = new List<WTSSession>();
|
||||
|
||||
var pServer = nint.Zero;
|
||||
var pSessionInfo = nint.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
var count = 0;
|
||||
var sessionCount = WTSEnumerateSessions(pServer, 0, 1, ref pSessionInfo, ref count);
|
||||
var dataSize = (long)Marshal.SizeOf(typeof(WTS_SESSION_INFO));
|
||||
var current = (long)pSessionInfo;
|
||||
|
||||
if (sessionCount <= 0)
|
||||
return sessions;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (Marshal.PtrToStructure((nint)current, typeof(WTS_SESSION_INFO)) is not object sessionStructure)
|
||||
continue;
|
||||
|
||||
var sessionInfo = (WTS_SESSION_INFO)sessionStructure;
|
||||
current += dataSize;
|
||||
|
||||
var session = new WTSSession
|
||||
{
|
||||
SessionId = sessionInfo.iSessionID,
|
||||
State = sessionInfo.oState,
|
||||
Workstation = sessionInfo.sWinsWorkstationName,
|
||||
};
|
||||
|
||||
var returned = (uint)0;
|
||||
|
||||
// get terminal user address
|
||||
var address = nint.Zero;
|
||||
var clientAddress = new WTS_CLIENT_ADDRESS();
|
||||
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientAddress, out address, out returned) == true)
|
||||
{
|
||||
if (Marshal.PtrToStructure(address, clientAddress.GetType()) is not object addressStructure)
|
||||
break;
|
||||
|
||||
clientAddress = (WTS_CLIENT_ADDRESS)addressStructure;
|
||||
session.IPAddress = clientAddress.bAddress[2] + "." + clientAddress.bAddress[3] + "." + clientAddress.bAddress[4] + "." + clientAddress.bAddress[5];
|
||||
}
|
||||
|
||||
// get terminal user name
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSUserName, out address, out returned) == true)
|
||||
{
|
||||
session.Username = Marshal.PtrToStringAnsi(address);
|
||||
}
|
||||
|
||||
// get terminal user domain name
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSDomainName, out address, out returned) == true)
|
||||
{
|
||||
session.Username = Marshal.PtrToStringAnsi(address) + @"\" + session.Username;
|
||||
}
|
||||
|
||||
// get terminal user display informations
|
||||
var clientDisplay = new WTS_CLIENT_DISPLAY();
|
||||
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDisplay, out address, out returned) == true)
|
||||
{
|
||||
if (Marshal.PtrToStructure(address, clientDisplay.GetType()) is not object displayStructure)
|
||||
break;
|
||||
|
||||
clientDisplay = (WTS_CLIENT_DISPLAY)displayStructure;
|
||||
session.HorizontalResolution = clientDisplay.iHorizontalResolution;
|
||||
session.VerticalResolution = clientDisplay.iVerticalResolution;
|
||||
session.ColorDepth = clientDisplay.iColorDepth;
|
||||
}
|
||||
|
||||
// get terminal user application directory
|
||||
if (WTSQuerySessionInformation(pServer, sessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDirectory, out address, out returned) == true)
|
||||
{
|
||||
session.ClientApplicationDirectory = Marshal.PtrToStringAnsi(address);
|
||||
}
|
||||
|
||||
sessions.Add(session);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
WTSFreeMemory(pSessionInfo);
|
||||
}
|
||||
|
||||
return sessions;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,119 +1,119 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Microsoft.Win32;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security.AccessControl;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class SoftwareHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class SoftwareHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var x64 = Task.Run(() => ApplicationRegistryQuery(RegistryView.Registry64), cancellationToken);
|
||||
var x86 = Task.Run(() => ApplicationRegistryQuery(RegistryView.Registry32), cancellationToken);
|
||||
var x64 = Task.Run(() => ApplicationRegistryQuery(RegistryView.Registry64), cancellationToken);
|
||||
var x86 = Task.Run(() => ApplicationRegistryQuery(RegistryView.Registry32), cancellationToken);
|
||||
|
||||
await Task.WhenAll(x64, x86).ConfigureAwait(false);
|
||||
await Task.WhenAll(x64, x86).ConfigureAwait(false);
|
||||
|
||||
var result = new ApplicationList();
|
||||
result.AddRange(x64.Result);
|
||||
result.AddRange(x86.Result.Where(p => result.All(app => p.Name != app.Name && p.Version != app.Version)));
|
||||
var result = new ApplicationList();
|
||||
result.AddRange(x64.Result);
|
||||
result.AddRange(x86.Result.Where(p => result.All(app => p.Name != app.Name && p.Version != app.Version)));
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<Application> ApplicationRegistryQuery(RegistryView registryView)
|
||||
{
|
||||
using var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView);
|
||||
|
||||
using var key = registry.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
|
||||
if (key is null) throw new NullReferenceException(nameof(key));
|
||||
|
||||
var apps = new List<Application>();
|
||||
|
||||
var architecture = registryView switch
|
||||
{
|
||||
RegistryView.Registry32 => Architecture.X86,
|
||||
_ => Architecture.X64
|
||||
};
|
||||
|
||||
foreach (string name in key.GetSubKeyNames())
|
||||
{
|
||||
using var query = key.OpenSubKey(name);
|
||||
if (query is null) continue;
|
||||
|
||||
var app = new Application
|
||||
{
|
||||
Architecture = architecture
|
||||
};
|
||||
|
||||
if (query.GetValue("DisplayName")?.ToString()?.Trim() is string displayName && string.IsNullOrWhiteSpace(displayName) is false)
|
||||
{
|
||||
app.Name = displayName;
|
||||
}
|
||||
|
||||
if (query.GetValue("Publisher")?.ToString()?.Trim() is string publisher && string.IsNullOrWhiteSpace(publisher) is false)
|
||||
{
|
||||
app.Publisher = publisher;
|
||||
}
|
||||
|
||||
if (query.GetValue("DisplayVersion")?.ToString()?.Trim() is string version && string.IsNullOrWhiteSpace(version) is false)
|
||||
{
|
||||
app.Version = version;
|
||||
}
|
||||
|
||||
if (query.GetValue("InstallLocation")?.ToString()?.Trim() is string location && string.IsNullOrWhiteSpace(location) is false)
|
||||
{
|
||||
app.Location = location;
|
||||
}
|
||||
|
||||
if (query.GetValue("InstallSource")?.ToString()?.Trim() is string source && string.IsNullOrWhiteSpace(source) is false)
|
||||
{
|
||||
app.Source = source;
|
||||
}
|
||||
|
||||
if (query.GetValue("UninstallString")?.ToString()?.Trim() is string uninstall && string.IsNullOrWhiteSpace(uninstall) is false)
|
||||
{
|
||||
app.Uninstall = uninstall;
|
||||
}
|
||||
|
||||
if (app.Uninstall is null)
|
||||
{
|
||||
if (query.GetValue("UninstallString_Hidden")?.ToString()?.Trim() is string uninstall2 && string.IsNullOrWhiteSpace(uninstall2) is false)
|
||||
{
|
||||
app.Uninstall = uninstall2;
|
||||
}
|
||||
}
|
||||
|
||||
if (query.GetValue("InstallDate")?.ToString()?.Trim() is string installDate)
|
||||
{
|
||||
if (DateTime.TryParseExact(installDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime valid))
|
||||
{
|
||||
app.InstallDate = valid;
|
||||
}
|
||||
|
||||
if (app.InstallDate is null)
|
||||
{
|
||||
if (DateTime.TryParseExact(installDate, "dd.MM.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime valid2))
|
||||
{
|
||||
app.InstallDate = valid2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (app.Name is not null)
|
||||
{
|
||||
apps.Add(app);
|
||||
}
|
||||
}
|
||||
|
||||
return apps;
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<Application> ApplicationRegistryQuery(RegistryView registryView)
|
||||
{
|
||||
using var registry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView);
|
||||
|
||||
using var key = registry.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
|
||||
if (key is null) throw new NullReferenceException(nameof(key));
|
||||
|
||||
var apps = new List<Application>();
|
||||
|
||||
var architecture = registryView switch
|
||||
{
|
||||
RegistryView.Registry32 => Architecture.X86,
|
||||
_ => Architecture.X64
|
||||
};
|
||||
|
||||
foreach (string name in key.GetSubKeyNames())
|
||||
{
|
||||
using var query = key.OpenSubKey(name);
|
||||
if (query is null) continue;
|
||||
|
||||
var app = new Application
|
||||
{
|
||||
Architecture = architecture
|
||||
};
|
||||
|
||||
if (query.GetValue("DisplayName")?.ToString()?.Trim() is string displayName && string.IsNullOrWhiteSpace(displayName) is false)
|
||||
{
|
||||
app.Name = displayName;
|
||||
}
|
||||
|
||||
if (query.GetValue("Publisher")?.ToString()?.Trim() is string publisher && string.IsNullOrWhiteSpace(publisher) is false)
|
||||
{
|
||||
app.Publisher = publisher;
|
||||
}
|
||||
|
||||
if (query.GetValue("DisplayVersion")?.ToString()?.Trim() is string version && string.IsNullOrWhiteSpace(version) is false)
|
||||
{
|
||||
app.Version = version;
|
||||
}
|
||||
|
||||
if (query.GetValue("InstallLocation")?.ToString()?.Trim() is string location && string.IsNullOrWhiteSpace(location) is false)
|
||||
{
|
||||
app.Location = location;
|
||||
}
|
||||
|
||||
if (query.GetValue("InstallSource")?.ToString()?.Trim() is string source && string.IsNullOrWhiteSpace(source) is false)
|
||||
{
|
||||
app.Source = source;
|
||||
}
|
||||
|
||||
if (query.GetValue("UninstallString")?.ToString()?.Trim() is string uninstall && string.IsNullOrWhiteSpace(uninstall) is false)
|
||||
{
|
||||
app.Uninstall = uninstall;
|
||||
}
|
||||
|
||||
if (app.Uninstall is null)
|
||||
{
|
||||
if (query.GetValue("UninstallString_Hidden")?.ToString()?.Trim() is string uninstall2 && string.IsNullOrWhiteSpace(uninstall2) is false)
|
||||
{
|
||||
app.Uninstall = uninstall2;
|
||||
}
|
||||
}
|
||||
|
||||
if (query.GetValue("InstallDate")?.ToString()?.Trim() is string installDate)
|
||||
{
|
||||
if (DateTime.TryParseExact(installDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime valid))
|
||||
{
|
||||
app.InstallDate = valid;
|
||||
}
|
||||
|
||||
if (app.InstallDate is null)
|
||||
{
|
||||
if (DateTime.TryParseExact(installDate, "dd.MM.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime valid2))
|
||||
{
|
||||
app.InstallDate = valid2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (app.Name is not null)
|
||||
{
|
||||
apps.Add(app);
|
||||
}
|
||||
}
|
||||
|
||||
return apps;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,308 +1,308 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
using static Insight.Agent.Messages.PhysicalDisk;
|
||||
using static Insight.Agent.Messages.StoragePool;
|
||||
using static Insight.Agent.Messages.VirtualDisk;
|
||||
using static Insight.Domain.Messages.Agent.PhysicalDisk;
|
||||
using static Insight.Domain.Messages.Agent.StoragePool;
|
||||
using static Insight.Domain.Messages.Agent.VirtualDisk;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class StoragePoolHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new StoragePoolList();
|
||||
result.AddRange(GetStoragePool());
|
||||
var result = new StoragePoolList();
|
||||
result.AddRange(GetStoragePool());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<StoragePool> GetStoragePool()
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major < 6 || Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor < 2)
|
||||
{
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, resiliencysettingnamedefault, isprimordial, isreadonly, isclustered, size, allocatedsize, logicalsectorsize, operationalstatus, healthstatus from msft_storagepool")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msft_storagepool");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var pools = new List<StoragePool>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var pool = new StoragePool();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
pool.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
pool.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
pool.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
pool.States = operationals.Select(p => (StoragePool.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
pool.Health = (StoragePool.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
pool.RetireMissingPhysicalDisks = (RetireMissingPhysicalDisksEnum)@object.GetValue<ushort>(properties, "retiremissingphysicaldisks");
|
||||
pool.Resiliency = @object.GetValue<string>(properties, "resiliencysettingnamedefault")?.Trim();
|
||||
pool.IsPrimordial = @object.GetValue<bool>(properties, "isprimordial");
|
||||
pool.IsReadOnly = @object.GetValue<bool>(properties, "isreadonly");
|
||||
pool.IsClustered = @object.GetValue<bool>(properties, "isclustered");
|
||||
pool.Size = @object.GetValue<ulong>(properties, "size");
|
||||
pool.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
pool.SectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
||||
|
||||
if (@object.GetValue<string>(properties, "objectid") is string objectId)
|
||||
{
|
||||
pool.PhysicalDisks = QueryPhysicalDisksByStoragePool(objectId);
|
||||
pool.VirtualDisks = QueryVirtualDisksByStoragePool(objectId);
|
||||
}
|
||||
|
||||
pools.Add(pool);
|
||||
}
|
||||
}
|
||||
|
||||
return pools;
|
||||
}
|
||||
|
||||
private static List<PhysicalDisk> GetPhysicalDisks()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname from msft_physicaldisk")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msft_physicaldisk");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var disks = new List<PhysicalDisk>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var disk = new PhysicalDisk();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
|
||||
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
|
||||
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
|
||||
{
|
||||
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
|
||||
}
|
||||
|
||||
disk.Usage = @object.GetValue<ushort>(properties, "usage");
|
||||
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
|
||||
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
|
||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
||||
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
|
||||
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
|
||||
return disks;
|
||||
}
|
||||
|
||||
private static List<VirtualDisk> GetVirtualDisks()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, access, provisioningtype, physicaldiskredundancy, resiliencysettingname, isdeduplicationenabled, issnapshot, operationalstatus, healthstatus, size, allocatedsize, footprintonpool, readcachesize, writecachesize from msft_virtualdisk")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msft_virtualdisk");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var disks = new List<VirtualDisk>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var disk = new VirtualDisk();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
|
||||
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
|
||||
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
|
||||
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
|
||||
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
|
||||
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
|
||||
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
|
||||
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
|
||||
return disks;
|
||||
}
|
||||
|
||||
private static List<PhysicalDisk> QueryPhysicalDisksByStoragePool(string storagePoolObjectId)
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToPhysicalDisk")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
|
||||
var disks = new List<PhysicalDisk>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var disk = new PhysicalDisk();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
disk.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
|
||||
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
|
||||
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
|
||||
{
|
||||
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
|
||||
}
|
||||
|
||||
disk.Usage = @object.GetValue<ushort>(properties, "usage");
|
||||
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
|
||||
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
|
||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
||||
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
|
||||
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
|
||||
return disks;
|
||||
}
|
||||
|
||||
private static List<VirtualDisk> QueryVirtualDisksByStoragePool(string storagePoolObjectId)
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToVirtualDisk")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
|
||||
var disks = new List<VirtualDisk>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var disk = new VirtualDisk();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
|
||||
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
|
||||
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
|
||||
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
|
||||
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
|
||||
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
|
||||
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
|
||||
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
|
||||
return disks;
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<StoragePool> GetStoragePool()
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major < 6 || Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor < 2)
|
||||
{
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, resiliencysettingnamedefault, isprimordial, isreadonly, isclustered, size, allocatedsize, logicalsectorsize, operationalstatus, healthstatus from msft_storagepool")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msft_storagepool");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var pools = new List<StoragePool>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var pool = new StoragePool();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
pool.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
pool.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
pool.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
pool.States = operationals.Select(p => (StoragePool.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
pool.Health = (StoragePool.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
pool.RetireMissingPhysicalDisks = (RetireMissingPhysicalDisksEnum)@object.GetValue<ushort>(properties, "retiremissingphysicaldisks");
|
||||
pool.Resiliency = @object.GetValue<string>(properties, "resiliencysettingnamedefault")?.Trim();
|
||||
pool.IsPrimordial = @object.GetValue<bool>(properties, "isprimordial");
|
||||
pool.IsReadOnly = @object.GetValue<bool>(properties, "isreadonly");
|
||||
pool.IsClustered = @object.GetValue<bool>(properties, "isclustered");
|
||||
pool.Size = @object.GetValue<ulong>(properties, "size");
|
||||
pool.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
pool.SectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
||||
|
||||
if (@object.GetValue<string>(properties, "objectid") is string objectId)
|
||||
{
|
||||
pool.PhysicalDisks = QueryPhysicalDisksByStoragePool(objectId);
|
||||
pool.VirtualDisks = QueryVirtualDisksByStoragePool(objectId);
|
||||
}
|
||||
|
||||
pools.Add(pool);
|
||||
}
|
||||
}
|
||||
|
||||
return pools;
|
||||
}
|
||||
|
||||
private static List<PhysicalDisk> GetPhysicalDisks()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname from msft_physicaldisk")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msft_physicaldisk");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var disks = new List<PhysicalDisk>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var disk = new PhysicalDisk();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
|
||||
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
|
||||
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
|
||||
{
|
||||
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
|
||||
}
|
||||
|
||||
disk.Usage = @object.GetValue<ushort>(properties, "usage");
|
||||
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
|
||||
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
|
||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
||||
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
|
||||
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
|
||||
return disks;
|
||||
}
|
||||
|
||||
private static List<VirtualDisk> GetVirtualDisks()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, access, provisioningtype, physicaldiskredundancy, resiliencysettingname, isdeduplicationenabled, issnapshot, operationalstatus, healthstatus, size, allocatedsize, footprintonpool, readcachesize, writecachesize from msft_virtualdisk")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msft_virtualdisk");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var disks = new List<VirtualDisk>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var disk = new VirtualDisk();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
|
||||
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
|
||||
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
|
||||
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
|
||||
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
|
||||
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
|
||||
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
|
||||
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
|
||||
return disks;
|
||||
}
|
||||
|
||||
private static List<PhysicalDisk> QueryPhysicalDisksByStoragePool(string storagePoolObjectId)
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToPhysicalDisk")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
|
||||
var disks = new List<PhysicalDisk>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var disk = new PhysicalDisk();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
disk.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
||||
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
|
||||
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
|
||||
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
|
||||
{
|
||||
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
|
||||
}
|
||||
|
||||
disk.Usage = @object.GetValue<ushort>(properties, "usage");
|
||||
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
|
||||
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
||||
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
|
||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
||||
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
|
||||
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
|
||||
return disks;
|
||||
}
|
||||
|
||||
private static List<VirtualDisk> QueryVirtualDisksByStoragePool(string storagePoolObjectId)
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
||||
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToVirtualDisk")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
|
||||
var disks = new List<VirtualDisk>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var disk = new VirtualDisk();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
||||
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
||||
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
|
||||
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
|
||||
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
|
||||
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
|
||||
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
|
||||
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
|
||||
|
||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
||||
{
|
||||
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
|
||||
}
|
||||
|
||||
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
||||
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
|
||||
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
|
||||
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
|
||||
return disks;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,175 +1,175 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Microsoft.Win32;
|
||||
using System.Collections;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class SystemInfoHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class SystemInfoHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
await sender.SendAsync(GetSystem(), cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static SystemInfo GetSystem()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select lastbootuptime, localdatetime, numberofprocesses from win32_operatingsystem")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_operatingsystem");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var system = new SystemInfo();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "lastbootuptime", out var lastbootuptime))
|
||||
{
|
||||
system.LastBootUpTime = ManagementDateTimeConverter.ToDateTime(lastbootuptime?.ToString());
|
||||
}
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "localdatetime", out var localdatetime))
|
||||
{
|
||||
system.LocalDateTime = ManagementDateTimeConverter.ToDateTime(localdatetime?.ToString());
|
||||
}
|
||||
|
||||
system.Processes = @object.GetValue<uint>(properties, "numberofprocesses");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
system.License = GetWindowsProductKeyFromRegistry();
|
||||
|
||||
return system;
|
||||
}
|
||||
|
||||
private static string GetWindowsProductKeyFromRegistry()
|
||||
{
|
||||
var localKey =
|
||||
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem
|
||||
? RegistryView.Registry64
|
||||
: RegistryView.Registry32);
|
||||
|
||||
var registryKeyValue = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion")?.GetValue("DigitalProductId");
|
||||
if (registryKeyValue == null)
|
||||
return "Failed to get DigitalProductId from registry";
|
||||
var digitalProductId = (byte[])registryKeyValue;
|
||||
localKey.Close();
|
||||
var isWin8OrUp =
|
||||
Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2
|
||||
||
|
||||
Environment.OSVersion.Version.Major > 6;
|
||||
return GetWindowsProductKeyFromDigitalProductId(digitalProductId,
|
||||
isWin8OrUp ? DigitalProductIdVersion.Windows8AndUp : DigitalProductIdVersion.UpToWindows7);
|
||||
}
|
||||
|
||||
private static string GetWindowsProductKeyFromDigitalProductId(byte[] digitalProductId, DigitalProductIdVersion digitalProductIdVersion)
|
||||
{
|
||||
|
||||
var productKey = digitalProductIdVersion == DigitalProductIdVersion.Windows8AndUp
|
||||
? DecodeProductKeyWin8AndUp(digitalProductId)
|
||||
: DecodeProductKey(digitalProductId);
|
||||
return productKey;
|
||||
}
|
||||
|
||||
private static string DecodeProductKey(byte[] digitalProductId)
|
||||
{
|
||||
const int keyStartIndex = 52;
|
||||
const int keyEndIndex = keyStartIndex + 15;
|
||||
var digits = new[]
|
||||
{
|
||||
'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R',
|
||||
'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9',
|
||||
};
|
||||
const int decodeLength = 29;
|
||||
const int decodeStringLength = 15;
|
||||
var decodedChars = new char[decodeLength];
|
||||
var hexPid = new ArrayList();
|
||||
for (var i = keyStartIndex; i <= keyEndIndex; i++)
|
||||
{
|
||||
hexPid.Add(digitalProductId[i]);
|
||||
}
|
||||
for (var i = decodeLength - 1; i >= 0; i--)
|
||||
{
|
||||
// Every sixth char is a separator.
|
||||
if ((i + 1) % 6 == 0)
|
||||
{
|
||||
decodedChars[i] = '-';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do the actual decoding.
|
||||
var digitMapIndex = 0;
|
||||
for (var j = decodeStringLength - 1; j >= 0; j--)
|
||||
{
|
||||
var byteValue = digitMapIndex << 8 | (byte)hexPid[j];
|
||||
hexPid[j] = (byte)(byteValue / 24);
|
||||
digitMapIndex = byteValue % 24;
|
||||
decodedChars[i] = digits[digitMapIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
return new string(decodedChars);
|
||||
}
|
||||
|
||||
private static string DecodeProductKeyWin8AndUp(byte[] digitalProductId)
|
||||
{
|
||||
var key = string.Empty;
|
||||
const int keyOffset = 52;
|
||||
var isWin8 = (byte)(digitalProductId[66] / 6 & 1);
|
||||
digitalProductId[66] = (byte)(digitalProductId[66] & 0xf7 | (isWin8 & 2) * 4);
|
||||
|
||||
const string digits = "BCDFGHJKMPQRTVWXY2346789";
|
||||
var last = 0;
|
||||
for (var i = 24; i >= 0; i--)
|
||||
{
|
||||
var current = 0;
|
||||
for (var j = 14; j >= 0; j--)
|
||||
{
|
||||
current = current * 256;
|
||||
current = digitalProductId[j + keyOffset] + current;
|
||||
digitalProductId[j + keyOffset] = (byte)(current / 24);
|
||||
current = current % 24;
|
||||
last = current;
|
||||
}
|
||||
key = digits[current] + key;
|
||||
}
|
||||
|
||||
var keypart1 = key.Substring(1, last);
|
||||
var keypart2 = key.Substring(last + 1, key.Length - (last + 1));
|
||||
key = keypart1 + "N" + keypart2;
|
||||
|
||||
for (var i = 5; i < key.Length; i += 6)
|
||||
{
|
||||
key = key.Insert(i, "-");
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
private enum DigitalProductIdVersion
|
||||
{
|
||||
UpToWindows7,
|
||||
Windows8AndUp
|
||||
await sender.SendAsync(GetSystem(), cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static SystemInfo GetSystem()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select lastbootuptime, localdatetime, numberofprocesses from win32_operatingsystem")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_operatingsystem");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var system = new SystemInfo();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "lastbootuptime", out var lastbootuptime))
|
||||
{
|
||||
system.LastBootUpTime = ManagementDateTimeConverter.ToDateTime(lastbootuptime?.ToString());
|
||||
}
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "localdatetime", out var localdatetime))
|
||||
{
|
||||
system.LocalDateTime = ManagementDateTimeConverter.ToDateTime(localdatetime?.ToString());
|
||||
}
|
||||
|
||||
system.Processes = @object.GetValue<uint>(properties, "numberofprocesses");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
system.License = GetWindowsProductKeyFromRegistry();
|
||||
|
||||
return system;
|
||||
}
|
||||
|
||||
private static string GetWindowsProductKeyFromRegistry()
|
||||
{
|
||||
var localKey =
|
||||
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem
|
||||
? RegistryView.Registry64
|
||||
: RegistryView.Registry32);
|
||||
|
||||
var registryKeyValue = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion")?.GetValue("DigitalProductId");
|
||||
if (registryKeyValue == null)
|
||||
return "Failed to get DigitalProductId from registry";
|
||||
var digitalProductId = (byte[])registryKeyValue;
|
||||
localKey.Close();
|
||||
var isWin8OrUp =
|
||||
Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2
|
||||
||
|
||||
Environment.OSVersion.Version.Major > 6;
|
||||
return GetWindowsProductKeyFromDigitalProductId(digitalProductId,
|
||||
isWin8OrUp ? DigitalProductIdVersion.Windows8AndUp : DigitalProductIdVersion.UpToWindows7);
|
||||
}
|
||||
|
||||
private static string GetWindowsProductKeyFromDigitalProductId(byte[] digitalProductId, DigitalProductIdVersion digitalProductIdVersion)
|
||||
{
|
||||
|
||||
var productKey = digitalProductIdVersion == DigitalProductIdVersion.Windows8AndUp
|
||||
? DecodeProductKeyWin8AndUp(digitalProductId)
|
||||
: DecodeProductKey(digitalProductId);
|
||||
return productKey;
|
||||
}
|
||||
|
||||
private static string DecodeProductKey(byte[] digitalProductId)
|
||||
{
|
||||
const int keyStartIndex = 52;
|
||||
const int keyEndIndex = keyStartIndex + 15;
|
||||
var digits = new[]
|
||||
{
|
||||
'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R',
|
||||
'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9',
|
||||
};
|
||||
const int decodeLength = 29;
|
||||
const int decodeStringLength = 15;
|
||||
var decodedChars = new char[decodeLength];
|
||||
var hexPid = new ArrayList();
|
||||
for (var i = keyStartIndex; i <= keyEndIndex; i++)
|
||||
{
|
||||
hexPid.Add(digitalProductId[i]);
|
||||
}
|
||||
for (var i = decodeLength - 1; i >= 0; i--)
|
||||
{
|
||||
// Every sixth char is a separator.
|
||||
if ((i + 1) % 6 == 0)
|
||||
{
|
||||
decodedChars[i] = '-';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do the actual decoding.
|
||||
var digitMapIndex = 0;
|
||||
for (var j = decodeStringLength - 1; j >= 0; j--)
|
||||
{
|
||||
var byteValue = digitMapIndex << 8 | (byte)hexPid[j];
|
||||
hexPid[j] = (byte)(byteValue / 24);
|
||||
digitMapIndex = byteValue % 24;
|
||||
decodedChars[i] = digits[digitMapIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
return new string(decodedChars);
|
||||
}
|
||||
|
||||
private static string DecodeProductKeyWin8AndUp(byte[] digitalProductId)
|
||||
{
|
||||
var key = string.Empty;
|
||||
const int keyOffset = 52;
|
||||
var isWin8 = (byte)(digitalProductId[66] / 6 & 1);
|
||||
digitalProductId[66] = (byte)(digitalProductId[66] & 0xf7 | (isWin8 & 2) * 4);
|
||||
|
||||
const string digits = "BCDFGHJKMPQRTVWXY2346789";
|
||||
var last = 0;
|
||||
for (var i = 24; i >= 0; i--)
|
||||
{
|
||||
var current = 0;
|
||||
for (var j = 14; j >= 0; j--)
|
||||
{
|
||||
current = current * 256;
|
||||
current = digitalProductId[j + keyOffset] + current;
|
||||
digitalProductId[j + keyOffset] = (byte)(current / 24);
|
||||
current = current % 24;
|
||||
last = current;
|
||||
}
|
||||
key = digits[current] + key;
|
||||
}
|
||||
|
||||
var keypart1 = key.Substring(1, last);
|
||||
var keypart2 = key.Substring(last + 1, key.Length - (last + 1));
|
||||
key = keypart1 + "N" + keypart2;
|
||||
|
||||
for (var i = 5; i < key.Length; i += 6)
|
||||
{
|
||||
key = key.Insert(i, "-");
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
private enum DigitalProductIdVersion
|
||||
{
|
||||
UpToWindows7,
|
||||
Windows8AndUp
|
||||
}
|
||||
}
|
||||
|
|
@ -1,130 +1,130 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text.RegularExpressions;
|
||||
using WUApiLib;
|
||||
using static Insight.Agent.Messages.Update;
|
||||
using static Insight.Domain.Messages.Agent.Update;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class UpdateHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class UpdateHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
await sender.SendAsync(GetUpdates(), cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static UpdateList GetUpdates()
|
||||
{
|
||||
return new UpdateList
|
||||
{
|
||||
Installed = QueryInstalledUpdates(),
|
||||
Pending = QueryPendingUpdates()
|
||||
};
|
||||
}
|
||||
|
||||
private static List<Update> QueryInstalledUpdates()
|
||||
{
|
||||
var updates = new List<Update>();
|
||||
|
||||
var session = new UpdateSessionClass();
|
||||
var searcher = session.CreateUpdateSearcher();
|
||||
searcher.Online = false;
|
||||
|
||||
var count = searcher.GetTotalHistoryCount();
|
||||
var result = searcher.QueryHistory(0, count);
|
||||
|
||||
foreach (IUpdateHistoryEntry wupdate in result)
|
||||
{
|
||||
var update = new Update
|
||||
{
|
||||
Id = wupdate.UpdateIdentity.UpdateID,
|
||||
Date = wupdate.Date,
|
||||
Name = wupdate.Title,
|
||||
Description = wupdate.Description,
|
||||
Result = wupdate.ResultCode switch
|
||||
{
|
||||
OperationResultCode.orcNotStarted => OsUpdateResultCodeEnum.NotStarted,
|
||||
OperationResultCode.orcInProgress => OsUpdateResultCodeEnum.InProgress,
|
||||
OperationResultCode.orcSucceeded => OsUpdateResultCodeEnum.Succeeded,
|
||||
OperationResultCode.orcSucceededWithErrors => OsUpdateResultCodeEnum.SucceededWithErrors,
|
||||
OperationResultCode.orcFailed => OsUpdateResultCodeEnum.Failed,
|
||||
OperationResultCode.orcAborted => OsUpdateResultCodeEnum.Aborted,
|
||||
_ => null
|
||||
},
|
||||
SupportUrl = wupdate.SupportUrl,
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var rx = new Regex(@"KB(\d+)");
|
||||
update.Hotfix = rx.Match(wupdate.Title).Value;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
updates.Add(update);
|
||||
}
|
||||
|
||||
return updates;
|
||||
}
|
||||
|
||||
private static List<Update> QueryPendingUpdates()
|
||||
{
|
||||
var updates = new List<Update>();
|
||||
|
||||
var session = new UpdateSessionClass();
|
||||
var searcher = session.CreateUpdateSearcher();
|
||||
searcher.Online = true;
|
||||
|
||||
var result = searcher.Search("IsInstalled=0");
|
||||
|
||||
foreach (IUpdate wupdate in result.Updates)
|
||||
{
|
||||
var update = new Update
|
||||
{
|
||||
Id = wupdate.Identity.UpdateID,
|
||||
Type = wupdate.Type switch
|
||||
{
|
||||
UpdateType.utSoftware => OsUpdateTypeEnum.Software,
|
||||
UpdateType.utDriver => OsUpdateTypeEnum.Driver,
|
||||
_ => null
|
||||
},
|
||||
Date = wupdate.LastDeploymentChangeTime,
|
||||
Name = wupdate.Title,
|
||||
Description = wupdate.Description,
|
||||
SupportUrl = wupdate.SupportUrl,
|
||||
Size = wupdate.MaxDownloadSize,
|
||||
IsDownloaded = wupdate.IsDownloaded,
|
||||
CanRequestUserInput = wupdate.InstallationBehavior.CanRequestUserInput,
|
||||
RebootBehavior = wupdate.InstallationBehavior.RebootBehavior switch
|
||||
{
|
||||
InstallationRebootBehavior.irbNeverReboots => OsUpdateRebootBehaviorEnum.NeverReboots,
|
||||
InstallationRebootBehavior.irbAlwaysRequiresReboot => OsUpdateRebootBehaviorEnum.AlwaysRequiresReboot,
|
||||
InstallationRebootBehavior.irbCanRequestReboot => OsUpdateRebootBehaviorEnum.CanRequestReboot,
|
||||
_ => null
|
||||
},
|
||||
};
|
||||
|
||||
if (wupdate.KBArticleIDs.Count > 0)
|
||||
{
|
||||
foreach (var id in wupdate.KBArticleIDs)
|
||||
{
|
||||
update.Hotfix = $"KB{id}";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updates.Add(update);
|
||||
}
|
||||
|
||||
return updates;
|
||||
await sender.SendAsync(GetUpdates(), cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static UpdateList GetUpdates()
|
||||
{
|
||||
return new UpdateList
|
||||
{
|
||||
Installed = QueryInstalledUpdates(),
|
||||
Pending = QueryPendingUpdates()
|
||||
};
|
||||
}
|
||||
|
||||
private static List<Update> QueryInstalledUpdates()
|
||||
{
|
||||
var updates = new List<Update>();
|
||||
|
||||
var session = new UpdateSessionClass();
|
||||
var searcher = session.CreateUpdateSearcher();
|
||||
searcher.Online = false;
|
||||
|
||||
var count = searcher.GetTotalHistoryCount();
|
||||
var result = searcher.QueryHistory(0, count);
|
||||
|
||||
foreach (IUpdateHistoryEntry wupdate in result)
|
||||
{
|
||||
var update = new Update
|
||||
{
|
||||
Id = wupdate.UpdateIdentity.UpdateID,
|
||||
Date = wupdate.Date,
|
||||
Name = wupdate.Title,
|
||||
Description = wupdate.Description,
|
||||
Result = wupdate.ResultCode switch
|
||||
{
|
||||
OperationResultCode.orcNotStarted => OsUpdateResultCodeEnum.NotStarted,
|
||||
OperationResultCode.orcInProgress => OsUpdateResultCodeEnum.InProgress,
|
||||
OperationResultCode.orcSucceeded => OsUpdateResultCodeEnum.Succeeded,
|
||||
OperationResultCode.orcSucceededWithErrors => OsUpdateResultCodeEnum.SucceededWithErrors,
|
||||
OperationResultCode.orcFailed => OsUpdateResultCodeEnum.Failed,
|
||||
OperationResultCode.orcAborted => OsUpdateResultCodeEnum.Aborted,
|
||||
_ => null
|
||||
},
|
||||
SupportUrl = wupdate.SupportUrl,
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var rx = new Regex(@"KB(\d+)");
|
||||
update.Hotfix = rx.Match(wupdate.Title).Value;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
updates.Add(update);
|
||||
}
|
||||
|
||||
return updates;
|
||||
}
|
||||
|
||||
private static List<Update> QueryPendingUpdates()
|
||||
{
|
||||
var updates = new List<Update>();
|
||||
|
||||
var session = new UpdateSessionClass();
|
||||
var searcher = session.CreateUpdateSearcher();
|
||||
searcher.Online = true;
|
||||
|
||||
var result = searcher.Search("IsInstalled=0");
|
||||
|
||||
foreach (IUpdate wupdate in result.Updates)
|
||||
{
|
||||
var update = new Update
|
||||
{
|
||||
Id = wupdate.Identity.UpdateID,
|
||||
Type = wupdate.Type switch
|
||||
{
|
||||
UpdateType.utSoftware => OsUpdateTypeEnum.Software,
|
||||
UpdateType.utDriver => OsUpdateTypeEnum.Driver,
|
||||
_ => null
|
||||
},
|
||||
Date = wupdate.LastDeploymentChangeTime,
|
||||
Name = wupdate.Title,
|
||||
Description = wupdate.Description,
|
||||
SupportUrl = wupdate.SupportUrl,
|
||||
Size = wupdate.MaxDownloadSize,
|
||||
IsDownloaded = wupdate.IsDownloaded,
|
||||
CanRequestUserInput = wupdate.InstallationBehavior.CanRequestUserInput,
|
||||
RebootBehavior = wupdate.InstallationBehavior.RebootBehavior switch
|
||||
{
|
||||
InstallationRebootBehavior.irbNeverReboots => OsUpdateRebootBehaviorEnum.NeverReboots,
|
||||
InstallationRebootBehavior.irbAlwaysRequiresReboot => OsUpdateRebootBehaviorEnum.AlwaysRequiresReboot,
|
||||
InstallationRebootBehavior.irbCanRequestReboot => OsUpdateRebootBehaviorEnum.CanRequestReboot,
|
||||
_ => null
|
||||
},
|
||||
};
|
||||
|
||||
if (wupdate.KBArticleIDs.Count > 0)
|
||||
{
|
||||
foreach (var id in wupdate.KBArticleIDs)
|
||||
{
|
||||
update.Hotfix = $"KB{id}";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updates.Add(update);
|
||||
}
|
||||
|
||||
return updates;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,188 +1,188 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class UserHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class UserHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new UserList();
|
||||
result.AddRange(GetUsers());
|
||||
var result = new UserList();
|
||||
result.AddRange(GetUsers());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<User> GetUsers()
|
||||
{
|
||||
var users = QueryUsers();
|
||||
var groups = GetGroups();
|
||||
var usergrouping = QueryUserGroupMaps();
|
||||
|
||||
foreach (var u in users)
|
||||
{
|
||||
u.Groups = new List<Group>();
|
||||
|
||||
foreach (var ug in usergrouping.Where(ug => ug.UserDomain == u.Domain && ug.UserName == u.Name))
|
||||
{
|
||||
var grps = groups.Where(g => g.Domain == ug.GroupDomain && g.Name == ug.GroupName);
|
||||
|
||||
if (grps is not null)
|
||||
{
|
||||
u.Groups.AddRange(grps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
private static List<Group> GetGroups()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select sid, domain, name, description, localaccount from win32_group")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_group");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var groups = new List<Group>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var group = new Group();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
group.Sid = @object.GetValue<string>(properties, "sid")?.Trim();
|
||||
group.Domain = @object.GetValue<string>(properties, "domain")?.Trim();
|
||||
group.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
group.Description = @object.GetValue<string>(properties, "description")?.Trim();
|
||||
group.LocalAccount = @object.GetValue<bool>(properties, "localaccount");
|
||||
|
||||
groups.Add(group);
|
||||
}
|
||||
}
|
||||
|
||||
return groups.OrderBy(x => x.Name)?.ToList();
|
||||
}
|
||||
|
||||
private static List<User> QueryUsers()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select sid, name, fullname, description, domain, localaccount, disabled, lockout, status, passwordchangeable, passwordexpires, passwordrequired from win32_useraccount")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_useraccount");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var users = new List<User>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var user = new User();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
user.Sid = @object.GetValue<string>(properties, "sid")?.Trim();
|
||||
user.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
user.FullName = @object.GetValue<string>(properties, "fullname")?.Trim();
|
||||
user.Description = @object.GetValue<string>(properties, "description")?.Trim();
|
||||
user.Domain = @object.GetValue<string>(properties, "domain")?.Trim();
|
||||
user.LocalAccount = @object.GetValue<bool>(properties, "localaccount");
|
||||
user.Disabled = @object.GetValue<bool>(properties, "disabled");
|
||||
user.Lockout = @object.GetValue<bool>(properties, "lockout");
|
||||
user.Status = @object.GetValue<string>(properties, "status")?.Trim();
|
||||
user.PasswordChangeable = @object.GetValue<bool>(properties, "passwordchangeable");
|
||||
user.PasswordExpires = @object.GetValue<bool>(properties, "passwordexpires");
|
||||
user.PasswordRequired = @object.GetValue<bool>(properties, "passwordrequired");
|
||||
|
||||
users.Add(user);
|
||||
}
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
private static List<UserGroupMap> QueryUserGroupMaps()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select groupcomponent, partcomponent from win32_groupuser")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_groupuser");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var usergroups = new List<UserGroupMap>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var usergroup = new UserGroupMap();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
var raw = @object.GetValue<string>(properties, "groupcomponent");
|
||||
var split = raw?.Split(".Domain=")[1]?.Split(",Name=");
|
||||
|
||||
if (split is not null && split.Length > 1)
|
||||
{
|
||||
usergroup.GroupDomain = split[0].TrimStart('"').TrimEnd('"');
|
||||
usergroup.GroupName = split[1].TrimStart('"').TrimEnd('"');
|
||||
}
|
||||
|
||||
raw = @object.GetValue<string>(properties, "partcomponent");
|
||||
split = raw?.Split(".Domain=")[1]?.Split(",Name=");
|
||||
|
||||
if (split is not null && split.Length > 1)
|
||||
{
|
||||
usergroup.UserDomain = split[0].TrimStart('"').TrimEnd('"');
|
||||
usergroup.UserName = split[1].TrimStart('"').TrimEnd('"');
|
||||
}
|
||||
|
||||
usergroups.Add(usergroup);
|
||||
}
|
||||
}
|
||||
|
||||
return usergroups;
|
||||
}
|
||||
|
||||
private class UserGroupMap
|
||||
{
|
||||
public string? GroupDomain { get; set; }
|
||||
public string? GroupName { get; set; }
|
||||
|
||||
public string? UserDomain { get; set; }
|
||||
public string? UserName { get; set; }
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<User> GetUsers()
|
||||
{
|
||||
var users = QueryUsers();
|
||||
var groups = GetGroups();
|
||||
var usergrouping = QueryUserGroupMaps();
|
||||
|
||||
foreach (var u in users)
|
||||
{
|
||||
u.Groups = new List<Group>();
|
||||
|
||||
foreach (var ug in usergrouping.Where(ug => ug.UserDomain == u.Domain && ug.UserName == u.Name))
|
||||
{
|
||||
var grps = groups.Where(g => g.Domain == ug.GroupDomain && g.Name == ug.GroupName);
|
||||
|
||||
if (grps is not null)
|
||||
{
|
||||
u.Groups.AddRange(grps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
private static List<Group> GetGroups()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select sid, domain, name, description, localaccount from win32_group")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_group");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var groups = new List<Group>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var group = new Group();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
group.Sid = @object.GetValue<string>(properties, "sid")?.Trim();
|
||||
group.Domain = @object.GetValue<string>(properties, "domain")?.Trim();
|
||||
group.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
group.Description = @object.GetValue<string>(properties, "description")?.Trim();
|
||||
group.LocalAccount = @object.GetValue<bool>(properties, "localaccount");
|
||||
|
||||
groups.Add(group);
|
||||
}
|
||||
}
|
||||
|
||||
return groups.OrderBy(x => x.Name)?.ToList();
|
||||
}
|
||||
|
||||
private static List<User> QueryUsers()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select sid, name, fullname, description, domain, localaccount, disabled, lockout, status, passwordchangeable, passwordexpires, passwordrequired from win32_useraccount")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_useraccount");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var users = new List<User>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var user = new User();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
user.Sid = @object.GetValue<string>(properties, "sid")?.Trim();
|
||||
user.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
user.FullName = @object.GetValue<string>(properties, "fullname")?.Trim();
|
||||
user.Description = @object.GetValue<string>(properties, "description")?.Trim();
|
||||
user.Domain = @object.GetValue<string>(properties, "domain")?.Trim();
|
||||
user.LocalAccount = @object.GetValue<bool>(properties, "localaccount");
|
||||
user.Disabled = @object.GetValue<bool>(properties, "disabled");
|
||||
user.Lockout = @object.GetValue<bool>(properties, "lockout");
|
||||
user.Status = @object.GetValue<string>(properties, "status")?.Trim();
|
||||
user.PasswordChangeable = @object.GetValue<bool>(properties, "passwordchangeable");
|
||||
user.PasswordExpires = @object.GetValue<bool>(properties, "passwordexpires");
|
||||
user.PasswordRequired = @object.GetValue<bool>(properties, "passwordrequired");
|
||||
|
||||
users.Add(user);
|
||||
}
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
private static List<UserGroupMap> QueryUserGroupMaps()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select groupcomponent, partcomponent from win32_groupuser")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_groupuser");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var usergroups = new List<UserGroupMap>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection)
|
||||
{
|
||||
var usergroup = new UserGroupMap();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
var raw = @object.GetValue<string>(properties, "groupcomponent");
|
||||
var split = raw?.Split(".Domain=")[1]?.Split(",Name=");
|
||||
|
||||
if (split is not null && split.Length > 1)
|
||||
{
|
||||
usergroup.GroupDomain = split[0].TrimStart('"').TrimEnd('"');
|
||||
usergroup.GroupName = split[1].TrimStart('"').TrimEnd('"');
|
||||
}
|
||||
|
||||
raw = @object.GetValue<string>(properties, "partcomponent");
|
||||
split = raw?.Split(".Domain=")[1]?.Split(",Name=");
|
||||
|
||||
if (split is not null && split.Length > 1)
|
||||
{
|
||||
usergroup.UserDomain = split[0].TrimStart('"').TrimEnd('"');
|
||||
usergroup.UserName = split[1].TrimStart('"').TrimEnd('"');
|
||||
}
|
||||
|
||||
usergroups.Add(usergroup);
|
||||
}
|
||||
}
|
||||
|
||||
return usergroups;
|
||||
}
|
||||
|
||||
private class UserGroupMap
|
||||
{
|
||||
public string? GroupDomain { get; set; }
|
||||
public string? GroupName { get; set; }
|
||||
|
||||
public string? UserDomain { get; set; }
|
||||
public string? UserName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +1,64 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class VideocardHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class VideocardHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new VideocardList();
|
||||
result.AddRange(GetVideocards());
|
||||
var result = new VideocardList();
|
||||
result.AddRange(GetVideocards());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Videocard> GetVideocards()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select deviceid, name, adapterram, driverdate, driverversion from win32_videocontroller")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_videocontroller");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var videocards = new List<Videocard>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var videocard = new Videocard();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
videocard.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
videocard.Model = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "driverdate", out var driverdate))
|
||||
{
|
||||
videocard.DriverDate = ManagementDateTimeConverter.ToDateTime(driverdate?.ToString());
|
||||
}
|
||||
|
||||
videocard.DriverVersion = @object.GetValue<string>(properties, "driverversion")?.Trim();
|
||||
|
||||
videocards.Add(videocard);
|
||||
}
|
||||
}
|
||||
|
||||
return videocards;
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Videocard> GetVideocards()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\cimv2"),
|
||||
Query = new ObjectQuery("select deviceid, name, adapterram, driverdate, driverversion from win32_videocontroller")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var collection) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from win32_videocontroller");
|
||||
|
||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var videocards = new List<Videocard>();
|
||||
|
||||
using (collection)
|
||||
{
|
||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||
{
|
||||
var videocard = new Videocard();
|
||||
|
||||
var properties = @object.GetPropertyHashes();
|
||||
|
||||
videocard.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
||||
videocard.Model = @object.GetValue<string>(properties, "name")?.Trim();
|
||||
|
||||
if (@object.TryGetValue<object>(properties, "driverdate", out var driverdate))
|
||||
{
|
||||
videocard.DriverDate = ManagementDateTimeConverter.ToDateTime(driverdate?.ToString());
|
||||
}
|
||||
|
||||
videocard.DriverVersion = @object.GetValue<string>(properties, "driverversion")?.Trim();
|
||||
|
||||
videocards.Add(videocard);
|
||||
}
|
||||
}
|
||||
|
||||
return videocards;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,359 +1,359 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using System.Management;
|
||||
using System.Runtime.Versioning;
|
||||
using static Insight.Agent.Messages.VirtualMaschine;
|
||||
using static Insight.Agent.Messages.VirtualMaschineConfiguration;
|
||||
using static Insight.Domain.Messages.Agent.VirtualMaschine;
|
||||
using static Insight.Domain.Messages.Agent.VirtualMaschineConfiguration;
|
||||
|
||||
namespace Insight.Agent.Network.Handlers
|
||||
namespace Insight.Agent.Network.Handlers;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class VirtualMaschineHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class VirtualMaschineHandler : IAgentMessageHandler<AgentSession>
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is InventoryRequest)
|
||||
{
|
||||
if (message is GetInventory)
|
||||
{
|
||||
var result = new VirtualMaschineList();
|
||||
result.AddRange(GetVirtualMaschines());
|
||||
var result = new VirtualMaschineList();
|
||||
result.AddRange(GetVirtualMaschines());
|
||||
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<VirtualMaschine> GetVirtualMaschines()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\virtualization\v2"),
|
||||
Query = new ObjectQuery("select * msvm_computersystem")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var computersystems) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msvm_computersystem");
|
||||
|
||||
if (searcher.TryGet(out computersystems) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var vms = new List<VirtualMaschine>();
|
||||
|
||||
using (computersystems)
|
||||
{
|
||||
foreach (ManagementObject cs in computersystems.Cast<ManagementObject>())
|
||||
{
|
||||
var vm = new VirtualMaschine();
|
||||
|
||||
var csProperties = cs.GetPropertyHashes();
|
||||
|
||||
var vmId = cs.GetValue<string>(csProperties, "name")?.Trim();
|
||||
|
||||
if (Guid.TryParse(vmId, out var vmGuid) is false) continue;
|
||||
|
||||
vm.Id = vmGuid;
|
||||
vm.ProcessId = cs.GetValue<uint>(csProperties, "processid");
|
||||
vm.Caption = cs.GetValue<string>(csProperties, "caption")?.Trim();
|
||||
vm.Name = cs.GetValue<string>(csProperties, "elementname")?.Trim();
|
||||
vm.Enabled = (EnabledEnum)cs.GetValue<ushort>(csProperties, "enabledstate");
|
||||
vm.EnabledDefault = (EnabledDefaultEnum)cs.GetValue<ushort>(csProperties, "enableddefault");
|
||||
vm.HealthState = (HealthStatusEnum)cs.GetValue<ushort>(csProperties, "healthstate");
|
||||
vm.Status = cs.GetValue<string>(csProperties, "status")?.Trim();
|
||||
vm.OnTime = cs.GetValue<ulong>(csProperties, "ontimeinmilliseconds");
|
||||
vm.ReplicationMode = cs.GetValue<ushort>(csProperties, "replicationmode");
|
||||
vm.ReplicationState = (ReplicationStateEnum)cs.GetValue<ushort>(csProperties, "replicationstate");
|
||||
vm.ReplicationHealth = (ReplicationHealthEnum)cs.GetValue<ushort>(csProperties, "replicationhealth");
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "installdate", out var installdate))
|
||||
{
|
||||
vm.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "timeoflastconfigurationchange", out var timeoflastconfigurationchange))
|
||||
{
|
||||
vm.TimeOfLastConfigurationChange = ManagementDateTimeConverter.ToDateTime(timeoflastconfigurationchange?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "timeoflaststatechange", out var timeoflaststatechange))
|
||||
{
|
||||
vm.TimeOfLastStateChange = ManagementDateTimeConverter.ToDateTime(timeoflaststatechange?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "lastreplicationtime", out var lastreplicationtime))
|
||||
{
|
||||
vm.LastReplicationTime = ManagementDateTimeConverter.ToDateTime(lastreplicationtime?.ToString());
|
||||
}
|
||||
|
||||
var summaryinformation = cs.GetRelated("msvm_summaryinformation");
|
||||
using (summaryinformation)
|
||||
{
|
||||
foreach (ManagementObject si in summaryinformation.Cast<ManagementObject>())
|
||||
{
|
||||
var siProperties = si.GetPropertyHashes();
|
||||
|
||||
vm.Notes = si.GetValue<string>(siProperties, "Notes");
|
||||
vm.ConfigurationVersion = si.GetValue<string>(siProperties, "Version");
|
||||
vm.IntegrationServicesVersionState = (IntegrationServicesVersionStateEnum)si.GetValue<ushort>(siProperties, "IntegrationServicesVersionState");
|
||||
vm.GuestOperatingSystem = si.GetValue<string>(siProperties, "GuestOperatingSystem");
|
||||
vm.NumberOfProcessors = si.GetValue<ushort>(siProperties, "NumberOfProcessors");
|
||||
vm.ProcessorLoad = si.GetValue<ushort>(siProperties, "ProcessorLoad");
|
||||
vm.MemoryAvailable = si.GetValue<int>(siProperties, "MemoryAvailable");
|
||||
vm.MemoryUsage = si.GetValue<ulong>(siProperties, "MemoryUsage");
|
||||
}
|
||||
}
|
||||
|
||||
var virtualSystemSettingData = cs.GetRelated("Msvm_VirtualSystemSettingData");
|
||||
using (virtualSystemSettingData)
|
||||
{
|
||||
var configs = new List<VirtualMaschineConfiguration>();
|
||||
|
||||
foreach (ManagementObject vssd in virtualSystemSettingData.Cast<ManagementObject>())
|
||||
{
|
||||
var vmc = new VirtualMaschineConfiguration();
|
||||
|
||||
var vssdProperties = vssd.GetPropertyHashes();
|
||||
|
||||
var vmcId = vssd.GetValue<string>(vssdProperties, "ConfigurationID")?.Trim();
|
||||
|
||||
if (Guid.TryParse(vmcId, out var vmcGuid) is false) continue;
|
||||
|
||||
vmc.Id = vmcGuid.ToString();
|
||||
|
||||
vmc.Type = vssd.GetValue<string>(vssdProperties, "VirtualSystemType");
|
||||
vmc.Name = vssd.GetValue<string>(vssdProperties, "ElementName");
|
||||
|
||||
if (vssd.TryGetValue<object>(vssdProperties, "CreationTime", out var creationtime))
|
||||
{
|
||||
vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(creationtime?.ToString());
|
||||
}
|
||||
|
||||
vmc.Generation = vssd.GetValue<string>(vssdProperties, "VirtualSystemSubType");
|
||||
vmc.Architecture = vssd.GetValue<string>(vssdProperties, "Architecture");
|
||||
vmc.AutomaticStartupAction = (AutomaticStartupActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticStartupAction");
|
||||
vmc.AutomaticShutdownAction = (AutomaticShutdownActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticShutdownAction");
|
||||
vmc.AutomaticRecoveryAction = (AutomaticRecoveryActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticRecoveryAction");
|
||||
vmc.AutomaticSnapshotsEnabled = vssd.GetValue<bool>(vssdProperties, "AutomaticSnapshotsEnabled");
|
||||
|
||||
//if (vssd.TryGetValue<object>(vssdProperties, "AutomaticStartupActionDelay", out var automaticstartupactiondelay))
|
||||
//{
|
||||
// vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(automaticstartupactiondelay?.ToString());
|
||||
//}
|
||||
|
||||
vmc.BaseBoardSerialNumber = vssd.GetValue<string>(vssdProperties, "BaseBoardSerialNumber");
|
||||
vmc.BIOSGUID = vssd.GetValue<string>(vssdProperties, "BIOSGUID");
|
||||
vmc.BIOSSerialNumber = vssd.GetValue<string>(vssdProperties, "BIOSSerialNumber");
|
||||
vmc.BootOrder = vssd.GetValue<ushort[]>(vssdProperties, "BootOrder");
|
||||
vmc.ConfigurationDataRoot = vssd.GetValue<string>(vssdProperties, "ConfigurationDataRoot");
|
||||
vmc.ConfigurationFile = vssd.GetValue<string>(vssdProperties, "ConfigurationFile");
|
||||
vmc.GuestStateDataRoot = vssd.GetValue<string>(vssdProperties, "GuestStateDataRoot");
|
||||
vmc.GuestStateFile = vssd.GetValue<string>(vssdProperties, "GuestStateFile");
|
||||
vmc.SnapshotDataRoot = vssd.GetValue<string>(vssdProperties, "SnapshotDataRoot");
|
||||
vmc.SuspendDataRoot = vssd.GetValue<string>(vssdProperties, "SuspendDataRoot");
|
||||
vmc.SwapFileDataRoot = vssd.GetValue<string>(vssdProperties, "SwapFileDataRoot");
|
||||
vmc.SecureBootEnabled = vssd.GetValue<bool>(vssdProperties, "SecureBootEnabled");
|
||||
vmc.IsAutomaticSnapshot = vssd.GetValue<bool>(vssdProperties, "IsAutomaticSnapshot");
|
||||
vmc.Notes = vssd.GetValue<string[]>(vssdProperties, "Notes");
|
||||
|
||||
if (vssd.GetValue<string>(vssdProperties, "Parent") is string parent)
|
||||
{
|
||||
using var vmcp = new ManagementObject(parent);
|
||||
vmcp.Get();
|
||||
|
||||
if (Guid.TryParse(vmcp["ConfigurationID"]?.ToString(), out var parentGuid) is false) continue;
|
||||
vmc.ParentId = parentGuid.ToString();
|
||||
}
|
||||
|
||||
//var storageallocationsettingdata = cs.GetRelated("Msvm_StorageAllocationSettingData");
|
||||
//using (storageallocationsettingdata)
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
configs.Add(vmc);
|
||||
}
|
||||
|
||||
vm.Configurations = configs.GroupBy(p => p.Id).Select(p => p.First()).ToList();
|
||||
}
|
||||
|
||||
vms.Add(vm);
|
||||
}
|
||||
}
|
||||
|
||||
return vms;
|
||||
}
|
||||
|
||||
private static List<VirtualMaschine> QueryVirtualMaschines0()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\virtualization\v2"),
|
||||
Query = new ObjectQuery("select * msvm_computersystem")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var computersystems) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msvm_computersystem");
|
||||
|
||||
if (searcher.TryGet(out computersystems) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var vms = new List<VirtualMaschine>();
|
||||
|
||||
using (computersystems)
|
||||
{
|
||||
foreach (ManagementObject cs in computersystems.Cast<ManagementObject>())
|
||||
{
|
||||
var vm = new VirtualMaschine();
|
||||
|
||||
var csProperties = cs.GetPropertyHashes();
|
||||
|
||||
var vmId = cs.GetValue<string>(csProperties, "name")?.Trim();
|
||||
|
||||
if (Guid.TryParse(vmId, out var vmGuid) is false) continue;
|
||||
|
||||
vm.Id = vmGuid;
|
||||
vm.ProcessId = cs.GetValue<uint>(csProperties, "processid");
|
||||
vm.Caption = cs.GetValue<string>(csProperties, "caption")?.Trim();
|
||||
vm.Name = cs.GetValue<string>(csProperties, "elementname")?.Trim();
|
||||
vm.Enabled = (EnabledEnum)cs.GetValue<ushort>(csProperties, "enabledstate");
|
||||
vm.EnabledDefault = (EnabledDefaultEnum)cs.GetValue<ushort>(csProperties, "enableddefault");
|
||||
vm.HealthState = (HealthStatusEnum)cs.GetValue<ushort>(csProperties, "healthstate");
|
||||
vm.Status = cs.GetValue<string>(csProperties, "status")?.Trim();
|
||||
vm.OnTime = cs.GetValue<ulong>(csProperties, "ontimeinmilliseconds");
|
||||
vm.ReplicationMode = cs.GetValue<ushort>(csProperties, "replicationmode");
|
||||
vm.ReplicationState = (ReplicationStateEnum)cs.GetValue<ushort>(csProperties, "replicationstate");
|
||||
vm.ReplicationHealth = (ReplicationHealthEnum)cs.GetValue<ushort>(csProperties, "replicationhealth");
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "installdate", out var installdate))
|
||||
{
|
||||
vm.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "timeoflastconfigurationchange", out var timeoflastconfigurationchange))
|
||||
{
|
||||
vm.TimeOfLastConfigurationChange = ManagementDateTimeConverter.ToDateTime(timeoflastconfigurationchange?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "timeoflaststatechange", out var timeoflaststatechange))
|
||||
{
|
||||
vm.TimeOfLastStateChange = ManagementDateTimeConverter.ToDateTime(timeoflaststatechange?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "lastreplicationtime", out var lastreplicationtime))
|
||||
{
|
||||
vm.LastReplicationTime = ManagementDateTimeConverter.ToDateTime(lastreplicationtime?.ToString());
|
||||
}
|
||||
|
||||
var summaryinformation = cs.GetRelated("msvm_summaryinformation");
|
||||
using (summaryinformation)
|
||||
{
|
||||
foreach (ManagementObject si in summaryinformation.Cast<ManagementObject>())
|
||||
{
|
||||
var siProperties = si.GetPropertyHashes();
|
||||
|
||||
vm.Notes = si.GetValue<string>(siProperties, "Notes");
|
||||
vm.ConfigurationVersion = si.GetValue<string>(siProperties, "Version");
|
||||
vm.IntegrationServicesVersionState = (IntegrationServicesVersionStateEnum)si.GetValue<ushort>(siProperties, "IntegrationServicesVersionState");
|
||||
vm.GuestOperatingSystem = si.GetValue<string>(siProperties, "GuestOperatingSystem");
|
||||
vm.NumberOfProcessors = si.GetValue<ushort>(siProperties, "NumberOfProcessors");
|
||||
vm.ProcessorLoad = si.GetValue<ushort>(siProperties, "ProcessorLoad");
|
||||
vm.MemoryAvailable = si.GetValue<int>(siProperties, "MemoryAvailable");
|
||||
vm.MemoryUsage = si.GetValue<ulong>(siProperties, "MemoryUsage");
|
||||
}
|
||||
}
|
||||
|
||||
var virtualSystemSettingData = cs.GetRelated("Msvm_VirtualSystemSettingData");
|
||||
using (virtualSystemSettingData)
|
||||
{
|
||||
var configs = new List<VirtualMaschineConfiguration>();
|
||||
|
||||
foreach (ManagementObject vssd in virtualSystemSettingData.Cast<ManagementObject>())
|
||||
{
|
||||
var vmc = new VirtualMaschineConfiguration();
|
||||
|
||||
var vssdProperties = vssd.GetPropertyHashes();
|
||||
|
||||
var vmcId = vssd.GetValue<string>(vssdProperties, "ConfigurationID")?.Trim();
|
||||
|
||||
if (Guid.TryParse(vmcId, out var vmcGuid) is false) continue;
|
||||
|
||||
vmc.Id = vmcGuid.ToString();
|
||||
|
||||
vmc.Type = vssd.GetValue<string>(vssdProperties, "VirtualSystemType");
|
||||
vmc.Name = vssd.GetValue<string>(vssdProperties, "ElementName");
|
||||
|
||||
if (vssd.TryGetValue<object>(vssdProperties, "CreationTime", out var creationtime))
|
||||
{
|
||||
vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(creationtime?.ToString());
|
||||
}
|
||||
|
||||
vmc.Generation = vssd.GetValue<string>(vssdProperties, "VirtualSystemSubType");
|
||||
vmc.Architecture = vssd.GetValue<string>(vssdProperties, "Architecture");
|
||||
vmc.AutomaticStartupAction = (AutomaticStartupActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticStartupAction");
|
||||
|
||||
//if (vssd.TryGetValue<object>(vssdProperties, "AutomaticStartupActionDelay", out var automaticstartupactiondelay))
|
||||
//{
|
||||
// vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(automaticstartupactiondelay?.ToString());
|
||||
//}
|
||||
|
||||
vmc.AutomaticShutdownAction = (AutomaticShutdownActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticShutdownAction");
|
||||
vmc.AutomaticRecoveryAction = (AutomaticRecoveryActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticRecoveryAction");
|
||||
vmc.AutomaticSnapshotsEnabled = vssd.GetValue<bool>(vssdProperties, "AutomaticSnapshotsEnabled");
|
||||
|
||||
vmc.BaseBoardSerialNumber = vssd.GetValue<string>(vssdProperties, "BaseBoardSerialNumber");
|
||||
vmc.BIOSGUID = vssd.GetValue<string>(vssdProperties, "BIOSGUID");
|
||||
vmc.BIOSSerialNumber = vssd.GetValue<string>(vssdProperties, "BIOSSerialNumber");
|
||||
vmc.BootOrder = vssd.GetValue<ushort[]>(vssdProperties, "BootOrder");
|
||||
vmc.ConfigurationDataRoot = vssd.GetValue<string>(vssdProperties, "ConfigurationDataRoot");
|
||||
vmc.ConfigurationFile = vssd.GetValue<string>(vssdProperties, "ConfigurationFile");
|
||||
vmc.GuestStateDataRoot = vssd.GetValue<string>(vssdProperties, "GuestStateDataRoot");
|
||||
vmc.GuestStateFile = vssd.GetValue<string>(vssdProperties, "GuestStateFile");
|
||||
vmc.SnapshotDataRoot = vssd.GetValue<string>(vssdProperties, "SnapshotDataRoot");
|
||||
vmc.SuspendDataRoot = vssd.GetValue<string>(vssdProperties, "SuspendDataRoot");
|
||||
vmc.SwapFileDataRoot = vssd.GetValue<string>(vssdProperties, "SwapFileDataRoot");
|
||||
vmc.SecureBootEnabled = vssd.GetValue<bool>(vssdProperties, "SecureBootEnabled");
|
||||
vmc.IsAutomaticSnapshot = vssd.GetValue<bool>(vssdProperties, "IsAutomaticSnapshot");
|
||||
vmc.Notes = vssd.GetValue<string[]>(vssdProperties, "Notes");
|
||||
vmc.ParentId = vssd.GetValue<string>(vssdProperties, "Parent");
|
||||
|
||||
var storageallocationsettingdata = cs.GetRelated("Msvm_StorageAllocationSettingData");
|
||||
using (storageallocationsettingdata)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
configs.Add(vmc);
|
||||
}
|
||||
|
||||
configs = configs.GroupBy(p => p.Id).Select(p => p.First()).ToList();
|
||||
if (configs.Any(p => p.ParentId is not null))
|
||||
{
|
||||
foreach (var conf in configs.Where(p => p.ParentId is not null))
|
||||
{
|
||||
using var parent = new ManagementObject(conf.ParentId);
|
||||
parent.Get();
|
||||
|
||||
if (Guid.TryParse(parent["ConfigurationID"]?.ToString(), out var parentGuid) && configs.FirstOrDefault(p => p.Id == parentGuid.ToString()) is VirtualMaschineConfiguration parentConfig)
|
||||
{
|
||||
conf.ParentId = parentGuid.ToString();
|
||||
|
||||
parentConfig.Childs ??= new List<VirtualMaschineConfiguration>();
|
||||
parentConfig.Childs.Add(conf);
|
||||
}
|
||||
else
|
||||
{
|
||||
conf.ParentId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.Configurations = configs.Where(p => p.ParentId is null).ToList();
|
||||
}
|
||||
|
||||
vms.Add(vm);
|
||||
}
|
||||
}
|
||||
|
||||
return vms;
|
||||
await sender.SendAsync(result, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<VirtualMaschine> GetVirtualMaschines()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\virtualization\v2"),
|
||||
Query = new ObjectQuery("select * msvm_computersystem")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var computersystems) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msvm_computersystem");
|
||||
|
||||
if (searcher.TryGet(out computersystems) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var vms = new List<VirtualMaschine>();
|
||||
|
||||
using (computersystems)
|
||||
{
|
||||
foreach (ManagementObject cs in computersystems.Cast<ManagementObject>())
|
||||
{
|
||||
var vm = new VirtualMaschine();
|
||||
|
||||
var csProperties = cs.GetPropertyHashes();
|
||||
|
||||
var vmId = cs.GetValue<string>(csProperties, "name")?.Trim();
|
||||
|
||||
if (Guid.TryParse(vmId, out var vmGuid) is false) continue;
|
||||
|
||||
vm.Id = vmGuid;
|
||||
vm.ProcessId = cs.GetValue<uint>(csProperties, "processid");
|
||||
vm.Caption = cs.GetValue<string>(csProperties, "caption")?.Trim();
|
||||
vm.Name = cs.GetValue<string>(csProperties, "elementname")?.Trim();
|
||||
vm.Enabled = (EnabledEnum)cs.GetValue<ushort>(csProperties, "enabledstate");
|
||||
vm.EnabledDefault = (EnabledDefaultEnum)cs.GetValue<ushort>(csProperties, "enableddefault");
|
||||
vm.HealthState = (HealthStatusEnum)cs.GetValue<ushort>(csProperties, "healthstate");
|
||||
vm.Status = cs.GetValue<string>(csProperties, "status")?.Trim();
|
||||
vm.OnTime = cs.GetValue<ulong>(csProperties, "ontimeinmilliseconds");
|
||||
vm.ReplicationMode = cs.GetValue<ushort>(csProperties, "replicationmode");
|
||||
vm.ReplicationState = (ReplicationStateEnum)cs.GetValue<ushort>(csProperties, "replicationstate");
|
||||
vm.ReplicationHealth = (ReplicationHealthEnum)cs.GetValue<ushort>(csProperties, "replicationhealth");
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "installdate", out var installdate))
|
||||
{
|
||||
vm.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "timeoflastconfigurationchange", out var timeoflastconfigurationchange))
|
||||
{
|
||||
vm.TimeOfLastConfigurationChange = ManagementDateTimeConverter.ToDateTime(timeoflastconfigurationchange?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "timeoflaststatechange", out var timeoflaststatechange))
|
||||
{
|
||||
vm.TimeOfLastStateChange = ManagementDateTimeConverter.ToDateTime(timeoflaststatechange?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "lastreplicationtime", out var lastreplicationtime))
|
||||
{
|
||||
vm.LastReplicationTime = ManagementDateTimeConverter.ToDateTime(lastreplicationtime?.ToString());
|
||||
}
|
||||
|
||||
var summaryinformation = cs.GetRelated("msvm_summaryinformation");
|
||||
using (summaryinformation)
|
||||
{
|
||||
foreach (ManagementObject si in summaryinformation.Cast<ManagementObject>())
|
||||
{
|
||||
var siProperties = si.GetPropertyHashes();
|
||||
|
||||
vm.Notes = si.GetValue<string>(siProperties, "Notes");
|
||||
vm.ConfigurationVersion = si.GetValue<string>(siProperties, "Version");
|
||||
vm.IntegrationServicesVersionState = (IntegrationServicesVersionStateEnum)si.GetValue<ushort>(siProperties, "IntegrationServicesVersionState");
|
||||
vm.GuestOperatingSystem = si.GetValue<string>(siProperties, "GuestOperatingSystem");
|
||||
vm.NumberOfProcessors = si.GetValue<ushort>(siProperties, "NumberOfProcessors");
|
||||
vm.ProcessorLoad = si.GetValue<ushort>(siProperties, "ProcessorLoad");
|
||||
vm.MemoryAvailable = si.GetValue<int>(siProperties, "MemoryAvailable");
|
||||
vm.MemoryUsage = si.GetValue<ulong>(siProperties, "MemoryUsage");
|
||||
}
|
||||
}
|
||||
|
||||
var virtualSystemSettingData = cs.GetRelated("Msvm_VirtualSystemSettingData");
|
||||
using (virtualSystemSettingData)
|
||||
{
|
||||
var configs = new List<VirtualMaschineConfiguration>();
|
||||
|
||||
foreach (ManagementObject vssd in virtualSystemSettingData.Cast<ManagementObject>())
|
||||
{
|
||||
var vmc = new VirtualMaschineConfiguration();
|
||||
|
||||
var vssdProperties = vssd.GetPropertyHashes();
|
||||
|
||||
var vmcId = vssd.GetValue<string>(vssdProperties, "ConfigurationID")?.Trim();
|
||||
|
||||
if (Guid.TryParse(vmcId, out var vmcGuid) is false) continue;
|
||||
|
||||
vmc.Id = vmcGuid.ToString();
|
||||
|
||||
vmc.Type = vssd.GetValue<string>(vssdProperties, "VirtualSystemType");
|
||||
vmc.Name = vssd.GetValue<string>(vssdProperties, "ElementName");
|
||||
|
||||
if (vssd.TryGetValue<object>(vssdProperties, "CreationTime", out var creationtime))
|
||||
{
|
||||
vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(creationtime?.ToString());
|
||||
}
|
||||
|
||||
vmc.Generation = vssd.GetValue<string>(vssdProperties, "VirtualSystemSubType");
|
||||
vmc.Architecture = vssd.GetValue<string>(vssdProperties, "Architecture");
|
||||
vmc.AutomaticStartupAction = (AutomaticStartupActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticStartupAction");
|
||||
vmc.AutomaticShutdownAction = (AutomaticShutdownActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticShutdownAction");
|
||||
vmc.AutomaticRecoveryAction = (AutomaticRecoveryActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticRecoveryAction");
|
||||
vmc.AutomaticSnapshotsEnabled = vssd.GetValue<bool>(vssdProperties, "AutomaticSnapshotsEnabled");
|
||||
|
||||
//if (vssd.TryGetValue<object>(vssdProperties, "AutomaticStartupActionDelay", out var automaticstartupactiondelay))
|
||||
//{
|
||||
// vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(automaticstartupactiondelay?.ToString());
|
||||
//}
|
||||
|
||||
vmc.BaseBoardSerialNumber = vssd.GetValue<string>(vssdProperties, "BaseBoardSerialNumber");
|
||||
vmc.BIOSGUID = vssd.GetValue<string>(vssdProperties, "BIOSGUID");
|
||||
vmc.BIOSSerialNumber = vssd.GetValue<string>(vssdProperties, "BIOSSerialNumber");
|
||||
vmc.BootOrder = vssd.GetValue<ushort[]>(vssdProperties, "BootOrder");
|
||||
vmc.ConfigurationDataRoot = vssd.GetValue<string>(vssdProperties, "ConfigurationDataRoot");
|
||||
vmc.ConfigurationFile = vssd.GetValue<string>(vssdProperties, "ConfigurationFile");
|
||||
vmc.GuestStateDataRoot = vssd.GetValue<string>(vssdProperties, "GuestStateDataRoot");
|
||||
vmc.GuestStateFile = vssd.GetValue<string>(vssdProperties, "GuestStateFile");
|
||||
vmc.SnapshotDataRoot = vssd.GetValue<string>(vssdProperties, "SnapshotDataRoot");
|
||||
vmc.SuspendDataRoot = vssd.GetValue<string>(vssdProperties, "SuspendDataRoot");
|
||||
vmc.SwapFileDataRoot = vssd.GetValue<string>(vssdProperties, "SwapFileDataRoot");
|
||||
vmc.SecureBootEnabled = vssd.GetValue<bool>(vssdProperties, "SecureBootEnabled");
|
||||
vmc.IsAutomaticSnapshot = vssd.GetValue<bool>(vssdProperties, "IsAutomaticSnapshot");
|
||||
vmc.Notes = vssd.GetValue<string[]>(vssdProperties, "Notes");
|
||||
|
||||
if (vssd.GetValue<string>(vssdProperties, "Parent") is string parent)
|
||||
{
|
||||
using var vmcp = new ManagementObject(parent);
|
||||
vmcp.Get();
|
||||
|
||||
if (Guid.TryParse(vmcp["ConfigurationID"]?.ToString(), out var parentGuid) is false) continue;
|
||||
vmc.ParentId = parentGuid.ToString();
|
||||
}
|
||||
|
||||
//var storageallocationsettingdata = cs.GetRelated("Msvm_StorageAllocationSettingData");
|
||||
//using (storageallocationsettingdata)
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
configs.Add(vmc);
|
||||
}
|
||||
|
||||
vm.Configurations = configs.GroupBy(p => p.Id).Select(p => p.First()).ToList();
|
||||
}
|
||||
|
||||
vms.Add(vm);
|
||||
}
|
||||
}
|
||||
|
||||
return vms;
|
||||
}
|
||||
|
||||
private static List<VirtualMaschine> QueryVirtualMaschines0()
|
||||
{
|
||||
using var searcher = new ManagementObjectSearcher
|
||||
{
|
||||
Scope = new ManagementScope(@"root\virtualization\v2"),
|
||||
Query = new ObjectQuery("select * msvm_computersystem")
|
||||
};
|
||||
|
||||
if (searcher.TryGet(out var computersystems) is false)
|
||||
{
|
||||
searcher.Query = new ObjectQuery("select * from msvm_computersystem");
|
||||
|
||||
if (searcher.TryGet(out computersystems) is false) throw new InvalidOperationException("WMI Collection NULL");
|
||||
}
|
||||
|
||||
var vms = new List<VirtualMaschine>();
|
||||
|
||||
using (computersystems)
|
||||
{
|
||||
foreach (ManagementObject cs in computersystems.Cast<ManagementObject>())
|
||||
{
|
||||
var vm = new VirtualMaschine();
|
||||
|
||||
var csProperties = cs.GetPropertyHashes();
|
||||
|
||||
var vmId = cs.GetValue<string>(csProperties, "name")?.Trim();
|
||||
|
||||
if (Guid.TryParse(vmId, out var vmGuid) is false) continue;
|
||||
|
||||
vm.Id = vmGuid;
|
||||
vm.ProcessId = cs.GetValue<uint>(csProperties, "processid");
|
||||
vm.Caption = cs.GetValue<string>(csProperties, "caption")?.Trim();
|
||||
vm.Name = cs.GetValue<string>(csProperties, "elementname")?.Trim();
|
||||
vm.Enabled = (EnabledEnum)cs.GetValue<ushort>(csProperties, "enabledstate");
|
||||
vm.EnabledDefault = (EnabledDefaultEnum)cs.GetValue<ushort>(csProperties, "enableddefault");
|
||||
vm.HealthState = (HealthStatusEnum)cs.GetValue<ushort>(csProperties, "healthstate");
|
||||
vm.Status = cs.GetValue<string>(csProperties, "status")?.Trim();
|
||||
vm.OnTime = cs.GetValue<ulong>(csProperties, "ontimeinmilliseconds");
|
||||
vm.ReplicationMode = cs.GetValue<ushort>(csProperties, "replicationmode");
|
||||
vm.ReplicationState = (ReplicationStateEnum)cs.GetValue<ushort>(csProperties, "replicationstate");
|
||||
vm.ReplicationHealth = (ReplicationHealthEnum)cs.GetValue<ushort>(csProperties, "replicationhealth");
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "installdate", out var installdate))
|
||||
{
|
||||
vm.InstallDate = ManagementDateTimeConverter.ToDateTime(installdate?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "timeoflastconfigurationchange", out var timeoflastconfigurationchange))
|
||||
{
|
||||
vm.TimeOfLastConfigurationChange = ManagementDateTimeConverter.ToDateTime(timeoflastconfigurationchange?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "timeoflaststatechange", out var timeoflaststatechange))
|
||||
{
|
||||
vm.TimeOfLastStateChange = ManagementDateTimeConverter.ToDateTime(timeoflaststatechange?.ToString());
|
||||
}
|
||||
|
||||
if (cs.TryGetValue<object>(csProperties, "lastreplicationtime", out var lastreplicationtime))
|
||||
{
|
||||
vm.LastReplicationTime = ManagementDateTimeConverter.ToDateTime(lastreplicationtime?.ToString());
|
||||
}
|
||||
|
||||
var summaryinformation = cs.GetRelated("msvm_summaryinformation");
|
||||
using (summaryinformation)
|
||||
{
|
||||
foreach (ManagementObject si in summaryinformation.Cast<ManagementObject>())
|
||||
{
|
||||
var siProperties = si.GetPropertyHashes();
|
||||
|
||||
vm.Notes = si.GetValue<string>(siProperties, "Notes");
|
||||
vm.ConfigurationVersion = si.GetValue<string>(siProperties, "Version");
|
||||
vm.IntegrationServicesVersionState = (IntegrationServicesVersionStateEnum)si.GetValue<ushort>(siProperties, "IntegrationServicesVersionState");
|
||||
vm.GuestOperatingSystem = si.GetValue<string>(siProperties, "GuestOperatingSystem");
|
||||
vm.NumberOfProcessors = si.GetValue<ushort>(siProperties, "NumberOfProcessors");
|
||||
vm.ProcessorLoad = si.GetValue<ushort>(siProperties, "ProcessorLoad");
|
||||
vm.MemoryAvailable = si.GetValue<int>(siProperties, "MemoryAvailable");
|
||||
vm.MemoryUsage = si.GetValue<ulong>(siProperties, "MemoryUsage");
|
||||
}
|
||||
}
|
||||
|
||||
var virtualSystemSettingData = cs.GetRelated("Msvm_VirtualSystemSettingData");
|
||||
using (virtualSystemSettingData)
|
||||
{
|
||||
var configs = new List<VirtualMaschineConfiguration>();
|
||||
|
||||
foreach (ManagementObject vssd in virtualSystemSettingData.Cast<ManagementObject>())
|
||||
{
|
||||
var vmc = new VirtualMaschineConfiguration();
|
||||
|
||||
var vssdProperties = vssd.GetPropertyHashes();
|
||||
|
||||
var vmcId = vssd.GetValue<string>(vssdProperties, "ConfigurationID")?.Trim();
|
||||
|
||||
if (Guid.TryParse(vmcId, out var vmcGuid) is false) continue;
|
||||
|
||||
vmc.Id = vmcGuid.ToString();
|
||||
|
||||
vmc.Type = vssd.GetValue<string>(vssdProperties, "VirtualSystemType");
|
||||
vmc.Name = vssd.GetValue<string>(vssdProperties, "ElementName");
|
||||
|
||||
if (vssd.TryGetValue<object>(vssdProperties, "CreationTime", out var creationtime))
|
||||
{
|
||||
vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(creationtime?.ToString());
|
||||
}
|
||||
|
||||
vmc.Generation = vssd.GetValue<string>(vssdProperties, "VirtualSystemSubType");
|
||||
vmc.Architecture = vssd.GetValue<string>(vssdProperties, "Architecture");
|
||||
vmc.AutomaticStartupAction = (AutomaticStartupActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticStartupAction");
|
||||
|
||||
//if (vssd.TryGetValue<object>(vssdProperties, "AutomaticStartupActionDelay", out var automaticstartupactiondelay))
|
||||
//{
|
||||
// vmc.CreationTime = ManagementDateTimeConverter.ToDateTime(automaticstartupactiondelay?.ToString());
|
||||
//}
|
||||
|
||||
vmc.AutomaticShutdownAction = (AutomaticShutdownActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticShutdownAction");
|
||||
vmc.AutomaticRecoveryAction = (AutomaticRecoveryActionEnum)vssd.GetValue<uint>(vssdProperties, "AutomaticRecoveryAction");
|
||||
vmc.AutomaticSnapshotsEnabled = vssd.GetValue<bool>(vssdProperties, "AutomaticSnapshotsEnabled");
|
||||
|
||||
vmc.BaseBoardSerialNumber = vssd.GetValue<string>(vssdProperties, "BaseBoardSerialNumber");
|
||||
vmc.BIOSGUID = vssd.GetValue<string>(vssdProperties, "BIOSGUID");
|
||||
vmc.BIOSSerialNumber = vssd.GetValue<string>(vssdProperties, "BIOSSerialNumber");
|
||||
vmc.BootOrder = vssd.GetValue<ushort[]>(vssdProperties, "BootOrder");
|
||||
vmc.ConfigurationDataRoot = vssd.GetValue<string>(vssdProperties, "ConfigurationDataRoot");
|
||||
vmc.ConfigurationFile = vssd.GetValue<string>(vssdProperties, "ConfigurationFile");
|
||||
vmc.GuestStateDataRoot = vssd.GetValue<string>(vssdProperties, "GuestStateDataRoot");
|
||||
vmc.GuestStateFile = vssd.GetValue<string>(vssdProperties, "GuestStateFile");
|
||||
vmc.SnapshotDataRoot = vssd.GetValue<string>(vssdProperties, "SnapshotDataRoot");
|
||||
vmc.SuspendDataRoot = vssd.GetValue<string>(vssdProperties, "SuspendDataRoot");
|
||||
vmc.SwapFileDataRoot = vssd.GetValue<string>(vssdProperties, "SwapFileDataRoot");
|
||||
vmc.SecureBootEnabled = vssd.GetValue<bool>(vssdProperties, "SecureBootEnabled");
|
||||
vmc.IsAutomaticSnapshot = vssd.GetValue<bool>(vssdProperties, "IsAutomaticSnapshot");
|
||||
vmc.Notes = vssd.GetValue<string[]>(vssdProperties, "Notes");
|
||||
vmc.ParentId = vssd.GetValue<string>(vssdProperties, "Parent");
|
||||
|
||||
var storageallocationsettingdata = cs.GetRelated("Msvm_StorageAllocationSettingData");
|
||||
using (storageallocationsettingdata)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
configs.Add(vmc);
|
||||
}
|
||||
|
||||
configs = configs.GroupBy(p => p.Id).Select(p => p.First()).ToList();
|
||||
if (configs.Any(p => p.ParentId is not null))
|
||||
{
|
||||
foreach (var conf in configs.Where(p => p.ParentId is not null))
|
||||
{
|
||||
using var parent = new ManagementObject(conf.ParentId);
|
||||
parent.Get();
|
||||
|
||||
if (Guid.TryParse(parent["ConfigurationID"]?.ToString(), out var parentGuid) && configs.FirstOrDefault(p => p.Id == parentGuid.ToString()) is VirtualMaschineConfiguration parentConfig)
|
||||
{
|
||||
conf.ParentId = parentGuid.ToString();
|
||||
|
||||
parentConfig.Childs ??= new List<VirtualMaschineConfiguration>();
|
||||
parentConfig.Childs.Add(conf);
|
||||
}
|
||||
else
|
||||
{
|
||||
conf.ParentId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.Configurations = configs.Where(p => p.ParentId is null).ToList();
|
||||
}
|
||||
|
||||
vms.Add(vm);
|
||||
}
|
||||
}
|
||||
|
||||
return vms;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
using Insight.Agent.Extensions;
|
||||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Agent.Network;
|
||||
using Insight.Agent.Network.Handlers;
|
||||
using Insight.Agent.Services;
|
||||
using Insight.Domain.Constants;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
|
@ -12,86 +12,85 @@ using Microsoft.Extensions.Logging;
|
|||
using Vaitr.Network;
|
||||
using Vaitr.Network.Hosting;
|
||||
|
||||
namespace Insight.Agent.Windows
|
||||
namespace Insight.Agent.Windows;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
internal class Program
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
var builder = Host.CreateDefaultBuilder(args);
|
||||
builder.UseWindowsService();
|
||||
builder.UseSystemd();
|
||||
|
||||
builder.ConfigureAppConfiguration(config =>
|
||||
{
|
||||
var builder = Host.CreateDefaultBuilder(args);
|
||||
builder.UseWindowsService();
|
||||
builder.UseSystemd();
|
||||
config.Defaults();
|
||||
});
|
||||
|
||||
builder.ConfigureAppConfiguration(config =>
|
||||
builder.ConfigureLogging(options =>
|
||||
{
|
||||
options.ClearProviders();
|
||||
options.SetMinimumLevel(LogLevel.Trace);
|
||||
|
||||
options.AddSimpleConsole(options =>
|
||||
{
|
||||
config.Defaults();
|
||||
options.IncludeScopes = true;
|
||||
options.SingleLine = true;
|
||||
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
|
||||
});
|
||||
|
||||
builder.ConfigureLogging(options =>
|
||||
options.AddFile($"{Configuration.AppDirectory?.FullName}/" + "logs/agent_{Date}.log", LogLevel.Trace, fileSizeLimitBytes: 104857600, retainedFileCountLimit: 10, outputTemplate: "{Timestamp:o} [{Level:u3}] {Message} {NewLine}{Exception}");
|
||||
});
|
||||
|
||||
builder.ConfigureServices((host, services) =>
|
||||
{
|
||||
// SERVICES
|
||||
services.AddHostedService<UpdateService>();
|
||||
services.AddHostedService<TrapService>();
|
||||
|
||||
// SERVICES (WINDOWS)
|
||||
if (OperatingSystem.IsWindows()) services.AddHostedService<EventService>();
|
||||
|
||||
// AGENT NETWORKING
|
||||
services.UseHostedClient<AgentSession, IMessage>(options =>
|
||||
{
|
||||
options.ClearProviders();
|
||||
options.SetMinimumLevel(LogLevel.Trace);
|
||||
options.Host = host.Configuration.GetValue<string?>(Appsettings.ServerHost) ?? throw new Exception($"{Appsettings.ServerHost} value not set (appsettings)");
|
||||
options.Port = host.Configuration.GetValue<int?>(Appsettings.ServerPort) ?? throw new Exception($"{Appsettings.ServerPort} value not set (appsettings)");
|
||||
options.Keepalive = 10000;
|
||||
options.Timeout = 30000;
|
||||
options.Encryption = Encryption.Tls12;
|
||||
|
||||
options.AddSimpleConsole(options =>
|
||||
{
|
||||
options.IncludeScopes = true;
|
||||
options.SingleLine = true;
|
||||
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
|
||||
});
|
||||
|
||||
options.AddFile($"{Configuration.AppDirectory?.FullName}/" + "logs/agent_{Date}.log", LogLevel.Trace, fileSizeLimitBytes: 104857600, retainedFileCountLimit: 10, outputTemplate: "{Timestamp:o} [{Level:u3}] {Message} {NewLine}{Exception}");
|
||||
options.UseSerializer<MemPackSerializer<IMessage>, IMessage>();
|
||||
});
|
||||
|
||||
builder.ConfigureServices((host, services) =>
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, AuthenticationHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, DriveHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, InterfaceHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, MainboardHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, MemoryHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, OperationSystemHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, PrinterHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, ProcessorHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, ServiceHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, SessionHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, SoftwareHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, StoragePoolHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, SystemInfoHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, UpdateHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, UserHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, VideocardHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, VirtualMaschineHandler>();
|
||||
services.AddSingleton<IMessageHandler<AgentSession>, ConsoleHandler>();
|
||||
|
||||
// GLOBAL DEPENDENCIES
|
||||
services.AddTransient(provider => new HttpClient(new HttpClientHandler
|
||||
{
|
||||
// SERVICES
|
||||
services.AddHostedService<UpdateService>();
|
||||
services.AddHostedService<TrapService>();
|
||||
ClientCertificateOptions = ClientCertificateOption.Manual,
|
||||
ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true
|
||||
}));
|
||||
});
|
||||
|
||||
// SERVICES (WINDOWS)
|
||||
if (OperatingSystem.IsWindows()) services.AddHostedService<EventService>();
|
||||
|
||||
// AGENT NETWORKING
|
||||
services.UseHostedClient<AgentSession, IAgentMessage>(options =>
|
||||
{
|
||||
options.Host = host.Configuration.GetValue<string?>(Appsettings.ServerHost) ?? throw new Exception($"{Appsettings.ServerHost} value not set (appsettings)");
|
||||
options.Port = host.Configuration.GetValue<int?>(Appsettings.ServerPort) ?? throw new Exception($"{Appsettings.ServerPort} value not set (appsettings)");
|
||||
options.Keepalive = 10000;
|
||||
options.Timeout = 30000;
|
||||
options.Encryption = Encryption.Tls12;
|
||||
|
||||
options.UseSerializer<MemPackSerializer<IAgentMessage>, IAgentMessage>();
|
||||
});
|
||||
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, AuthenticationHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, DriveHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, InterfaceHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, MainboardHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, MemoryHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, OperationSystemHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, PrinterHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, ProcessorHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, ServiceHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, SessionHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, SoftwareHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, StoragePoolHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, SystemInfoHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, UpdateHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, UserHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, VideocardHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, VirtualMaschineHandler>();
|
||||
services.AddSingleton<IAgentMessageHandler<AgentSession>, ConsoleHandler>();
|
||||
|
||||
// GLOBAL DEPENDENCIES
|
||||
services.AddTransient(provider => new HttpClient(new HttpClientHandler
|
||||
{
|
||||
ClientCertificateOptions = ClientCertificateOption.Manual,
|
||||
ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true
|
||||
}));
|
||||
});
|
||||
|
||||
var host = builder.Build();
|
||||
await host.RunAsync().ConfigureAwait(false);
|
||||
}
|
||||
var host = builder.Build();
|
||||
await host.RunAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,170 +1,170 @@
|
|||
using Insight.Agent.Messages;
|
||||
using Insight.Agent.Network;
|
||||
using Insight.Agent.Network;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading.Channels;
|
||||
using Vaitr.Network;
|
||||
using static Insight.Agent.Messages.Event;
|
||||
using static Insight.Domain.Messages.Agent.Event;
|
||||
using EventLevel = System.Diagnostics.Tracing.EventLevel;
|
||||
|
||||
namespace Insight.Agent.Services
|
||||
namespace Insight.Agent.Services;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class EventService : BackgroundService
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class EventService : BackgroundService
|
||||
private readonly Channel<Event> _queue;
|
||||
private readonly ISessionPool<AgentSession, IMessage> _pool;
|
||||
private readonly ILogger<EventService> _logger;
|
||||
|
||||
public EventService(ISessionPool<AgentSession, IMessage> pool, ILogger<EventService> logger)
|
||||
{
|
||||
private readonly Channel<Event> _queue;
|
||||
private readonly ISessionPool<AgentSession, IAgentMessage> _pool;
|
||||
private readonly ILogger<EventService> _logger;
|
||||
_pool = pool;
|
||||
_logger = logger;
|
||||
|
||||
public EventService(ISessionPool<AgentSession, IAgentMessage> pool, ILogger<EventService> logger)
|
||||
_queue = Channel.CreateBounded<Event>(new BoundedChannelOptions(1000)
|
||||
{
|
||||
_pool = pool;
|
||||
_logger = logger;
|
||||
SingleReader = true,
|
||||
SingleWriter = true,
|
||||
AllowSynchronousContinuations = false,
|
||||
FullMode = BoundedChannelFullMode.DropOldest
|
||||
});
|
||||
}
|
||||
|
||||
_queue = Channel.CreateBounded<Event>(new BoundedChannelOptions(1000)
|
||||
{
|
||||
SingleReader = true,
|
||||
SingleWriter = true,
|
||||
AllowSynchronousContinuations = false,
|
||||
FullMode = BoundedChannelFullMode.DropOldest
|
||||
});
|
||||
}
|
||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogTrace("ExecuteAsync");
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
while (cancellationToken.IsCancellationRequested is false)
|
||||
{
|
||||
_logger.LogTrace("ExecuteAsync");
|
||||
|
||||
while (cancellationToken.IsCancellationRequested is false)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tasks = new List<Task>
|
||||
{
|
||||
HandleQueueAsync(cancellationToken),
|
||||
WatchAsync("Application", "*", cancellationToken),
|
||||
WatchAsync("Security", "*", cancellationToken),
|
||||
WatchAsync("System", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-PrintService/Admin", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-TaskScheduler/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-TerminalServices-LocalSessionManager/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-TerminalServices-RDPClient/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-SmbClient/Connectivity", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-SmbClient/Security", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-SMBServer/Security", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-StorageSpaces-Driver/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-Diagnostics-Performance/Operational", "*", cancellationToken)
|
||||
};
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task WatchAsync(string path, string query, CancellationToken cancellationToken)
|
||||
{
|
||||
var config = new EventLogConfiguration(path);
|
||||
if (config is null) return;
|
||||
|
||||
if (config.IsEnabled is false)
|
||||
{
|
||||
config.IsEnabled = true;
|
||||
config.SaveChanges();
|
||||
}
|
||||
|
||||
var watcher = new EventLogWatcher(new EventLogQuery(path, PathType.LogName, query)
|
||||
{
|
||||
TolerateQueryErrors = true,
|
||||
Session = EventLogSession.GlobalSession
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
watcher.EventRecordWritten += new EventHandler<EventRecordWrittenEventArgs>(OnEvent);
|
||||
watcher.Enabled = true;
|
||||
|
||||
using var semaphore = new SemaphoreSlim(0, 1);
|
||||
await semaphore.WaitAsync(cancellationToken);
|
||||
}
|
||||
catch (Exception) { }
|
||||
finally
|
||||
{
|
||||
watcher.EventRecordWritten -= new EventHandler<EventRecordWrittenEventArgs>(OnEvent);
|
||||
watcher.Enabled = false;
|
||||
|
||||
watcher?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleQueueAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
while (await _queue.Reader.WaitToReadAsync(cancellationToken))
|
||||
{
|
||||
var session = _pool.FirstOrDefault();
|
||||
|
||||
if (session.Value is null)
|
||||
var tasks = new List<Task>
|
||||
{
|
||||
await Task.Delay(10000, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_queue.Reader.TryRead(out var item) is false)
|
||||
{
|
||||
await Task.Delay(1000, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await session.Value.SendAsync(item, cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
await Task.Delay(10000, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEvent(object? sender, EventRecordWrittenEventArgs e)
|
||||
{
|
||||
if (e is null || e.EventRecord is null) return;
|
||||
|
||||
try
|
||||
{
|
||||
var @event = new Event
|
||||
{
|
||||
Timestamp = e?.EventRecord?.TimeCreated,
|
||||
EventId = e?.EventRecord?.Id,
|
||||
Source = e?.EventRecord?.ProviderName,
|
||||
Category = e?.EventRecord?.LogName,
|
||||
Task = e?.EventRecord?.TaskDisplayName,
|
||||
Message = e?.EventRecord?.FormatDescription(),
|
||||
HandleQueueAsync(cancellationToken),
|
||||
WatchAsync("Application", "*", cancellationToken),
|
||||
WatchAsync("Security", "*", cancellationToken),
|
||||
WatchAsync("System", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-PrintService/Admin", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-TaskScheduler/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-TerminalServices-LocalSessionManager/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-TerminalServices-RDPClient/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-SmbClient/Connectivity", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-SmbClient/Security", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-SMBServer/Security", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-StorageSpaces-Driver/Operational", "*", cancellationToken),
|
||||
WatchAsync("Microsoft-Windows-Diagnostics-Performance/Operational", "*", cancellationToken)
|
||||
};
|
||||
|
||||
if (e?.EventRecord?.Level is not null)
|
||||
{
|
||||
@event.Status = (EventLevel)Convert.ToInt32(e?.EventRecord?.Level) switch
|
||||
{
|
||||
EventLevel.Informational => StatusType.Information,
|
||||
EventLevel.Warning => StatusType.Warning,
|
||||
EventLevel.Error => StatusType.Error,
|
||||
EventLevel.Critical => StatusType.Critical,
|
||||
_ => StatusType.Information,
|
||||
};
|
||||
}
|
||||
|
||||
_queue.Writer.WriteAsync(@event, default);
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
}
|
||||
catch (Exception) { } // app crash
|
||||
}
|
||||
}
|
||||
|
||||
private async Task WatchAsync(string path, string query, CancellationToken cancellationToken)
|
||||
{
|
||||
var config = new EventLogConfiguration(path);
|
||||
if (config is null) return;
|
||||
|
||||
if (config.IsEnabled is false)
|
||||
{
|
||||
config.IsEnabled = true;
|
||||
config.SaveChanges();
|
||||
}
|
||||
|
||||
var watcher = new EventLogWatcher(new EventLogQuery(path, PathType.LogName, query)
|
||||
{
|
||||
TolerateQueryErrors = true,
|
||||
Session = EventLogSession.GlobalSession
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
watcher.EventRecordWritten += new EventHandler<EventRecordWrittenEventArgs>(OnEvent);
|
||||
watcher.Enabled = true;
|
||||
|
||||
using var semaphore = new SemaphoreSlim(0, 1);
|
||||
await semaphore.WaitAsync(cancellationToken);
|
||||
}
|
||||
catch (Exception) { }
|
||||
finally
|
||||
{
|
||||
watcher.EventRecordWritten -= new EventHandler<EventRecordWrittenEventArgs>(OnEvent);
|
||||
watcher.Enabled = false;
|
||||
|
||||
watcher?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleQueueAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
while (await _queue.Reader.WaitToReadAsync(cancellationToken))
|
||||
{
|
||||
var session = _pool.FirstOrDefault();
|
||||
|
||||
if (session.Value is null)
|
||||
{
|
||||
await Task.Delay(10000, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_queue.Reader.TryRead(out var item) is false)
|
||||
{
|
||||
await Task.Delay(1000, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await session.Value.SendAsync(item, cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
await Task.Delay(10000, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEvent(object? sender, EventRecordWrittenEventArgs e)
|
||||
{
|
||||
if (e is null || e.EventRecord is null) return;
|
||||
|
||||
try
|
||||
{
|
||||
var @event = new Event
|
||||
{
|
||||
Timestamp = e?.EventRecord?.TimeCreated,
|
||||
EventId = e?.EventRecord?.Id,
|
||||
Source = e?.EventRecord?.ProviderName,
|
||||
Category = e?.EventRecord?.LogName,
|
||||
Task = e?.EventRecord?.TaskDisplayName,
|
||||
Message = e?.EventRecord?.FormatDescription(),
|
||||
};
|
||||
|
||||
if (e?.EventRecord?.Level is not null)
|
||||
{
|
||||
@event.Status = (EventLevel)Convert.ToInt32(e?.EventRecord?.Level) switch
|
||||
{
|
||||
EventLevel.Informational => StatusType.Information,
|
||||
EventLevel.Warning => StatusType.Warning,
|
||||
EventLevel.Error => StatusType.Error,
|
||||
EventLevel.Critical => StatusType.Critical,
|
||||
_ => StatusType.Information,
|
||||
};
|
||||
}
|
||||
|
||||
_queue.Writer.WriteAsync(@event, default);
|
||||
}
|
||||
catch (Exception) { } // app crash
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using Insight.Agent.Messages;
|
||||
using Insight.Agent.Network;
|
||||
using Insight.Agent.Network;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -9,192 +10,190 @@ using System.Net.Sockets;
|
|||
using System.Threading.Channels;
|
||||
using Vaitr.Network;
|
||||
|
||||
namespace Insight.Agent.Services
|
||||
namespace Insight.Agent.Services;
|
||||
|
||||
public class TrapService : BackgroundService
|
||||
{
|
||||
public class TrapService : BackgroundService
|
||||
private static IPEndPoint EndpointCache { get; } = new(IPAddress.Any, 0);
|
||||
private readonly Channel<Trap> _queue;
|
||||
|
||||
private readonly int _port;
|
||||
private readonly ISessionPool<AgentSession, IMessage> _pool;
|
||||
private readonly ILogger<TrapService> _logger;
|
||||
|
||||
public TrapService(ISessionPool<AgentSession, IMessage> pool, IConfiguration configuration, ILogger<TrapService> logger)
|
||||
{
|
||||
private static IPEndPoint EndpointCache { get; } = new(IPAddress.Any, 0);
|
||||
private readonly Channel<Trap> _queue;
|
||||
_port = configuration.GetValue<int?>(Appsettings.TrapPort) ?? throw new Exception($"{Appsettings.TrapPort} value not set (appsettings)");
|
||||
_pool = pool;
|
||||
_logger = logger;
|
||||
|
||||
|
||||
private readonly int _port;
|
||||
private readonly ISessionPool<AgentSession, IAgentMessage> _pool;
|
||||
private readonly ILogger<TrapService> _logger;
|
||||
|
||||
public TrapService(ISessionPool<AgentSession, IAgentMessage> pool, IConfiguration configuration, ILogger<TrapService> logger)
|
||||
_queue = Channel.CreateBounded<Trap>(new BoundedChannelOptions(100)
|
||||
{
|
||||
_port = configuration.GetValue<int?>(Appsettings.TrapPort) ?? throw new Exception($"{Appsettings.TrapPort} value not set (appsettings)");
|
||||
_pool = pool;
|
||||
_logger = logger;
|
||||
SingleReader = false,
|
||||
SingleWriter = true,
|
||||
AllowSynchronousContinuations = false,
|
||||
FullMode = BoundedChannelFullMode.DropOldest
|
||||
});
|
||||
}
|
||||
|
||||
_queue = Channel.CreateBounded<Trap>(new BoundedChannelOptions(100)
|
||||
{
|
||||
SingleReader = false,
|
||||
SingleWriter = true,
|
||||
AllowSynchronousContinuations = false,
|
||||
FullMode = BoundedChannelFullMode.DropOldest
|
||||
});
|
||||
}
|
||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogTrace("ExecuteAsync");
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
while (cancellationToken.IsCancellationRequested is false)
|
||||
{
|
||||
_logger.LogTrace("ExecuteAsync");
|
||||
|
||||
while (cancellationToken.IsCancellationRequested is false)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tasks = new List<Task>
|
||||
{
|
||||
HandleQueueAsync(cancellationToken),
|
||||
ListenAsync(cancellationToken)
|
||||
};
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleQueueAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
while (await _queue.Reader.WaitToReadAsync(cancellationToken))
|
||||
{
|
||||
var session = _pool.FirstOrDefault();
|
||||
|
||||
if (session.Value is null)
|
||||
{
|
||||
await Task.Delay(10000, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_queue.Reader.TryRead(out var item) is false)
|
||||
{
|
||||
await Task.Delay(1000, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await session.Value.SendAsync(item, cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
await Task.Delay(10000, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ListenAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
using var udpSocket = new Socket(SocketType.Dgram, ProtocolType.Udp);
|
||||
|
||||
cancellationToken.Register(udpSocket.Dispose);
|
||||
|
||||
udpSocket.Bind(new IPEndPoint(IPAddress.Any, _port));
|
||||
|
||||
var buffer = GC.AllocateArray<byte>(length: 65527, pinned: true);
|
||||
var bufferMem = buffer.AsMemory();
|
||||
|
||||
while (cancellationToken.IsCancellationRequested is false)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await udpSocket.ReceiveFromAsync(bufferMem, SocketFlags.None, EndpointCache, cancellationToken);
|
||||
|
||||
if (result.ReceivedBytes == 0) continue;
|
||||
|
||||
var actualBytes = bufferMem[..result.ReceivedBytes].ToArray();
|
||||
|
||||
var ep = (IPEndPoint)result.RemoteEndPoint;
|
||||
|
||||
await ProcessAsync(ep, actualBytes, cancellationToken);
|
||||
}
|
||||
catch (SocketException) { continue; }
|
||||
catch (IOException) { continue; }
|
||||
catch (Exception) { continue; }
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask ProcessAsync(IPEndPoint endpoint, byte[] buffer, CancellationToken cancellationToken)
|
||||
{
|
||||
var trap = new Trap
|
||||
{
|
||||
Timestamp = DateTime.Now,
|
||||
Endpoint = endpoint.ToString(),
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var protocol = (SnmpVersion)SnmpPacket.GetProtocolVersion(buffer, buffer.Length);
|
||||
|
||||
trap.Version = protocol.ToString();
|
||||
trap.Hostname = Dns.GetHostEntry(endpoint.Address)?.HostName;
|
||||
|
||||
if (protocol == SnmpVersion.Ver1)
|
||||
var tasks = new List<Task>
|
||||
{
|
||||
var packet = new SnmpV1TrapPacket();
|
||||
packet.decode(buffer, buffer.Length);
|
||||
HandleQueueAsync(cancellationToken),
|
||||
ListenAsync(cancellationToken)
|
||||
};
|
||||
|
||||
trap.Community = packet?.Community?.ToString();
|
||||
|
||||
if (packet?.Pdu?.VbList is not null)
|
||||
{
|
||||
trap.Data = ConvertVbs(packet.Pdu.VbList);
|
||||
}
|
||||
}
|
||||
|
||||
if (protocol == SnmpVersion.Ver2)
|
||||
{
|
||||
var packet = new SnmpV2Packet();
|
||||
packet.decode(buffer, buffer.Length);
|
||||
|
||||
trap.Community = packet?.Community?.ToString();
|
||||
|
||||
if (packet?.Pdu?.VbList is not null)
|
||||
{
|
||||
trap.Data = ConvertVbs(packet.Pdu.VbList);
|
||||
}
|
||||
}
|
||||
|
||||
if (protocol == SnmpVersion.Ver3)
|
||||
{
|
||||
var packet = new SnmpV3Packet();
|
||||
}
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
}
|
||||
|
||||
await _queue.Writer.WriteAsync(trap, cancellationToken);
|
||||
}
|
||||
|
||||
private List<KeyValuePair<string, string?>>? ConvertVbs(VbCollection vbs)
|
||||
{
|
||||
var data = new List<KeyValuePair<string, string?>>();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var item in vbs)
|
||||
{
|
||||
if (item.Oid is null) continue;
|
||||
|
||||
data.Add(new KeyValuePair<string, string?>(item.Oid.ToString(), item?.Value?.ToString()));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleQueueAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
while (await _queue.Reader.WaitToReadAsync(cancellationToken))
|
||||
{
|
||||
var session = _pool.FirstOrDefault();
|
||||
|
||||
if (session.Value is null)
|
||||
{
|
||||
await Task.Delay(10000, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_queue.Reader.TryRead(out var item) is false)
|
||||
{
|
||||
await Task.Delay(1000, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await session.Value.SendAsync(item, cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
await Task.Delay(10000, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ListenAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
using var udpSocket = new Socket(SocketType.Dgram, ProtocolType.Udp);
|
||||
|
||||
cancellationToken.Register(udpSocket.Dispose);
|
||||
|
||||
udpSocket.Bind(new IPEndPoint(IPAddress.Any, _port));
|
||||
|
||||
var buffer = GC.AllocateArray<byte>(length: 65527, pinned: true);
|
||||
var bufferMem = buffer.AsMemory();
|
||||
|
||||
while (cancellationToken.IsCancellationRequested is false)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await udpSocket.ReceiveFromAsync(bufferMem, SocketFlags.None, EndpointCache, cancellationToken);
|
||||
|
||||
if (result.ReceivedBytes == 0) continue;
|
||||
|
||||
var actualBytes = bufferMem[..result.ReceivedBytes].ToArray();
|
||||
|
||||
var ep = (IPEndPoint)result.RemoteEndPoint;
|
||||
|
||||
await ProcessAsync(ep, actualBytes, cancellationToken);
|
||||
}
|
||||
catch (SocketException) { continue; }
|
||||
catch (IOException) { continue; }
|
||||
catch (Exception) { continue; }
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask ProcessAsync(IPEndPoint endpoint, byte[] buffer, CancellationToken cancellationToken)
|
||||
{
|
||||
var trap = new Trap
|
||||
{
|
||||
Timestamp = DateTime.Now,
|
||||
Endpoint = endpoint.ToString(),
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var protocol = (SnmpVersion)SnmpPacket.GetProtocolVersion(buffer, buffer.Length);
|
||||
|
||||
trap.Version = protocol.ToString();
|
||||
trap.Hostname = Dns.GetHostEntry(endpoint.Address)?.HostName;
|
||||
|
||||
if (protocol == SnmpVersion.Ver1)
|
||||
{
|
||||
var packet = new SnmpV1TrapPacket();
|
||||
packet.decode(buffer, buffer.Length);
|
||||
|
||||
trap.Community = packet?.Community?.ToString();
|
||||
|
||||
if (packet?.Pdu?.VbList is not null)
|
||||
{
|
||||
trap.Data = ConvertVbs(packet.Pdu.VbList);
|
||||
}
|
||||
}
|
||||
|
||||
if (protocol == SnmpVersion.Ver2)
|
||||
{
|
||||
var packet = new SnmpV2Packet();
|
||||
packet.decode(buffer, buffer.Length);
|
||||
|
||||
trap.Community = packet?.Community?.ToString();
|
||||
|
||||
if (packet?.Pdu?.VbList is not null)
|
||||
{
|
||||
trap.Data = ConvertVbs(packet.Pdu.VbList);
|
||||
}
|
||||
}
|
||||
|
||||
if (protocol == SnmpVersion.Ver3)
|
||||
{
|
||||
var packet = new SnmpV3Packet();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
}
|
||||
|
||||
await _queue.Writer.WriteAsync(trap, cancellationToken);
|
||||
}
|
||||
|
||||
private List<KeyValuePair<string, string?>>? ConvertVbs(VbCollection vbs)
|
||||
{
|
||||
var data = new List<KeyValuePair<string, string?>>();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var item in vbs)
|
||||
{
|
||||
if (item.Oid is null) continue;
|
||||
|
||||
data.Add(new KeyValuePair<string, string?>(item.Oid.ToString(), item?.Value?.ToString()));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("{ex}", ex);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,351 +10,350 @@ using System.Runtime.Versioning;
|
|||
using System.ServiceProcess;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Insight.Agent.Services
|
||||
namespace Insight.Agent.Services;
|
||||
|
||||
internal class UpdateService : BackgroundService
|
||||
{
|
||||
internal class UpdateService : BackgroundService
|
||||
private readonly Uri _uri;
|
||||
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly ILogger<UpdateService> _logger;
|
||||
|
||||
public UpdateService(HttpClient httpClient, IConfiguration configuration, ILogger<UpdateService> logger)
|
||||
{
|
||||
private readonly Uri _uri;
|
||||
_httpClient = httpClient;
|
||||
_uri = configuration.GetValue<Uri?>("api") ?? throw new Exception($"api value not set (appsettings)");
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly ILogger<UpdateService> _logger;
|
||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogTrace("ExecuteAsync");
|
||||
|
||||
public UpdateService(HttpClient httpClient, IConfiguration configuration, ILogger<UpdateService> logger)
|
||||
while (cancellationToken.IsCancellationRequested is false)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_uri = configuration.GetValue<Uri?>("api") ?? throw new Exception($"api value not set (appsettings)");
|
||||
_logger = logger;
|
||||
try
|
||||
{
|
||||
UpdateResult? result = null;
|
||||
|
||||
if (OperatingSystem.IsWindows()) result = await WindowsUpdateAsync(cancellationToken);
|
||||
if (OperatingSystem.IsLinux()) result = await LinuxUpdateAsync(cancellationToken);
|
||||
|
||||
_logger.LogInformation("Update Result: {result}", result?.Success);
|
||||
if (result?.UpdateErrors is not null)
|
||||
{
|
||||
_logger.LogError("Update Errors: {errors}", string.Concat(result?.UpdateErrors));
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex) // may inform via client / api about errors
|
||||
{
|
||||
_logger.LogError("{ex}", ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
[SupportedOSPlatform("windows")]
|
||||
private async ValueTask<UpdateResult> WindowsUpdateAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return await Windows.Service.UpdateAsync(
|
||||
_httpClient,
|
||||
Deploy.GetUpdateHref(_uri, Deploy.Updater.Name),
|
||||
Deploy.GetAppExecutable(Deploy.Updater.Name),
|
||||
Deploy.Updater.ServiceName,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("linux")]
|
||||
private ValueTask<UpdateResult> LinuxUpdateAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private static class Windows
|
||||
{
|
||||
public static class Service
|
||||
{
|
||||
_logger.LogTrace("ExecuteAsync");
|
||||
|
||||
while (cancellationToken.IsCancellationRequested is false)
|
||||
public static bool ServiceExistence(string serviceName)
|
||||
{
|
||||
try
|
||||
{
|
||||
UpdateResult? result = null;
|
||||
if (ServiceController.GetServices().Any(s => s.ServiceName.Equals(serviceName, StringComparison.InvariantCultureIgnoreCase))) return true;
|
||||
return false;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
if (OperatingSystem.IsWindows()) result = await WindowsUpdateAsync(cancellationToken);
|
||||
if (OperatingSystem.IsLinux()) result = await LinuxUpdateAsync(cancellationToken);
|
||||
|
||||
_logger.LogInformation("Update Result: {result}", result?.Success);
|
||||
if (result?.UpdateErrors is not null)
|
||||
{
|
||||
_logger.LogError("Update Errors: {errors}", string.Concat(result?.UpdateErrors));
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
catch (Exception ex) // may inform via client / api about errors
|
||||
{
|
||||
_logger.LogError("{ex}", ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private async ValueTask<UpdateResult> WindowsUpdateAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return await Windows.Service.UpdateAsync(
|
||||
_httpClient,
|
||||
Deploy.GetUpdateHref(_uri, Deploy.Updater.Name),
|
||||
Deploy.GetAppExecutable(Deploy.Updater.Name),
|
||||
Deploy.Updater.ServiceName,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("linux")]
|
||||
private ValueTask<UpdateResult> LinuxUpdateAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private static class Windows
|
||||
{
|
||||
public static class Service
|
||||
public static bool SetServiceState(string app, ServiceControllerStatus status, TimeSpan timeout)
|
||||
{
|
||||
public static bool ServiceExistence(string serviceName)
|
||||
try
|
||||
{
|
||||
try
|
||||
using var sc = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName.Equals(app, StringComparison.InvariantCultureIgnoreCase));
|
||||
if (sc is null) return false;
|
||||
|
||||
if (sc.Status != status)
|
||||
{
|
||||
if (ServiceController.GetServices().Any(s => s.ServiceName.Equals(serviceName, StringComparison.InvariantCultureIgnoreCase))) return true;
|
||||
return false;
|
||||
switch (status)
|
||||
{
|
||||
case ServiceControllerStatus.Running:
|
||||
sc.Start();
|
||||
break;
|
||||
|
||||
case ServiceControllerStatus.Stopped:
|
||||
sc.Stop();
|
||||
break;
|
||||
}
|
||||
|
||||
sc.WaitForStatus(status, timeout);
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
public static bool SetServiceState(string app, ServiceControllerStatus status, TimeSpan timeout)
|
||||
return false;
|
||||
}
|
||||
|
||||
public static async ValueTask<UpdateResult> UpdateAsync(HttpClient httpClient, Uri api, FileInfo bin, string serviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = new UpdateResult
|
||||
{
|
||||
try
|
||||
Api = api?.ToString(),
|
||||
SourceDirectory = bin.Directory?.FullName,
|
||||
App = bin.Name,
|
||||
ServiceName = serviceName
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
// check if service exists
|
||||
if (ServiceExistence(serviceName) is false)
|
||||
{
|
||||
using var sc = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName.Equals(app, StringComparison.InvariantCultureIgnoreCase));
|
||||
if (sc is null) return false;
|
||||
|
||||
if (sc.Status != status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case ServiceControllerStatus.Running:
|
||||
sc.Start();
|
||||
break;
|
||||
|
||||
case ServiceControllerStatus.Stopped:
|
||||
sc.Stop();
|
||||
break;
|
||||
}
|
||||
|
||||
sc.WaitForStatus(status, timeout);
|
||||
}
|
||||
|
||||
return true;
|
||||
result.UpdateErrors.Add("service not found");
|
||||
return result;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static async ValueTask<UpdateResult> UpdateAsync(HttpClient httpClient, Uri api, FileInfo bin, string serviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = new UpdateResult
|
||||
// get service update details
|
||||
var response = await httpClient.GetFromJsonAsync<UpdateResponse>(api, cancellationToken);
|
||||
if (response is null)
|
||||
{
|
||||
Api = api?.ToString(),
|
||||
SourceDirectory = bin.Directory?.FullName,
|
||||
App = bin.Name,
|
||||
ServiceName = serviceName
|
||||
};
|
||||
result.ApiErrors.Add("not available / response null");
|
||||
return result;
|
||||
}
|
||||
|
||||
try
|
||||
result.ApiAvailable = true;
|
||||
|
||||
// check if local binary exists
|
||||
if (bin is null)
|
||||
{
|
||||
// check if service exists
|
||||
if (ServiceExistence(serviceName) is false)
|
||||
{
|
||||
result.UpdateErrors.Add("service not found");
|
||||
return result;
|
||||
}
|
||||
result.UpdateErrors.Add("source binary not found");
|
||||
return result;
|
||||
}
|
||||
|
||||
// get service update details
|
||||
var response = await httpClient.GetFromJsonAsync<UpdateResponse>(api, cancellationToken);
|
||||
if (response is null)
|
||||
{
|
||||
result.ApiErrors.Add("not available / response null");
|
||||
return result;
|
||||
}
|
||||
|
||||
result.ApiAvailable = true;
|
||||
|
||||
// check if local binary exists
|
||||
if (bin is null)
|
||||
{
|
||||
result.UpdateErrors.Add("source binary not found");
|
||||
return result;
|
||||
}
|
||||
|
||||
// get local file binary version
|
||||
if (FileVersionInfo.GetVersionInfo(bin.FullName).FileVersion is not string binVersionString)
|
||||
{
|
||||
result.UpdateErrors.Add("source binary fileversion not valid");
|
||||
return result;
|
||||
}
|
||||
|
||||
// compare local against update version, skip lower or equal update version
|
||||
var actualVersion = Version.Parse(binVersionString);
|
||||
if (actualVersion >= response.Version)
|
||||
{
|
||||
result.Success = true;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.UpdateAvailable = true;
|
||||
}
|
||||
|
||||
// get update file (bytes) to memory
|
||||
using var update = await httpClient.GetAsync(response.Uri, cancellationToken);
|
||||
if (update is null)
|
||||
{
|
||||
result.ApiErrors.Add("update source not available");
|
||||
return result;
|
||||
}
|
||||
|
||||
// stop service
|
||||
if (SetServiceState(serviceName, ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10)) is false)
|
||||
{
|
||||
result.UpdateErrors.Add("service control failed / failed to stop service");
|
||||
return result;
|
||||
}
|
||||
|
||||
// read update archive to temp (overwrite)
|
||||
var temp = Directory.CreateTempSubdirectory();
|
||||
var updateFile = new FileInfo($@"{temp.FullName}/{bin.Name}.zip");
|
||||
|
||||
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
|
||||
|
||||
// extract update archive from temp to app dir (overwrite)
|
||||
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
|
||||
|
||||
// delete temp folder
|
||||
if (temp.Exists) temp.Delete(true);
|
||||
|
||||
// start updateds service
|
||||
if (SetServiceState(serviceName, ServiceControllerStatus.Running, TimeSpan.FromSeconds(10)) is false)
|
||||
{
|
||||
result.UpdateErrors.Add("service control failed / failed to start service");
|
||||
return result;
|
||||
}
|
||||
// get local file binary version
|
||||
if (FileVersionInfo.GetVersionInfo(bin.FullName).FileVersion is not string binVersionString)
|
||||
{
|
||||
result.UpdateErrors.Add("source binary fileversion not valid");
|
||||
return result;
|
||||
}
|
||||
|
||||
// compare local against update version, skip lower or equal update version
|
||||
var actualVersion = Version.Parse(binVersionString);
|
||||
if (actualVersion >= response.Version)
|
||||
{
|
||||
result.Success = true;
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
else
|
||||
{
|
||||
result.UpdateErrors.Add(ex.Message);
|
||||
result.UpdateAvailable = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
// get update file (bytes) to memory
|
||||
using var update = await httpClient.GetAsync(response.Uri, cancellationToken);
|
||||
if (update is null)
|
||||
{
|
||||
result.ApiErrors.Add("update source not available");
|
||||
return result;
|
||||
}
|
||||
|
||||
// stop service
|
||||
if (SetServiceState(serviceName, ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10)) is false)
|
||||
{
|
||||
result.UpdateErrors.Add("service control failed / failed to stop service");
|
||||
return result;
|
||||
}
|
||||
|
||||
// read update archive to temp (overwrite)
|
||||
var temp = Directory.CreateTempSubdirectory();
|
||||
var updateFile = new FileInfo($@"{temp.FullName}/{bin.Name}.zip");
|
||||
|
||||
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
|
||||
|
||||
// extract update archive from temp to app dir (overwrite)
|
||||
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
|
||||
|
||||
// delete temp folder
|
||||
if (temp.Exists) temp.Delete(true);
|
||||
|
||||
// start updateds service
|
||||
if (SetServiceState(serviceName, ServiceControllerStatus.Running, TimeSpan.FromSeconds(10)) is false)
|
||||
{
|
||||
result.UpdateErrors.Add("service control failed / failed to start service");
|
||||
return result;
|
||||
}
|
||||
|
||||
result.Success = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.UpdateErrors.Add(ex.Message);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Process
|
||||
{
|
||||
public static bool IsRunning(FileInfo bin)
|
||||
{
|
||||
if (bin.Exists is false) return false;
|
||||
|
||||
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
|
||||
|
||||
if (matched is null || matched.Any() is false) return false;
|
||||
|
||||
if (matched.Any(p =>
|
||||
p.MainModule is not null &&
|
||||
p.MainModule.FileName is not null &&
|
||||
p.MainModule.FileName.Equals(bin.FullName,
|
||||
StringComparison.InvariantCultureIgnoreCase))) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class Process
|
||||
public static bool Start(FileInfo binary)
|
||||
{
|
||||
public static bool IsRunning(FileInfo bin)
|
||||
try
|
||||
{
|
||||
if (bin.Exists is false) return false;
|
||||
if (IsRunning(binary) is false) return false;
|
||||
|
||||
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
|
||||
|
||||
if (matched is null || matched.Any() is false) return false;
|
||||
|
||||
if (matched.Any(p =>
|
||||
p.MainModule is not null &&
|
||||
p.MainModule.FileName is not null &&
|
||||
p.MainModule.FileName.Equals(bin.FullName,
|
||||
StringComparison.InvariantCultureIgnoreCase))) return true;
|
||||
|
||||
return false;
|
||||
using var process = System.Diagnostics.Process.Start(binary.FullName);
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
public static bool Start(FileInfo binary)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsRunning(binary) is false) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
using var process = System.Diagnostics.Process.Start(binary.FullName);
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool Stop(FileInfo bin, TimeSpan timeout)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsRunning(bin) is false) return false;
|
||||
|
||||
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
|
||||
|
||||
if (matched is null || matched.Any() is false) return true;
|
||||
|
||||
foreach (var procsInfo in matched.Where(p =>
|
||||
p.MainModule is not null &&
|
||||
p.MainModule.FileName is not null &&
|
||||
p.MainModule.FileName.Equals(bin.FullName, StringComparison.InvariantCultureIgnoreCase)))
|
||||
{
|
||||
if (procsInfo.CloseMainWindow()) procsInfo.WaitForExit((int)timeout.TotalMilliseconds);
|
||||
if (procsInfo.HasExited is false) procsInfo.Kill(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static async ValueTask<bool> UpdateAsync(HttpClient httpClient, Uri api, FileInfo bin, CancellationToken cancellationToken)
|
||||
public static bool Stop(FileInfo bin, TimeSpan timeout)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsRunning(bin) is false) return false;
|
||||
|
||||
var response = await httpClient.GetFromJsonAsync<UpdateResponse>(api.AbsoluteUri, new JsonSerializerOptions
|
||||
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
|
||||
|
||||
if (matched is null || matched.Any() is false) return true;
|
||||
|
||||
foreach (var procsInfo in matched.Where(p =>
|
||||
p.MainModule is not null &&
|
||||
p.MainModule.FileName is not null &&
|
||||
p.MainModule.FileName.Equals(bin.FullName, StringComparison.InvariantCultureIgnoreCase)))
|
||||
{
|
||||
IncludeFields = true
|
||||
}, cancellationToken);
|
||||
|
||||
if (response is null) return false;
|
||||
|
||||
Version actualVersion;
|
||||
|
||||
if (FileVersionInfo.GetVersionInfo(bin.FullName).FileVersion is not string binVersionString) return false;
|
||||
|
||||
try
|
||||
{
|
||||
actualVersion = Version.Parse(binVersionString);
|
||||
if (actualVersion >= response.Version) return false;
|
||||
|
||||
using var update = await httpClient.GetAsync(response.Uri, cancellationToken);
|
||||
if (update is null) return false;
|
||||
|
||||
Stop(bin, TimeSpan.FromSeconds(60));
|
||||
|
||||
// read update archive to temp (overwrite)
|
||||
var temp = Directory.CreateTempSubdirectory();
|
||||
var updateFile = new FileInfo($@"{temp.FullName}/{bin.Name}.zip");
|
||||
|
||||
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
|
||||
|
||||
// extract update archive from temp to app dir (overwrite)
|
||||
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
|
||||
|
||||
// delete temp folder
|
||||
if (temp.Exists) temp.Delete(true);
|
||||
|
||||
// rewrite with options to start user session process
|
||||
//Start(app, directory, TimeSpan.FromSeconds(60));
|
||||
|
||||
return true;
|
||||
if (procsInfo.CloseMainWindow()) procsInfo.WaitForExit((int)timeout.TotalMilliseconds);
|
||||
if (procsInfo.HasExited is false) procsInfo.Kill(true);
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
public static bool Delete(FileInfo bin, TimeSpan timeout)
|
||||
return false;
|
||||
}
|
||||
|
||||
public static async ValueTask<bool> UpdateAsync(HttpClient httpClient, Uri api, FileInfo bin, CancellationToken cancellationToken)
|
||||
{
|
||||
if (IsRunning(bin) is false) return false;
|
||||
|
||||
var response = await httpClient.GetFromJsonAsync<UpdateResponse>(api.AbsoluteUri, new JsonSerializerOptions
|
||||
{
|
||||
try
|
||||
{
|
||||
Stop(bin, timeout);
|
||||
bin.Delete();
|
||||
IncludeFields = true
|
||||
}, cancellationToken);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
if (response is null) return false;
|
||||
|
||||
return false;
|
||||
Version actualVersion;
|
||||
|
||||
if (FileVersionInfo.GetVersionInfo(bin.FullName).FileVersion is not string binVersionString) return false;
|
||||
|
||||
try
|
||||
{
|
||||
actualVersion = Version.Parse(binVersionString);
|
||||
if (actualVersion >= response.Version) return false;
|
||||
|
||||
using var update = await httpClient.GetAsync(response.Uri, cancellationToken);
|
||||
if (update is null) return false;
|
||||
|
||||
Stop(bin, TimeSpan.FromSeconds(60));
|
||||
|
||||
// read update archive to temp (overwrite)
|
||||
var temp = Directory.CreateTempSubdirectory();
|
||||
var updateFile = new FileInfo($@"{temp.FullName}/{bin.Name}.zip");
|
||||
|
||||
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
|
||||
|
||||
// extract update archive from temp to app dir (overwrite)
|
||||
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
|
||||
|
||||
// delete temp folder
|
||||
if (temp.Exists) temp.Delete(true);
|
||||
|
||||
// rewrite with options to start user session process
|
||||
//Start(app, directory, TimeSpan.FromSeconds(60));
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool Delete(FileInfo bin, TimeSpan timeout)
|
||||
{
|
||||
try
|
||||
{
|
||||
Stop(bin, timeout);
|
||||
bin.Delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateResult
|
||||
{
|
||||
public string? Api { get; set; }
|
||||
public string? SourceDirectory { get; set; }
|
||||
public string? App { get; set; }
|
||||
public string? ServiceName { get; set; }
|
||||
public class UpdateResult
|
||||
{
|
||||
public string? Api { get; set; }
|
||||
public string? SourceDirectory { get; set; }
|
||||
public string? App { get; set; }
|
||||
public string? ServiceName { get; set; }
|
||||
|
||||
public bool ApiAvailable { get; set; } = false;
|
||||
public bool UpdateAvailable { get; set; } = false;
|
||||
public bool Success { get; set; } = false;
|
||||
public List<string> ApiErrors { get; } = new();
|
||||
public List<string> UpdateErrors { get; } = new();
|
||||
}
|
||||
public bool ApiAvailable { get; set; } = false;
|
||||
public bool UpdateAvailable { get; set; } = false;
|
||||
public bool Success { get; set; } = false;
|
||||
public List<string> ApiErrors { get; } = new();
|
||||
public List<string> UpdateErrors { get; } = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,106 +1,105 @@
|
|||
using Insight.Agent.Extensions;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Insight.Agent.Services
|
||||
namespace Insight.Agent.Services;
|
||||
|
||||
public partial class CollectorService
|
||||
{
|
||||
public partial class CollectorService
|
||||
public OperationSystem? GetOperatingSystem()
|
||||
{
|
||||
public OperationSystem? GetOperatingSystem()
|
||||
{
|
||||
Logger.LogTrace("GetOperatingSystem");
|
||||
Logger.LogTrace("GetOperatingSystem");
|
||||
|
||||
var os = new OperationSystem();
|
||||
var os = new OperationSystem();
|
||||
|
||||
// get uptime
|
||||
var output = string.Empty;
|
||||
// get uptime
|
||||
var output = string.Empty;
|
||||
|
||||
// read file
|
||||
using var stream = File.OpenText(@"/proc/uptime");
|
||||
output = stream.ReadToEnd();
|
||||
// read file
|
||||
using var stream = File.OpenText(@"/proc/uptime");
|
||||
output = stream.ReadToEnd();
|
||||
|
||||
// clean output
|
||||
var clean = Regex
|
||||
.Replace(output
|
||||
// clean output
|
||||
var clean = Regex
|
||||
.Replace(output
|
||||
.Trim()
|
||||
.Replace("\t", " "), @"[ ]{2,}", " ");
|
||||
|
||||
var elements = clean.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// assign values
|
||||
//os.Uptime = DateTime.Now - TimeSpan.FromSeconds(double.Parse(elements.ElementAt(0)));
|
||||
|
||||
// request data with process
|
||||
output = "hostnamectl".Bash();
|
||||
|
||||
// linebreak list conversion
|
||||
var lines = new List<string>(output
|
||||
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
|
||||
.Select(l =>
|
||||
{
|
||||
return Regex
|
||||
.Replace(l
|
||||
.Trim()
|
||||
.Replace("\t", " "), @"[ ]{2,}", " ");
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var elements = clean.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
|
||||
// assign values
|
||||
os.Virtual = lines
|
||||
.Any(l => l
|
||||
.StartsWith("Virtualization:")) && !string.IsNullOrEmpty(lines
|
||||
.Where(l => l
|
||||
.StartsWith("Virtualization:"))
|
||||
.First()
|
||||
.Split("Virtualization:")[1]
|
||||
.Trim());
|
||||
|
||||
// assign values
|
||||
//os.Uptime = DateTime.Now - TimeSpan.FromSeconds(double.Parse(elements.ElementAt(0)));
|
||||
// OS
|
||||
// request data with process
|
||||
output = "hostnamectl".Bash();
|
||||
|
||||
// request data with process
|
||||
output = "hostnamectl".Bash();
|
||||
// linebreak list conversion
|
||||
lines = new List<string>(output
|
||||
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
|
||||
.Select(l =>
|
||||
{
|
||||
return Regex
|
||||
.Replace(l
|
||||
.Trim()
|
||||
.Replace("\t", " "), @"[ ]{2,}", " ");
|
||||
})
|
||||
.ToList();
|
||||
|
||||
// linebreak list conversion
|
||||
var lines = new List<string>(output
|
||||
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
|
||||
.Select(l =>
|
||||
{
|
||||
return Regex
|
||||
.Replace(l
|
||||
.Trim()
|
||||
.Replace("\t", " "), @"[ ]{2,}", " ");
|
||||
})
|
||||
.ToList();
|
||||
// assign values
|
||||
os.Name = lines
|
||||
.Any(l => l
|
||||
.StartsWith("Operating System:")) ? lines
|
||||
.Where(l => l
|
||||
.StartsWith("Operating System:"))
|
||||
.First()
|
||||
.Split("Operating System:")[1]
|
||||
.Trim() : string.Empty;
|
||||
|
||||
// assign values
|
||||
os.Virtual = lines
|
||||
.Any(l => l
|
||||
.StartsWith("Virtualization:")) && !string.IsNullOrEmpty(lines
|
||||
.Where(l => l
|
||||
.StartsWith("Virtualization:"))
|
||||
.First()
|
||||
.Split("Virtualization:")[1]
|
||||
.Trim());
|
||||
os.Version = lines
|
||||
.Any(l => l
|
||||
.StartsWith("Kernel:")) ? lines
|
||||
.Where(l => l
|
||||
.StartsWith("Kernel:"))
|
||||
.First()
|
||||
.Split("Kernel:")[1]
|
||||
.Trim() : string.Empty;
|
||||
|
||||
// OS
|
||||
// request data with process
|
||||
output = "hostnamectl".Bash();
|
||||
var architecture = lines
|
||||
.Any(l => l
|
||||
.StartsWith("Architecture:")) ? lines
|
||||
.Where(l => l
|
||||
.StartsWith("Architecture:"))
|
||||
.First()
|
||||
.Split("Architecture:")[1]
|
||||
.Trim() : string.Empty;
|
||||
|
||||
// linebreak list conversion
|
||||
lines = new List<string>(output
|
||||
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
|
||||
.Select(l =>
|
||||
{
|
||||
return Regex
|
||||
.Replace(l
|
||||
.Trim()
|
||||
.Replace("\t", " "), @"[ ]{2,}", " ");
|
||||
})
|
||||
.ToList();
|
||||
|
||||
// assign values
|
||||
os.Name = lines
|
||||
.Any(l => l
|
||||
.StartsWith("Operating System:")) ? lines
|
||||
.Where(l => l
|
||||
.StartsWith("Operating System:"))
|
||||
.First()
|
||||
.Split("Operating System:")[1]
|
||||
.Trim() : string.Empty;
|
||||
|
||||
os.Version = lines
|
||||
.Any(l => l
|
||||
.StartsWith("Kernel:")) ? lines
|
||||
.Where(l => l
|
||||
.StartsWith("Kernel:"))
|
||||
.First()
|
||||
.Split("Kernel:")[1]
|
||||
.Trim() : string.Empty;
|
||||
|
||||
var architecture = lines
|
||||
.Any(l => l
|
||||
.StartsWith("Architecture:")) ? lines
|
||||
.Where(l => l
|
||||
.StartsWith("Architecture:"))
|
||||
.First()
|
||||
.Split("Architecture:")[1]
|
||||
.Trim() : string.Empty;
|
||||
|
||||
return os;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +1,49 @@
|
|||
using Insight.Agent.Extensions;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Insight.Agent.Services
|
||||
namespace Insight.Agent.Services;
|
||||
|
||||
public partial class CollectorService
|
||||
{
|
||||
public partial class CollectorService
|
||||
public List<Session>? GetSessions()
|
||||
{
|
||||
public List<Session>? GetSessions()
|
||||
Logger.LogTrace("GetSessions");
|
||||
|
||||
var sessions = new List<Session>();
|
||||
|
||||
// request data with process
|
||||
var output = "w".Bash();
|
||||
|
||||
// linebreak list conversion
|
||||
var lines = output.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
|
||||
lines = lines.Select(l =>
|
||||
{
|
||||
Logger.LogTrace("GetSessions");
|
||||
return Regex.Replace(l.Trim().Replace("\t", " "), @"[ ]{2,}", " ");
|
||||
}).ToList();
|
||||
|
||||
var sessions = new List<Session>();
|
||||
// cleaning
|
||||
lines.RemoveRange(0, 2);
|
||||
|
||||
// request data with process
|
||||
var output = "w".Bash();
|
||||
// process list elements
|
||||
foreach (var l in lines)
|
||||
{
|
||||
// split into elements
|
||||
var elements = l.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// linebreak list conversion
|
||||
var lines = output.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
|
||||
lines = lines.Select(l =>
|
||||
// add user, assign values
|
||||
sessions.Add(new Session
|
||||
{
|
||||
return Regex.Replace(l.Trim().Replace("\t", " "), @"[ ]{2,}", " ");
|
||||
}).ToList();
|
||||
|
||||
// cleaning
|
||||
lines.RemoveRange(0, 2);
|
||||
|
||||
// process list elements
|
||||
foreach (var l in lines)
|
||||
{
|
||||
// split into elements
|
||||
var elements = l.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// add user, assign values
|
||||
sessions.Add(new Session
|
||||
{
|
||||
User = elements.ElementAt(0),
|
||||
//Id = elements.ElementAt(1),
|
||||
Remote = elements.ElementAt(2),
|
||||
//Login = elements.ElementAt(3),
|
||||
//Idle = elements.ElementAt(4)
|
||||
});
|
||||
}
|
||||
|
||||
return sessions;
|
||||
User = elements.ElementAt(0),
|
||||
//Id = elements.ElementAt(1),
|
||||
Remote = elements.ElementAt(2),
|
||||
//Login = elements.ElementAt(3),
|
||||
//Idle = elements.ElementAt(4)
|
||||
});
|
||||
}
|
||||
|
||||
return sessions;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Product>Insight</Product>
|
||||
<AssemblyName>api</AssemblyName>
|
||||
<AssemblyVersion>2023.8.23.1</AssemblyVersion>
|
||||
<AssemblyVersion>2023.9.21.1</AssemblyVersion>
|
||||
<RootNamespace>Insight.Api</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
using System.Net;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Insight.Domain.Constants
|
||||
namespace Insight.Domain.Constants;
|
||||
|
||||
public static class Configuration
|
||||
{
|
||||
public static class Configuration
|
||||
{
|
||||
public static string Hostname => Dns.GetHostEntry("localhost").HostName;
|
||||
public static Version Version => Assembly.GetEntryAssembly()?.GetName().Version ?? throw new ArgumentNullException("Version");
|
||||
public static DirectoryInfo? AppDirectory => string.IsNullOrWhiteSpace(Environment.ProcessPath) ? null : new DirectoryInfo(Environment.ProcessPath).Parent;
|
||||
public static string DefaultConfig => Path.Combine(AppDirectory?.FullName ?? string.Empty, "config.json");
|
||||
}
|
||||
public static string Hostname => Dns.GetHostEntry("localhost").HostName;
|
||||
public static Version Version => Assembly.GetEntryAssembly()?.GetName().Version ?? throw new ArgumentNullException("Version");
|
||||
public static DirectoryInfo? AppDirectory => string.IsNullOrWhiteSpace(Environment.ProcessPath) ? null : new DirectoryInfo(Environment.ProcessPath).Parent;
|
||||
public static string DefaultConfig => Path.Combine(AppDirectory?.FullName ?? string.Empty, "config.json");
|
||||
}
|
||||
13
src/Core/Insight.Domain/Enums/CategoryEnum.cs
Normal file
13
src/Core/Insight.Domain/Enums/CategoryEnum.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
namespace Insight.Domain.Enums;
|
||||
|
||||
public enum CategoryEnum
|
||||
{
|
||||
Network = 1,
|
||||
System = 2,
|
||||
Application = 3,
|
||||
Security = 4,
|
||||
Monitoring = 5,
|
||||
Task = 6,
|
||||
Printer = 7,
|
||||
RDP = 8
|
||||
}
|
||||
8
src/Core/Insight.Domain/Enums/DispatchEnum.cs
Normal file
8
src/Core/Insight.Domain/Enums/DispatchEnum.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
namespace Insight.Domain.Enums;
|
||||
|
||||
public enum DispatchEnum
|
||||
{
|
||||
Pending = 1,
|
||||
Failure = 2,
|
||||
Success = 3,
|
||||
}
|
||||
8
src/Core/Insight.Domain/Enums/StatusEnum.cs
Normal file
8
src/Core/Insight.Domain/Enums/StatusEnum.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
namespace Insight.Domain.Enums;
|
||||
|
||||
public enum StatusEnum
|
||||
{
|
||||
Information = 1,
|
||||
Warning = 2,
|
||||
Error = 3
|
||||
}
|
||||
|
|
@ -6,9 +6,13 @@
|
|||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Insight.Domain</RootNamespace>
|
||||
<Product>Insight</Product>
|
||||
<AssemblyVersion>2023.7.3.0</AssemblyVersion>
|
||||
<AssemblyVersion>2023.9.21.1</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Vaitr.Network" Version="2023.9.13" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
|
@ -17,4 +21,4 @@
|
|||
<DebugType>none</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
using Insight.Domain.Messages;
|
||||
|
||||
namespace Insight.Domain.Interfaces;
|
||||
|
||||
public partial interface IMessageHandler<TSender>
|
||||
{
|
||||
ValueTask HandleAsync<TMessage>(TSender sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage;
|
||||
}
|
||||
35
src/Core/Insight.Domain/Messages/Agent/Application.cs
Normal file
35
src/Core/Insight.Domain/Messages/Agent/Application.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using MemoryPack;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Application : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Publisher { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Location { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Source { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Uninstall { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public DateTime? InstallDate { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public Architecture? Architecture { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class ApplicationList : List<Application>, IMessage { }
|
||||
29
src/Core/Insight.Domain/Messages/Agent/Authentication.cs
Normal file
29
src/Core/Insight.Domain/Messages/Agent/Authentication.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Authentication : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public PlatformType? Platform { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public Guid Serial { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public Version? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Hostname { get; set; }
|
||||
|
||||
public enum PlatformType
|
||||
{
|
||||
Unknown = 0,
|
||||
Windows = 1,
|
||||
Unix = 2
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class AuthenticationRequest : IMessage { }
|
||||
6
src/Core/Insight.Domain/Messages/Agent/Commands.cs
Normal file
6
src/Core/Insight.Domain/Messages/Agent/Commands.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class InventoryRequest : IMessage { }
|
||||
44
src/Core/Insight.Domain/Messages/Agent/ConsoleQuery.cs
Normal file
44
src/Core/Insight.Domain/Messages/Agent/ConsoleQuery.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ConsoleQuery : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? HostId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Query { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Data { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Errors { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public bool IsString { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public bool IsArray { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool HadErrors { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ConsoleQueryRequest : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? HostId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Query { get; set; }
|
||||
}
|
||||
98
src/Core/Insight.Domain/Messages/Agent/Drive.cs
Normal file
98
src/Core/Insight.Domain/Messages/Agent/Drive.cs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Drive : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public string? InterfaceType { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public string? FirmwareRevision { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public string? PNPDeviceID { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public List<Volume>? Volumes { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class DriveList : List<Drive>, IMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Volume : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public ulong? FreeSpace { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public string? FileSystem { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public bool? Compressed { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? Bootable { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? PrimaryPartition { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public bool? BootPartition { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public ulong? BlockSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public ulong? NumberOfBlocks { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public ulong? StartingOffset { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public DriveType? DriveType { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public string? ProviderName { get; set; }
|
||||
}
|
||||
37
src/Core/Insight.Domain/Messages/Agent/Event.cs
Normal file
37
src/Core/Insight.Domain/Messages/Agent/Event.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Event : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? Timestamp { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public StatusType? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Source { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Category { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public int? EventId { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Task { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Message { get; set; }
|
||||
|
||||
public enum StatusType
|
||||
{
|
||||
Unknown = 0,
|
||||
Information = 1,
|
||||
Warning = 2,
|
||||
Error = 3,
|
||||
Critical = 4
|
||||
}
|
||||
}
|
||||
190
src/Core/Insight.Domain/Messages/Agent/Interface.cs
Normal file
190
src/Core/Insight.Domain/Messages/Agent/Interface.cs
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
using MemoryPack;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Interface : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public Guid? Guid { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Mac { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Suffix { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool? Physical { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public NetworkInterfaceType? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public OperationalStatus? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public long? Speed { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public long? Ipv4Mtu { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public bool? Ipv4Dhcp { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public bool? Ipv4Forwarding { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public long? Ipv6Mtu { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public long? Sent { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public long? Received { get; set; }
|
||||
|
||||
[MemoryPackOrder(17)]
|
||||
public long? IncomingPacketsDiscarded { get; set; }
|
||||
|
||||
[MemoryPackOrder(18)]
|
||||
public long? IncomingPacketsWithErrors { get; set; }
|
||||
|
||||
[MemoryPackOrder(19)]
|
||||
public long? IncomingUnknownProtocolPackets { get; set; }
|
||||
|
||||
[MemoryPackOrder(20)]
|
||||
public long? OutgoingPacketsDiscarded { get; set; }
|
||||
|
||||
[MemoryPackOrder(21)]
|
||||
public long? OutgoingPacketsWithErrors { get; set; }
|
||||
|
||||
[MemoryPackOrder(22)]
|
||||
public List<Unicast>? Addresses { get; set; }
|
||||
|
||||
[MemoryPackOrder(23)]
|
||||
public List<IPAddress2>? Gateways { get; set; }
|
||||
|
||||
[MemoryPackOrder(24)]
|
||||
public List<IPAddress2>? Dns { get; set; }
|
||||
|
||||
[MemoryPackOrder(25)]
|
||||
public List<IPAddress2>? Dhcp { get; set; }
|
||||
|
||||
[MemoryPackOrder(26)]
|
||||
public List<Route>? Routes { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class InterfaceList : List<Interface>, IMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Unicast : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public IPAddress2? IpAddress { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public IPAddress2? Ipv4Mask { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public long? AddressPreferredLifetime { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public long? AddressValidLifetime { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public long? DhcpLeaseLifetime { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public DuplicateAddressDetectionState? DuplicateAddressDetectionState { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public int? PrefixLength { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public PrefixOrigin? PrefixOrigin { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public SuffixOrigin? SuffixOrigin { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Route : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? InterfaceIndex { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public IPAddress2? Destination { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public IPAddress2? Gateway { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Mask { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public int? Metric { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class IPAddress2 : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public AddressFamily? AddressFamily { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Address { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public bool? IsIPv6Teredo { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public bool? IsIPv6SiteLocal { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public bool? IsIPv6Multicast { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public bool? IsIPv6LinkLocal { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public bool? IsIPv4MappedToIPv6 { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool? IsIPv6UniqueLocal { get; set; }
|
||||
|
||||
[MemoryPackConstructor]
|
||||
public IPAddress2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public IPAddress2(IPAddress address)
|
||||
{
|
||||
AddressFamily = address.AddressFamily;
|
||||
Address = address.ToString();
|
||||
IsIPv4MappedToIPv6 = address.IsIPv4MappedToIPv6;
|
||||
IsIPv6LinkLocal = address.IsIPv6LinkLocal;
|
||||
IsIPv6Multicast = address.IsIPv6Multicast;
|
||||
IsIPv6SiteLocal = address.IsIPv6SiteLocal;
|
||||
IsIPv6Teredo = address.IsIPv6Teredo;
|
||||
IsIPv6UniqueLocal = address.IsIPv6UniqueLocal;
|
||||
}
|
||||
}
|
||||
25
src/Core/Insight.Domain/Messages/Agent/Mainboard.cs
Normal file
25
src/Core/Insight.Domain/Messages/Agent/Mainboard.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Mainboard : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Model { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Serial { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? BiosManufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? BiosVersion { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public DateTime? BiosDate { get; set; }
|
||||
}
|
||||
62
src/Core/Insight.Domain/Messages/Agent/Memory.cs
Normal file
62
src/Core/Insight.Domain/Messages/Agent/Memory.cs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Memory : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Tag { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Location { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Model { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Serial { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public ulong? Capacity { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public uint? Speed { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public uint? Voltage { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public uint? ConfiguredSpeed { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public uint? ConfiguredVoltage { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class MemoryList : List<Memory>, IMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class MemoryMetric : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? Timestamp { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public float? MemoryAvailable { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public float? MemoryAvailablePercentage { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public float? MemoryUsed { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public float? MemoryUsagePercentage { get; set; }
|
||||
}
|
||||
26
src/Core/Insight.Domain/Messages/Agent/OperationSystem.cs
Normal file
26
src/Core/Insight.Domain/Messages/Agent/OperationSystem.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using MemoryPack;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class OperationSystem : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public Architecture? Architecture { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public bool? Virtual { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public DateTime? InstallDate { get; set; }
|
||||
}
|
||||
25
src/Core/Insight.Domain/Messages/Agent/Printer.cs
Normal file
25
src/Core/Insight.Domain/Messages/Agent/Printer.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Printer : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Driver { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Port { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Location { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Comment { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class PrinterList : List<Printer>, IMessage { }
|
||||
65
src/Core/Insight.Domain/Messages/Agent/Processor.cs
Normal file
65
src/Core/Insight.Domain/Messages/Agent/Processor.cs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Processor : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? Index { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Socket { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? DeviceId { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public uint? Cores { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public uint? LogicalCores { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public uint? CurrentSpeed { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public uint? MaxSpeed { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public uint? L1Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public uint? L2Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public uint? L3Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public bool? Virtualization { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class ProcessorList : List<Processor>, IMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ProcessorMetric : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? Timestamp { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public float? ProcessorUsagePercentage { get; set; }
|
||||
}
|
||||
59
src/Core/Insight.Domain/Messages/Agent/Service.cs
Normal file
59
src/Core/Insight.Domain/Messages/Agent/Service.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Service : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public uint? ProcessId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Display { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? PathName { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Account { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public bool? Delay { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public ServiceStatus? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public ServiceMode? StartMode { get; set; }
|
||||
|
||||
public enum ServiceStatus
|
||||
{
|
||||
Unknown = -1,
|
||||
Stopped = 1,
|
||||
StartPending = 2,
|
||||
StopPending = 3,
|
||||
Running = 4,
|
||||
ContinuePending = 5,
|
||||
PausePending = 6,
|
||||
Paused = 7
|
||||
}
|
||||
|
||||
public enum ServiceMode
|
||||
{
|
||||
Unknown = -1,
|
||||
Boot = 0,
|
||||
System = 1,
|
||||
Automatic = 2,
|
||||
Manual = 3,
|
||||
Disabled = 4
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class ServiceList : List<Service>, IMessage { }
|
||||
25
src/Core/Insight.Domain/Messages/Agent/Session.cs
Normal file
25
src/Core/Insight.Domain/Messages/Agent/Session.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Session : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Sid { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? User { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Remote { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class SessionList : List<Session>, IMessage { }
|
||||
13
src/Core/Insight.Domain/Messages/Agent/Status.cs
Normal file
13
src/Core/Insight.Domain/Messages/Agent/Status.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Status : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime Timestamp { get; } = DateTime.Now;
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public TimeSpan Uptime { get; set; }
|
||||
}
|
||||
297
src/Core/Insight.Domain/Messages/Agent/StoragePool.cs
Normal file
297
src/Core/Insight.Domain/Messages/Agent/StoragePool.cs
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class StoragePool : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? UniqueId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? FriendlyName { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public List<OperationalState>? States { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public HealthState? Health { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public RetireMissingPhysicalDisksEnum? RetireMissingPhysicalDisks { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Resiliency { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool? IsPrimordial { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public bool? IsReadOnly { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? IsClustered { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public ulong? AllocatedSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public ulong? SectorSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public List<PhysicalDisk>? PhysicalDisks { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public List<VirtualDisk>? VirtualDisks { get; set; }
|
||||
|
||||
public enum OperationalState
|
||||
{
|
||||
Unknown = 0,
|
||||
Other = 1,
|
||||
OK = 2,
|
||||
Degraded = 3,
|
||||
Stressed = 4,
|
||||
Predictive_Failure = 5,
|
||||
Error = 6,
|
||||
Non_Recoverable_Error = 7,
|
||||
Starting = 8,
|
||||
Stopping = 9,
|
||||
Stopped = 10,
|
||||
In_Service = 11,
|
||||
No_Contact = 12,
|
||||
Lost_Communication = 13,
|
||||
Aborted = 14,
|
||||
Dormant = 15,
|
||||
Supporting_Entity_In_Error = 16,
|
||||
Completed = 17,
|
||||
Power_Mode = 18,
|
||||
Relocating = 19
|
||||
}
|
||||
|
||||
public enum HealthState
|
||||
{
|
||||
Healthy = 0,
|
||||
Warning = 1,
|
||||
Unhealthy = 2,
|
||||
Unknown = 3
|
||||
}
|
||||
|
||||
public enum RetireMissingPhysicalDisksEnum
|
||||
{
|
||||
Auto = 1,
|
||||
Always = 2,
|
||||
Never = 3
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class StoragePoolList : List<StoragePool>, IMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class PhysicalDisk : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? UniqueId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? DeviceId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? FriendlyName { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Manufacturer { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Model { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public ushort? MediaType { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public ushort? BusType { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public List<OperationalState>? States { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public HealthState? Health { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public List<SupportedUsagesEnum>? SupportedUsages { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public ushort? Usage { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public string? PhysicalLocation { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public string? SerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public string? FirmwareVersion { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public ulong? AllocatedSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public ulong? LogicalSectorSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(17)]
|
||||
public ulong? PhysicalSectorSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(18)]
|
||||
public ulong? VirtualDiskFootprint { get; set; }
|
||||
|
||||
public enum OperationalState
|
||||
{
|
||||
Unknown = 0,
|
||||
Other = 1,
|
||||
OK = 2,
|
||||
Degraded = 3,
|
||||
Stressed = 4,
|
||||
Predictive_Failure = 5,
|
||||
Error = 6,
|
||||
Non_Recoverable_Error = 7,
|
||||
Starting = 8,
|
||||
Stopping = 9,
|
||||
Stopped = 10,
|
||||
In_Service = 11,
|
||||
No_Contact = 12,
|
||||
Lost_Communication = 13,
|
||||
Aborted = 14,
|
||||
Dormant = 15,
|
||||
Supporting_Entity_In_Error = 16,
|
||||
Completed = 17,
|
||||
Power_Mode = 18,
|
||||
Relocating = 19
|
||||
}
|
||||
|
||||
public enum HealthState
|
||||
{
|
||||
Healthy = 0,
|
||||
Warning = 1,
|
||||
Unhealthy = 2,
|
||||
Unknown = 3
|
||||
}
|
||||
|
||||
public enum SupportedUsagesEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
Auto_Select = 1,
|
||||
Manual_Select = 2,
|
||||
Hot_Spare = 3,
|
||||
Retired = 4,
|
||||
Journal = 5
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class VirtualDisk : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? UniqueId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? FriendlyName { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public List<OperationalState>? States { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public HealthState? Health { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public AccessTypeEnum? AccessType { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public ProvisioningTypeEnum? ProvisioningType { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public ushort? PhysicalDiskRedundancy { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public string? ResiliencySettingName { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? Deduplication { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? IsSnapshot { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public ulong? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public ulong? AllocatedSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public ulong? FootprintOnPool { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public ulong? ReadCacheSize { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public ulong? WriteCacheSize { get; set; }
|
||||
|
||||
public enum OperationalState
|
||||
{
|
||||
Unknown = 0,
|
||||
Other = 1,
|
||||
OK = 2,
|
||||
Degraded = 3,
|
||||
Stressed = 4,
|
||||
Predictive_Failure = 5,
|
||||
Error = 6,
|
||||
Non_Recoverable_Error = 7,
|
||||
Starting = 8,
|
||||
Stopping = 9,
|
||||
Stopped = 10,
|
||||
In_Service = 11,
|
||||
No_Contact = 12,
|
||||
Lost_Communication = 13,
|
||||
Aborted = 14,
|
||||
Dormant = 15,
|
||||
Supporting_Entity_In_Error = 16,
|
||||
Completed = 17,
|
||||
Power_Mode = 18,
|
||||
Relocating = 19
|
||||
}
|
||||
|
||||
public enum HealthState
|
||||
{
|
||||
Healthy = 0,
|
||||
Warning = 1,
|
||||
Unhealthy = 2,
|
||||
Unknown = 3
|
||||
}
|
||||
|
||||
public enum AccessTypeEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
Readable = 1,
|
||||
Writeable = 2,
|
||||
Read_Write = 3,
|
||||
Write_Once = 4
|
||||
}
|
||||
|
||||
public enum ProvisioningTypeEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
Thin = 1,
|
||||
Fixed = 2
|
||||
}
|
||||
}
|
||||
19
src/Core/Insight.Domain/Messages/Agent/SystemInfo.cs
Normal file
19
src/Core/Insight.Domain/Messages/Agent/SystemInfo.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class SystemInfo : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? LastBootUpTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public DateTime? LocalDateTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public uint? Processes { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? License { get; set; }
|
||||
}
|
||||
25
src/Core/Insight.Domain/Messages/Agent/Trap.cs
Normal file
25
src/Core/Insight.Domain/Messages/Agent/Trap.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Trap : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public DateTime? Timestamp { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Endpoint { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Hostname { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Community { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public List<KeyValuePair<string, string?>>? Data { get; set; }
|
||||
}
|
||||
78
src/Core/Insight.Domain/Messages/Agent/Update.cs
Normal file
78
src/Core/Insight.Domain/Messages/Agent/Update.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Update : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public DateTime? Date { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? SupportUrl { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Hotfix { get; set; }
|
||||
|
||||
// if installed
|
||||
[MemoryPackOrder(6)]
|
||||
public OsUpdateResultCodeEnum? Result { get; set; }
|
||||
|
||||
// if pending
|
||||
[MemoryPackOrder(7)]
|
||||
public OsUpdateTypeEnum? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public decimal? Size { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? IsDownloaded { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? CanRequestUserInput { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public OsUpdateRebootBehaviorEnum? RebootBehavior { get; set; }
|
||||
|
||||
public enum OsUpdateRebootBehaviorEnum
|
||||
{
|
||||
NeverReboots = 1,
|
||||
AlwaysRequiresReboot = 2,
|
||||
CanRequestReboot = 3
|
||||
}
|
||||
|
||||
public enum OsUpdateResultCodeEnum
|
||||
{
|
||||
NotStarted = 1,
|
||||
InProgress = 2,
|
||||
Succeeded = 3,
|
||||
SucceededWithErrors = 4,
|
||||
Failed = 5,
|
||||
Aborted = 6
|
||||
}
|
||||
|
||||
public enum OsUpdateTypeEnum
|
||||
{
|
||||
Software = 1,
|
||||
Driver = 2
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class UpdateList : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public List<Update>? Installed { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public List<Update>? Pending { get; set; }
|
||||
}
|
||||
68
src/Core/Insight.Domain/Messages/Agent/User.cs
Normal file
68
src/Core/Insight.Domain/Messages/Agent/User.cs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class User : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Sid { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Domain { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? FullName { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public bool? LocalAccount { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool? Disabled { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public bool? Lockout { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public bool? PasswordChangeable { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? PasswordExpires { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public bool? PasswordRequired { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public List<Group>? Groups { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class UserList : List<User>, IMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Group : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Sid { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Domain { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public bool? LocalAccount { get; set; }
|
||||
}
|
||||
25
src/Core/Insight.Domain/Messages/Agent/Videocard.cs
Normal file
25
src/Core/Insight.Domain/Messages/Agent/Videocard.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Videocard : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? DeviceId { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? Model { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public ulong Memory { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public DateTime DriverDate { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? DriverVersion { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class VideocardList : List<Videocard>, IMessage { }
|
||||
260
src/Core/Insight.Domain/Messages/Agent/VirtualMaschine.cs
Normal file
260
src/Core/Insight.Domain/Messages/Agent/VirtualMaschine.cs
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Agent;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class VirtualMaschine : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public uint? ProcessId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Caption { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Notes { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public EnabledEnum? Enabled { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public EnabledDefaultEnum? EnabledDefault { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public HealthStatusEnum? HealthState { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public ulong? OnTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public uint? ReplicationMode { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public ReplicationStateEnum? ReplicationState { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public ReplicationHealthEnum? ReplicationHealth { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public string? ConfigurationVersion { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public IntegrationServicesVersionStateEnum? IntegrationServicesVersionState { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public uint? NumberOfProcessors { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public uint? ProcessorLoad { get; set; }
|
||||
|
||||
[MemoryPackOrder(17)]
|
||||
public int? MemoryAvailable { get; set; }
|
||||
|
||||
[MemoryPackOrder(18)]
|
||||
public ulong? MemoryUsage { get; set; }
|
||||
|
||||
[MemoryPackOrder(19)]
|
||||
public DateTime? InstallDate { get; set; }
|
||||
|
||||
[MemoryPackOrder(20)]
|
||||
public DateTime? TimeOfLastConfigurationChange { get; set; }
|
||||
|
||||
[MemoryPackOrder(21)]
|
||||
public DateTime? TimeOfLastStateChange { get; set; }
|
||||
|
||||
[MemoryPackOrder(22)]
|
||||
public DateTime? LastReplicationTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(23)]
|
||||
public string? GuestOperatingSystem { get; set; }
|
||||
|
||||
[MemoryPackOrder(24)]
|
||||
public List<VirtualMaschineConfiguration>? Configurations { get; set; }
|
||||
|
||||
public enum EnabledEnum
|
||||
{
|
||||
Unbekannt = 0,
|
||||
Andere = 1,
|
||||
Aktiviert = 2,
|
||||
Deaktiviert = 3,
|
||||
Herunterfahren = 4,
|
||||
Nicht_Verfügbar = 5,
|
||||
Aktiviert_Offline = 6,
|
||||
In_Test = 7,
|
||||
Latent = 8,
|
||||
Eingeschränkt = 9,
|
||||
Wird_gestartet = 10
|
||||
}
|
||||
|
||||
public enum EnabledDefaultEnum
|
||||
{
|
||||
Aktiviert = 2,
|
||||
Deaktiviert = 3,
|
||||
Aktiviert_Offline = 6
|
||||
}
|
||||
|
||||
public enum HealthStatusEnum
|
||||
{
|
||||
OK = 5,
|
||||
Hauptfehler = 20,
|
||||
Kritischer_Fehler = 25
|
||||
}
|
||||
|
||||
public enum ReplicationStateEnum
|
||||
{
|
||||
Deaktiviert = 0,
|
||||
Bereit = 1,
|
||||
Warten_auf_Erstreplikation = 2,
|
||||
Replikat = 3,
|
||||
Synchronisierte_Replication_abgeschlossen = 4,
|
||||
Wiederhergestellt = 5,
|
||||
Commit = 6,
|
||||
Angehalten = 7,
|
||||
Kritisch = 8,
|
||||
Warten_auf_die_Neusynchronisierung = 9,
|
||||
Resynchronisierung = 10,
|
||||
Resynchronisierung_angehalten = 11,
|
||||
Failover_in_Bearbeitung = 12,
|
||||
Failback_in_Fortschritt = 13,
|
||||
Failback_abgeschlossen = 14,
|
||||
Datenträgerupdate_in_Bearbeitung = 15,
|
||||
Datenträgeraktualisierung_kritisch = 16,
|
||||
Unbekannt = 17,
|
||||
Repurpose_Replikation_in_Bearbeitung = 18,
|
||||
Vorbereitet_für_die_Synchronisierungsreplikation = 19,
|
||||
Vorbereitet_für_die_Umgekehrte_Replikation_der_Gruppe = 20,
|
||||
Failover_in_Fortschritt = 21
|
||||
}
|
||||
|
||||
public enum ReplicationHealthEnum
|
||||
{
|
||||
OK = 1,
|
||||
Warnung = 2,
|
||||
Kritisch = 3
|
||||
}
|
||||
|
||||
public enum IntegrationServicesVersionStateEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
UpToDate = 1,
|
||||
Mismatch = 2
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable(GenerateType.Collection)]
|
||||
public partial class VirtualMaschineList : List<VirtualMaschine>, IMessage { }
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class VirtualMaschineConfiguration : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? ParentId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
[MemoryPackOrder(5)]
|
||||
public string? Generation { get; set; }
|
||||
|
||||
[MemoryPackOrder(6)]
|
||||
public string? Architecture { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public AutomaticStartupActionEnum? AutomaticStartupAction { get; set; }
|
||||
//public DateTime? AutomaticStartupActionDelay { get; set; }
|
||||
|
||||
[MemoryPackOrder(8)]
|
||||
public AutomaticShutdownActionEnum? AutomaticShutdownAction { get; set; }
|
||||
|
||||
[MemoryPackOrder(9)]
|
||||
public AutomaticRecoveryActionEnum? AutomaticRecoveryAction { get; set; }
|
||||
|
||||
[MemoryPackOrder(10)]
|
||||
public bool? AutomaticSnapshotsEnabled { get; set; }
|
||||
|
||||
[MemoryPackOrder(11)]
|
||||
public string? BaseBoardSerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(12)]
|
||||
public string? BIOSGUID { get; set; }
|
||||
|
||||
[MemoryPackOrder(13)]
|
||||
public string? BIOSSerialNumber { get; set; }
|
||||
|
||||
[MemoryPackOrder(14)]
|
||||
public ushort[]? BootOrder { get; set; }
|
||||
|
||||
[MemoryPackOrder(15)]
|
||||
public string? ConfigurationDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(16)]
|
||||
public string? ConfigurationFile { get; set; }
|
||||
|
||||
[MemoryPackOrder(17)]
|
||||
public string? GuestStateDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(18)]
|
||||
public string? GuestStateFile { get; set; }
|
||||
|
||||
[MemoryPackOrder(19)]
|
||||
public string? SnapshotDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(20)]
|
||||
public string? SuspendDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(21)]
|
||||
public string? SwapFileDataRoot { get; set; }
|
||||
|
||||
[MemoryPackOrder(22)]
|
||||
public bool? SecureBootEnabled { get; set; }
|
||||
|
||||
[MemoryPackOrder(23)]
|
||||
public bool? IsAutomaticSnapshot { get; set; }
|
||||
|
||||
[MemoryPackOrder(24)]
|
||||
public string[]? Notes { get; set; }
|
||||
|
||||
[MemoryPackOrder(25)]
|
||||
public List<VirtualMaschineConfiguration>? Childs { get; set; }
|
||||
|
||||
//public string[]? HostResource { get; set; }
|
||||
|
||||
public enum AutomaticStartupActionEnum
|
||||
{
|
||||
Nothing = 2,
|
||||
RestartIfLastStateActive = 3,
|
||||
Alway = 4
|
||||
}
|
||||
|
||||
public enum AutomaticShutdownActionEnum
|
||||
{
|
||||
Ausschalten = 2,
|
||||
Speichern = 3,
|
||||
Herunterfahren = 4
|
||||
}
|
||||
|
||||
public enum AutomaticRecoveryActionEnum
|
||||
{
|
||||
Keine = 2,
|
||||
Neustart = 3,
|
||||
Rollback = 4
|
||||
}
|
||||
}
|
||||
46
src/Core/Insight.Domain/Messages/IMessage.cs
Normal file
46
src/Core/Insight.Domain/Messages/IMessage.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages;
|
||||
|
||||
[MemoryPackable]
|
||||
[MemoryPackUnion(0, typeof(Keepalive))]
|
||||
[MemoryPackUnion(1, typeof(Agent.Authentication))]
|
||||
[MemoryPackUnion(2, typeof(Agent.AuthenticationRequest))]
|
||||
[MemoryPackUnion(10, typeof(Agent.InventoryRequest))]
|
||||
[MemoryPackUnion(20, typeof(Agent.ConsoleQuery))]
|
||||
[MemoryPackUnion(21, typeof(Agent.ConsoleQueryRequest))]
|
||||
[MemoryPackUnion(100, typeof(Agent.Application))]
|
||||
[MemoryPackUnion(101, typeof(Agent.ApplicationList))]
|
||||
[MemoryPackUnion(102, typeof(Agent.Drive))]
|
||||
[MemoryPackUnion(103, typeof(Agent.DriveList))]
|
||||
[MemoryPackUnion(104, typeof(Agent.Event))]
|
||||
[MemoryPackUnion(105, typeof(Agent.Interface))]
|
||||
[MemoryPackUnion(106, typeof(Agent.InterfaceList))]
|
||||
[MemoryPackUnion(107, typeof(Agent.Mainboard))]
|
||||
[MemoryPackUnion(108, typeof(Agent.Memory))]
|
||||
[MemoryPackUnion(109, typeof(Agent.MemoryList))]
|
||||
[MemoryPackUnion(110, typeof(Agent.OperationSystem))]
|
||||
[MemoryPackUnion(111, typeof(Agent.Printer))]
|
||||
[MemoryPackUnion(112, typeof(Agent.PrinterList))]
|
||||
[MemoryPackUnion(113, typeof(Agent.Processor))]
|
||||
[MemoryPackUnion(114, typeof(Agent.ProcessorList))]
|
||||
[MemoryPackUnion(115, typeof(Agent.Service))]
|
||||
[MemoryPackUnion(116, typeof(Agent.ServiceList))]
|
||||
[MemoryPackUnion(117, typeof(Agent.Session))]
|
||||
[MemoryPackUnion(118, typeof(Agent.SessionList))]
|
||||
[MemoryPackUnion(119, typeof(Agent.Status))]
|
||||
[MemoryPackUnion(120, typeof(Agent.StoragePool))]
|
||||
[MemoryPackUnion(121, typeof(Agent.StoragePoolList))]
|
||||
[MemoryPackUnion(122, typeof(Agent.SystemInfo))]
|
||||
[MemoryPackUnion(123, typeof(Agent.Trap))]
|
||||
[MemoryPackUnion(124, typeof(Agent.Update))]
|
||||
[MemoryPackUnion(125, typeof(Agent.UpdateList))]
|
||||
[MemoryPackUnion(126, typeof(Agent.User))]
|
||||
[MemoryPackUnion(127, typeof(Agent.UserList))]
|
||||
[MemoryPackUnion(128, typeof(Agent.Videocard))]
|
||||
[MemoryPackUnion(129, typeof(Agent.VideocardList))]
|
||||
[MemoryPackUnion(130, typeof(Agent.VirtualMaschine))]
|
||||
[MemoryPackUnion(131, typeof(Agent.VirtualMaschineList))]
|
||||
[MemoryPackUnion(400, typeof(Web.ConsoleQueryProxy))]
|
||||
[MemoryPackUnion(401, typeof(Web.ConsoleQueryProxyRequest))]
|
||||
public partial interface IMessage { }
|
||||
6
src/Core/Insight.Domain/Messages/Keepalive.cs
Normal file
6
src/Core/Insight.Domain/Messages/Keepalive.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class Keepalive : IMessage { }
|
||||
38
src/Core/Insight.Domain/Messages/Web/ConsoleProxy.cs
Normal file
38
src/Core/Insight.Domain/Messages/Web/ConsoleProxy.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
using MemoryPack;
|
||||
|
||||
namespace Insight.Domain.Messages.Web;
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ConsoleQueryProxy : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? HostId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Query { get; set; }
|
||||
|
||||
[MemoryPackOrder(3)]
|
||||
public string? Data { get; set; }
|
||||
|
||||
[MemoryPackOrder(4)]
|
||||
public string? Errors { get; set; }
|
||||
|
||||
[MemoryPackOrder(7)]
|
||||
public bool HadErrors { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public partial class ConsoleQueryProxyRequest : IMessage
|
||||
{
|
||||
[MemoryPackOrder(0)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[MemoryPackOrder(1)]
|
||||
public string? HostId { get; set; }
|
||||
|
||||
[MemoryPackOrder(2)]
|
||||
public string? Query { get; set; }
|
||||
}
|
||||
|
|
@ -1,55 +1,54 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Insight.Domain.Models
|
||||
namespace Insight.Domain.Models;
|
||||
|
||||
public class TokenRequest
|
||||
{
|
||||
public class TokenRequest
|
||||
[JsonPropertyName("username"), EmailAddress, Required]
|
||||
public string? Username { get; set; }
|
||||
|
||||
[JsonPropertyName("password"), DataType(DataType.Password), Required]
|
||||
public string? Password { get; set; }
|
||||
|
||||
[JsonPropertyName("code"), DataType(DataType.Text)]
|
||||
public string? Code { get; set; }
|
||||
}
|
||||
|
||||
public class TokenResponse
|
||||
{
|
||||
[JsonPropertyName("access_token")]
|
||||
public string? AccessToken { get; set; }
|
||||
|
||||
[JsonPropertyName("expires_in")]
|
||||
public int ExpireInSeconds { get; set; }
|
||||
|
||||
[JsonPropertyName("refresh_token")]
|
||||
public string? RefreshToken { get; set; }
|
||||
}
|
||||
|
||||
public class TokenRevokeRequest
|
||||
{
|
||||
[JsonPropertyName("token"), Required]
|
||||
public string? Token { get; set; }
|
||||
|
||||
[JsonPropertyName("reason")]
|
||||
public string? Reason { get; set; }
|
||||
|
||||
public TokenRevokeRequest(string token, string? reason)
|
||||
{
|
||||
[JsonPropertyName("username"), EmailAddress, Required]
|
||||
public string Username { get; set; }
|
||||
|
||||
[JsonPropertyName("password"), DataType(DataType.Password), Required]
|
||||
public string Password { get; set; }
|
||||
|
||||
[JsonPropertyName("code"), DataType(DataType.Text)]
|
||||
public string? Code { get; set; }
|
||||
Token = token;
|
||||
Reason = reason;
|
||||
}
|
||||
}
|
||||
|
||||
public class TokenResponse
|
||||
public class TokenRefreshRequest
|
||||
{
|
||||
[JsonPropertyName("token"), Required]
|
||||
public string? Token { get; set; }
|
||||
|
||||
public TokenRefreshRequest(string token)
|
||||
{
|
||||
[JsonPropertyName("access_token")]
|
||||
public string AccessToken { get; set; }
|
||||
|
||||
[JsonPropertyName("expires_in")]
|
||||
public int ExpireInSeconds { get; set; }
|
||||
|
||||
[JsonPropertyName("refresh_token")]
|
||||
public string RefreshToken { get; set; }
|
||||
}
|
||||
|
||||
public class TokenRevokeRequest
|
||||
{
|
||||
[JsonPropertyName("token"), Required]
|
||||
public string Token { get; set; }
|
||||
|
||||
[JsonPropertyName("reason")]
|
||||
public string? Reason { get; set; }
|
||||
|
||||
public TokenRevokeRequest(string token, string? reason)
|
||||
{
|
||||
Token = token;
|
||||
Reason = reason;
|
||||
}
|
||||
}
|
||||
|
||||
public class TokenRefreshRequest
|
||||
{
|
||||
[JsonPropertyName("token"), Required]
|
||||
public string Token { get; set; }
|
||||
|
||||
public TokenRefreshRequest(string token)
|
||||
{
|
||||
Token = token;
|
||||
}
|
||||
Token = token;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
namespace Insight.Domain.Models
|
||||
namespace Insight.Domain.Models;
|
||||
|
||||
public class UpdateResponse
|
||||
{
|
||||
public class UpdateResponse
|
||||
{
|
||||
public Version? Version { get; set; }
|
||||
public Uri? Uri { get; set; }
|
||||
}
|
||||
public Version? Version { get; set; }
|
||||
public Uri? Uri { get; set; }
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Insight.Infrastructure</RootNamespace>
|
||||
<Product>Insight</Product>
|
||||
<AssemblyVersion>2023.7.12.0</AssemblyVersion>
|
||||
<AssemblyVersion>2023.9.21.1</AssemblyVersion>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Product>Insight</Product>
|
||||
<AssemblyName>server</AssemblyName>
|
||||
<AssemblyVersion>2023.9.14.0</AssemblyVersion>
|
||||
<AssemblyVersion>2023.9.21.1</AssemblyVersion>
|
||||
<RootNamespace>Insight.Server</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
|
@ -53,9 +53,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Agent\Insight.Agent.Assets\Insight.Agent.Assets.csproj" />
|
||||
<ProjectReference Include="..\..\Core\Insight.Infrastructure\Insight.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\Web\Insight.Web.Assets\Insight.Web.Assets.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,26 @@
|
|||
using Insight.Agent.Enums;
|
||||
using Insight.Domain.Enums;
|
||||
|
||||
namespace Insight.Server.Models
|
||||
namespace Insight.Server.Models;
|
||||
|
||||
internal class MonitorMessage
|
||||
{
|
||||
internal class MonitorMessage
|
||||
{
|
||||
public DateTime? Timestamp { get; set; }
|
||||
public string? Community { get; set; }
|
||||
public ApplicationEnum? Application { get; set; }
|
||||
public CategoryEnum? Category { get; set; }
|
||||
public StatusEnum? Status { get; set; }
|
||||
public string? Endpoint { get; set; }
|
||||
public string? Hostname { get; set; }
|
||||
public string? Subject { get; set; }
|
||||
public string? Message { get; set; }
|
||||
public DateTime? Timestamp { get; set; }
|
||||
public string? Community { get; set; }
|
||||
public ApplicationEnum? Application { get; set; }
|
||||
public CategoryEnum? Category { get; set; }
|
||||
public StatusEnum? Status { get; set; }
|
||||
public string? Endpoint { get; set; }
|
||||
public string? Hostname { get; set; }
|
||||
public string? Subject { get; set; }
|
||||
public string? Message { get; set; }
|
||||
|
||||
public enum ApplicationEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
Insight = 1,
|
||||
Acronis = 2,
|
||||
Veeam = 3,
|
||||
QNAP = 4,
|
||||
FreeNas = 5
|
||||
}
|
||||
public enum ApplicationEnum
|
||||
{
|
||||
Unknown = 0,
|
||||
Insight = 1,
|
||||
Acronis = 2,
|
||||
Veeam = 3,
|
||||
QNAP = 4,
|
||||
FreeNas = 5
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,89 +1,89 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Insight.Server.Network.Handlers.Agent;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Vaitr.Network;
|
||||
|
||||
namespace Insight.Server.Network
|
||||
namespace Insight.Server.Network;
|
||||
|
||||
public class AgentSession : TcpSession<IMessage>
|
||||
{
|
||||
public class AgentSession : TcpSession<IAgentMessage>
|
||||
public string? Id { get; set; }
|
||||
|
||||
private readonly AgentHandler _agentHandler;
|
||||
private readonly IEnumerable<IMessageHandler<AgentSession>> _handlers;
|
||||
|
||||
public AgentSession(AgentHandler agentHandler, IEnumerable<IMessageHandler<AgentSession>> handlers, ISerializer<IMessage> serializer, ILogger<AgentSession> logger) : base(serializer, logger)
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
_agentHandler = agentHandler;
|
||||
_handlers = handlers;
|
||||
}
|
||||
|
||||
private readonly AgentHandler _agentHandler;
|
||||
private readonly IEnumerable<IAgentMessageHandler<AgentSession>> _handlers;
|
||||
protected override async ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) connected", RemoteEndPoint);
|
||||
|
||||
public AgentSession(AgentHandler agentHandler, IEnumerable<IAgentMessageHandler<AgentSession>> handlers, ISerializer<IAgentMessage> serializer, ILogger<AgentSession> logger) : base(serializer, logger)
|
||||
var request = new AuthenticationRequest();
|
||||
|
||||
foreach (var handler in _handlers)
|
||||
{
|
||||
_agentHandler = agentHandler;
|
||||
_handlers = handlers;
|
||||
await handler.HandleAsync(this, request, cancellationToken);
|
||||
}
|
||||
|
||||
protected override async ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
||||
await _agentHandler.ConnectedAsync(this, default);
|
||||
await _agentHandler.StatisticUpdateAsync(this, default);
|
||||
|
||||
_logger.LogInformation("Agent ({ep?}) ID: {id}", RemoteEndPoint, Id);
|
||||
}
|
||||
|
||||
protected override async ValueTask OnDisconnectedAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) disconnected", RemoteEndPoint);
|
||||
|
||||
await _agentHandler.StatisticUpdateAsync(this, default);
|
||||
await _agentHandler.DisconnectedAsync(this, default);
|
||||
}
|
||||
|
||||
protected override async ValueTask OnSentAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
|
||||
{
|
||||
await base.OnSentAsync(context, cancellationToken);
|
||||
|
||||
await _agentHandler.StatisticUpdateAsync(this, cancellationToken);
|
||||
}
|
||||
|
||||
protected override async ValueTask OnReceivedAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
|
||||
{
|
||||
await base.OnReceivedAsync(context, cancellationToken);
|
||||
|
||||
if (Id is null && context.Packet is not Authentication) return;
|
||||
|
||||
await _agentHandler.StatisticUpdateAsync(this, cancellationToken);
|
||||
|
||||
foreach (var handler in _handlers)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) connected", RemoteEndPoint);
|
||||
|
||||
var request = new AuthenticationRequest();
|
||||
|
||||
foreach (var handler in _handlers)
|
||||
try
|
||||
{
|
||||
await handler.HandleAsync(this, request, cancellationToken);
|
||||
await handler.HandleAsync(this, context.Packet, cancellationToken);
|
||||
}
|
||||
|
||||
await _agentHandler.ConnectedAsync(this, default);
|
||||
await _agentHandler.StatisticUpdateAsync(this, default);
|
||||
|
||||
_logger.LogInformation("Agent ({ep?}) ID: {id}", RemoteEndPoint, Id);
|
||||
}
|
||||
|
||||
protected override async ValueTask OnDisconnectedAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) disconnected", RemoteEndPoint);
|
||||
|
||||
await _agentHandler.StatisticUpdateAsync(this, default);
|
||||
await _agentHandler.DisconnectedAsync(this, default);
|
||||
}
|
||||
|
||||
protected override async ValueTask OnSentAsync(IPacketContext<IAgentMessage> context, CancellationToken cancellationToken)
|
||||
{
|
||||
await base.OnSentAsync(context, cancellationToken);
|
||||
|
||||
await _agentHandler.StatisticUpdateAsync(this, cancellationToken);
|
||||
}
|
||||
|
||||
protected override async ValueTask OnReceivedAsync(IPacketContext<IAgentMessage> context, CancellationToken cancellationToken)
|
||||
{
|
||||
await base.OnReceivedAsync(context, cancellationToken);
|
||||
|
||||
if (Id is null && context.Packet is not Authentication) return;
|
||||
|
||||
await _agentHandler.StatisticUpdateAsync(this, cancellationToken);
|
||||
|
||||
foreach (var handler in _handlers)
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
await handler.HandleAsync(this, context.Packet, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning("Agent ({ep?}) {ex}", RemoteEndPoint, ex.ToString());
|
||||
_logger.LogWarning("Agent ({ep?}) {ex}", RemoteEndPoint, ex.ToString());
|
||||
|
||||
//await _mediator.Send(new AgentLog(new AgentLogEntity
|
||||
//{
|
||||
// Category = CategoryEnum.Network.ToString(),
|
||||
// Status = StatusEnum.Error.ToString(),
|
||||
// Message = e.StackTrace
|
||||
//}, this), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
//await _mediator.Send(new AgentLog(new AgentLogEntity
|
||||
//{
|
||||
// Category = CategoryEnum.Network.ToString(),
|
||||
// Status = StatusEnum.Error.ToString(),
|
||||
// Message = e.StackTrace
|
||||
//}, this), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override async ValueTask OnHeartbeatAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) Heartbeat", RemoteEndPoint);
|
||||
|
||||
await _agentHandler.StatisticUpdateAsync(this, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
protected override async ValueTask OnHeartbeatAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) Heartbeat", RemoteEndPoint);
|
||||
|
||||
await _agentHandler.StatisticUpdateAsync(this, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,162 +1,162 @@
|
|||
using Insight.Agent.Enums;
|
||||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Enums;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Insight.Infrastructure;
|
||||
using Insight.Infrastructure.Entities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace Insight.Server.Network.Handlers.Agent
|
||||
namespace Insight.Server.Network.Handlers.Agent;
|
||||
|
||||
public class AgentHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
public class AgentHandler : IAgentMessageHandler<AgentSession>
|
||||
private readonly IMongoDatabase _database;
|
||||
private readonly ILogger<AgentHandler> _logger;
|
||||
|
||||
public AgentHandler(IMongoDatabase database, ILogger<AgentHandler> logger)
|
||||
{
|
||||
private readonly IMongoDatabase _database;
|
||||
private readonly ILogger<AgentHandler> _logger;
|
||||
_database = database;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public AgentHandler(IMongoDatabase database, ILogger<AgentHandler> logger)
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
if (message is AuthenticationRequest authenticationRequest)
|
||||
{
|
||||
_database = database;
|
||||
_logger = logger;
|
||||
await AuthenticationRequestAsync(sender, authenticationRequest, cancellationToken);
|
||||
}
|
||||
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
if (message is Authentication authentication)
|
||||
{
|
||||
if (message is AuthenticationRequest authenticationRequest)
|
||||
{
|
||||
await AuthenticationRequestAsync(sender, authenticationRequest, cancellationToken);
|
||||
}
|
||||
|
||||
if (message is Authentication authentication)
|
||||
{
|
||||
await AuthenticationAsync(sender, authentication, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask AuthenticationRequestAsync(AgentSession session, AuthenticationRequest message, CancellationToken cancellationToken)
|
||||
{
|
||||
await session.SendAsync(message, cancellationToken);
|
||||
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
if (session.Id is not null)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) authenticated", session.RemoteEndPoint);
|
||||
return;
|
||||
}
|
||||
|
||||
await Task.Delay(50, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_logger.LogError("Authentication Timeout ({ep?})", session.RemoteEndPoint);
|
||||
session.Disconnect();
|
||||
}
|
||||
|
||||
private async ValueTask AuthenticationAsync(AgentSession session, Authentication authentication, CancellationToken cancellationToken)
|
||||
{
|
||||
if (authentication is null)
|
||||
{
|
||||
throw new NullReferenceException($"authentication failed (empty response)");
|
||||
}
|
||||
|
||||
if (authentication.Serial == default)
|
||||
{
|
||||
throw new InvalidDataException($"authentication failed ({nameof(authentication.Serial)})");
|
||||
}
|
||||
|
||||
//if (authentication.Version == default || authentication.Version < Domain.Constants.Configuration.Version)
|
||||
//{
|
||||
// throw new InvalidDataException($"authentication failed ({nameof(authentication.Version)})");
|
||||
//}
|
||||
|
||||
// upsert agent
|
||||
await _database.Agent().UpdateOneAsync(Builders<AgentEntity>
|
||||
.Filter
|
||||
.Eq(p => p.Serial, authentication.Serial.ToString()), Builders<AgentEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, DateTime.Now)
|
||||
.SetOnInsert(p => p.Serial, authentication.Serial.ToString())
|
||||
.Set(p => p.Update, DateTime.Now)
|
||||
.Set(p => p.Connected, DateTime.Now)
|
||||
.Set(p => p.Version, authentication.Version)
|
||||
.Set(p => p.Endpoint, session.RemoteEndPoint?.ToString())
|
||||
.Set(p => p.Hostname, authentication.Hostname), new UpdateOptions
|
||||
{
|
||||
IsUpsert = true
|
||||
}, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// get agent
|
||||
var agentEntity = await _database.Agent()
|
||||
.Find(Builders<AgentEntity>
|
||||
.Filter
|
||||
.Eq(p => p.Serial, authentication.Serial.ToString()))
|
||||
.FirstOrDefaultAsync(cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// set session id
|
||||
session.Id = agentEntity.Id;
|
||||
}
|
||||
|
||||
public async ValueTask ConnectedAsync(AgentSession session, CancellationToken cancellationToken)
|
||||
{
|
||||
if (session.Id is null) return;
|
||||
|
||||
// insert connect log
|
||||
await _database.AgentLog()
|
||||
.InsertOneAsync(new AgentLogEntity
|
||||
{
|
||||
Insert = DateTime.Now,
|
||||
Agent = session.Id,
|
||||
Category = CategoryEnum.Network.ToString(),
|
||||
Status = StatusEnum.Information.ToString(),
|
||||
Message = $"Connected ({session.RemoteEndPoint})",
|
||||
Timestamp = DateTime.Now
|
||||
}, cancellationToken: cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async ValueTask DisconnectedAsync(AgentSession session, CancellationToken cancellationToken)
|
||||
{
|
||||
if (session.Id is null) return;
|
||||
|
||||
// insert disconnect log
|
||||
await _database.AgentLog()
|
||||
.InsertOneAsync(new AgentLogEntity
|
||||
{
|
||||
Insert = DateTime.Now,
|
||||
Agent = session.Id,
|
||||
Category = CategoryEnum.Network.ToString(),
|
||||
Status = StatusEnum.Information.ToString(),
|
||||
Message = $"Disconnected ({session.RemoteEndPoint})",
|
||||
Timestamp = DateTime.Now
|
||||
}, cancellationToken: cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async ValueTask StatisticUpdateAsync(AgentSession session, CancellationToken cancellationToken)
|
||||
{
|
||||
if (session.Id is null) return;
|
||||
|
||||
// update agents stats
|
||||
await _database.Agent().UpdateOneAsync(Builders<AgentEntity>
|
||||
.Filter
|
||||
.Eq(p => p.Id, session.Id), Builders<AgentEntity>
|
||||
.Update
|
||||
.Set(p => p.Update, DateTime.Now)
|
||||
.Set(p => p.Activity, session.Activity)
|
||||
.Set(p => p.SentBytes, session.SentBytes)
|
||||
.Set(p => p.ReceivedBytes, session.ReceivedBytes)
|
||||
.Set(p => p.SentPackets, session.SentPackets)
|
||||
.Set(p => p.ReceivedPackets, session.ReceivedPackets), null, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async ValueTask LogAsync(AgentSession session, AgentLogEntity log, CancellationToken cancellationToken)
|
||||
{
|
||||
if (session.Id is null) return;
|
||||
|
||||
await _database.AgentLog()
|
||||
.InsertOneAsync(log, cancellationToken: cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
await AuthenticationAsync(sender, authentication, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask AuthenticationRequestAsync(AgentSession session, AuthenticationRequest message, CancellationToken cancellationToken)
|
||||
{
|
||||
await session.SendAsync(message, cancellationToken);
|
||||
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
if (session.Id is not null)
|
||||
{
|
||||
_logger.LogInformation("Agent ({ep?}) authenticated", session.RemoteEndPoint);
|
||||
return;
|
||||
}
|
||||
|
||||
await Task.Delay(50, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_logger.LogError("Authentication Timeout ({ep?})", session.RemoteEndPoint);
|
||||
session.Disconnect();
|
||||
}
|
||||
|
||||
private async ValueTask AuthenticationAsync(AgentSession session, Authentication authentication, CancellationToken cancellationToken)
|
||||
{
|
||||
if (authentication is null)
|
||||
{
|
||||
throw new NullReferenceException($"authentication failed (empty response)");
|
||||
}
|
||||
|
||||
if (authentication.Serial == default)
|
||||
{
|
||||
throw new InvalidDataException($"authentication failed ({nameof(authentication.Serial)})");
|
||||
}
|
||||
|
||||
//if (authentication.Version == default || authentication.Version < Domain.Constants.Configuration.Version)
|
||||
//{
|
||||
// throw new InvalidDataException($"authentication failed ({nameof(authentication.Version)})");
|
||||
//}
|
||||
|
||||
// upsert agent
|
||||
await _database.Agent().UpdateOneAsync(Builders<AgentEntity>
|
||||
.Filter
|
||||
.Eq(p => p.Serial, authentication.Serial.ToString()), Builders<AgentEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, DateTime.Now)
|
||||
.SetOnInsert(p => p.Serial, authentication.Serial.ToString())
|
||||
.Set(p => p.Update, DateTime.Now)
|
||||
.Set(p => p.Connected, DateTime.Now)
|
||||
.Set(p => p.Version, authentication.Version)
|
||||
.Set(p => p.Endpoint, session.RemoteEndPoint?.ToString())
|
||||
.Set(p => p.Hostname, authentication.Hostname), new UpdateOptions
|
||||
{
|
||||
IsUpsert = true
|
||||
}, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// get agent
|
||||
var agentEntity = await _database.Agent()
|
||||
.Find(Builders<AgentEntity>
|
||||
.Filter
|
||||
.Eq(p => p.Serial, authentication.Serial.ToString()))
|
||||
.FirstOrDefaultAsync(cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// set session id
|
||||
session.Id = agentEntity.Id;
|
||||
}
|
||||
|
||||
public async ValueTask ConnectedAsync(AgentSession session, CancellationToken cancellationToken)
|
||||
{
|
||||
if (session.Id is null) return;
|
||||
|
||||
// insert connect log
|
||||
await _database.AgentLog()
|
||||
.InsertOneAsync(new AgentLogEntity
|
||||
{
|
||||
Insert = DateTime.Now,
|
||||
Agent = session.Id,
|
||||
Category = CategoryEnum.Network.ToString(),
|
||||
Status = StatusEnum.Information.ToString(),
|
||||
Message = $"Connected ({session.RemoteEndPoint})",
|
||||
Timestamp = DateTime.Now
|
||||
}, cancellationToken: cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async ValueTask DisconnectedAsync(AgentSession session, CancellationToken cancellationToken)
|
||||
{
|
||||
if (session.Id is null) return;
|
||||
|
||||
// insert disconnect log
|
||||
await _database.AgentLog()
|
||||
.InsertOneAsync(new AgentLogEntity
|
||||
{
|
||||
Insert = DateTime.Now,
|
||||
Agent = session.Id,
|
||||
Category = CategoryEnum.Network.ToString(),
|
||||
Status = StatusEnum.Information.ToString(),
|
||||
Message = $"Disconnected ({session.RemoteEndPoint})",
|
||||
Timestamp = DateTime.Now
|
||||
}, cancellationToken: cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async ValueTask StatisticUpdateAsync(AgentSession session, CancellationToken cancellationToken)
|
||||
{
|
||||
if (session.Id is null) return;
|
||||
|
||||
// update agents stats
|
||||
await _database.Agent().UpdateOneAsync(Builders<AgentEntity>
|
||||
.Filter
|
||||
.Eq(p => p.Id, session.Id), Builders<AgentEntity>
|
||||
.Update
|
||||
.Set(p => p.Update, DateTime.Now)
|
||||
.Set(p => p.Activity, session.Activity)
|
||||
.Set(p => p.SentBytes, session.SentBytes)
|
||||
.Set(p => p.ReceivedBytes, session.ReceivedBytes)
|
||||
.Set(p => p.SentPackets, session.SentPackets)
|
||||
.Set(p => p.ReceivedPackets, session.ReceivedPackets), null, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async ValueTask LogAsync(AgentSession session, AgentLogEntity log, CancellationToken cancellationToken)
|
||||
{
|
||||
if (session.Id is null) return;
|
||||
|
||||
await _database.AgentLog()
|
||||
.InsertOneAsync(log, cancellationToken: cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +1,50 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Web.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Insight.Domain.Messages.Web;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MongoDB.Driver;
|
||||
using Vaitr.Network;
|
||||
|
||||
namespace Insight.Server.Network.Handlers.Agent
|
||||
namespace Insight.Server.Network.Handlers.Agent;
|
||||
|
||||
public class ConsoleHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
public class ConsoleHandler : IAgentMessageHandler<AgentSession>
|
||||
private readonly ISessionPool<WebSession, IMessage> _webPool;
|
||||
private readonly IMongoDatabase _database;
|
||||
private readonly ILogger<ConsoleHandler> _logger;
|
||||
|
||||
public ConsoleHandler(
|
||||
ISessionPool<WebSession, IMessage> webPool,
|
||||
IMongoDatabase database,
|
||||
ILogger<ConsoleHandler> logger)
|
||||
{
|
||||
private readonly ISessionPool<WebSession, IWebMessage> _webPool;
|
||||
private readonly IMongoDatabase _database;
|
||||
private readonly ILogger<ConsoleHandler> _logger;
|
||||
_webPool = webPool;
|
||||
_database = database;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public ConsoleHandler(
|
||||
ISessionPool<WebSession, IWebMessage> webPool,
|
||||
IMongoDatabase database,
|
||||
ILogger<ConsoleHandler> logger)
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
if (message is ConsoleQuery consoleQuery)
|
||||
{
|
||||
_webPool = webPool;
|
||||
_database = database;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
{
|
||||
if (message is ConsoleQuery consoleQuery)
|
||||
{
|
||||
await OnConsoleQueryAsync(sender, consoleQuery, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask OnConsoleQueryAsync(AgentSession session, ConsoleQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
// check if web online
|
||||
if (_webPool.FirstOrDefault().Value is not WebSession web) return;
|
||||
|
||||
await web.SendAsync(new ConsoleQueryProxy
|
||||
{
|
||||
Id = query.Id,
|
||||
HostId = query.HostId,
|
||||
Query = query.Query,
|
||||
Data = query.Data,
|
||||
Errors = query.Errors,
|
||||
HadErrors = query.HadErrors
|
||||
}, cancellationToken);
|
||||
await OnConsoleQueryAsync(sender, consoleQuery, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask OnConsoleQueryAsync(AgentSession session, ConsoleQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
// check if web online
|
||||
if (_webPool.FirstOrDefault().Value is not WebSession web) return;
|
||||
|
||||
await web.SendAsync(new ConsoleQueryProxy
|
||||
{
|
||||
Id = query.Id,
|
||||
HostId = query.HostId,
|
||||
Query = query.Query,
|
||||
Data = query.Data,
|
||||
Errors = query.Errors,
|
||||
HadErrors = query.HadErrors
|
||||
}, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,145 +1,145 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Insight.Infrastructure;
|
||||
using Insight.Infrastructure.Entities;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace Insight.Server.Network.Handlers.Agent
|
||||
namespace Insight.Server.Network.Handlers.Agent;
|
||||
|
||||
public class DriveHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
public class DriveHandler : IAgentMessageHandler<AgentSession>
|
||||
private readonly IMongoDatabase _database;
|
||||
|
||||
public DriveHandler(IMongoDatabase database)
|
||||
{
|
||||
private readonly IMongoDatabase _database;
|
||||
_database = database;
|
||||
}
|
||||
|
||||
public DriveHandler(IMongoDatabase database)
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
if (message is DriveList drives)
|
||||
{
|
||||
_database = database;
|
||||
await OnDrivesAsync(sender, drives, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
private async ValueTask OnDrivesAsync(AgentSession session, List<Drive> drives, CancellationToken cancellationToken)
|
||||
{
|
||||
var agentEntity = await _database.Agent().Find(Builders<AgentEntity>.Filter.Eq(p => p.Id, session.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (agentEntity is null) return;
|
||||
|
||||
var hostEntity = await _database.Host().Find(Builders<HostEntity>.Filter.Eq(p => p.Agent, agentEntity.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (hostEntity is null) return;
|
||||
|
||||
var batch = ObjectId.GenerateNewId().ToString();
|
||||
var date = DateTime.Now;
|
||||
|
||||
var driveBulk = new List<WriteModel<HostDriveEntity>>();
|
||||
|
||||
if (drives is not null && drives.Any())
|
||||
{
|
||||
if (message is DriveList drives)
|
||||
foreach (var drive in drives)
|
||||
{
|
||||
await OnDrivesAsync(sender, drives, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask OnDrivesAsync(AgentSession session, List<Drive> drives, CancellationToken cancellationToken)
|
||||
{
|
||||
var agentEntity = await _database.Agent().Find(Builders<AgentEntity>.Filter.Eq(p => p.Id, session.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (agentEntity is null) return;
|
||||
|
||||
var hostEntity = await _database.Host().Find(Builders<HostEntity>.Filter.Eq(p => p.Agent, agentEntity.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (hostEntity is null) return;
|
||||
|
||||
var batch = ObjectId.GenerateNewId().ToString();
|
||||
var date = DateTime.Now;
|
||||
|
||||
var driveBulk = new List<WriteModel<HostDriveEntity>>();
|
||||
|
||||
if (drives is not null && drives.Any())
|
||||
{
|
||||
foreach (var drive in drives)
|
||||
{
|
||||
var driveFilter = Builders<HostDriveEntity>.Filter.And(new List<FilterDefinition<HostDriveEntity>>
|
||||
{
|
||||
Builders<HostDriveEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostDriveEntity>.Filter.Eq(x => x.Index, drive.Index)
|
||||
});
|
||||
|
||||
var driveUpdate = Builders<HostDriveEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Index, drive.Index)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch)
|
||||
.Set(p => p.Company, drive.Manufacturer)
|
||||
.Set(p => p.Name, drive.Name)
|
||||
.Set(p => p.Size, drive.Size)
|
||||
.Set(p => p.Type, drive.InterfaceType)
|
||||
.Set(p => p.Serial, drive.SerialNumber)
|
||||
.Set(p => p.Firmware, drive.FirmwareRevision)
|
||||
.Set(p => p.Status, drive.Status)
|
||||
.Set(p => p.Pnp, drive.PNPDeviceID);
|
||||
|
||||
driveBulk.Add(new UpdateOneModel<HostDriveEntity>(driveFilter, driveUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
driveBulk.Add(new DeleteManyModel<HostDriveEntity>(Builders<HostDriveEntity>.Filter.And(new List<FilterDefinition<HostDriveEntity>>
|
||||
var driveFilter = Builders<HostDriveEntity>.Filter.And(new List<FilterDefinition<HostDriveEntity>>
|
||||
{
|
||||
Builders<HostDriveEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostDriveEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
Builders<HostDriveEntity>.Filter.Eq(x => x.Index, drive.Index)
|
||||
});
|
||||
|
||||
var driveResult = await _database.HostDrive().BulkWriteAsync(driveBulk, cancellationToken: cancellationToken);
|
||||
var driveUpdate = Builders<HostDriveEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Index, drive.Index)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch)
|
||||
.Set(p => p.Company, drive.Manufacturer)
|
||||
.Set(p => p.Name, drive.Name)
|
||||
.Set(p => p.Size, drive.Size)
|
||||
.Set(p => p.Type, drive.InterfaceType)
|
||||
.Set(p => p.Serial, drive.SerialNumber)
|
||||
.Set(p => p.Firmware, drive.FirmwareRevision)
|
||||
.Set(p => p.Status, drive.Status)
|
||||
.Set(p => p.Pnp, drive.PNPDeviceID);
|
||||
|
||||
// volumes
|
||||
|
||||
var volumeBulk = new List<WriteModel<HostVolumeEntity>>();
|
||||
|
||||
if (drives is not null && drives.Any())
|
||||
{
|
||||
foreach (var drive in drives)
|
||||
driveBulk.Add(new UpdateOneModel<HostDriveEntity>(driveFilter, driveUpdate)
|
||||
{
|
||||
var driveId = await _database.HostDrive()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == drive.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (drive.Volumes is not null && drive.Volumes.Any())
|
||||
driveBulk.Add(new DeleteManyModel<HostDriveEntity>(Builders<HostDriveEntity>.Filter.And(new List<FilterDefinition<HostDriveEntity>>
|
||||
{
|
||||
Builders<HostDriveEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostDriveEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var driveResult = await _database.HostDrive().BulkWriteAsync(driveBulk, cancellationToken: cancellationToken);
|
||||
|
||||
// volumes
|
||||
|
||||
var volumeBulk = new List<WriteModel<HostVolumeEntity>>();
|
||||
|
||||
if (drives is not null && drives.Any())
|
||||
{
|
||||
foreach (var drive in drives)
|
||||
{
|
||||
var driveId = await _database.HostDrive()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == drive.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (drive.Volumes is not null && drive.Volumes.Any())
|
||||
{
|
||||
foreach (var volume in drive.Volumes)
|
||||
{
|
||||
foreach (var volume in drive.Volumes)
|
||||
{
|
||||
var volumeFilter = Builders<HostVolumeEntity>.Filter.And(new List<FilterDefinition<HostVolumeEntity>>
|
||||
{
|
||||
Builders<HostVolumeEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostVolumeEntity>.Filter.Eq(x => x.Drive, driveId),
|
||||
Builders<HostVolumeEntity>.Filter.Eq(x => x.Index, volume.Index)
|
||||
});
|
||||
|
||||
var volumeUpdate = Builders<HostVolumeEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Drive, driveId)
|
||||
.SetOnInsert(p => p.Index, volume.Index)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch)
|
||||
.Set(p => p.Name, volume.Name)
|
||||
.Set(p => p.Label, volume.Id)
|
||||
.Set(p => p.Serial, volume.SerialNumber)
|
||||
.Set(p => p.Size, volume.Size)
|
||||
.Set(p => p.FreeSpace, volume.FreeSpace)
|
||||
.Set(p => p.Type, volume.Type)
|
||||
.Set(p => p.FileSystem, volume.FileSystem)
|
||||
.Set(p => p.Compressed, volume.Compressed)
|
||||
.Set(p => p.Bootable, volume.Bootable)
|
||||
.Set(p => p.Primary, volume.PrimaryPartition)
|
||||
.Set(p => p.Boot, volume.Bootable)
|
||||
.Set(p => p.BlockSize, volume.BlockSize)
|
||||
.Set(p => p.Blocks, volume.NumberOfBlocks)
|
||||
.Set(p => p.StartingOffset, volume.StartingOffset)
|
||||
.Set(p => p.Provider, volume.ProviderName);
|
||||
|
||||
volumeBulk.Add(new UpdateOneModel<HostVolumeEntity>(volumeFilter, volumeUpdate)
|
||||
var volumeFilter = Builders<HostVolumeEntity>.Filter.And(new List<FilterDefinition<HostVolumeEntity>>
|
||||
{
|
||||
IsUpsert = true
|
||||
Builders<HostVolumeEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostVolumeEntity>.Filter.Eq(x => x.Drive, driveId),
|
||||
Builders<HostVolumeEntity>.Filter.Eq(x => x.Index, volume.Index)
|
||||
});
|
||||
}
|
||||
|
||||
var volumeUpdate = Builders<HostVolumeEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Drive, driveId)
|
||||
.SetOnInsert(p => p.Index, volume.Index)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch)
|
||||
.Set(p => p.Name, volume.Name)
|
||||
.Set(p => p.Label, volume.Id)
|
||||
.Set(p => p.Serial, volume.SerialNumber)
|
||||
.Set(p => p.Size, volume.Size)
|
||||
.Set(p => p.FreeSpace, volume.FreeSpace)
|
||||
.Set(p => p.Type, volume.Type)
|
||||
.Set(p => p.FileSystem, volume.FileSystem)
|
||||
.Set(p => p.Compressed, volume.Compressed)
|
||||
.Set(p => p.Bootable, volume.Bootable)
|
||||
.Set(p => p.Primary, volume.PrimaryPartition)
|
||||
.Set(p => p.Boot, volume.Bootable)
|
||||
.Set(p => p.BlockSize, volume.BlockSize)
|
||||
.Set(p => p.Blocks, volume.NumberOfBlocks)
|
||||
.Set(p => p.StartingOffset, volume.StartingOffset)
|
||||
.Set(p => p.Provider, volume.ProviderName);
|
||||
|
||||
volumeBulk.Add(new UpdateOneModel<HostVolumeEntity>(volumeFilter, volumeUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volumeBulk.Add(new DeleteManyModel<HostVolumeEntity>(Builders<HostVolumeEntity>.Filter.And(new List<FilterDefinition<HostVolumeEntity>>
|
||||
{
|
||||
Builders<HostVolumeEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostVolumeEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var volumeResult = await _database.HostVolume().BulkWriteAsync(volumeBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
volumeBulk.Add(new DeleteManyModel<HostVolumeEntity>(Builders<HostVolumeEntity>.Filter.And(new List<FilterDefinition<HostVolumeEntity>>
|
||||
{
|
||||
Builders<HostVolumeEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostVolumeEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var volumeResult = await _database.HostVolume().BulkWriteAsync(volumeBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,266 +1,266 @@
|
|||
using Insight.Agent.Enums;
|
||||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Enums;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Insight.Infrastructure;
|
||||
using Insight.Infrastructure.Entities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MongoDB.Driver;
|
||||
using static Insight.Agent.Messages.Event;
|
||||
using static Insight.Domain.Messages.Agent.Event;
|
||||
|
||||
namespace Insight.Server.Network.Handlers.Agent
|
||||
namespace Insight.Server.Network.Handlers.Agent;
|
||||
|
||||
public class EventHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
public class EventHandler : IAgentMessageHandler<AgentSession>
|
||||
private readonly IMongoDatabase _database;
|
||||
private readonly ILogger<EventHandler> _logger;
|
||||
|
||||
public EventHandler(IMongoDatabase database, ILogger<EventHandler> logger)
|
||||
{
|
||||
private readonly IMongoDatabase _database;
|
||||
private readonly ILogger<EventHandler> _logger;
|
||||
_database = database;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public EventHandler(IMongoDatabase database, ILogger<EventHandler> logger)
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
if (message is Event @event)
|
||||
{
|
||||
_database = database;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
{
|
||||
if (message is Event @event)
|
||||
{
|
||||
await OnEventAsync(sender, @event, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask OnEventAsync(AgentSession session, Event @event, CancellationToken cancellationToken)
|
||||
{
|
||||
var agentEntity = await _database.Agent().Find(Builders<AgentEntity>.Filter.Eq(p => p.Id, session.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (agentEntity is null) return;
|
||||
|
||||
var hostEntity = await _database.Host().Find(Builders<HostEntity>.Filter.Eq(p => p.Agent, agentEntity.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (hostEntity is null) return;
|
||||
|
||||
if (FilterEventId(@event)) return;
|
||||
|
||||
var hostLog = await InsertHostLogAsync(hostEntity, @event, cancellationToken);
|
||||
|
||||
if (hostLog is null || FilterMonitoringHostLog(hostLog)) return;
|
||||
|
||||
await _database.HostLogMonitoring()
|
||||
.InsertOneAsync(new HostLogMonitoringEntity
|
||||
{
|
||||
Host = hostEntity.Id,
|
||||
Insert = hostLog.Insert,
|
||||
Timestamp = hostLog.Timestamp,
|
||||
Category = hostLog.Category,
|
||||
Status = hostLog.Status,
|
||||
Message = hostLog.Message,
|
||||
Dispatch = DispatchEnum.Pending.ToString()
|
||||
}, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
private async ValueTask<AgentLogEntity?> InsertAgentLogAsync(AgentSession session, Event @event, CancellationToken cancellationToken)
|
||||
{
|
||||
var agentEntity = await _database.Agent()
|
||||
.Aggregate()
|
||||
.Match(Builders<AgentEntity>.Filter.Eq(p => p.Id, session.Id))
|
||||
.Lookup<AgentEntity, HostEntity, AgentEntity>(_database.Host(), p => p.Serial, p => p.Agent, p => p.Hosts)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (agentEntity is null) return null;
|
||||
|
||||
StatusEnum? status = @event.Status switch
|
||||
{
|
||||
StatusType.Information => StatusEnum.Information,
|
||||
StatusType.Warning => StatusEnum.Warning,
|
||||
StatusType.Error => StatusEnum.Error,
|
||||
_ => null
|
||||
};
|
||||
|
||||
CategoryEnum? category = @event.Category.ToLower() switch
|
||||
{
|
||||
"network" => CategoryEnum.Network,
|
||||
"application" => CategoryEnum.Application,
|
||||
"security" => CategoryEnum.Security,
|
||||
"system" => CategoryEnum.System,
|
||||
_ => null
|
||||
};
|
||||
|
||||
var date = DateTime.Now;
|
||||
|
||||
var log = new AgentLogEntity
|
||||
{
|
||||
Insert = date,
|
||||
Agent = agentEntity.Id,
|
||||
Timestamp = @event.Timestamp,
|
||||
EventId = @event.EventId.ToString(),
|
||||
Source = @event.Source,
|
||||
Status = status.ToString(),
|
||||
Category = category.ToString(),
|
||||
Message = @event.Message
|
||||
};
|
||||
|
||||
await _database.AgentLog().InsertOneAsync(log, cancellationToken: cancellationToken);
|
||||
return log;
|
||||
}
|
||||
|
||||
private async ValueTask<HostLogEntity?> InsertHostLogAsync(HostEntity hostEntity, Event @event, CancellationToken cancellationToken)
|
||||
{
|
||||
StatusEnum? status = @event.Status switch
|
||||
{
|
||||
StatusType.Information => StatusEnum.Information,
|
||||
StatusType.Warning => StatusEnum.Warning,
|
||||
StatusType.Error => StatusEnum.Error,
|
||||
StatusType.Critical => StatusEnum.Error,
|
||||
StatusType.Unknown => null,
|
||||
_ => null
|
||||
};
|
||||
|
||||
CategoryEnum? category = null;
|
||||
switch (@event.Category)
|
||||
{
|
||||
case var _ when @event.Category.Contains("network", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Network;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("application", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Application;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("security", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Security;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("system", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.System;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("printservice", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Printer;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("taskscheduler", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Task;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("terminalservices", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.RDP;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("smbclient", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Network;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("smbserver", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Network;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("storagespaces", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.System;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("diagnostics", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.System;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var date = DateTime.Now;
|
||||
|
||||
var log = new HostLogEntity
|
||||
{
|
||||
Insert = date,
|
||||
Host = hostEntity.Id,
|
||||
Timestamp = @event.Timestamp,
|
||||
EventId = @event.EventId.ToString(),
|
||||
Status = status.ToString(),
|
||||
Source = @event.Source,
|
||||
Category = category?.ToString(),
|
||||
Message = @event.Message
|
||||
};
|
||||
|
||||
await _database.HostLog().InsertOneAsync(log, cancellationToken: cancellationToken);
|
||||
return log;
|
||||
}
|
||||
|
||||
private bool FilterEventId(Event @event)
|
||||
{
|
||||
var filter = new List<int>
|
||||
{
|
||||
0,
|
||||
3,
|
||||
4,
|
||||
16,
|
||||
37,
|
||||
900,
|
||||
902,
|
||||
903,
|
||||
1001,
|
||||
1003,
|
||||
1008,
|
||||
1023,
|
||||
1066,
|
||||
4624,
|
||||
4625,
|
||||
4634,
|
||||
4648,
|
||||
4672,
|
||||
4776,
|
||||
4798,
|
||||
4799,
|
||||
5058,
|
||||
5059,
|
||||
5061,
|
||||
5379,
|
||||
5612,
|
||||
5781,
|
||||
//7036,
|
||||
8014,
|
||||
8016,
|
||||
8019,
|
||||
8194,
|
||||
8224,
|
||||
9009,
|
||||
9027,
|
||||
10001,
|
||||
10016,
|
||||
16384,
|
||||
16394,
|
||||
36874,
|
||||
36888,
|
||||
};
|
||||
|
||||
if (filter.Any(p => p == @event.EventId)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool FilterMonitoringHostLog(HostLogEntity hostLog)
|
||||
{
|
||||
//_logger.LogDebug($"try filter event: {hostLog.Category}.{hostLog.Source}.{hostLog.Status}");
|
||||
|
||||
if (Enum.TryParse(hostLog.Status, out StatusType status) is false) return true;
|
||||
|
||||
if (hostLog.Category == CategoryEnum.System.ToString())
|
||||
{
|
||||
if (hostLog.Source == "Service Control Manager" && status < StatusType.Warning) return true;
|
||||
}
|
||||
|
||||
if (hostLog.Category == CategoryEnum.Task.ToString())
|
||||
{
|
||||
if (status < StatusType.Error) return true;
|
||||
}
|
||||
|
||||
// skip rdp infos
|
||||
if (hostLog.Category == CategoryEnum.RDP.ToString())
|
||||
{
|
||||
if (hostLog.EventId == "261") return true;
|
||||
}
|
||||
|
||||
// skip smbclient (veeam errors)
|
||||
if (hostLog.Category == CategoryEnum.Security.ToString())
|
||||
{
|
||||
if (hostLog.Source == "Microsoft-Windows-SMBClient") return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
await OnEventAsync(sender, @event, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask OnEventAsync(AgentSession session, Event @event, CancellationToken cancellationToken)
|
||||
{
|
||||
var agentEntity = await _database.Agent().Find(Builders<AgentEntity>.Filter.Eq(p => p.Id, session.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (agentEntity is null) return;
|
||||
|
||||
var hostEntity = await _database.Host().Find(Builders<HostEntity>.Filter.Eq(p => p.Agent, agentEntity.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (hostEntity is null) return;
|
||||
|
||||
if (FilterEventId(@event)) return;
|
||||
|
||||
var hostLog = await InsertHostLogAsync(hostEntity, @event, cancellationToken);
|
||||
|
||||
if (hostLog is null || FilterMonitoringHostLog(hostLog)) return;
|
||||
|
||||
await _database.HostLogMonitoring()
|
||||
.InsertOneAsync(new HostLogMonitoringEntity
|
||||
{
|
||||
Host = hostEntity.Id,
|
||||
Insert = hostLog.Insert,
|
||||
Timestamp = hostLog.Timestamp,
|
||||
Category = hostLog.Category,
|
||||
Status = hostLog.Status,
|
||||
Message = hostLog.Message,
|
||||
Dispatch = DispatchEnum.Pending.ToString()
|
||||
}, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
private async ValueTask<AgentLogEntity?> InsertAgentLogAsync(AgentSession session, Event @event, CancellationToken cancellationToken)
|
||||
{
|
||||
var agentEntity = await _database.Agent()
|
||||
.Aggregate()
|
||||
.Match(Builders<AgentEntity>.Filter.Eq(p => p.Id, session.Id))
|
||||
.Lookup<AgentEntity, HostEntity, AgentEntity>(_database.Host(), p => p.Serial, p => p.Agent, p => p.Hosts)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (agentEntity is null) return null;
|
||||
|
||||
StatusEnum? status = @event.Status switch
|
||||
{
|
||||
StatusType.Information => StatusEnum.Information,
|
||||
StatusType.Warning => StatusEnum.Warning,
|
||||
StatusType.Error => StatusEnum.Error,
|
||||
_ => null
|
||||
};
|
||||
|
||||
CategoryEnum? category = @event.Category.ToLower() switch
|
||||
{
|
||||
"network" => CategoryEnum.Network,
|
||||
"application" => CategoryEnum.Application,
|
||||
"security" => CategoryEnum.Security,
|
||||
"system" => CategoryEnum.System,
|
||||
_ => null
|
||||
};
|
||||
|
||||
var date = DateTime.Now;
|
||||
|
||||
var log = new AgentLogEntity
|
||||
{
|
||||
Insert = date,
|
||||
Agent = agentEntity.Id,
|
||||
Timestamp = @event.Timestamp,
|
||||
EventId = @event.EventId.ToString(),
|
||||
Source = @event.Source,
|
||||
Status = status.ToString(),
|
||||
Category = category.ToString(),
|
||||
Message = @event.Message
|
||||
};
|
||||
|
||||
await _database.AgentLog().InsertOneAsync(log, cancellationToken: cancellationToken);
|
||||
return log;
|
||||
}
|
||||
|
||||
private async ValueTask<HostLogEntity?> InsertHostLogAsync(HostEntity hostEntity, Event @event, CancellationToken cancellationToken)
|
||||
{
|
||||
StatusEnum? status = @event.Status switch
|
||||
{
|
||||
StatusType.Information => StatusEnum.Information,
|
||||
StatusType.Warning => StatusEnum.Warning,
|
||||
StatusType.Error => StatusEnum.Error,
|
||||
StatusType.Critical => StatusEnum.Error,
|
||||
StatusType.Unknown => null,
|
||||
_ => null
|
||||
};
|
||||
|
||||
CategoryEnum? category = null;
|
||||
switch (@event.Category)
|
||||
{
|
||||
case var _ when @event.Category.Contains("network", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Network;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("application", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Application;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("security", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Security;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("system", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.System;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("printservice", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Printer;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("taskscheduler", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Task;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("terminalservices", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.RDP;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("smbclient", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Network;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("smbserver", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.Network;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("storagespaces", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.System;
|
||||
break;
|
||||
|
||||
case var _ when @event.Category.Contains("diagnostics", StringComparison.InvariantCultureIgnoreCase):
|
||||
category = CategoryEnum.System;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var date = DateTime.Now;
|
||||
|
||||
var log = new HostLogEntity
|
||||
{
|
||||
Insert = date,
|
||||
Host = hostEntity.Id,
|
||||
Timestamp = @event.Timestamp,
|
||||
EventId = @event.EventId.ToString(),
|
||||
Status = status.ToString(),
|
||||
Source = @event.Source,
|
||||
Category = category?.ToString(),
|
||||
Message = @event.Message
|
||||
};
|
||||
|
||||
await _database.HostLog().InsertOneAsync(log, cancellationToken: cancellationToken);
|
||||
return log;
|
||||
}
|
||||
|
||||
private bool FilterEventId(Event @event)
|
||||
{
|
||||
var filter = new List<int>
|
||||
{
|
||||
0,
|
||||
3,
|
||||
4,
|
||||
16,
|
||||
37,
|
||||
900,
|
||||
902,
|
||||
903,
|
||||
1001,
|
||||
1003,
|
||||
1008,
|
||||
1023,
|
||||
1066,
|
||||
4624,
|
||||
4625,
|
||||
4634,
|
||||
4648,
|
||||
4672,
|
||||
4776,
|
||||
4798,
|
||||
4799,
|
||||
5058,
|
||||
5059,
|
||||
5061,
|
||||
5379,
|
||||
5612,
|
||||
5781,
|
||||
//7036,
|
||||
8014,
|
||||
8016,
|
||||
8019,
|
||||
8194,
|
||||
8224,
|
||||
9009,
|
||||
9027,
|
||||
10001,
|
||||
10016,
|
||||
16384,
|
||||
16394,
|
||||
36874,
|
||||
36888,
|
||||
};
|
||||
|
||||
if (filter.Any(p => p == @event.EventId)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool FilterMonitoringHostLog(HostLogEntity hostLog)
|
||||
{
|
||||
//_logger.LogDebug($"try filter event: {hostLog.Category}.{hostLog.Source}.{hostLog.Status}");
|
||||
|
||||
if (Enum.TryParse(hostLog.Status, out StatusType status) is false) return true;
|
||||
|
||||
if (hostLog.Category == CategoryEnum.System.ToString())
|
||||
{
|
||||
if (hostLog.Source == "Service Control Manager" && status < StatusType.Warning) return true;
|
||||
}
|
||||
|
||||
if (hostLog.Category == CategoryEnum.Task.ToString())
|
||||
{
|
||||
if (status < StatusType.Error) return true;
|
||||
}
|
||||
|
||||
// skip rdp infos
|
||||
if (hostLog.Category == CategoryEnum.RDP.ToString())
|
||||
{
|
||||
if (hostLog.EventId == "261") return true;
|
||||
}
|
||||
|
||||
// skip smbclient (veeam errors)
|
||||
if (hostLog.Category == CategoryEnum.Security.ToString())
|
||||
{
|
||||
if (hostLog.Source == "Microsoft-Windows-SMBClient") return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,299 +1,299 @@
|
|||
using Insight.Agent.Interfaces;
|
||||
using Insight.Agent.Messages;
|
||||
using Insight.Domain.Interfaces;
|
||||
using Insight.Domain.Messages;
|
||||
using Insight.Domain.Messages.Agent;
|
||||
using Insight.Infrastructure;
|
||||
using Insight.Infrastructure.Entities;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace Insight.Server.Network.Handlers.Agent
|
||||
namespace Insight.Server.Network.Handlers.Agent;
|
||||
|
||||
public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||
{
|
||||
public class InterfaceHandler : IAgentMessageHandler<AgentSession>
|
||||
private readonly IMongoDatabase _database;
|
||||
|
||||
public InterfaceHandler(IMongoDatabase database)
|
||||
{
|
||||
private readonly IMongoDatabase _database;
|
||||
_database = database;
|
||||
}
|
||||
|
||||
public InterfaceHandler(IMongoDatabase database)
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||
{
|
||||
if (message is InterfaceList interfaces)
|
||||
{
|
||||
_database = database;
|
||||
await OnInterfacesAsync(sender, interfaces, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
||||
private async ValueTask OnInterfacesAsync(AgentSession session, List<Interface> interfaces, CancellationToken cancellationToken)
|
||||
{
|
||||
var agentEntity = await _database.Agent().Find(Builders<AgentEntity>.Filter.Eq(p => p.Id, session.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (agentEntity is null) return;
|
||||
|
||||
var hostEntity = await _database.Host().Find(Builders<HostEntity>.Filter.Eq(p => p.Agent, agentEntity.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (hostEntity is null) return;
|
||||
|
||||
var batch = ObjectId.GenerateNewId().ToString();
|
||||
var date = DateTime.Now;
|
||||
|
||||
// interfaces
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
if (message is InterfaceList interfaces)
|
||||
var interfaceBulk = new List<WriteModel<HostInterfaceEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
await OnInterfacesAsync(sender, interfaces, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask OnInterfacesAsync(AgentSession session, List<Interface> interfaces, CancellationToken cancellationToken)
|
||||
{
|
||||
var agentEntity = await _database.Agent().Find(Builders<AgentEntity>.Filter.Eq(p => p.Id, session.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (agentEntity is null) return;
|
||||
|
||||
var hostEntity = await _database.Host().Find(Builders<HostEntity>.Filter.Eq(p => p.Agent, agentEntity.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||
if (hostEntity is null) return;
|
||||
|
||||
var batch = ObjectId.GenerateNewId().ToString();
|
||||
var date = DateTime.Now;
|
||||
|
||||
// interfaces
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
var interfaceBulk = new List<WriteModel<HostInterfaceEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
var interfaceFilter = Builders<HostInterfaceEntity>.Filter.And(new List<FilterDefinition<HostInterfaceEntity>>
|
||||
{
|
||||
Builders<HostInterfaceEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceEntity>.Filter.Eq(x => x.Index, @interface.Index)
|
||||
});
|
||||
|
||||
var interfaceUpdate = Builders<HostInterfaceEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Index, @interface.Index)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch)
|
||||
|
||||
.Set(p => p.Mac, @interface?.Mac)
|
||||
.Set(p => p.Name, @interface?.Name)
|
||||
.Set(p => p.Description, @interface?.Description)
|
||||
.Set(p => p.Physical, @interface?.Physical)
|
||||
.Set(p => p.Status, @interface?.Status?.ToString())
|
||||
.Set(p => p.Suffix, @interface?.Suffix)
|
||||
.Set(p => p.Speed, @interface?.Speed)
|
||||
.Set(p => p.Ipv4Mtu, @interface?.Ipv4Mtu)
|
||||
.Set(p => p.Ipv4Dhcp, @interface?.Ipv4Dhcp)
|
||||
|
||||
.Set(p => p.Ipv4Forwarding, @interface?.Ipv4Forwarding)
|
||||
.Set(p => p.Ipv6Mtu, @interface?.Ipv6Mtu)
|
||||
.Set(p => p.Sent, @interface?.Sent)
|
||||
.Set(p => p.Received, @interface?.Received)
|
||||
.Set(p => p.IncomingPacketsDiscarded, @interface?.IncomingPacketsDiscarded)
|
||||
.Set(p => p.IncomingPacketsWithErrors, @interface?.IncomingPacketsWithErrors)
|
||||
.Set(p => p.IncomingUnknownProtocolPackets, @interface?.IncomingUnknownProtocolPackets)
|
||||
.Set(p => p.OutgoingPacketsDiscarded, @interface?.OutgoingPacketsDiscarded)
|
||||
.Set(p => p.OutgoingPacketsWithErrors, @interface?.OutgoingPacketsWithErrors);
|
||||
|
||||
interfaceBulk.Add(new UpdateOneModel<HostInterfaceEntity>(interfaceFilter, interfaceUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
|
||||
interfaceBulk.Add(new DeleteManyModel<HostInterfaceEntity>(Builders<HostInterfaceEntity>.Filter.And(new List<FilterDefinition<HostInterfaceEntity>>
|
||||
var interfaceFilter = Builders<HostInterfaceEntity>.Filter.And(new List<FilterDefinition<HostInterfaceEntity>>
|
||||
{
|
||||
Builders<HostInterfaceEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
Builders<HostInterfaceEntity>.Filter.Eq(x => x.Index, @interface.Index)
|
||||
});
|
||||
|
||||
var interfaceResult = await _database.HostInterface().BulkWriteAsync(interfaceBulk, cancellationToken: cancellationToken);
|
||||
var interfaceUpdate = Builders<HostInterfaceEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Index, @interface.Index)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch)
|
||||
|
||||
.Set(p => p.Mac, @interface?.Mac)
|
||||
.Set(p => p.Name, @interface?.Name)
|
||||
.Set(p => p.Description, @interface?.Description)
|
||||
.Set(p => p.Physical, @interface?.Physical)
|
||||
.Set(p => p.Status, @interface?.Status?.ToString())
|
||||
.Set(p => p.Suffix, @interface?.Suffix)
|
||||
.Set(p => p.Speed, @interface?.Speed)
|
||||
.Set(p => p.Ipv4Mtu, @interface?.Ipv4Mtu)
|
||||
.Set(p => p.Ipv4Dhcp, @interface?.Ipv4Dhcp)
|
||||
|
||||
.Set(p => p.Ipv4Forwarding, @interface?.Ipv4Forwarding)
|
||||
.Set(p => p.Ipv6Mtu, @interface?.Ipv6Mtu)
|
||||
.Set(p => p.Sent, @interface?.Sent)
|
||||
.Set(p => p.Received, @interface?.Received)
|
||||
.Set(p => p.IncomingPacketsDiscarded, @interface?.IncomingPacketsDiscarded)
|
||||
.Set(p => p.IncomingPacketsWithErrors, @interface?.IncomingPacketsWithErrors)
|
||||
.Set(p => p.IncomingUnknownProtocolPackets, @interface?.IncomingUnknownProtocolPackets)
|
||||
.Set(p => p.OutgoingPacketsDiscarded, @interface?.OutgoingPacketsDiscarded)
|
||||
.Set(p => p.OutgoingPacketsWithErrors, @interface?.OutgoingPacketsWithErrors);
|
||||
|
||||
interfaceBulk.Add(new UpdateOneModel<HostInterfaceEntity>(interfaceFilter, interfaceUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
|
||||
// addresses
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
var addressBulk = new List<WriteModel<HostInterfaceAddressEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
interfaceBulk.Add(new DeleteManyModel<HostInterfaceEntity>(Builders<HostInterfaceEntity>.Filter.And(new List<FilterDefinition<HostInterfaceEntity>>
|
||||
{
|
||||
var interfaceId = await _database.HostInterface()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
Builders<HostInterfaceEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
if (@interface.Addresses is not null && @interface.Addresses.Any())
|
||||
var interfaceResult = await _database.HostInterface().BulkWriteAsync(interfaceBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
// addresses
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
var addressBulk = new List<WriteModel<HostInterfaceAddressEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
var interfaceId = await _database.HostInterface()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (@interface.Addresses is not null && @interface.Addresses.Any())
|
||||
{
|
||||
foreach (var address in @interface.Addresses)
|
||||
{
|
||||
foreach (var address in @interface.Addresses)
|
||||
{
|
||||
var addressFilter = Builders<HostInterfaceAddressEntity>.Filter.And(new List<FilterDefinition<HostInterfaceAddressEntity>>
|
||||
{
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Eq(x => x.Interface, interfaceId),
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Eq(x => x.Address, address?.IpAddress?.Address),
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Eq(x => x.Mask, address?.Ipv4Mask?.Address)
|
||||
});
|
||||
|
||||
var addressUpdate = Builders<HostInterfaceAddressEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Interface, interfaceId)
|
||||
.SetOnInsert(p => p.Address, address?.IpAddress?.Address)
|
||||
.SetOnInsert(p => p.Mask, address?.Ipv4Mask?.Address)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch);
|
||||
|
||||
addressBulk.Add(new UpdateOneModel<HostInterfaceAddressEntity>(addressFilter, addressUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addressBulk.Add(new DeleteManyModel<HostInterfaceAddressEntity>(Builders<HostInterfaceAddressEntity>.Filter.And(new List<FilterDefinition<HostInterfaceAddressEntity>>
|
||||
var addressFilter = Builders<HostInterfaceAddressEntity>.Filter.And(new List<FilterDefinition<HostInterfaceAddressEntity>>
|
||||
{
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var addressResult = await _database.HostInterfaceAddress().BulkWriteAsync(addressBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
// gateways
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
var gatewayBulk = new List<WriteModel<HostInterfaceGatewayEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
var interfaceId = await _database.HostInterface()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (@interface.Gateways is not null && @interface.Gateways.Any())
|
||||
{
|
||||
foreach (var gateway in @interface.Gateways)
|
||||
{
|
||||
var gatewayFilter = Builders<HostInterfaceGatewayEntity>.Filter.And(new List<FilterDefinition<HostInterfaceGatewayEntity>>
|
||||
{
|
||||
Builders<HostInterfaceGatewayEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceGatewayEntity>.Filter.Eq(x => x.Interface, interfaceId),
|
||||
Builders<HostInterfaceGatewayEntity>.Filter.Eq(x => x.Address, gateway?.Address)
|
||||
});
|
||||
|
||||
var gatewayUpdate = Builders<HostInterfaceGatewayEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Interface, interfaceId)
|
||||
.SetOnInsert(p => p.Address, gateway?.Address)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch);
|
||||
|
||||
gatewayBulk.Add(new UpdateOneModel<HostInterfaceGatewayEntity>(gatewayFilter, gatewayUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Eq(x => x.Interface, interfaceId),
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Eq(x => x.Address, address?.IpAddress?.Address),
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Eq(x => x.Mask, address?.Ipv4Mask?.Address)
|
||||
});
|
||||
}
|
||||
|
||||
var addressUpdate = Builders<HostInterfaceAddressEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Interface, interfaceId)
|
||||
.SetOnInsert(p => p.Address, address?.IpAddress?.Address)
|
||||
.SetOnInsert(p => p.Mask, address?.Ipv4Mask?.Address)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch);
|
||||
|
||||
addressBulk.Add(new UpdateOneModel<HostInterfaceAddressEntity>(addressFilter, addressUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gatewayBulk.Add(new DeleteManyModel<HostInterfaceGatewayEntity>(Builders<HostInterfaceGatewayEntity>.Filter.And(new List<FilterDefinition<HostInterfaceGatewayEntity>>
|
||||
addressBulk.Add(new DeleteManyModel<HostInterfaceAddressEntity>(Builders<HostInterfaceAddressEntity>.Filter.And(new List<FilterDefinition<HostInterfaceAddressEntity>>
|
||||
{
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceAddressEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var addressResult = await _database.HostInterfaceAddress().BulkWriteAsync(addressBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
// gateways
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
var gatewayBulk = new List<WriteModel<HostInterfaceGatewayEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
var interfaceId = await _database.HostInterface()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (@interface.Gateways is not null && @interface.Gateways.Any())
|
||||
{
|
||||
foreach (var gateway in @interface.Gateways)
|
||||
{
|
||||
var gatewayFilter = Builders<HostInterfaceGatewayEntity>.Filter.And(new List<FilterDefinition<HostInterfaceGatewayEntity>>
|
||||
{
|
||||
Builders<HostInterfaceGatewayEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceGatewayEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var gatewayResult = await _database.HostInterfaceGateway().BulkWriteAsync(gatewayBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
// nameservers
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
var nameserverBulk = new List<WriteModel<HostInterfaceNameserverEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
var interfaceId = await _database.HostInterface()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (@interface.Dns is not null && @interface.Dns.Any())
|
||||
{
|
||||
foreach (var nameserver in @interface.Dns)
|
||||
{
|
||||
var nameserverFilter = Builders<HostInterfaceNameserverEntity>.Filter.And(new List<FilterDefinition<HostInterfaceNameserverEntity>>
|
||||
{
|
||||
Builders<HostInterfaceNameserverEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceNameserverEntity>.Filter.Eq(x => x.Interface, interfaceId),
|
||||
Builders<HostInterfaceNameserverEntity>.Filter.Eq(x => x.Address, nameserver?.Address)
|
||||
});
|
||||
|
||||
var nameserverUpdate = Builders<HostInterfaceNameserverEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Interface, interfaceId)
|
||||
.SetOnInsert(p => p.Address, nameserver?.Address)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch);
|
||||
|
||||
nameserverBulk.Add(new UpdateOneModel<HostInterfaceNameserverEntity>(nameserverFilter, nameserverUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
Builders<HostInterfaceGatewayEntity>.Filter.Eq(x => x.Interface, interfaceId),
|
||||
Builders<HostInterfaceGatewayEntity>.Filter.Eq(x => x.Address, gateway?.Address)
|
||||
});
|
||||
}
|
||||
|
||||
var gatewayUpdate = Builders<HostInterfaceGatewayEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Interface, interfaceId)
|
||||
.SetOnInsert(p => p.Address, gateway?.Address)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch);
|
||||
|
||||
gatewayBulk.Add(new UpdateOneModel<HostInterfaceGatewayEntity>(gatewayFilter, gatewayUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nameserverBulk.Add(new DeleteManyModel<HostInterfaceNameserverEntity>(Builders<HostInterfaceNameserverEntity>.Filter.And(new List<FilterDefinition<HostInterfaceNameserverEntity>>
|
||||
gatewayBulk.Add(new DeleteManyModel<HostInterfaceGatewayEntity>(Builders<HostInterfaceGatewayEntity>.Filter.And(new List<FilterDefinition<HostInterfaceGatewayEntity>>
|
||||
{
|
||||
Builders<HostInterfaceGatewayEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceGatewayEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var gatewayResult = await _database.HostInterfaceGateway().BulkWriteAsync(gatewayBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
// nameservers
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
var nameserverBulk = new List<WriteModel<HostInterfaceNameserverEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
var interfaceId = await _database.HostInterface()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (@interface.Dns is not null && @interface.Dns.Any())
|
||||
{
|
||||
foreach (var nameserver in @interface.Dns)
|
||||
{
|
||||
var nameserverFilter = Builders<HostInterfaceNameserverEntity>.Filter.And(new List<FilterDefinition<HostInterfaceNameserverEntity>>
|
||||
{
|
||||
Builders<HostInterfaceNameserverEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceNameserverEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var nameserverResult = await _database.HostInterfaceNameserver().BulkWriteAsync(nameserverBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
// routes
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
var routeBulk = new List<WriteModel<HostInterfaceRouteEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
var interfaceId = await _database.HostInterface()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (@interface.Routes is not null && @interface.Routes.Any())
|
||||
{
|
||||
foreach (var route in @interface.Routes)
|
||||
{
|
||||
var routeFilter = Builders<HostInterfaceRouteEntity>.Filter.And(new List<FilterDefinition<HostInterfaceRouteEntity>>
|
||||
{
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Interface, interfaceId),
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Destination, route?.Destination?.Address),
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Gateway, route?.Gateway?.Address),
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Mask, route?.Mask),
|
||||
});
|
||||
|
||||
var routeUpdate = Builders<HostInterfaceRouteEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Interface, interfaceId)
|
||||
.SetOnInsert(p => p.Destination, route?.Destination?.Address)
|
||||
.SetOnInsert(p => p.Gateway, route?.Gateway?.Address)
|
||||
.SetOnInsert(p => p.Mask, route?.Mask)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch)
|
||||
|
||||
.Set(p => p.Metric, route?.Metric);
|
||||
|
||||
routeBulk.Add(new UpdateOneModel<HostInterfaceRouteEntity>(routeFilter, routeUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
Builders<HostInterfaceNameserverEntity>.Filter.Eq(x => x.Interface, interfaceId),
|
||||
Builders<HostInterfaceNameserverEntity>.Filter.Eq(x => x.Address, nameserver?.Address)
|
||||
});
|
||||
}
|
||||
|
||||
var nameserverUpdate = Builders<HostInterfaceNameserverEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Interface, interfaceId)
|
||||
.SetOnInsert(p => p.Address, nameserver?.Address)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch);
|
||||
|
||||
nameserverBulk.Add(new UpdateOneModel<HostInterfaceNameserverEntity>(nameserverFilter, nameserverUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
routeBulk.Add(new DeleteManyModel<HostInterfaceRouteEntity>(Builders<HostInterfaceRouteEntity>.Filter.And(new List<FilterDefinition<HostInterfaceRouteEntity>>
|
||||
nameserverBulk.Add(new DeleteManyModel<HostInterfaceNameserverEntity>(Builders<HostInterfaceNameserverEntity>.Filter.And(new List<FilterDefinition<HostInterfaceNameserverEntity>>
|
||||
{
|
||||
Builders<HostInterfaceNameserverEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceNameserverEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var nameserverResult = await _database.HostInterfaceNameserver().BulkWriteAsync(nameserverBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
// routes
|
||||
|
||||
if (interfaces is not null && interfaces.Any())
|
||||
{
|
||||
var routeBulk = new List<WriteModel<HostInterfaceRouteEntity>>();
|
||||
|
||||
foreach (var @interface in interfaces)
|
||||
{
|
||||
var interfaceId = await _database.HostInterface()
|
||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||
.Project(p => p.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (@interface.Routes is not null && @interface.Routes.Any())
|
||||
{
|
||||
foreach (var route in @interface.Routes)
|
||||
{
|
||||
var routeFilter = Builders<HostInterfaceRouteEntity>.Filter.And(new List<FilterDefinition<HostInterfaceRouteEntity>>
|
||||
{
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Interface, interfaceId),
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Destination, route?.Destination?.Address),
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Gateway, route?.Gateway?.Address),
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Mask, route?.Mask),
|
||||
});
|
||||
|
||||
var routeResult = await _database.HostInterfaceRoute().BulkWriteAsync(routeBulk, cancellationToken: cancellationToken);
|
||||
var routeUpdate = Builders<HostInterfaceRouteEntity>.Update
|
||||
.SetOnInsert(p => p.Insert, date)
|
||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||
.SetOnInsert(p => p.Interface, interfaceId)
|
||||
.SetOnInsert(p => p.Destination, route?.Destination?.Address)
|
||||
.SetOnInsert(p => p.Gateway, route?.Gateway?.Address)
|
||||
.SetOnInsert(p => p.Mask, route?.Mask)
|
||||
.Set(p => p.Update, date)
|
||||
.Set(p => p.Batch, batch)
|
||||
|
||||
.Set(p => p.Metric, route?.Metric);
|
||||
|
||||
routeBulk.Add(new UpdateOneModel<HostInterfaceRouteEntity>(routeFilter, routeUpdate)
|
||||
{
|
||||
IsUpsert = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
routeBulk.Add(new DeleteManyModel<HostInterfaceRouteEntity>(Builders<HostInterfaceRouteEntity>.Filter.And(new List<FilterDefinition<HostInterfaceRouteEntity>>
|
||||
{
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
|
||||
Builders<HostInterfaceRouteEntity>.Filter.Ne(x => x.Batch, batch)
|
||||
})));
|
||||
|
||||
var routeResult = await _database.HostInterfaceRoute().BulkWriteAsync(routeBulk, cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue