using Insight.Infrastructure; using Insight.Infrastructure.Entities; using Insight.Web.Constants; using Microsoft.AspNetCore.Components; using MongoDB.Bson; using MongoDB.Driver; using MudBlazor; namespace Insight.Web.Pages.Monitoring.Maintenance; [Route(Navigation.Monitoring.Maintenance.Index)] public partial class Index { [Inject] private IMongoDatabase Database { get; init; } = default!; [Inject] private ISnackbar Snackbar { get; init; } = default!; private string Title { get; set; } = Global.Name; private List Breadcrumbs { get; } = new(); public ViewModel Model { get; } = new(); protected override void OnInitialized() { Title = $"Monitoring » Maintenance|Insight"; Breadcrumbs.Add(new BreadcrumbItem("Home", href: Navigation.Home)); Breadcrumbs.Add(new BreadcrumbItem("Monitoring", href: Navigation.Monitoring.Index)); Breadcrumbs.Add(new BreadcrumbItem("Maintenance", href: "#", true)); } private async Task LoadDataAsync() { try { // drives (errors) var drives = await Database.HostDrive().Aggregate() .Match(Builders.Filter.Ne(p => p.Status, "OK")) .Lookup("host", "_host", "_id", "hosts") .Match(new BsonDocument("hosts", new BsonDocument("$exists", new BsonDocument("$ne", BsonNull.Value)))) .AppendStage(new BsonDocument("$count", "size")) .FirstOrDefaultAsync(cancellationToken: default); if (drives is not null && drives.Any()) { Model.Updates = drives[0].AsInt32; } // storage pools (errors) var storagePools = await Database.HostStoragePool().Aggregate() .Match(Builders.Filter.Ne(p => p.Health, "Healthy")) .Lookup("host", "_host", "_id", "hosts") .Match(new BsonDocument("hosts", new BsonDocument("$exists", new BsonDocument("$ne", BsonNull.Value)))) .AppendStage(new BsonDocument("$count", "size")) .FirstOrDefaultAsync(cancellationToken: default); if (storagePools is not null && storagePools.Any()) { Model.StoragePools = storagePools[0].AsInt32; } // volumes (freespace) var freespace = await Database.HostVolume().Aggregate() .Match(Builders.Filter.Ne(p => p.FreeSpace, null)) .Lookup("host", "_host", "_id", "hosts") .Match(new BsonDocument("hosts", new BsonDocument("$exists", new BsonDocument("$ne", BsonNull.Value)))) .Project(new BsonDocument { { "percent_free", new BsonDocument("$multiply", new BsonArray { new BsonDocument("$divide", new BsonArray { "$freespace", "$size" }), 100 }) } }) .Match(Builders.Filter.Lt("percent_free", 5)) .AppendStage(new BsonDocument("$count", "size")) .FirstOrDefaultAsync(cancellationToken: default); if (freespace is not null && freespace.Any()) { Model.Volumes = freespace[0].AsInt32; } // virtual maschines var virtualMaschines = await Database.HostHypervisorVirtualMaschine().Aggregate() .Match(new BsonDocument("health", new BsonDocument("$ne", "OK"))) .Lookup("host", "_host", "_id", "hosts") .Match(new BsonDocument("hosts", new BsonDocument("$exists", new BsonDocument("$ne", BsonNull.Value)))) .AppendStage(new BsonDocument("$count", "size")) .FirstOrDefaultAsync(cancellationToken: default); if (virtualMaschines is not null && virtualMaschines.Any()) { Model.Guests = virtualMaschines[0].AsInt32; } // snapshots (old) var snapshots = await Database.HostVirtualMaschineConfig().Aggregate() .Lookup("host_hv_vm", "virtualmaschine", "_id", "virtualmaschines") .Project(new BsonDocument { { "_id", 1 }, { "uniqueid", 1 }, { "host", 1 }, { "virtualmaschine", new BsonDocument("$first", "$virtualmaschines") } }) .Match(new BsonDocument("$expr", new BsonDocument("$ne", new BsonArray { "$uniqueid", "$virtualmaschine.uniqueid" }))) .Lookup("host", "host", "_id", "hosts") .Match(new BsonDocument("hosts", new BsonDocument("$exists", new BsonDocument("$ne", BsonNull.Value)))) .AppendStage(new BsonDocument("$count", "size")) .FirstOrDefaultAsync(cancellationToken: default); if (snapshots is not null && snapshots.Any()) { Model.Snapshots = snapshots[0].AsInt32; } // updates (pending) var updates = await Database.HostUpdate().Aggregate() .Match(Builders.Filter.Eq(p => p.Pending, true)) .Lookup("host", "_host", "_id", "hosts") .Match(new BsonDocument("hosts", new BsonDocument("$exists", new BsonDocument("$ne", BsonNull.Value)))) .AppendStage(new BsonDocument("$count", "size")) .FirstOrDefaultAsync(cancellationToken: default); if (updates is not null && updates.Any()) { Model.Updates = updates[0].AsInt32; } } catch (Exception ex) { Console.WriteLine(ex); Notification.Error(Snackbar); } } public class ViewModel { public int Drives { get; set; } public int StoragePools { get; set; } public int Volumes { get; set; } public int Guests { get; set; } public int Snapshots { get; set; } public int Updates { get; set; } } }