diff --git a/src/hiPower.Abstracts/IDataCenterService.cs b/src/hiPower.Abstracts/IDataCenterService.cs index f4c37a4..3e76f73 100644 --- a/src/hiPower.Abstracts/IDataCenterService.cs +++ b/src/hiPower.Abstracts/IDataCenterService.cs @@ -2,8 +2,8 @@ public interface IDataCenterService { - Task> CreateAsync(DataCenter location); - Task> UpdateAsync(string id, DataCenter location); + Task> CreateAsync(DataCenter dataCenter); + Task> UpdateAsync(string id, DataCenter dataCenter); Task> DeleteAsync (string id); Task> GetAsync (string id); Task>> GetAsync (); diff --git a/src/hiPower.Abstracts/IRemoteService.cs b/src/hiPower.Abstracts/IRemoteService.cs index bc2f4ef..8bdb818 100644 --- a/src/hiPower.Abstracts/IRemoteService.cs +++ b/src/hiPower.Abstracts/IRemoteService.cs @@ -3,6 +3,6 @@ public interface IRemoteService { Task>> GetConfigurationAsync (RemoteServiceOptions options); - Task>> GetStatisticsAsync (RemoteServiceOptions options); + Task>> GetStatisticsAsync (RemoteServiceOptions options, IEnumerable statItemsList); Task> GetInfoAsync (RemoteServiceOptions options); } diff --git a/src/hiPower.Abstracts/IServerService.cs b/src/hiPower.Abstracts/IServerService.cs index 2450952..9f19831 100644 --- a/src/hiPower.Abstracts/IServerService.cs +++ b/src/hiPower.Abstracts/IServerService.cs @@ -12,5 +12,6 @@ public interface IServerService Task>> GetRemoteConfigurationAsync(string id); Task>> GetRemoteStatisticsAsync (string id); + Task>> GetRemoteUptimeAsync (string id); Task> GetRemoteServerInfoAsync(string id); } diff --git a/src/hiPower.Abstracts/IUnitOfWork.cs b/src/hiPower.Abstracts/IUnitOfWork.cs index 38d0aad..6913f67 100644 --- a/src/hiPower.Abstracts/IUnitOfWork.cs +++ b/src/hiPower.Abstracts/IUnitOfWork.cs @@ -4,7 +4,7 @@ namespace hiPower.Abstracts; public interface IUnitOfWork : IDisposable { - IGenericRepository DataCenterRepository { get; } - IGenericRepository ServerRepository { get; } + IGenericRepository DataCenterRepository { get; } + IGenericRepository ServerRepository { get; } Task SaveAsync (); } diff --git a/src/hiPower.Common.Type/MonitorState.cs b/src/hiPower.Common.Type/MonitorState.cs new file mode 100644 index 0000000..c5ee948 --- /dev/null +++ b/src/hiPower.Common.Type/MonitorState.cs @@ -0,0 +1,9 @@ +namespace hiPower.Common.Type; + +public enum MonitorState +{ + None, + Ready, + Stop, + Suspend +} diff --git a/src/hiPower.Common.Type/ServerState.cs b/src/hiPower.Common.Type/ServiceState.cs similarity index 83% rename from src/hiPower.Common.Type/ServerState.cs rename to src/hiPower.Common.Type/ServiceState.cs index 1813418..6bd06fe 100644 --- a/src/hiPower.Common.Type/ServerState.cs +++ b/src/hiPower.Common.Type/ServiceState.cs @@ -1,6 +1,6 @@ namespace hiPower.Common.Type; -public enum ServerState +public enum ServiceState { Unknown = 0, On = 10, diff --git a/src/hiPower.Core/DataCenterService.cs b/src/hiPower.Core/DataCenterService.cs index c73cbc0..764b158 100644 --- a/src/hiPower.Core/DataCenterService.cs +++ b/src/hiPower.Core/DataCenterService.cs @@ -7,16 +7,16 @@ namespace hiPower.Core; public class DataCenterService(IUnitOfWork unit, IMapper mapper) : IDataCenterService { - public async Task> CreateAsync (DataCenter location) + public async Task> CreateAsync (Dto.Manager.DataCenter dataCenter) { - var result = await unit.DataCenterRepository.CreateAsync(location.Adapt()); + var result = await unit.DataCenterRepository.CreateAsync(dataCenter.Adapt()); await unit.SaveAsync (); - return mapper.Map (result); + return mapper.Map (result); } public async Task> DeleteAsync (string id) { - var servers = await unit.ServerRepository.GetAll(x => x.LocationId.Equals(id.ToUpper()), null, null); + var servers = await unit.ServerRepository.GetAll(x => x.DataCenterId.Equals(id.ToUpper()), null, null); if (servers.Any()) { return DataCenterErrors.DeleteError; @@ -26,39 +26,39 @@ public async Task> DeleteAsync (string id) return true; } - public async Task> GetAsync (string id) + public async Task> GetAsync (string id) { var result = await unit.DataCenterRepository.GetAsync(x => x.Id.Equals(id.ToUpperInvariant()), null); if (result is null) { return Error.NotFound(); } - return result.Adapt (); + return result.Adapt (); } - public async Task>> GetAsync () + public async Task>> GetAsync () { var result = await unit.DataCenterRepository.GetAll(null, null,null); - return result.Adapt> ().ToErrorOr (); + return result.Adapt> ().ToErrorOr (); } public async Task>> GetServers (string id) { - var result = await unit.ServerRepository.GetAll(x => x.LocationId.Equals(id.ToUpper()), null, null); + var result = await unit.ServerRepository.GetAll(x => x.DataCenterId.Equals(id.ToUpper()), null, null); return result.Adapt> () .ToErrorOr(); } - public async Task> UpdateAsync (string id, DataCenter dataCenter) + public async Task> UpdateAsync (string id, Dto.Manager.DataCenter dataCenter) { if (!id.Equals(dataCenter.Id, StringComparison.OrdinalIgnoreCase)) { return Error.NotFound (dataCenter.Id); } var result = unit.DataCenterRepository - .Update(dataCenter.Adapt()) + .Update(dataCenter.Adapt()) .ToErrorOr(); await unit.SaveAsync (); - return await Task.FromResult(result.Adapt ()); + return await Task.FromResult(result.Adapt ()); } } diff --git a/src/hiPower.Core/Mappings/LocationMapping.cs b/src/hiPower.Core/Mappings/DataCenterMapping.cs similarity index 83% rename from src/hiPower.Core/Mappings/LocationMapping.cs rename to src/hiPower.Core/Mappings/DataCenterMapping.cs index e57236e..3071be1 100644 --- a/src/hiPower.Core/Mappings/LocationMapping.cs +++ b/src/hiPower.Core/Mappings/DataCenterMapping.cs @@ -2,11 +2,11 @@ namespace hiPower.Core.Mappings; -internal class LocationMapping : IRegister +internal class DataCenterMapping : IRegister { public void Register (TypeAdapterConfig config) { - config.NewConfig () + config.NewConfig () .Map (dest => dest.Id, src => src.Id) .Map (dest => dest.Name, src => src.Name) .Map (dest => dest.Address, src => src.Address) @@ -16,7 +16,7 @@ public void Register (TypeAdapterConfig config) .Map (dest => dest.Country, src => src.Country) .Map (dest => dest.Description, src => src.Description); - config.NewConfig () + config.NewConfig () .Map (dest => dest.Id, src => src.Id) .Map (dest => dest.Name, src => src.Name) .Map (dest => dest.Address, src => src.Address) @@ -26,7 +26,7 @@ public void Register (TypeAdapterConfig config) .Map (dest => dest.Country, src => src.Country) .Map( dest => dest.Description, src => src.Description); - config.NewConfig() + config.NewConfig() .Map(dest => dest.Id, src => src.Id) .Map(dest => dest.Name, src => src.Name); } diff --git a/src/hiPower.Core/Mappings/ServerMappring.cs b/src/hiPower.Core/Mappings/ServerMappring.cs index 074f067..94021b3 100644 --- a/src/hiPower.Core/Mappings/ServerMappring.cs +++ b/src/hiPower.Core/Mappings/ServerMappring.cs @@ -7,10 +7,10 @@ internal class ServerMappring : IRegister { public void Register (TypeAdapterConfig config) { - config.NewConfig () + config.NewConfig () .Map (dest => dest.Id, src => src.Id) .Map (dest => dest.LocalId, src => src.LocalId) - .Map (dest => dest.LocationId, src => src.LocationId) + .Map (dest => dest.DataCenterId, src => src.DataCenterId) .Map (dest => dest.Name, src => src.Name) .Map (dest => dest.Description, src => src.Description) .Map (dest => dest.Proto, src => src.Proto) @@ -22,10 +22,10 @@ public void Register (TypeAdapterConfig config) .Map (dest => dest.OS, src => src.OS) .Map (dest => dest.Configuration, src => src.Configuration); - config.NewConfig () + config.NewConfig () .Map (dest => dest.Id, src => src.Id) .Map (dest => dest.LocalId, src => src.LocalId) - .Map (dest => dest.LocationId, src => src.LocationId) + .Map (dest => dest.DataCenterId, src => src.DataCenterId) .Map (dest => dest.Name, src => src.Name) .Map (dest => dest.Description, src => src.Description) .Map (dest => dest.Proto, src => src.Proto) @@ -37,7 +37,7 @@ public void Register (TypeAdapterConfig config) .Map (dest => dest.OS, src => src.OS) .Map (dest => dest.Configuration, src => src.Configuration); - config.NewConfig () + config.NewConfig () .MapWith (src => new RemoteServiceOptions(src.Proto.ToProtocol(), src.HostAddress, Convert.ToUInt16(src.Port), src.LocalId, src.ApiKey, src.Auth)); } } diff --git a/src/hiPower.Core/ServerService.cs b/src/hiPower.Core/ServerService.cs index 145cc78..b79d326 100644 --- a/src/hiPower.Core/ServerService.cs +++ b/src/hiPower.Core/ServerService.cs @@ -11,7 +11,7 @@ public class ServerService(IUnitOfWork unit, { public async Task> CreateAsync (Server server) { - var result = await unit.ServerRepository.CreateAsync(server.Adapt()); + var result = await unit.ServerRepository.CreateAsync(server.Adapt()); await unit.SaveAsync (); return mapper.Map (result); } @@ -24,7 +24,7 @@ public async Task> DeleteAsync (string id) public async Task>> GetAllAsync (string dataCenterId) { - var result = await unit.ServerRepository.GetAll(x => x.LocationId.Equals(dataCenterId.ToUpper()), null, null); + var result = await unit.ServerRepository.GetAll(x => x.DataCenterId.Equals(dataCenterId.ToUpper()), null, null); if (result.Any ()) { return result.Adapt> () @@ -66,7 +66,7 @@ public async Task> UpdateAsync (string id, Server server) { if (id.ToUpper ().Equals (server.Id.ToUpper ())) { - var updateServer = server.Adapt (); + var updateServer = server.Adapt (); var result = unit.ServerRepository.Update(updateServer); await unit.SaveAsync (); return await Task.FromResult(result.Adapt()); @@ -96,6 +96,25 @@ public async Task>> GetRemoteConfigurationAsy public async Task>> GetRemoteStatisticsAsync (string id) { + IEnumerable statiscticsParams = [ + "corrupt-packets", + "dnsupdate-answers", + "dnsupdate-changes", + "dnsupdate-queries", + "dnsupdate-refused", + "incoming-notifications", + "noerror-packets", + "nxdomain-packets", + "tcp-answers", + "tcp-queries", + "tcp4-answers", + "tcp4-queries", + "udp-do-queries", + "udp-in-errors", + "udp-queries", + "udp4-answers", + "udp4-queries"]; + var service = await GetAsync(id); if (service.IsError && service.FirstError.Type == ErrorType.NotFound) @@ -104,7 +123,29 @@ public async Task>> GetRemoteStatisticsAsync } var options = service.Value.Adapt (); - var response = await remoteService.GetStatisticsAsync (options); + var response = await remoteService.GetStatisticsAsync (options, statiscticsParams); + + if (response.IsError) + { + return response.FirstError; + } + + return response; + } + + public async Task>> GetRemoteUptimeAsync (string id) + { + IEnumerable statiscticsParams = ["uptime"]; + + var service = await GetAsync(id); + + if (service.IsError && service.FirstError.Type == ErrorType.NotFound) + { + return Error.NotFound (); + } + + var options = service.Value.Adapt (); + var response = await remoteService.GetStatisticsAsync (options, statiscticsParams); if (response.IsError) { diff --git a/src/hiPower.Database/Configuration/ServerLocationEntityConfiguration.cs b/src/hiPower.Database/Configuration/DataCenterEntityConfiguration.cs similarity index 79% rename from src/hiPower.Database/Configuration/ServerLocationEntityConfiguration.cs rename to src/hiPower.Database/Configuration/DataCenterEntityConfiguration.cs index 7cc23e8..83cb116 100644 --- a/src/hiPower.Database/Configuration/ServerLocationEntityConfiguration.cs +++ b/src/hiPower.Database/Configuration/DataCenterEntityConfiguration.cs @@ -4,11 +4,11 @@ namespace hiPower.Database.Configuration; -internal class ServerLocationEntityConfiguration : IEntityTypeConfiguration +internal class DataCenterEntityConfiguration : IEntityTypeConfiguration { - public void Configure (EntityTypeBuilder builder) + public void Configure (EntityTypeBuilder builder) { - builder.ToTable($"{Prefix.Table}{nameof(ServerLocation)}"); + builder.ToTable($"{Prefix.Table}{nameof(DataCenter)}"); builder.HasKey( x => x.Id ); @@ -43,14 +43,14 @@ public void Configure (EntityTypeBuilder builder) .HasMaxLength (50); builder.HasMany(x => x.Servers) - .WithOne(y => y.Location) - .HasForeignKey(x => x.LocationId) + .WithOne(y => y.DataCenter) + .HasForeignKey(x => x.DataCenterId) .OnDelete(DeleteBehavior.NoAction); builder.HasData (DefaultLocation); } - private IEnumerable DefaultLocation => [ + private IEnumerable DefaultLocation => [ new (){ Id = "7eb5999f-aef5-11ef-9fd9-47f022e22a50", Name = "Default", diff --git a/src/hiPower.Database/Configuration/MonitorServiceEntityConfiguration.cs b/src/hiPower.Database/Configuration/MonitorServiceEntityConfiguration.cs new file mode 100644 index 0000000..374316f --- /dev/null +++ b/src/hiPower.Database/Configuration/MonitorServiceEntityConfiguration.cs @@ -0,0 +1,31 @@ +using hiPower.Common.Type; +using hiPower.Entity; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace hiPower.Database.Configuration; + +internal class MonitorServiceEntityConfiguration : IEntityTypeConfiguration +{ + public void Configure (EntityTypeBuilder builder) + { + builder.ToTable ($"{Prefix.Table}{nameof(MonitorService)}"); + + builder.HasKey ( t => t.ServiceId ); + + builder.HasIndex (i => new { i.ServiceId, i.MonitorState }); + + builder.Property (p => p.ServiceId) + .HasMaxLength (36) + .HasConversion (value => value.ToUpperInvariant (), + value => value) + .IsRequired(); + + builder.Property(p => p.MonitorState) + .HasConversion(value => value.ToString().ToLowerInvariant(), + value => Enum.Parse(value, true)) + .HasMaxLength(10) + .IsRequired(); + + } +} diff --git a/src/hiPower.Database/Configuration/MonitorVariablesEntityConfiguration.cs b/src/hiPower.Database/Configuration/MonitorVariablesEntityConfiguration.cs new file mode 100644 index 0000000..e6f84f2 --- /dev/null +++ b/src/hiPower.Database/Configuration/MonitorVariablesEntityConfiguration.cs @@ -0,0 +1,25 @@ +using hiPower.Entity; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace hiPower.Database.Configuration; + +internal class MonitorVariablesEntityConfiguration : IEntityTypeConfiguration +{ + public void Configure (EntityTypeBuilder builder) + { + builder.ToTable ($"{Prefix.Table}{nameof (MonitorVariables)}"); + + builder.HasKey (k => k.ServiceId); + + builder.Property (p => p.ServiceId) + .HasMaxLength (36) + .HasConversion (value => value.ToUpperInvariant (), + value => value) + .IsRequired (); + + builder.Property (p => p.Variable) + .HasMaxLength (30) + .IsRequired (); + } +} diff --git a/src/hiPower.Database/Configuration/ServerEntityConfiguration.cs b/src/hiPower.Database/Configuration/ServiceDetailsEntityConfiguration.cs similarity index 68% rename from src/hiPower.Database/Configuration/ServerEntityConfiguration.cs rename to src/hiPower.Database/Configuration/ServiceDetailsEntityConfiguration.cs index 7d87d8b..400a0dd 100644 --- a/src/hiPower.Database/Configuration/ServerEntityConfiguration.cs +++ b/src/hiPower.Database/Configuration/ServiceDetailsEntityConfiguration.cs @@ -1,14 +1,15 @@ -using hiPower.Entity; +using hiPower.Common.Type; +using hiPower.Entity; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace hiPower.Database.Configuration; -internal class ServerEntityConfiguration : IEntityTypeConfiguration +internal class ServiceDetailsEntityConfiguration : IEntityTypeConfiguration { - public void Configure (EntityTypeBuilder builder) + public void Configure (EntityTypeBuilder builder) { - builder.ToTable ($"{Prefix.Table}Server"); + builder.ToTable ($"{Prefix.Table}{nameof(ServiceDetails)}"); builder.HasKey ( t => t.Id ); @@ -18,7 +19,7 @@ public void Configure (EntityTypeBuilder builder) value => value) .IsRequired (); - builder.Property(p => p.LocationId) + builder.Property(p => p.DataCenterId) .HasMaxLength(36) .HasConversion(value => value.ToUpperInvariant(), value => value) @@ -59,13 +60,14 @@ public void Configure (EntityTypeBuilder builder) .HasMaxLength (250); builder.Property (p => p.State) - .HasPrecision (0, 3) + .HasConversion(value => value.ToString(), + value => Enum.Parse(value,true)) + .HasMaxLength(10) .IsRequired(); - builder.Property (p => p.Timeout) - .HasPrecision (0, 5); - - builder.Property (p => p.Retries) - .HasPrecision (0, 2); + builder.HasMany (x => x.MonitorStatistics) + .WithOne (y => y.ServiceDetails) + .HasForeignKey (k => k.ServiceId) + .OnDelete(DeleteBehavior.ClientCascade); } } diff --git a/src/hiPower.Database/Configuration/StatisticsVariableEntityConfiguration.cs b/src/hiPower.Database/Configuration/StatisticsVariableEntityConfiguration.cs new file mode 100644 index 0000000..a9014f8 --- /dev/null +++ b/src/hiPower.Database/Configuration/StatisticsVariableEntityConfiguration.cs @@ -0,0 +1,114 @@ +using hiPower.Entity; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace hiPower.Database.Configuration; + +internal class StatisticsVariableEntityConfiguration : IEntityTypeConfiguration +{ + public void Configure (EntityTypeBuilder builder) + { + builder.ToTable ($"{Prefix.Table}{nameof (StatisticsVariable)}"); + + builder.HasKey (k => k.Variable); + + builder.Property (p => p.Variable) + .HasMaxLength (35) + .IsRequired (); + + builder.Property (p => p.Description) + .HasMaxLength(200); + + builder.HasData (Variables); + } + + internal static StatisticsVariable [] Variables => [ +new () {Variable = "backend-queries", Description = "Number of queries sent to the backend(s)"}, +new () {Variable = "corrupt-packets", Description = "Number of corrupt packets received"}, +new () {Variable = "deferred-cache-inserts", Description = "Amount of cache inserts that were deferred because of maintenance" }, +new () {Variable = "deferred-cache-lookup", Description = "Amount of cache lookups that were deferred because of maintenance" }, +new () {Variable = "deferred-packetcache-inserts", Description = "Amount of packet cache inserts that were deferred because of maintenance" }, +new () {Variable = "deferred-packetcache-lookup", Description = "Amount of packet cache lookups that were deferred because of maintenance" }, +new () {Variable = "dnsupdate-answers", Description = "DNS update packets successfully answered."}, +new () {Variable = "dnsupdate-changes", Description = "DNS update changes to records in total."}, +new () {Variable = "dnsupdate-queries", Description = "DNS update packets received."}, +new () {Variable = "dnsupdate-refused", Description = "DNS update packets that are refused."}, +new () {Variable = "incoming-notifications", Description = "NOTIFY packets received."}, +new () {Variable = "noerror-packets", Description = "Number of times a NOERROR packet was sent out" }, +new () {Variable = "nxdomain-packets", Description = "Number of times an NXDOMAIN packet was sent out" }, +new () {Variable = "overload-drops", Description = "Queries dropped because backends overloaded" }, +new () {Variable = "packetcache-hit", Description = "Number of hits on the packet cache" }, +new () {Variable = "packetcache-miss", Description = "Number of misses on the packet cache" }, +new () {Variable = "packetcache-size", Description = "Number of entries in the packet cache" }, +new () {Variable = "query-cache-hit", Description = "Number of hits on the query cache" }, +new () {Variable = "query-cache-miss", Description = "Number of misses on the query cache" }, +new () {Variable = "query-cache-size", Description = "Number of entries in the query cache" }, +new () {Variable = "rd-queries", Description = "Number of recursion desired questions" }, +new () {Variable = "recursing-answers", Description = "Number of recursive answers sent out" }, +new () {Variable = "recursing-questions", Description = "Number of questions sent to recursor" }, +new () {Variable = "recursion-unanswered", Description = "Number of packets unanswered by configured recursor" }, +new () {Variable = "security-status", Description = "Security status based on regular polling" }, +new () {Variable = "servfail-packets", Description = "Number of times a server-failed packet was sent out" }, +new () {Variable = "signatures", Description = "Number of DNSSEC signatures made" }, +new () {Variable = "tcp-answers", Description = "Number of answers sent out over TCP" }, +new () {Variable = "tcp-answers-bytes", Description = "Total size of answers sent out over TCP" }, +new () {Variable = "tcp-queries", Description = "Number of TCP queries received" }, +new () {Variable = "tcp4-answers", Description = "Number of IPv4 answers sent out over TCP" }, +new () {Variable = "tcp4-answers-bytes", Description = "Total size of answers sent out over TCPv4" }, +new () {Variable = "tcp4-queries", Description = "Number of IPv4 TCP queries received" }, +new () {Variable = "tcp6-answers", Description = "Number of IPv6 answers sent out over TCP" }, +new () {Variable = "tcp6-answers-bytes", Description = "Total size of answers sent out over TCPv6" }, +new () {Variable = "tcp6-queries", Description = "Number of IPv6 TCP queries received" }, +new () {Variable = "timedout-packets", Description = "Number of packets which weren't answered within timeout set" }, +new () {Variable = "udp-answers", Description = "Number of answers sent out over UDP" }, +new () {Variable = "udp-answers-bytes", Description = "Total size of answers sent out over UDP" }, +new () {Variable = "udp-do-queries", Description = "Number of UDP queries received with DO bit" }, +new () {Variable = "udp-queries", Description = "Number of UDP queries received" }, +new () {Variable = "udp4-answers", Description = "Number of IPv4 answers sent out over UDP" }, +new () {Variable = "udp4-answers-bytes", Description = "Total size of answers sent out over UDPv4" }, +new () {Variable = "udp4-queries", Description = "Number of IPv4 UDP queries received" }, +new () {Variable = "udp6-answers", Description = "Number of IPv6 answers sent out over UDP" }, +new () {Variable = "udp6-answers-bytes", Description = "Total size of answers sent out over UDPv6" }, +new () {Variable = "udp6-queries", Description = "Number of IPv6 UDP queries received" }, +new () {Variable = "unauth-packets", Description = "Number of times a zone we are not auth for was queried" }, +new () {Variable = "zone-cache-hit", Description = "Number of zone cache hits" }, +new () {Variable = "zone-cache-miss", Description = "Number of zone cache misses" }, +new () {Variable = "zone-cache-size", Description = "Number of entries in the zone cache" }, +new () {Variable = "cpu-iowait", Description = "Time spent waiting for I/O to complete by the whole system, in units of USER_HZ" }, +new () {Variable = "cpu-steal", Description = "Stolen time, which is the time spent by the whole system in other operating systems when running in a virtualized environment, in units of USER_HZ" }, +new () {Variable = "fd-usage", Description = "Number of open filedescriptors" }, +new () {Variable = "key-cache-size", Description = "Number of entries in the key cache" }, +new () {Variable = "latency", Description = "Average number of microseconds needed to answer a question" }, +new () {Variable = "meta-cache-size", Description = "Number of entries in the metadata cache" }, +new () {Variable = "open-tcp-connections", Description = "Number of currently open TCP connections" }, +new () {Variable = "qsize-q", Description = "Number of questions waiting for database attention" }, +new () {Variable = "real-memory-usage", Description = "Actual unique use of memory in bytes (approx)" }, +new () {Variable = "ring-logmessages-capacity", Description = "Maximum number of entries in the logmessages ring" }, +new () {Variable = "ring-logmessages-size", Description = "Number of entries in the logmessages ring" }, +new () {Variable = "ring-noerror-queries-capacity", Description = "Maximum number of entries in the noerror-queries ring" }, +new () {Variable = "ring-noerror-queries-size", Description = "Number of entries in the noerror-queries ring" }, +new () {Variable = "ring-nxdomain-queries-capacity", Description = "Maximum number of entries in the nxdomain-queries ring" }, +new () {Variable = "ring-nxdomain-queries-size", Description = "Number of entries in the nxdomain-queries ring" }, +new () {Variable = "ring-queries-capacity", Description = "Maximum number of entries in the queries ring" }, +new () {Variable = "ring-queries-size", Description = "Number of entries in the queries ring" }, +new () {Variable = "ring-remotes-capacity", Description = "Maximum number of entries in the remotes ring" }, +new () {Variable = "ring-remotes-corrupt-capacity", Description = "Maximum number of entries in the remotes-corrupt ring" }, +new () {Variable = "ring-remotes-corrupt-size", Description = "Number of entries in the remotes-corrupt ring" }, +new () {Variable = "ring-remotes-size", Description = "Number of entries in the remotes ring" }, +new () {Variable = "ring-remotes-unauth-capacity", Description = "Maximum number of entries in the remotes-unauth ring" }, +new () {Variable = "ring-remotes-unauth-size", Description = "Number of entries in the remotes-unauth ring" }, +new () {Variable = "ring-servfail-queries-capacity", Description = "Maximum number of entries in the servfail-queries ring" }, +new () {Variable = "ring-servfail-queries-size", Description = "Number of entries in the servfail-queries ring" }, +new () {Variable = "ring-unauth-queries-capacity", Description = "Maximum number of entries in the unauth-queries ring" }, +new () {Variable = "ring-unauth-queries-size", Description = "Number of entries in the unauth-queries ring" }, +new () {Variable = "signature-cache-size", Description = "Number of entries in the signature cache" }, +new () {Variable = "sys-msec", Description = "Number of msec spent in system time" }, +new () {Variable = "udp-in-errors", Description = "UDP 'in' errors" }, +new () {Variable = "udp-noport-errors", Description = "UDP 'noport' errors" }, +new () {Variable = "udp-recvbuf-errors", Description = "UDP 'recvbuf' errors" }, +new () {Variable = "udp-sndbuf-errors", Description = "UDP 'sndbuf' errors" }, +new () {Variable = "uptime", Description = "Uptime of process in seconds" }, +new () {Variable = "user-msec", Description = "Number of msec spent in user time" }, +new () {Variable = "xfr-queue", Description = "Size of the queue of zones to be XFRd" } + ]; +} diff --git a/src/hiPower.Database/ManagerDbContext.DbSet.cs b/src/hiPower.Database/ManagerDbContext.DbSet.cs index 64b0e36..a21bb9a 100644 --- a/src/hiPower.Database/ManagerDbContext.DbSet.cs +++ b/src/hiPower.Database/ManagerDbContext.DbSet.cs @@ -5,6 +5,9 @@ namespace hiPower.Database; public partial class ManagerDbContext { - public DbSet Servers { get; set; } - public DbSet Locations { get; set; } + public DbSet Servers { get; set; } + public DbSet Locations { get; set; } + public DbSet StatisticsVariables { get; set; } + public DbSet Monitors { get; set; } + public DbSet MonitorVariables { get; set; } } diff --git a/src/hiPower.Database/ManagerDbContext.cs b/src/hiPower.Database/ManagerDbContext.cs index 0b3ac36..66bb7f5 100644 --- a/src/hiPower.Database/ManagerDbContext.cs +++ b/src/hiPower.Database/ManagerDbContext.cs @@ -13,7 +13,10 @@ protected override void OnConfiguring (DbContextOptionsBuilder optionsBuilder) protected override void OnModelCreating (ModelBuilder modelBuilder) { - modelBuilder.ApplyConfiguration (new ServerLocationEntityConfiguration ()); - modelBuilder.ApplyConfiguration (new ServerEntityConfiguration ()); + modelBuilder.ApplyConfiguration (new DataCenterEntityConfiguration ()); + modelBuilder.ApplyConfiguration (new ServiceDetailsEntityConfiguration ()); + modelBuilder.ApplyConfiguration(new StatisticsVariableEntityConfiguration ()); + modelBuilder.ApplyConfiguration(new MonitorServiceEntityConfiguration ()); + modelBuilder.ApplyConfiguration(new MonitorVariablesEntityConfiguration ()); } } diff --git a/src/hiPower.Database/Migrations/20241208150558_AddMonitorService.Designer.cs b/src/hiPower.Database/Migrations/20241208150558_AddMonitorService.Designer.cs new file mode 100644 index 0000000..f3523ce --- /dev/null +++ b/src/hiPower.Database/Migrations/20241208150558_AddMonitorService.Designer.cs @@ -0,0 +1,678 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using hiPower.Database; + +#nullable disable + +namespace hiPower.Database.Migrations +{ + [DbContext(typeof(ManagerDbContext))] + [Migration("20241208150558_AddMonitorService")] + partial class AddMonitorService + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("hiPower.Entity.MonitorService", b => + { + b.Property("ServiceId") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitorState") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("ServiceId"); + + b.HasIndex("ServiceId", "MonitorState"); + + b.ToTable("T_MonitorService", (string)null); + }); + + modelBuilder.Entity("hiPower.Entity.MonitorVariables", b => + { + b.Property("ServiceId") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Variable") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("ServiceId"); + + b.ToTable("T_MonitorVariables", (string)null); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceDetails", b => + { + b.Property("Id") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("ApiKey") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("Auth") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("Configuration") + .HasColumnType("text"); + + b.Property("Description") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("HostAddress") + .IsRequired() + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("LocalId") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("LocationId") + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("MonitorId") + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("OS") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Port") + .HasColumnType("text"); + + b.Property("Proto") + .IsRequired() + .HasMaxLength(10) + .HasPrecision(0, 5) + .HasColumnType("character varying(10)"); + + b.Property("State") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Version") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("LocationId"); + + b.ToTable("T_ServiceDetails", (string)null); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceLocation", b => + { + b.Property("Id") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Address") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("City") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Country") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Description") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PostalCode") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Region") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("T_ServiceLocation", (string)null); + + b.HasData( + new + { + Id = "7EB5999F-AEF5-11EF-9FD9-47F022E22A50", + Address = "", + City = "", + Country = "Default", + Description = "Initial location", + Name = "Default", + PostalCode = "", + Region = "" + }); + }); + + modelBuilder.Entity("hiPower.Entity.StatisticsVariable", b => + { + b.Property("Variable") + .HasMaxLength(35) + .HasColumnType("character varying(35)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.HasKey("Variable"); + + b.ToTable("T_StatisticsVariable", (string)null); + + b.HasData( + new + { + Variable = "backend-queries", + Description = "Number of queries sent to the backend(s)" + }, + new + { + Variable = "corrupt-packets", + Description = "Number of corrupt packets received" + }, + new + { + Variable = "deferred-cache-inserts", + Description = "Amount of cache inserts that were deferred because of maintenance" + }, + new + { + Variable = "deferred-cache-lookup", + Description = "Amount of cache lookups that were deferred because of maintenance" + }, + new + { + Variable = "deferred-packetcache-inserts", + Description = "Amount of packet cache inserts that were deferred because of maintenance" + }, + new + { + Variable = "deferred-packetcache-lookup", + Description = "Amount of packet cache lookups that were deferred because of maintenance" + }, + new + { + Variable = "dnsupdate-answers", + Description = "DNS update packets successfully answered." + }, + new + { + Variable = "dnsupdate-changes", + Description = "DNS update changes to records in total." + }, + new + { + Variable = "dnsupdate-queries", + Description = "DNS update packets received." + }, + new + { + Variable = "dnsupdate-refused", + Description = "DNS update packets that are refused." + }, + new + { + Variable = "incoming-notifications", + Description = "NOTIFY packets received." + }, + new + { + Variable = "noerror-packets", + Description = "Number of times a NOERROR packet was sent out" + }, + new + { + Variable = "nxdomain-packets", + Description = "Number of times an NXDOMAIN packet was sent out" + }, + new + { + Variable = "overload-drops", + Description = "Queries dropped because backends overloaded" + }, + new + { + Variable = "packetcache-hit", + Description = "Number of hits on the packet cache" + }, + new + { + Variable = "packetcache-miss", + Description = "Number of misses on the packet cache" + }, + new + { + Variable = "packetcache-size", + Description = "Number of entries in the packet cache" + }, + new + { + Variable = "query-cache-hit", + Description = "Number of hits on the query cache" + }, + new + { + Variable = "query-cache-miss", + Description = "Number of misses on the query cache" + }, + new + { + Variable = "query-cache-size", + Description = "Number of entries in the query cache" + }, + new + { + Variable = "rd-queries", + Description = "Number of recursion desired questions" + }, + new + { + Variable = "recursing-answers", + Description = "Number of recursive answers sent out" + }, + new + { + Variable = "recursing-questions", + Description = "Number of questions sent to recursor" + }, + new + { + Variable = "recursion-unanswered", + Description = "Number of packets unanswered by configured recursor" + }, + new + { + Variable = "security-status", + Description = "Security status based on regular polling" + }, + new + { + Variable = "servfail-packets", + Description = "Number of times a server-failed packet was sent out" + }, + new + { + Variable = "signatures", + Description = "Number of DNSSEC signatures made" + }, + new + { + Variable = "tcp-answers", + Description = "Number of answers sent out over TCP" + }, + new + { + Variable = "tcp-answers-bytes", + Description = "Total size of answers sent out over TCP" + }, + new + { + Variable = "tcp-queries", + Description = "Number of TCP queries received" + }, + new + { + Variable = "tcp4-answers", + Description = "Number of IPv4 answers sent out over TCP" + }, + new + { + Variable = "tcp4-answers-bytes", + Description = "Total size of answers sent out over TCPv4" + }, + new + { + Variable = "tcp4-queries", + Description = "Number of IPv4 TCP queries received" + }, + new + { + Variable = "tcp6-answers", + Description = "Number of IPv6 answers sent out over TCP" + }, + new + { + Variable = "tcp6-answers-bytes", + Description = "Total size of answers sent out over TCPv6" + }, + new + { + Variable = "tcp6-queries", + Description = "Number of IPv6 TCP queries received" + }, + new + { + Variable = "timedout-packets", + Description = "Number of packets which weren't answered within timeout set" + }, + new + { + Variable = "udp-answers", + Description = "Number of answers sent out over UDP" + }, + new + { + Variable = "udp-answers-bytes", + Description = "Total size of answers sent out over UDP" + }, + new + { + Variable = "udp-do-queries", + Description = "Number of UDP queries received with DO bit" + }, + new + { + Variable = "udp-queries", + Description = "Number of UDP queries received" + }, + new + { + Variable = "udp4-answers", + Description = "Number of IPv4 answers sent out over UDP" + }, + new + { + Variable = "udp4-answers-bytes", + Description = "Total size of answers sent out over UDPv4" + }, + new + { + Variable = "udp4-queries", + Description = "Number of IPv4 UDP queries received" + }, + new + { + Variable = "udp6-answers", + Description = "Number of IPv6 answers sent out over UDP" + }, + new + { + Variable = "udp6-answers-bytes", + Description = "Total size of answers sent out over UDPv6" + }, + new + { + Variable = "udp6-queries", + Description = "Number of IPv6 UDP queries received" + }, + new + { + Variable = "unauth-packets", + Description = "Number of times a zone we are not auth for was queried" + }, + new + { + Variable = "zone-cache-hit", + Description = "Number of zone cache hits" + }, + new + { + Variable = "zone-cache-miss", + Description = "Number of zone cache misses" + }, + new + { + Variable = "zone-cache-size", + Description = "Number of entries in the zone cache" + }, + new + { + Variable = "cpu-iowait", + Description = "Time spent waiting for I/O to complete by the whole system, in units of USER_HZ" + }, + new + { + Variable = "cpu-steal", + Description = "Stolen time, which is the time spent by the whole system in other operating systems when running in a virtualized environment, in units of USER_HZ" + }, + new + { + Variable = "fd-usage", + Description = "Number of open filedescriptors" + }, + new + { + Variable = "key-cache-size", + Description = "Number of entries in the key cache" + }, + new + { + Variable = "latency", + Description = "Average number of microseconds needed to answer a question" + }, + new + { + Variable = "meta-cache-size", + Description = "Number of entries in the metadata cache" + }, + new + { + Variable = "open-tcp-connections", + Description = "Number of currently open TCP connections" + }, + new + { + Variable = "qsize-q", + Description = "Number of questions waiting for database attention" + }, + new + { + Variable = "real-memory-usage", + Description = "Actual unique use of memory in bytes (approx)" + }, + new + { + Variable = "ring-logmessages-capacity", + Description = "Maximum number of entries in the logmessages ring" + }, + new + { + Variable = "ring-logmessages-size", + Description = "Number of entries in the logmessages ring" + }, + new + { + Variable = "ring-noerror-queries-capacity", + Description = "Maximum number of entries in the noerror-queries ring" + }, + new + { + Variable = "ring-noerror-queries-size", + Description = "Number of entries in the noerror-queries ring" + }, + new + { + Variable = "ring-nxdomain-queries-capacity", + Description = "Maximum number of entries in the nxdomain-queries ring" + }, + new + { + Variable = "ring-nxdomain-queries-size", + Description = "Number of entries in the nxdomain-queries ring" + }, + new + { + Variable = "ring-queries-capacity", + Description = "Maximum number of entries in the queries ring" + }, + new + { + Variable = "ring-queries-size", + Description = "Number of entries in the queries ring" + }, + new + { + Variable = "ring-remotes-capacity", + Description = "Maximum number of entries in the remotes ring" + }, + new + { + Variable = "ring-remotes-corrupt-capacity", + Description = "Maximum number of entries in the remotes-corrupt ring" + }, + new + { + Variable = "ring-remotes-corrupt-size", + Description = "Number of entries in the remotes-corrupt ring" + }, + new + { + Variable = "ring-remotes-size", + Description = "Number of entries in the remotes ring" + }, + new + { + Variable = "ring-remotes-unauth-capacity", + Description = "Maximum number of entries in the remotes-unauth ring" + }, + new + { + Variable = "ring-remotes-unauth-size", + Description = "Number of entries in the remotes-unauth ring" + }, + new + { + Variable = "ring-servfail-queries-capacity", + Description = "Maximum number of entries in the servfail-queries ring" + }, + new + { + Variable = "ring-servfail-queries-size", + Description = "Number of entries in the servfail-queries ring" + }, + new + { + Variable = "ring-unauth-queries-capacity", + Description = "Maximum number of entries in the unauth-queries ring" + }, + new + { + Variable = "ring-unauth-queries-size", + Description = "Number of entries in the unauth-queries ring" + }, + new + { + Variable = "signature-cache-size", + Description = "Number of entries in the signature cache" + }, + new + { + Variable = "sys-msec", + Description = "Number of msec spent in system time" + }, + new + { + Variable = "udp-in-errors", + Description = "UDP 'in' errors" + }, + new + { + Variable = "udp-noport-errors", + Description = "UDP 'noport' errors" + }, + new + { + Variable = "udp-recvbuf-errors", + Description = "UDP 'recvbuf' errors" + }, + new + { + Variable = "udp-sndbuf-errors", + Description = "UDP 'sndbuf' errors" + }, + new + { + Variable = "uptime", + Description = "Uptime of process in seconds" + }, + new + { + Variable = "user-msec", + Description = "Number of msec spent in user time" + }, + new + { + Variable = "xfr-queue", + Description = "Size of the queue of zones to be XFRd" + }); + }); + + modelBuilder.Entity("hiPower.Entity.MonitorVariables", b => + { + b.HasOne("hiPower.Entity.ServiceDetails", "ServiceDetails") + .WithMany("MonitorStatistics") + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + + b.Navigation("ServiceDetails"); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceDetails", b => + { + b.HasOne("hiPower.Entity.ServiceLocation", "Location") + .WithMany("Servers") + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Location"); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceDetails", b => + { + b.Navigation("MonitorStatistics"); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceLocation", b => + { + b.Navigation("Servers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/hiPower.Database/Migrations/20241208150558_AddMonitorService.cs b/src/hiPower.Database/Migrations/20241208150558_AddMonitorService.cs new file mode 100644 index 0000000..7a858ce --- /dev/null +++ b/src/hiPower.Database/Migrations/20241208150558_AddMonitorService.cs @@ -0,0 +1,310 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace hiPower.Database.Migrations +{ + /// + public partial class AddMonitorService : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "T_Server"); + + migrationBuilder.DropTable( + name: "T_ServerLocation"); + + migrationBuilder.CreateTable( + name: "T_MonitorService", + columns: table => new + { + ServiceId = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + MonitorState = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), + Created = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_T_MonitorService", x => x.ServiceId); + }); + + migrationBuilder.CreateTable( + name: "T_ServiceLocation", + columns: table => new + { + Id = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + Name = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + Description = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Address = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + City = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + Region = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + PostalCode = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + Country = table.Column(type: "character varying(50)", maxLength: 50, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_ServiceLocation", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "T_StatisticsVariable", + columns: table => new + { + Variable = table.Column(type: "character varying(35)", maxLength: 35, nullable: false), + Description = table.Column(type: "character varying(200)", maxLength: 200, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_StatisticsVariable", x => x.Variable); + }); + + migrationBuilder.CreateTable( + name: "T_ServiceDetails", + columns: table => new + { + Id = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + Name = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + LocalId = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Proto = table.Column(type: "character varying(10)", maxLength: 10, precision: 0, scale: 5, nullable: false), + HostAddress = table.Column(type: "character varying(250)", maxLength: 250, nullable: false), + Port = table.Column(type: "text", nullable: true), + Description = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Version = table.Column(type: "character varying(20)", maxLength: 20, nullable: true), + ApiKey = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Auth = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + OS = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + Configuration = table.Column(type: "text", nullable: true), + State = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), + LocationId = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + MonitorId = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_ServiceDetails", x => x.Id); + table.ForeignKey( + name: "FK_T_ServiceDetails_T_ServiceLocation_LocationId", + column: x => x.LocationId, + principalTable: "T_ServiceLocation", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "T_MonitorVariables", + columns: table => new + { + ServiceId = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + Variable = table.Column(type: "character varying(30)", maxLength: 30, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_T_MonitorVariables", x => x.ServiceId); + table.ForeignKey( + name: "FK_T_MonitorVariables_T_ServiceDetails_ServiceId", + column: x => x.ServiceId, + principalTable: "T_ServiceDetails", + principalColumn: "Id"); + }); + + migrationBuilder.InsertData( + table: "T_ServiceLocation", + columns: new[] { "Id", "Address", "City", "Country", "Description", "Name", "PostalCode", "Region" }, + values: new object[] { "7EB5999F-AEF5-11EF-9FD9-47F022E22A50", "", "", "Default", "Initial location", "Default", "", "" }); + + migrationBuilder.InsertData( + table: "T_StatisticsVariable", + columns: new[] { "Variable", "Description" }, + values: new object[,] + { + { "backend-queries", "Number of queries sent to the backend(s)" }, + { "corrupt-packets", "Number of corrupt packets received" }, + { "cpu-iowait", "Time spent waiting for I/O to complete by the whole system, in units of USER_HZ" }, + { "cpu-steal", "Stolen time, which is the time spent by the whole system in other operating systems when running in a virtualized environment, in units of USER_HZ" }, + { "deferred-cache-inserts", "Amount of cache inserts that were deferred because of maintenance" }, + { "deferred-cache-lookup", "Amount of cache lookups that were deferred because of maintenance" }, + { "deferred-packetcache-inserts", "Amount of packet cache inserts that were deferred because of maintenance" }, + { "deferred-packetcache-lookup", "Amount of packet cache lookups that were deferred because of maintenance" }, + { "dnsupdate-answers", "DNS update packets successfully answered." }, + { "dnsupdate-changes", "DNS update changes to records in total." }, + { "dnsupdate-queries", "DNS update packets received." }, + { "dnsupdate-refused", "DNS update packets that are refused." }, + { "fd-usage", "Number of open filedescriptors" }, + { "incoming-notifications", "NOTIFY packets received." }, + { "key-cache-size", "Number of entries in the key cache" }, + { "latency", "Average number of microseconds needed to answer a question" }, + { "meta-cache-size", "Number of entries in the metadata cache" }, + { "noerror-packets", "Number of times a NOERROR packet was sent out" }, + { "nxdomain-packets", "Number of times an NXDOMAIN packet was sent out" }, + { "open-tcp-connections", "Number of currently open TCP connections" }, + { "overload-drops", "Queries dropped because backends overloaded" }, + { "packetcache-hit", "Number of hits on the packet cache" }, + { "packetcache-miss", "Number of misses on the packet cache" }, + { "packetcache-size", "Number of entries in the packet cache" }, + { "qsize-q", "Number of questions waiting for database attention" }, + { "query-cache-hit", "Number of hits on the query cache" }, + { "query-cache-miss", "Number of misses on the query cache" }, + { "query-cache-size", "Number of entries in the query cache" }, + { "rd-queries", "Number of recursion desired questions" }, + { "real-memory-usage", "Actual unique use of memory in bytes (approx)" }, + { "recursing-answers", "Number of recursive answers sent out" }, + { "recursing-questions", "Number of questions sent to recursor" }, + { "recursion-unanswered", "Number of packets unanswered by configured recursor" }, + { "ring-logmessages-capacity", "Maximum number of entries in the logmessages ring" }, + { "ring-logmessages-size", "Number of entries in the logmessages ring" }, + { "ring-noerror-queries-capacity", "Maximum number of entries in the noerror-queries ring" }, + { "ring-noerror-queries-size", "Number of entries in the noerror-queries ring" }, + { "ring-nxdomain-queries-capacity", "Maximum number of entries in the nxdomain-queries ring" }, + { "ring-nxdomain-queries-size", "Number of entries in the nxdomain-queries ring" }, + { "ring-queries-capacity", "Maximum number of entries in the queries ring" }, + { "ring-queries-size", "Number of entries in the queries ring" }, + { "ring-remotes-capacity", "Maximum number of entries in the remotes ring" }, + { "ring-remotes-corrupt-capacity", "Maximum number of entries in the remotes-corrupt ring" }, + { "ring-remotes-corrupt-size", "Number of entries in the remotes-corrupt ring" }, + { "ring-remotes-size", "Number of entries in the remotes ring" }, + { "ring-remotes-unauth-capacity", "Maximum number of entries in the remotes-unauth ring" }, + { "ring-remotes-unauth-size", "Number of entries in the remotes-unauth ring" }, + { "ring-servfail-queries-capacity", "Maximum number of entries in the servfail-queries ring" }, + { "ring-servfail-queries-size", "Number of entries in the servfail-queries ring" }, + { "ring-unauth-queries-capacity", "Maximum number of entries in the unauth-queries ring" }, + { "ring-unauth-queries-size", "Number of entries in the unauth-queries ring" }, + { "security-status", "Security status based on regular polling" }, + { "servfail-packets", "Number of times a server-failed packet was sent out" }, + { "signature-cache-size", "Number of entries in the signature cache" }, + { "signatures", "Number of DNSSEC signatures made" }, + { "sys-msec", "Number of msec spent in system time" }, + { "tcp-answers", "Number of answers sent out over TCP" }, + { "tcp-answers-bytes", "Total size of answers sent out over TCP" }, + { "tcp-queries", "Number of TCP queries received" }, + { "tcp4-answers", "Number of IPv4 answers sent out over TCP" }, + { "tcp4-answers-bytes", "Total size of answers sent out over TCPv4" }, + { "tcp4-queries", "Number of IPv4 TCP queries received" }, + { "tcp6-answers", "Number of IPv6 answers sent out over TCP" }, + { "tcp6-answers-bytes", "Total size of answers sent out over TCPv6" }, + { "tcp6-queries", "Number of IPv6 TCP queries received" }, + { "timedout-packets", "Number of packets which weren't answered within timeout set" }, + { "udp-answers", "Number of answers sent out over UDP" }, + { "udp-answers-bytes", "Total size of answers sent out over UDP" }, + { "udp-do-queries", "Number of UDP queries received with DO bit" }, + { "udp-in-errors", "UDP 'in' errors" }, + { "udp-noport-errors", "UDP 'noport' errors" }, + { "udp-queries", "Number of UDP queries received" }, + { "udp-recvbuf-errors", "UDP 'recvbuf' errors" }, + { "udp-sndbuf-errors", "UDP 'sndbuf' errors" }, + { "udp4-answers", "Number of IPv4 answers sent out over UDP" }, + { "udp4-answers-bytes", "Total size of answers sent out over UDPv4" }, + { "udp4-queries", "Number of IPv4 UDP queries received" }, + { "udp6-answers", "Number of IPv6 answers sent out over UDP" }, + { "udp6-answers-bytes", "Total size of answers sent out over UDPv6" }, + { "udp6-queries", "Number of IPv6 UDP queries received" }, + { "unauth-packets", "Number of times a zone we are not auth for was queried" }, + { "uptime", "Uptime of process in seconds" }, + { "user-msec", "Number of msec spent in user time" }, + { "xfr-queue", "Size of the queue of zones to be XFRd" }, + { "zone-cache-hit", "Number of zone cache hits" }, + { "zone-cache-miss", "Number of zone cache misses" }, + { "zone-cache-size", "Number of entries in the zone cache" } + }); + + migrationBuilder.CreateIndex( + name: "IX_T_MonitorService_ServiceId_MonitorState", + table: "T_MonitorService", + columns: new[] { "ServiceId", "MonitorState" }); + + migrationBuilder.CreateIndex( + name: "IX_T_ServiceDetails_LocationId", + table: "T_ServiceDetails", + column: "LocationId"); + + migrationBuilder.CreateIndex( + name: "IX_T_ServiceLocation_Name", + table: "T_ServiceLocation", + column: "Name"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "T_MonitorService"); + + migrationBuilder.DropTable( + name: "T_MonitorVariables"); + + migrationBuilder.DropTable( + name: "T_StatisticsVariable"); + + migrationBuilder.DropTable( + name: "T_ServiceDetails"); + + migrationBuilder.DropTable( + name: "T_ServiceLocation"); + + migrationBuilder.CreateTable( + name: "T_ServerLocation", + columns: table => new + { + Id = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + Address = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + City = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + Country = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + Description = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Name = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + PostalCode = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + Region = table.Column(type: "character varying(50)", maxLength: 50, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_ServerLocation", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "T_Server", + columns: table => new + { + Id = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + LocationId = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + ApiKey = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Auth = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Configuration = table.Column(type: "text", nullable: true), + Description = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + HostAddress = table.Column(type: "character varying(250)", maxLength: 250, nullable: false), + LocalId = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Name = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + OS = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + Port = table.Column(type: "text", nullable: true), + Proto = table.Column(type: "character varying(10)", maxLength: 10, precision: 0, scale: 5, nullable: false), + Retries = table.Column(type: "integer", precision: 0, scale: 2, nullable: false), + State = table.Column(type: "integer", precision: 0, scale: 3, nullable: false), + Timeout = table.Column(type: "integer", precision: 0, scale: 5, nullable: false), + Version = table.Column(type: "character varying(20)", maxLength: 20, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_Server", x => x.Id); + table.ForeignKey( + name: "FK_T_Server_T_ServerLocation_LocationId", + column: x => x.LocationId, + principalTable: "T_ServerLocation", + principalColumn: "Id"); + }); + + migrationBuilder.InsertData( + table: "T_ServerLocation", + columns: new[] { "Id", "Address", "City", "Country", "Description", "Name", "PostalCode", "Region" }, + values: new object[] { "7EB5999F-AEF5-11EF-9FD9-47F022E22A50", "", "", "Default", "Initial location", "Default", "", "" }); + + migrationBuilder.CreateIndex( + name: "IX_T_Server_LocationId", + table: "T_Server", + column: "LocationId"); + + migrationBuilder.CreateIndex( + name: "IX_T_ServerLocation_Name", + table: "T_ServerLocation", + column: "Name"); + } + } +} diff --git a/src/hiPower.Database/Migrations/20241208160756_RenameToDataCenter.Designer.cs b/src/hiPower.Database/Migrations/20241208160756_RenameToDataCenter.Designer.cs new file mode 100644 index 0000000..980c1ad --- /dev/null +++ b/src/hiPower.Database/Migrations/20241208160756_RenameToDataCenter.Designer.cs @@ -0,0 +1,678 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using hiPower.Database; + +#nullable disable + +namespace hiPower.Database.Migrations +{ + [DbContext(typeof(ManagerDbContext))] + [Migration("20241208160756_RenameToDataCenter")] + partial class RenameToDataCenter + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("hiPower.Entity.DataCenter", b => + { + b.Property("Id") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Address") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("City") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Country") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Description") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PostalCode") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Region") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("T_DataCenter", (string)null); + + b.HasData( + new + { + Id = "7EB5999F-AEF5-11EF-9FD9-47F022E22A50", + Address = "", + City = "", + Country = "Default", + Description = "Initial location", + Name = "Default", + PostalCode = "", + Region = "" + }); + }); + + modelBuilder.Entity("hiPower.Entity.MonitorService", b => + { + b.Property("ServiceId") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitorState") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("ServiceId"); + + b.HasIndex("ServiceId", "MonitorState"); + + b.ToTable("T_MonitorService", (string)null); + }); + + modelBuilder.Entity("hiPower.Entity.MonitorVariables", b => + { + b.Property("ServiceId") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Variable") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("ServiceId"); + + b.ToTable("T_MonitorVariables", (string)null); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceDetails", b => + { + b.Property("Id") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("ApiKey") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("Auth") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("Configuration") + .HasColumnType("text"); + + b.Property("DataCenterId") + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Description") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("HostAddress") + .IsRequired() + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("LocalId") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("MonitorId") + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("OS") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Port") + .HasColumnType("text"); + + b.Property("Proto") + .IsRequired() + .HasMaxLength(10) + .HasPrecision(0, 5) + .HasColumnType("character varying(10)"); + + b.Property("State") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Version") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("DataCenterId"); + + b.ToTable("T_ServiceDetails", (string)null); + }); + + modelBuilder.Entity("hiPower.Entity.StatisticsVariable", b => + { + b.Property("Variable") + .HasMaxLength(35) + .HasColumnType("character varying(35)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.HasKey("Variable"); + + b.ToTable("T_StatisticsVariable", (string)null); + + b.HasData( + new + { + Variable = "backend-queries", + Description = "Number of queries sent to the backend(s)" + }, + new + { + Variable = "corrupt-packets", + Description = "Number of corrupt packets received" + }, + new + { + Variable = "deferred-cache-inserts", + Description = "Amount of cache inserts that were deferred because of maintenance" + }, + new + { + Variable = "deferred-cache-lookup", + Description = "Amount of cache lookups that were deferred because of maintenance" + }, + new + { + Variable = "deferred-packetcache-inserts", + Description = "Amount of packet cache inserts that were deferred because of maintenance" + }, + new + { + Variable = "deferred-packetcache-lookup", + Description = "Amount of packet cache lookups that were deferred because of maintenance" + }, + new + { + Variable = "dnsupdate-answers", + Description = "DNS update packets successfully answered." + }, + new + { + Variable = "dnsupdate-changes", + Description = "DNS update changes to records in total." + }, + new + { + Variable = "dnsupdate-queries", + Description = "DNS update packets received." + }, + new + { + Variable = "dnsupdate-refused", + Description = "DNS update packets that are refused." + }, + new + { + Variable = "incoming-notifications", + Description = "NOTIFY packets received." + }, + new + { + Variable = "noerror-packets", + Description = "Number of times a NOERROR packet was sent out" + }, + new + { + Variable = "nxdomain-packets", + Description = "Number of times an NXDOMAIN packet was sent out" + }, + new + { + Variable = "overload-drops", + Description = "Queries dropped because backends overloaded" + }, + new + { + Variable = "packetcache-hit", + Description = "Number of hits on the packet cache" + }, + new + { + Variable = "packetcache-miss", + Description = "Number of misses on the packet cache" + }, + new + { + Variable = "packetcache-size", + Description = "Number of entries in the packet cache" + }, + new + { + Variable = "query-cache-hit", + Description = "Number of hits on the query cache" + }, + new + { + Variable = "query-cache-miss", + Description = "Number of misses on the query cache" + }, + new + { + Variable = "query-cache-size", + Description = "Number of entries in the query cache" + }, + new + { + Variable = "rd-queries", + Description = "Number of recursion desired questions" + }, + new + { + Variable = "recursing-answers", + Description = "Number of recursive answers sent out" + }, + new + { + Variable = "recursing-questions", + Description = "Number of questions sent to recursor" + }, + new + { + Variable = "recursion-unanswered", + Description = "Number of packets unanswered by configured recursor" + }, + new + { + Variable = "security-status", + Description = "Security status based on regular polling" + }, + new + { + Variable = "servfail-packets", + Description = "Number of times a server-failed packet was sent out" + }, + new + { + Variable = "signatures", + Description = "Number of DNSSEC signatures made" + }, + new + { + Variable = "tcp-answers", + Description = "Number of answers sent out over TCP" + }, + new + { + Variable = "tcp-answers-bytes", + Description = "Total size of answers sent out over TCP" + }, + new + { + Variable = "tcp-queries", + Description = "Number of TCP queries received" + }, + new + { + Variable = "tcp4-answers", + Description = "Number of IPv4 answers sent out over TCP" + }, + new + { + Variable = "tcp4-answers-bytes", + Description = "Total size of answers sent out over TCPv4" + }, + new + { + Variable = "tcp4-queries", + Description = "Number of IPv4 TCP queries received" + }, + new + { + Variable = "tcp6-answers", + Description = "Number of IPv6 answers sent out over TCP" + }, + new + { + Variable = "tcp6-answers-bytes", + Description = "Total size of answers sent out over TCPv6" + }, + new + { + Variable = "tcp6-queries", + Description = "Number of IPv6 TCP queries received" + }, + new + { + Variable = "timedout-packets", + Description = "Number of packets which weren't answered within timeout set" + }, + new + { + Variable = "udp-answers", + Description = "Number of answers sent out over UDP" + }, + new + { + Variable = "udp-answers-bytes", + Description = "Total size of answers sent out over UDP" + }, + new + { + Variable = "udp-do-queries", + Description = "Number of UDP queries received with DO bit" + }, + new + { + Variable = "udp-queries", + Description = "Number of UDP queries received" + }, + new + { + Variable = "udp4-answers", + Description = "Number of IPv4 answers sent out over UDP" + }, + new + { + Variable = "udp4-answers-bytes", + Description = "Total size of answers sent out over UDPv4" + }, + new + { + Variable = "udp4-queries", + Description = "Number of IPv4 UDP queries received" + }, + new + { + Variable = "udp6-answers", + Description = "Number of IPv6 answers sent out over UDP" + }, + new + { + Variable = "udp6-answers-bytes", + Description = "Total size of answers sent out over UDPv6" + }, + new + { + Variable = "udp6-queries", + Description = "Number of IPv6 UDP queries received" + }, + new + { + Variable = "unauth-packets", + Description = "Number of times a zone we are not auth for was queried" + }, + new + { + Variable = "zone-cache-hit", + Description = "Number of zone cache hits" + }, + new + { + Variable = "zone-cache-miss", + Description = "Number of zone cache misses" + }, + new + { + Variable = "zone-cache-size", + Description = "Number of entries in the zone cache" + }, + new + { + Variable = "cpu-iowait", + Description = "Time spent waiting for I/O to complete by the whole system, in units of USER_HZ" + }, + new + { + Variable = "cpu-steal", + Description = "Stolen time, which is the time spent by the whole system in other operating systems when running in a virtualized environment, in units of USER_HZ" + }, + new + { + Variable = "fd-usage", + Description = "Number of open filedescriptors" + }, + new + { + Variable = "key-cache-size", + Description = "Number of entries in the key cache" + }, + new + { + Variable = "latency", + Description = "Average number of microseconds needed to answer a question" + }, + new + { + Variable = "meta-cache-size", + Description = "Number of entries in the metadata cache" + }, + new + { + Variable = "open-tcp-connections", + Description = "Number of currently open TCP connections" + }, + new + { + Variable = "qsize-q", + Description = "Number of questions waiting for database attention" + }, + new + { + Variable = "real-memory-usage", + Description = "Actual unique use of memory in bytes (approx)" + }, + new + { + Variable = "ring-logmessages-capacity", + Description = "Maximum number of entries in the logmessages ring" + }, + new + { + Variable = "ring-logmessages-size", + Description = "Number of entries in the logmessages ring" + }, + new + { + Variable = "ring-noerror-queries-capacity", + Description = "Maximum number of entries in the noerror-queries ring" + }, + new + { + Variable = "ring-noerror-queries-size", + Description = "Number of entries in the noerror-queries ring" + }, + new + { + Variable = "ring-nxdomain-queries-capacity", + Description = "Maximum number of entries in the nxdomain-queries ring" + }, + new + { + Variable = "ring-nxdomain-queries-size", + Description = "Number of entries in the nxdomain-queries ring" + }, + new + { + Variable = "ring-queries-capacity", + Description = "Maximum number of entries in the queries ring" + }, + new + { + Variable = "ring-queries-size", + Description = "Number of entries in the queries ring" + }, + new + { + Variable = "ring-remotes-capacity", + Description = "Maximum number of entries in the remotes ring" + }, + new + { + Variable = "ring-remotes-corrupt-capacity", + Description = "Maximum number of entries in the remotes-corrupt ring" + }, + new + { + Variable = "ring-remotes-corrupt-size", + Description = "Number of entries in the remotes-corrupt ring" + }, + new + { + Variable = "ring-remotes-size", + Description = "Number of entries in the remotes ring" + }, + new + { + Variable = "ring-remotes-unauth-capacity", + Description = "Maximum number of entries in the remotes-unauth ring" + }, + new + { + Variable = "ring-remotes-unauth-size", + Description = "Number of entries in the remotes-unauth ring" + }, + new + { + Variable = "ring-servfail-queries-capacity", + Description = "Maximum number of entries in the servfail-queries ring" + }, + new + { + Variable = "ring-servfail-queries-size", + Description = "Number of entries in the servfail-queries ring" + }, + new + { + Variable = "ring-unauth-queries-capacity", + Description = "Maximum number of entries in the unauth-queries ring" + }, + new + { + Variable = "ring-unauth-queries-size", + Description = "Number of entries in the unauth-queries ring" + }, + new + { + Variable = "signature-cache-size", + Description = "Number of entries in the signature cache" + }, + new + { + Variable = "sys-msec", + Description = "Number of msec spent in system time" + }, + new + { + Variable = "udp-in-errors", + Description = "UDP 'in' errors" + }, + new + { + Variable = "udp-noport-errors", + Description = "UDP 'noport' errors" + }, + new + { + Variable = "udp-recvbuf-errors", + Description = "UDP 'recvbuf' errors" + }, + new + { + Variable = "udp-sndbuf-errors", + Description = "UDP 'sndbuf' errors" + }, + new + { + Variable = "uptime", + Description = "Uptime of process in seconds" + }, + new + { + Variable = "user-msec", + Description = "Number of msec spent in user time" + }, + new + { + Variable = "xfr-queue", + Description = "Size of the queue of zones to be XFRd" + }); + }); + + modelBuilder.Entity("hiPower.Entity.MonitorVariables", b => + { + b.HasOne("hiPower.Entity.ServiceDetails", "ServiceDetails") + .WithMany("MonitorStatistics") + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + + b.Navigation("ServiceDetails"); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceDetails", b => + { + b.HasOne("hiPower.Entity.DataCenter", "DataCenter") + .WithMany("Servers") + .HasForeignKey("DataCenterId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("DataCenter"); + }); + + modelBuilder.Entity("hiPower.Entity.DataCenter", b => + { + b.Navigation("Servers"); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceDetails", b => + { + b.Navigation("MonitorStatistics"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/hiPower.Database/Migrations/20241208160756_RenameToDataCenter.cs b/src/hiPower.Database/Migrations/20241208160756_RenameToDataCenter.cs new file mode 100644 index 0000000..f4f30da --- /dev/null +++ b/src/hiPower.Database/Migrations/20241208160756_RenameToDataCenter.cs @@ -0,0 +1,122 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace hiPower.Database.Migrations +{ + /// + public partial class RenameToDataCenter : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_T_ServiceDetails_T_ServiceLocation_LocationId", + table: "T_ServiceDetails"); + + migrationBuilder.DropTable( + name: "T_ServiceLocation"); + + migrationBuilder.RenameColumn( + name: "LocationId", + table: "T_ServiceDetails", + newName: "DataCenterId"); + + migrationBuilder.RenameIndex( + name: "IX_T_ServiceDetails_LocationId", + table: "T_ServiceDetails", + newName: "IX_T_ServiceDetails_DataCenterId"); + + migrationBuilder.CreateTable( + name: "T_DataCenter", + columns: table => new + { + Id = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + Name = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + Description = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Address = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + City = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + Region = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + PostalCode = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + Country = table.Column(type: "character varying(50)", maxLength: 50, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_DataCenter", x => x.Id); + }); + + migrationBuilder.InsertData( + table: "T_DataCenter", + columns: new[] { "Id", "Address", "City", "Country", "Description", "Name", "PostalCode", "Region" }, + values: new object[] { "7EB5999F-AEF5-11EF-9FD9-47F022E22A50", "", "", "Default", "Initial location", "Default", "", "" }); + + migrationBuilder.CreateIndex( + name: "IX_T_DataCenter_Name", + table: "T_DataCenter", + column: "Name"); + + migrationBuilder.AddForeignKey( + name: "FK_T_ServiceDetails_T_DataCenter_DataCenterId", + table: "T_ServiceDetails", + column: "DataCenterId", + principalTable: "T_DataCenter", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_T_ServiceDetails_T_DataCenter_DataCenterId", + table: "T_ServiceDetails"); + + migrationBuilder.DropTable( + name: "T_DataCenter"); + + migrationBuilder.RenameColumn( + name: "DataCenterId", + table: "T_ServiceDetails", + newName: "LocationId"); + + migrationBuilder.RenameIndex( + name: "IX_T_ServiceDetails_DataCenterId", + table: "T_ServiceDetails", + newName: "IX_T_ServiceDetails_LocationId"); + + migrationBuilder.CreateTable( + name: "T_ServiceLocation", + columns: table => new + { + Id = table.Column(type: "character varying(36)", maxLength: 36, nullable: false), + Address = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + City = table.Column(type: "character varying(150)", maxLength: 150, nullable: true), + Country = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + Description = table.Column(type: "character varying(250)", maxLength: 250, nullable: true), + Name = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + PostalCode = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + Region = table.Column(type: "character varying(50)", maxLength: 50, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_T_ServiceLocation", x => x.Id); + }); + + migrationBuilder.InsertData( + table: "T_ServiceLocation", + columns: new[] { "Id", "Address", "City", "Country", "Description", "Name", "PostalCode", "Region" }, + values: new object[] { "7EB5999F-AEF5-11EF-9FD9-47F022E22A50", "", "", "Default", "Initial location", "Default", "", "" }); + + migrationBuilder.CreateIndex( + name: "IX_T_ServiceLocation_Name", + table: "T_ServiceLocation", + column: "Name"); + + migrationBuilder.AddForeignKey( + name: "FK_T_ServiceDetails_T_ServiceLocation_LocationId", + table: "T_ServiceDetails", + column: "LocationId", + principalTable: "T_ServiceLocation", + principalColumn: "Id"); + } + } +} diff --git a/src/hiPower.Database/Migrations/ManagerDbContextModelSnapshot.cs b/src/hiPower.Database/Migrations/ManagerDbContextModelSnapshot.cs index 3adcc28..5d980d7 100644 --- a/src/hiPower.Database/Migrations/ManagerDbContextModelSnapshot.cs +++ b/src/hiPower.Database/Migrations/ManagerDbContextModelSnapshot.cs @@ -1,4 +1,5 @@ // +using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; @@ -21,7 +22,99 @@ protected override void BuildModel(ModelBuilder modelBuilder) NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - modelBuilder.Entity("hiPower.Entity.Server", b => + modelBuilder.Entity("hiPower.Entity.DataCenter", b => + { + b.Property("Id") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Address") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("City") + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Country") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Description") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PostalCode") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Region") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("T_DataCenter", (string)null); + + b.HasData( + new + { + Id = "7EB5999F-AEF5-11EF-9FD9-47F022E22A50", + Address = "", + City = "", + Country = "Default", + Description = "Initial location", + Name = "Default", + PostalCode = "", + Region = "" + }); + }); + + modelBuilder.Entity("hiPower.Entity.MonitorService", b => + { + b.Property("ServiceId") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("MonitorState") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("ServiceId"); + + b.HasIndex("ServiceId", "MonitorState"); + + b.ToTable("T_MonitorService", (string)null); + }); + + modelBuilder.Entity("hiPower.Entity.MonitorVariables", b => + { + b.Property("ServiceId") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Variable") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("ServiceId"); + + b.ToTable("T_MonitorVariables", (string)null); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceDetails", b => { b.Property("Id") .HasMaxLength(36) @@ -38,6 +131,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Configuration") .HasColumnType("text"); + b.Property("DataCenterId") + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + b.Property("Description") .HasMaxLength(250) .HasColumnType("character varying(250)"); @@ -51,10 +149,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(250) .HasColumnType("character varying(250)"); - b.Property("LocationId") - .IsRequired() - .HasMaxLength(36) - .HasColumnType("character varying(36)"); + b.Property("MonitorId") + .HasColumnType("text"); b.Property("Name") .IsRequired() @@ -74,17 +170,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasPrecision(0, 5) .HasColumnType("character varying(10)"); - b.Property("Retries") - .HasPrecision(0, 2) - .HasColumnType("integer"); - - b.Property("State") - .HasPrecision(0, 3) - .HasColumnType("integer"); - - b.Property("Timeout") - .HasPrecision(0, 5) - .HasColumnType("integer"); + b.Property("State") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); b.Property("Version") .HasMaxLength(20) @@ -92,81 +181,494 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("LocationId"); + b.HasIndex("DataCenterId"); - b.ToTable("T_Server", (string)null); + b.ToTable("T_ServiceDetails", (string)null); }); - modelBuilder.Entity("hiPower.Entity.ServerLocation", b => + modelBuilder.Entity("hiPower.Entity.StatisticsVariable", b => { - b.Property("Id") - .HasMaxLength(36) - .HasColumnType("character varying(36)"); - - b.Property("Address") - .HasMaxLength(150) - .HasColumnType("character varying(150)"); - - b.Property("City") - .HasMaxLength(150) - .HasColumnType("character varying(150)"); - - b.Property("Country") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); + b.Property("Variable") + .HasMaxLength(35) + .HasColumnType("character varying(35)"); b.Property("Description") - .HasMaxLength(250) - .HasColumnType("character varying(250)"); + .HasMaxLength(200) + .HasColumnType("character varying(200)"); - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); + b.HasKey("Variable"); - b.Property("PostalCode") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Region") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("Id"); - - b.HasIndex("Name"); - - b.ToTable("T_ServerLocation", (string)null); + b.ToTable("T_StatisticsVariable", (string)null); b.HasData( new { - Id = "7EB5999F-AEF5-11EF-9FD9-47F022E22A50", - Address = "", - City = "", - Country = "Default", - Description = "Initial location", - Name = "Default", - PostalCode = "", - Region = "" + Variable = "backend-queries", + Description = "Number of queries sent to the backend(s)" + }, + new + { + Variable = "corrupt-packets", + Description = "Number of corrupt packets received" + }, + new + { + Variable = "deferred-cache-inserts", + Description = "Amount of cache inserts that were deferred because of maintenance" + }, + new + { + Variable = "deferred-cache-lookup", + Description = "Amount of cache lookups that were deferred because of maintenance" + }, + new + { + Variable = "deferred-packetcache-inserts", + Description = "Amount of packet cache inserts that were deferred because of maintenance" + }, + new + { + Variable = "deferred-packetcache-lookup", + Description = "Amount of packet cache lookups that were deferred because of maintenance" + }, + new + { + Variable = "dnsupdate-answers", + Description = "DNS update packets successfully answered." + }, + new + { + Variable = "dnsupdate-changes", + Description = "DNS update changes to records in total." + }, + new + { + Variable = "dnsupdate-queries", + Description = "DNS update packets received." + }, + new + { + Variable = "dnsupdate-refused", + Description = "DNS update packets that are refused." + }, + new + { + Variable = "incoming-notifications", + Description = "NOTIFY packets received." + }, + new + { + Variable = "noerror-packets", + Description = "Number of times a NOERROR packet was sent out" + }, + new + { + Variable = "nxdomain-packets", + Description = "Number of times an NXDOMAIN packet was sent out" + }, + new + { + Variable = "overload-drops", + Description = "Queries dropped because backends overloaded" + }, + new + { + Variable = "packetcache-hit", + Description = "Number of hits on the packet cache" + }, + new + { + Variable = "packetcache-miss", + Description = "Number of misses on the packet cache" + }, + new + { + Variable = "packetcache-size", + Description = "Number of entries in the packet cache" + }, + new + { + Variable = "query-cache-hit", + Description = "Number of hits on the query cache" + }, + new + { + Variable = "query-cache-miss", + Description = "Number of misses on the query cache" + }, + new + { + Variable = "query-cache-size", + Description = "Number of entries in the query cache" + }, + new + { + Variable = "rd-queries", + Description = "Number of recursion desired questions" + }, + new + { + Variable = "recursing-answers", + Description = "Number of recursive answers sent out" + }, + new + { + Variable = "recursing-questions", + Description = "Number of questions sent to recursor" + }, + new + { + Variable = "recursion-unanswered", + Description = "Number of packets unanswered by configured recursor" + }, + new + { + Variable = "security-status", + Description = "Security status based on regular polling" + }, + new + { + Variable = "servfail-packets", + Description = "Number of times a server-failed packet was sent out" + }, + new + { + Variable = "signatures", + Description = "Number of DNSSEC signatures made" + }, + new + { + Variable = "tcp-answers", + Description = "Number of answers sent out over TCP" + }, + new + { + Variable = "tcp-answers-bytes", + Description = "Total size of answers sent out over TCP" + }, + new + { + Variable = "tcp-queries", + Description = "Number of TCP queries received" + }, + new + { + Variable = "tcp4-answers", + Description = "Number of IPv4 answers sent out over TCP" + }, + new + { + Variable = "tcp4-answers-bytes", + Description = "Total size of answers sent out over TCPv4" + }, + new + { + Variable = "tcp4-queries", + Description = "Number of IPv4 TCP queries received" + }, + new + { + Variable = "tcp6-answers", + Description = "Number of IPv6 answers sent out over TCP" + }, + new + { + Variable = "tcp6-answers-bytes", + Description = "Total size of answers sent out over TCPv6" + }, + new + { + Variable = "tcp6-queries", + Description = "Number of IPv6 TCP queries received" + }, + new + { + Variable = "timedout-packets", + Description = "Number of packets which weren't answered within timeout set" + }, + new + { + Variable = "udp-answers", + Description = "Number of answers sent out over UDP" + }, + new + { + Variable = "udp-answers-bytes", + Description = "Total size of answers sent out over UDP" + }, + new + { + Variable = "udp-do-queries", + Description = "Number of UDP queries received with DO bit" + }, + new + { + Variable = "udp-queries", + Description = "Number of UDP queries received" + }, + new + { + Variable = "udp4-answers", + Description = "Number of IPv4 answers sent out over UDP" + }, + new + { + Variable = "udp4-answers-bytes", + Description = "Total size of answers sent out over UDPv4" + }, + new + { + Variable = "udp4-queries", + Description = "Number of IPv4 UDP queries received" + }, + new + { + Variable = "udp6-answers", + Description = "Number of IPv6 answers sent out over UDP" + }, + new + { + Variable = "udp6-answers-bytes", + Description = "Total size of answers sent out over UDPv6" + }, + new + { + Variable = "udp6-queries", + Description = "Number of IPv6 UDP queries received" + }, + new + { + Variable = "unauth-packets", + Description = "Number of times a zone we are not auth for was queried" + }, + new + { + Variable = "zone-cache-hit", + Description = "Number of zone cache hits" + }, + new + { + Variable = "zone-cache-miss", + Description = "Number of zone cache misses" + }, + new + { + Variable = "zone-cache-size", + Description = "Number of entries in the zone cache" + }, + new + { + Variable = "cpu-iowait", + Description = "Time spent waiting for I/O to complete by the whole system, in units of USER_HZ" + }, + new + { + Variable = "cpu-steal", + Description = "Stolen time, which is the time spent by the whole system in other operating systems when running in a virtualized environment, in units of USER_HZ" + }, + new + { + Variable = "fd-usage", + Description = "Number of open filedescriptors" + }, + new + { + Variable = "key-cache-size", + Description = "Number of entries in the key cache" + }, + new + { + Variable = "latency", + Description = "Average number of microseconds needed to answer a question" + }, + new + { + Variable = "meta-cache-size", + Description = "Number of entries in the metadata cache" + }, + new + { + Variable = "open-tcp-connections", + Description = "Number of currently open TCP connections" + }, + new + { + Variable = "qsize-q", + Description = "Number of questions waiting for database attention" + }, + new + { + Variable = "real-memory-usage", + Description = "Actual unique use of memory in bytes (approx)" + }, + new + { + Variable = "ring-logmessages-capacity", + Description = "Maximum number of entries in the logmessages ring" + }, + new + { + Variable = "ring-logmessages-size", + Description = "Number of entries in the logmessages ring" + }, + new + { + Variable = "ring-noerror-queries-capacity", + Description = "Maximum number of entries in the noerror-queries ring" + }, + new + { + Variable = "ring-noerror-queries-size", + Description = "Number of entries in the noerror-queries ring" + }, + new + { + Variable = "ring-nxdomain-queries-capacity", + Description = "Maximum number of entries in the nxdomain-queries ring" + }, + new + { + Variable = "ring-nxdomain-queries-size", + Description = "Number of entries in the nxdomain-queries ring" + }, + new + { + Variable = "ring-queries-capacity", + Description = "Maximum number of entries in the queries ring" + }, + new + { + Variable = "ring-queries-size", + Description = "Number of entries in the queries ring" + }, + new + { + Variable = "ring-remotes-capacity", + Description = "Maximum number of entries in the remotes ring" + }, + new + { + Variable = "ring-remotes-corrupt-capacity", + Description = "Maximum number of entries in the remotes-corrupt ring" + }, + new + { + Variable = "ring-remotes-corrupt-size", + Description = "Number of entries in the remotes-corrupt ring" + }, + new + { + Variable = "ring-remotes-size", + Description = "Number of entries in the remotes ring" + }, + new + { + Variable = "ring-remotes-unauth-capacity", + Description = "Maximum number of entries in the remotes-unauth ring" + }, + new + { + Variable = "ring-remotes-unauth-size", + Description = "Number of entries in the remotes-unauth ring" + }, + new + { + Variable = "ring-servfail-queries-capacity", + Description = "Maximum number of entries in the servfail-queries ring" + }, + new + { + Variable = "ring-servfail-queries-size", + Description = "Number of entries in the servfail-queries ring" + }, + new + { + Variable = "ring-unauth-queries-capacity", + Description = "Maximum number of entries in the unauth-queries ring" + }, + new + { + Variable = "ring-unauth-queries-size", + Description = "Number of entries in the unauth-queries ring" + }, + new + { + Variable = "signature-cache-size", + Description = "Number of entries in the signature cache" + }, + new + { + Variable = "sys-msec", + Description = "Number of msec spent in system time" + }, + new + { + Variable = "udp-in-errors", + Description = "UDP 'in' errors" + }, + new + { + Variable = "udp-noport-errors", + Description = "UDP 'noport' errors" + }, + new + { + Variable = "udp-recvbuf-errors", + Description = "UDP 'recvbuf' errors" + }, + new + { + Variable = "udp-sndbuf-errors", + Description = "UDP 'sndbuf' errors" + }, + new + { + Variable = "uptime", + Description = "Uptime of process in seconds" + }, + new + { + Variable = "user-msec", + Description = "Number of msec spent in user time" + }, + new + { + Variable = "xfr-queue", + Description = "Size of the queue of zones to be XFRd" }); }); - modelBuilder.Entity("hiPower.Entity.Server", b => + modelBuilder.Entity("hiPower.Entity.MonitorVariables", b => { - b.HasOne("hiPower.Entity.ServerLocation", "Location") + b.HasOne("hiPower.Entity.ServiceDetails", "ServiceDetails") + .WithMany("MonitorStatistics") + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + + b.Navigation("ServiceDetails"); + }); + + modelBuilder.Entity("hiPower.Entity.ServiceDetails", b => + { + b.HasOne("hiPower.Entity.DataCenter", "DataCenter") .WithMany("Servers") - .HasForeignKey("LocationId") + .HasForeignKey("DataCenterId") .OnDelete(DeleteBehavior.NoAction) .IsRequired(); - b.Navigation("Location"); + b.Navigation("DataCenter"); }); - modelBuilder.Entity("hiPower.Entity.ServerLocation", b => + modelBuilder.Entity("hiPower.Entity.DataCenter", b => { b.Navigation("Servers"); }); + + modelBuilder.Entity("hiPower.Entity.ServiceDetails", b => + { + b.Navigation("MonitorStatistics"); + }); #pragma warning restore 612, 618 } } diff --git a/src/hiPower.Dto/Manager/Server.cs b/src/hiPower.Dto/Manager/Server.cs index a0a8aed..71c5de0 100644 --- a/src/hiPower.Dto/Manager/Server.cs +++ b/src/hiPower.Dto/Manager/Server.cs @@ -4,7 +4,7 @@ namespace hiPower.Dto.Manager; public class Server { public string Id { get; set; } - public string LocationId { get; set; } + public string DataCenterId { get; set; } public string Name { get; set; } public string Description { get; set; } public CommunicationProto Proto { get; set; } diff --git a/src/hiPower.Dto/Remote/StatisticsItem.cs b/src/hiPower.Dto/Remote/StatisticsItem.cs index 9924b55..d86570a 100644 --- a/src/hiPower.Dto/Remote/StatisticsItem.cs +++ b/src/hiPower.Dto/Remote/StatisticsItem.cs @@ -4,5 +4,5 @@ public class StatisticsItem { public string Name { get; set; } public string Type { get; set; } - public string Value { get; set; } + public object Value { get; set; } } diff --git a/src/hiPower.Entity/DashboardMonitor.cs b/src/hiPower.Entity/DashboardMonitor.cs new file mode 100644 index 0000000..9cfe163 --- /dev/null +++ b/src/hiPower.Entity/DashboardMonitor.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace hiPower.Entity +{ + internal class DashboardMonitor + { + } +} diff --git a/src/hiPower.Entity/ServerLocation.cs b/src/hiPower.Entity/DataCenter.cs similarity index 75% rename from src/hiPower.Entity/ServerLocation.cs rename to src/hiPower.Entity/DataCenter.cs index fe73ea5..eb0f40a 100644 --- a/src/hiPower.Entity/ServerLocation.cs +++ b/src/hiPower.Entity/DataCenter.cs @@ -1,6 +1,6 @@ namespace hiPower.Entity; -public class ServerLocation : EntityBase +public class DataCenter : EntityBase { public string Name { get; set; } public string Description { get; set; } @@ -10,5 +10,5 @@ public class ServerLocation : EntityBase public string PostalCode { get; set; } public string Country { get; set; } - public ICollection Servers { get; set; } + public ICollection Servers { get; set; } } diff --git a/src/hiPower.Entity/MonitorService.cs b/src/hiPower.Entity/MonitorService.cs new file mode 100644 index 0000000..d57d21a --- /dev/null +++ b/src/hiPower.Entity/MonitorService.cs @@ -0,0 +1,10 @@ +using hiPower.Common.Type; + +namespace hiPower.Entity; + +public class MonitorService +{ + public MonitorState MonitorState { get; set; } + public DateTime Created { get; set; } + public string ServiceId { get; set; } +} diff --git a/src/hiPower.Entity/MonitorVariables.cs b/src/hiPower.Entity/MonitorVariables.cs new file mode 100644 index 0000000..5dfe083 --- /dev/null +++ b/src/hiPower.Entity/MonitorVariables.cs @@ -0,0 +1,8 @@ +namespace hiPower.Entity; + +public class MonitorVariables +{ + public string ServiceId { get; set; } + public string Variable { get; set; } + public virtual ServiceDetails ServiceDetails { get; set; } +} diff --git a/src/hiPower.Entity/ServerDetails.cs b/src/hiPower.Entity/ServiceDetails.cs similarity index 62% rename from src/hiPower.Entity/ServerDetails.cs rename to src/hiPower.Entity/ServiceDetails.cs index adfe2cd..6bdf529 100644 --- a/src/hiPower.Entity/ServerDetails.cs +++ b/src/hiPower.Entity/ServiceDetails.cs @@ -2,7 +2,7 @@ namespace hiPower.Entity; -public class ServerDetails: EntityBase +public class ServiceDetails : EntityBase { public string Name { get; set; } @@ -26,15 +26,13 @@ public class ServerDetails: EntityBase public string Configuration { get; set; } - public ServerState State { get; set; } + public ServiceState State { get; set; } - [Obsolete] - public int Timeout { get; set; } + public string DataCenterId { get; set; } - [Obsolete] - public int Retries { get; set; } + public DataCenter DataCenter { get; set; } - public string LocationId { get; set; } + public virtual string MonitorId {get; set; } - public ServerLocation Location { get; set; } + public virtual ICollection MonitorStatistics { get; set; } } diff --git a/src/hiPower.Entity/StatisticsVariable.cs b/src/hiPower.Entity/StatisticsVariable.cs new file mode 100644 index 0000000..3159bad --- /dev/null +++ b/src/hiPower.Entity/StatisticsVariable.cs @@ -0,0 +1,8 @@ +namespace hiPower.Entity; + +public class StatisticsVariable +{ + public string Variable { get;set; } + public string Description { get; set; } + +} diff --git a/src/hiPower.Repository/UnitOfWork.cs b/src/hiPower.Repository/UnitOfWork.cs index eb8b934..c1e1c94 100644 --- a/src/hiPower.Repository/UnitOfWork.cs +++ b/src/hiPower.Repository/UnitOfWork.cs @@ -10,12 +10,12 @@ public class UnitOfWork(DbContextOptions options) : IUnitOfWor private bool _disposed = false; private readonly ManagerDbContext dbContext = new(options); - private IGenericRepository? dataCenterRepository; - private IGenericRepository? serverRepository; + private IGenericRepository? dataCenterRepository; + private IGenericRepository? serverRepository; - public IGenericRepository DataCenterRepository => dataCenterRepository ??= new GenericRepository (dbContext); + public IGenericRepository DataCenterRepository => dataCenterRepository ??= new GenericRepository (dbContext); - public IGenericRepository ServerRepository => serverRepository ??= new GenericRepository (dbContext); + public IGenericRepository ServerRepository => serverRepository ??= new GenericRepository (dbContext); public async Task SaveAsync () { diff --git a/src/hiPower.Server.Communication/GlobalSuppressions.cs b/src/hiPower.Server.Communication/GlobalSuppressions.cs new file mode 100644 index 0000000..dbc342f --- /dev/null +++ b/src/hiPower.Server.Communication/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage ("Minor Code Smell", "S3267:Loops should be simplified with \"LINQ\" expressions", Justification = "", Scope = "member", Target = "~M:hiPower.Server.Communication.RemoteService.GetStatisticsAsync(hiPower.Common.Type.Options.RemoteServiceOptions,System.Collections.Generic.IEnumerable{System.String})~System.Threading.Tasks.Task{ErrorOr.ErrorOr{System.Collections.Generic.IEnumerable{hiPower.Dto.Remote.StatisticsItem}}}")] diff --git a/src/hiPower.Server.Communication/RemoteService.cs b/src/hiPower.Server.Communication/RemoteService.cs index 0138dff..0dcb4fc 100644 --- a/src/hiPower.Server.Communication/RemoteService.cs +++ b/src/hiPower.Server.Communication/RemoteService.cs @@ -1,5 +1,6 @@ #nullable disable +using System.Net.Http.Json; using System.Text.Json; using ErrorOr; using hiPower.Abstracts; @@ -14,7 +15,7 @@ public class RemoteService (IHttpClientFactory clientFactory) : IRemoteService private readonly ApiAddressConfiguration addressBuilder = new(); private readonly JsonSerializerOptions jsonSerializerOptions = new () { - PropertyNameCaseInsensitive = true, + PropertyNameCaseInsensitive = true }; public async Task>> GetConfigurationAsync (RemoteServiceOptions options) @@ -49,19 +50,38 @@ public async Task> GetInfoAsync (RemoteServiceOptions option .ToErrorOr (); } - public async Task>> GetStatisticsAsync (RemoteServiceOptions options) + public async Task>> GetStatisticsAsync (RemoteServiceOptions options, IEnumerable statItemsList) { ConfigureRequest (options); - var response = await httpClient.GetAsync($"{Consts.EnpointApiPrefix}/servers/{options.LocalId}/statistics"); - if (!response.IsSuccessStatusCode) + string endpointUrl = $"{Consts.EnpointApiPrefix}/servers/{options.LocalId}/statistics"; + var statistics = new List (); + try { - return Error.Failure (); - } + await foreach(var item in httpClient.GetFromJsonAsAsyncEnumerable (endpointUrl, jsonSerializerOptions, default)) + { + if (statItemsList.Any() && statItemsList.Contains (item.Name, StringComparer.OrdinalIgnoreCase) && item?.Type == "StatisticItem") + { + statistics.Add (item); + bool isListFilledout = statistics.Count == statItemsList.Count(); + if (isListFilledout) + { + break; + } + continue; + } - var content = await response.Content.ReadAsStringAsync (); + if (!statItemsList.Any ()) + { + statistics.Add (item); + } + } + } + catch (Exception ex) + { + Console.WriteLine($"Wystąpił błąd: {ex.Message}"); + } - return JsonSerializer.Deserialize> (content, jsonSerializerOptions) - .ToErrorOr (); + return statistics; } private void ConfigureRequest(RemoteServiceOptions options) diff --git a/src/hiPower.WebApi/Controllers/ServersController.cs b/src/hiPower.WebApi/Controllers/ServersController.cs index 000fac7..d6e4c50 100644 --- a/src/hiPower.WebApi/Controllers/ServersController.cs +++ b/src/hiPower.WebApi/Controllers/ServersController.cs @@ -1,5 +1,4 @@ using hiPower.Abstracts; -using hiPower.Dto.Remote; using Mapster; using Microsoft.AspNetCore.Mvc; @@ -62,6 +61,14 @@ public async Task GetStatistics ([FromRoute] string id) { var result = await serverService.GetRemoteStatisticsAsync (id); return Ok (result.Value); + } + + [HttpGet ("{id}/uptime")] + [ValidateIdFilter] + public async Task GetUptime ([FromRoute] string id) + { + var result = await serverService.GetRemoteUptimeAsync (id); + return Ok (result.Value); } [HttpGet ("{id}/info")] diff --git a/src/powerdns-manager/src/app/features/dashboard/dashboard.module.ts b/src/powerdns-manager/src/app/features/dashboard/dashboard.module.ts index b7af237..8acffad 100644 --- a/src/powerdns-manager/src/app/features/dashboard/dashboard.module.ts +++ b/src/powerdns-manager/src/app/features/dashboard/dashboard.module.ts @@ -15,10 +15,15 @@ import { HomeComponent } from './home/home.component'; import { LoadingModule } from '@shared/components/loading/loading.module'; import { LoadingService } from '@shared/components/loading/loading.service'; +import { CommonModuleComponent } from './features/common-module/common-module.component'; +import { RemoteModuleComponent } from './features/remote-module/remote-module.component'; + @NgModule({ declarations: [ LayoutComponent, - HomeComponent + HomeComponent, + CommonModuleComponent, + RemoteModuleComponent ], imports: [ CoreModule, diff --git a/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.html b/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.html index 3f5e55a..6430dc4 100644 --- a/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.html +++ b/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.html @@ -1 +1,17 @@ -

common-module works!

+
+ + + + Uptime +

{{ calculateDays(UptimeData.value) }}days

+

{{ UptimeData.name }}

+
+ + Uptime +

N/Adays

+

{{ serviceName }}

+
+
+
+
+ diff --git a/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.scss b/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.scss index e69de29..303421e 100644 --- a/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.scss +++ b/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.scss @@ -0,0 +1,50 @@ +@import '/src/styles/utils/variables'; + +:host { + mat-card { + margin-right: 1rem; + background: rgb(2,0,36); + background: linear-gradient(160deg, + rgba(2,0,36,1) 0%, + rgba(31,28,212,1) 84%, + rgba(40,37,215,1) 100%); + + color: $color-white; + min-width: 250px; + max-width: 250px; + height: 8rem; + box-shadow: $border-shadow; + + mat-card-content { + padding: 0 0.5rem 0 .5rem; + margin: 0; + + span { + display: block; + margin: .8rem 0 0 .8rem; + font-size: 0.8rem; + } + + h2 { + margin: 0 0 0 .8rem; + font-size: 2.5rem; + + span { + display: inline-block; + font-size: 1rem; + } + } + + p { + font-size: 0.8rem; + font-style: normal; + text-align: right; + } + + p:before { + content: "service: "; + font-style: italic; + } + } + } +} \ No newline at end of file diff --git a/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.ts b/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.ts index 534bcfe..70d7edf 100644 --- a/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.ts +++ b/src/powerdns-manager/src/app/features/dashboard/features/common-module/common-module.component.ts @@ -1,4 +1,12 @@ -import { Component } from '@angular/core'; +import { Component, + Input, + TemplateRef } from '@angular/core'; + +import { StatisticsItem } from '../../models/statistics-item'; +import { EMPTY, + Observable } from 'rxjs'; + +const SecondsPerDay = 86400; @Component({ selector: 'common-module', @@ -6,5 +14,25 @@ import { Component } from '@angular/core'; styleUrl: './common-module.component.scss' }) export class CommonModuleComponent { + @Input() + placeholderTpl!: TemplateRef; + + @Input() + data: Observable = EMPTY; + + @Input() + serviceName = 'uknown service'; + + calculateDays(seconds: string): string { + if (isNaN(+seconds)) + { + return '0'; + } + + return this.round(+seconds / SecondsPerDay, 2); + } + private round(value: number, precision: number): string { + return Number(value).toFixed(precision); + } } diff --git a/src/powerdns-manager/src/app/features/dashboard/features/log-msgs-module/log-msgs-module.component.scss b/src/powerdns-manager/src/app/features/dashboard/features/log-msgs-module/log-msgs-module.component.scss index e69de29..7d9c45e 100644 --- a/src/powerdns-manager/src/app/features/dashboard/features/log-msgs-module/log-msgs-module.component.scss +++ b/src/powerdns-manager/src/app/features/dashboard/features/log-msgs-module/log-msgs-module.component.scss @@ -0,0 +1 @@ +@import '/src/styles/utils/variables'; \ No newline at end of file diff --git a/src/powerdns-manager/src/app/features/dashboard/features/remote-module/remote-module.component.scss b/src/powerdns-manager/src/app/features/dashboard/features/remote-module/remote-module.component.scss index e69de29..7d9c45e 100644 --- a/src/powerdns-manager/src/app/features/dashboard/features/remote-module/remote-module.component.scss +++ b/src/powerdns-manager/src/app/features/dashboard/features/remote-module/remote-module.component.scss @@ -0,0 +1 @@ +@import '/src/styles/utils/variables'; \ No newline at end of file diff --git a/src/powerdns-manager/src/app/features/dashboard/home/home.component.html b/src/powerdns-manager/src/app/features/dashboard/home/home.component.html index 7c98fca..8dbddef 100644 --- a/src/powerdns-manager/src/app/features/dashboard/home/home.component.html +++ b/src/powerdns-manager/src/app/features/dashboard/home/home.component.html @@ -1,4 +1,18 @@
-

dashboard main content

+

Dashboard

+
+ +
+ + + + + + + + +
+
+
diff --git a/src/powerdns-manager/src/app/features/dashboard/home/home.component.scss b/src/powerdns-manager/src/app/features/dashboard/home/home.component.scss index e69de29..2d0dd24 100644 --- a/src/powerdns-manager/src/app/features/dashboard/home/home.component.scss +++ b/src/powerdns-manager/src/app/features/dashboard/home/home.component.scss @@ -0,0 +1,28 @@ +@import '/src/styles/utils/variables'; + +:host { + div.row { + display: flex; + flex-direction: row; + margin: 1rem 0 1rem 0; + } + + div.no-data-placeholder { + h2 { + margin: 0 0 .65rem 0; + padding: .3rem 0 0 .4rem; + font-size: 2.5rem; + } + + p { + font-size: 0.8rem; + font-style: normal; + text-align: right; + } + + p:before { + content: "service: "; + font-style: italic; + } + } +} \ No newline at end of file diff --git a/src/powerdns-manager/src/app/features/dashboard/home/home.component.ts b/src/powerdns-manager/src/app/features/dashboard/home/home.component.ts index d10a34e..46370a3 100644 --- a/src/powerdns-manager/src/app/features/dashboard/home/home.component.ts +++ b/src/powerdns-manager/src/app/features/dashboard/home/home.component.ts @@ -1,4 +1,6 @@ import { Component } from '@angular/core'; +import { EMPTY, Observable, of } from 'rxjs'; +import { StatisticsItem } from '../models/statistics-item'; @Component({ selector: 'app-home-dashboard', @@ -6,5 +8,8 @@ import { Component } from '@angular/core'; styleUrl: './home.component.scss' }) export class HomeComponent { - + service1: Observable = of({name: 'ns001eu', value: '449300001'}); + service2: Observable = of({name: 'ns002eu', value: '442394151'}); + service3: Observable = of({name: 'master001eu', value: '449307091'}); + service4: Observable = of({name: 'ns-dev', value: ''}); } diff --git a/src/powerdns-manager/src/app/features/dashboard/layout/layout.component.scss b/src/powerdns-manager/src/app/features/dashboard/layout/layout.component.scss index 066c904..2d8c6f4 100644 --- a/src/powerdns-manager/src/app/features/dashboard/layout/layout.component.scss +++ b/src/powerdns-manager/src/app/features/dashboard/layout/layout.component.scss @@ -8,7 +8,12 @@ } mat-toolbar { - background-color: $color-blue-navy; + background: rgb(12,7,110); + background: linear-gradient(87deg, + rgba(12,7,110,1) 0%, + rgba(33,33,212,1) 84%, + rgba(5,3,138,1) 100%); + color: $color-black; span { @@ -20,7 +25,7 @@ margin: 1.2rem; width: 15rem; border-right: none; - background-color: $color-black; + background-color: #05038a; color: $color-white; border-radius: 1rem; padding: 1rem; @@ -68,8 +73,8 @@ border-radius: 1rem; background-color: $color-gray-light; border: solid .5px silver; - box-shadow: $border-shadow; - + box-shadow: $border-shadow; + > div { display: flex; align-items: flex-start; diff --git a/src/powerdns-manager/src/app/features/dashboard/models/statistics-item.ts b/src/powerdns-manager/src/app/features/dashboard/models/statistics-item.ts new file mode 100644 index 0000000..8e891fa --- /dev/null +++ b/src/powerdns-manager/src/app/features/dashboard/models/statistics-item.ts @@ -0,0 +1,4 @@ +export interface StatisticsItem { + name: string; + value: string; +} \ No newline at end of file diff --git a/src/powerdns-manager/src/app/features/dashboard/servers/core/models/server.ts b/src/powerdns-manager/src/app/features/dashboard/servers/core/models/server.ts index 91d333c..f7a7957 100644 --- a/src/powerdns-manager/src/app/features/dashboard/servers/core/models/server.ts +++ b/src/powerdns-manager/src/app/features/dashboard/servers/core/models/server.ts @@ -1,7 +1,7 @@ export interface Server { id: string; name: string; - locationId?: string; + dataCenterId?: string; description?: string; proto: string; hostAddress: string; @@ -11,7 +11,5 @@ export interface Server { version?: string; os?: string; configuration?: string; - localId?: string; - timeout?: number; - retries?: number; + localId?: string } \ No newline at end of file diff --git a/src/powerdns-manager/src/app/features/dashboard/servers/create-new/create-new.component.html b/src/powerdns-manager/src/app/features/dashboard/servers/create-new/create-new.component.html index 9a9bb2d..7d0d3b4 100644 --- a/src/powerdns-manager/src/app/features/dashboard/servers/create-new/create-new.component.html +++ b/src/powerdns-manager/src/app/features/dashboard/servers/create-new/create-new.component.html @@ -8,14 +8,15 @@ Name + formControlName="name" + maxlength="50" + placeholder="Name"> Data center - + Choose one @for(item of dataCenters; track item) { {{item.name}} @@ -34,48 +35,55 @@ + formControlName="hostAddress" + maxlength="250" + placeholder="Host address"> + formControlName="port" + maxlength="5" + placeholder="Port TCP"> Api key + formControlName="apiKey" + maxlength="250" + placeholder="Api key"> Auth token + formControlName="auth" + maxlength="250" + placeholder="Auth token"> Local Id + formControlName="localId" + maxlength="250" + placeholder="Local Id"> Version + formControlName="version" + maxlength="20" + placeholder="Varsion"> OS + formControlName="os" + maxlength="150" + placeholder="OS"> @@ -83,16 +91,17 @@ Configuration Description diff --git a/src/powerdns-manager/src/app/features/dashboard/servers/create-new/create-new.component.ts b/src/powerdns-manager/src/app/features/dashboard/servers/create-new/create-new.component.ts index fd8d111..05226de 100644 --- a/src/powerdns-manager/src/app/features/dashboard/servers/create-new/create-new.component.ts +++ b/src/powerdns-manager/src/app/features/dashboard/servers/create-new/create-new.component.ts @@ -19,7 +19,7 @@ export class CreateNewComponent implements OnInit { name: ['', [ Validators.required ]], - locationId: ['', [ + dataCenterId: ['', [ Validators.required ]], proto: ['', [ @@ -59,7 +59,7 @@ export class CreateNewComponent implements OnInit { .createServer({ id: '', name: serverData.name!, - locationId: serverData.locationId, + dataCenterId: serverData.dataCenterId, proto: serverData.proto!, hostAddress: serverData.hostAddress!, port: serverData.port!, @@ -68,9 +68,7 @@ export class CreateNewComponent implements OnInit { version: serverData.version, os: serverData.os, configuration: serverData.configuration, - localId: serverData.localId, - timeout: serverData.timeout, - retries: serverData.retries + localId: serverData.localId }); save$.subscribe({ diff --git a/src/powerdns-manager/src/app/features/dashboard/servers/edit-server/edit-server.component.html b/src/powerdns-manager/src/app/features/dashboard/servers/edit-server/edit-server.component.html index 8258bc9..a8b28e2 100644 --- a/src/powerdns-manager/src/app/features/dashboard/servers/edit-server/edit-server.component.html +++ b/src/powerdns-manager/src/app/features/dashboard/servers/edit-server/edit-server.component.html @@ -9,6 +9,7 @@ Name @@ -22,48 +23,55 @@ + formControlName="hostAddress" + maxlength="250" + placeholder="Host address"> Api key + formControlName="apiKey" + maxlength="250" + placeholder="Api key"> Auth token + formControlName="auth" + maxlength="250" + placeholder="Auth token"> Local Id + formControlName="localId" + maxlength="250" + placeholder="Local Id"> Version OS + formControlName="os" + maxlength="150" + placeholder="OS"> @@ -80,7 +88,8 @@ Description diff --git a/src/powerdns-manager/src/app/features/dashboard/servers/edit-server/edit-server.component.ts b/src/powerdns-manager/src/app/features/dashboard/servers/edit-server/edit-server.component.ts index c39439c..be51715 100644 --- a/src/powerdns-manager/src/app/features/dashboard/servers/edit-server/edit-server.component.ts +++ b/src/powerdns-manager/src/app/features/dashboard/servers/edit-server/edit-server.component.ts @@ -21,7 +21,7 @@ export class EditServerComponent implements OnInit { Validators.required ]], description: [''], - locationId: ['', [ + dataCenterId: ['', [ Validators.required ]], proto: ['', [ diff --git a/src/powerdns-manager/src/app/shared/directives/max-length.directive.spec.ts b/src/powerdns-manager/src/app/shared/directives/max-length.directive.spec.ts new file mode 100644 index 0000000..712cf60 --- /dev/null +++ b/src/powerdns-manager/src/app/shared/directives/max-length.directive.spec.ts @@ -0,0 +1,8 @@ +import { MaxLengthDirective } from './max-length.directive'; + +describe('MaxLengthDirective', () => { + it('should create an instance', () => { + const directive = new MaxLengthDirective(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/src/powerdns-manager/src/app/shared/directives/max-length.directive.ts b/src/powerdns-manager/src/app/shared/directives/max-length.directive.ts new file mode 100644 index 0000000..31e39d4 --- /dev/null +++ b/src/powerdns-manager/src/app/shared/directives/max-length.directive.ts @@ -0,0 +1,23 @@ +import { Directive, + HostListener, + Input } from '@angular/core'; + +@Directive({ + selector: '[appMaxLength]' +}) +export class MaxLengthDirective { + + @Input() + maxLength!: number; + + constructor() { } + + @HostListener('input', ['$event']) + onInput(event: Event) { + const input = event.target as HTMLInputElement; + if (input.value.length > this.maxLength) { + input.value = input.value.substring(0, this.maxLength); + } + } + +} diff --git a/src/powerdns-manager/src/app/shared/shared.module.ts b/src/powerdns-manager/src/app/shared/shared.module.ts index f1e1faa..1afe9e5 100644 --- a/src/powerdns-manager/src/app/shared/shared.module.ts +++ b/src/powerdns-manager/src/app/shared/shared.module.ts @@ -10,7 +10,6 @@ import { MatCommonModule } from '@angular/material/core'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { ManagerErrorHandler } from './handlers/manager-error-handler'; - @NgModule({ imports: [ CommonModule, @@ -21,7 +20,8 @@ import { ManagerErrorHandler } from './handlers/manager-error-handler'; MatCommonModule, MatProgressBarModule ], - exports: [], + exports: [ + ], providers: [ { provide: ErrorHandler,