insight/src/Server/Insight.Server/Network/Agent/Handlers/InterfaceHandler.cs

295 lines
No EOL
15 KiB
C#

using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using Insight.Infrastructure.Entities;
using MongoDB.Bson;
using MongoDB.Driver;
namespace Insight.Server.Network.Agent.Handlers;
public class InterfaceHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
{
private readonly IMongoDatabase _database = database;
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
switch (message)
{
case Collection<Interface> interfaces:
await OnInterfacesAsync(sender, interfaces, cancellationToken);
break;
}
}
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.Count != 0)
{
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>>
{
Builders<HostInterfaceEntity>.Filter.Eq(x => x.Host, hostEntity.Id),
Builders<HostInterfaceEntity>.Filter.Ne(x => x.Batch, batch)
})));
var interfaceResult = await _database.HostInterface().BulkWriteAsync(interfaceBulk, cancellationToken: cancellationToken);
}
// addresses
if (interfaces is not null && interfaces.Count != 0)
{
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(cancellationToken: default);
if (@interface.Addresses is not null && @interface.Addresses.Count != 0)
{
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>>
{
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.Count != 0)
{
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(cancellationToken: default);
if (@interface.Gateways is not null && @interface.Gateways.Count != 0)
{
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
});
}
}
}
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.Count != 0)
{
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(cancellationToken: default);
if (@interface.Dns is not null && @interface.Dns.Count != 0)
{
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
});
}
}
}
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.Count != 0)
{
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(cancellationToken: default);
if (@interface.Routes is not null && @interface.Routes.Count != 0)
{
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
});
}
}
}
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);
}
}
}