295 lines
No EOL
15 KiB
C#
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);
|
|
}
|
|
}
|
|
} |