From 906879aada2e64771466219778f4ff5b8e91c9d2 Mon Sep 17 00:00:00 2001 From: Oliver Kieselbach Date: Tue, 31 Mar 2026 23:23:54 +0200 Subject: [PATCH] bugfix ntpserver null value --- .../Monitoring/Core/MonitoringService.cs | 2 +- .../AutopilotMonitor.Agent/buildcounter.txt | 2 +- .../TableStorage/TableConfigRepository.cs | 2 +- .../Config/GetAgentConfigFunction.cs | 2 +- .../Services/MaintenanceService.cs | 49 +++++++++++++++++++ .../Models/Config/TenantConfiguration.cs | 3 +- 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Core/MonitoringService.cs b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Core/MonitoringService.cs index ef947d63..177b5a91 100644 --- a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Core/MonitoringService.cs +++ b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Core/MonitoringService.cs @@ -437,7 +437,7 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Core { try { - var ntpServer = _configuration.NtpServer ?? "time.windows.com"; + var ntpServer = string.IsNullOrEmpty(_configuration.NtpServer) ? "time.windows.com" : _configuration.NtpServer; var result = NtpTimeCheckService.CheckTime(ntpServer, _logger); if (result.Success) diff --git a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt index fdeeeba2..3e40c389 100644 --- a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt +++ b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt @@ -1 +1 @@ -737 +738 diff --git a/src/Backend/AutopilotMonitor.Functions/DataAccess/TableStorage/TableConfigRepository.cs b/src/Backend/AutopilotMonitor.Functions/DataAccess/TableStorage/TableConfigRepository.cs index 94c2855d..bc920e5d 100644 --- a/src/Backend/AutopilotMonitor.Functions/DataAccess/TableStorage/TableConfigRepository.cs +++ b/src/Backend/AutopilotMonitor.Functions/DataAccess/TableStorage/TableConfigRepository.cs @@ -464,7 +464,7 @@ namespace AutopilotMonitor.Functions.DataAccess.TableStorage RebootDelaySeconds = entity.GetInt32("RebootDelaySeconds"), EnableGeoLocation = entity.GetBoolean("EnableGeoLocation"), EnableTimezoneAutoSet = entity.GetBoolean("EnableTimezoneAutoSet"), - NtpServer = entity.GetString("NtpServer") ?? "time.windows.com", + NtpServer = string.IsNullOrWhiteSpace(entity.GetString("NtpServer")) ? "time.windows.com" : entity.GetString("NtpServer"), EnableImeMatchLog = entity.GetBoolean("EnableImeMatchLog"), LogLevel = entity.GetString("LogLevel"), MaxBatchSize = entity.GetInt32("MaxBatchSize"), diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAgentConfigFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAgentConfigFunction.cs index 9e33487a..37d6e95f 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAgentConfigFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetAgentConfigFunction.cs @@ -163,7 +163,7 @@ namespace AutopilotMonitor.Functions.Functions.Config EnableSoftwareInventoryAnalyzer = tenantConfig.EnableSoftwareInventoryAnalyzer ?? false }, LatestAgentSha256 = adminConfig.LatestAgentSha256, - NtpServer = tenantConfig.NtpServer ?? "time.windows.com", + NtpServer = string.IsNullOrEmpty(tenantConfig.NtpServer) ? "time.windows.com" : tenantConfig.NtpServer, EnableTimezoneAutoSet = tenantConfig.EnableTimezoneAutoSet ?? false, SendTraceEvents = tenantConfig.SendTraceEvents, UnrestrictedMode = tenantConfig.UnrestrictedModeEnabled && tenantConfig.UnrestrictedMode, diff --git a/src/Backend/AutopilotMonitor.Functions/Services/MaintenanceService.cs b/src/Backend/AutopilotMonitor.Functions/Services/MaintenanceService.cs index df418531..1e512510 100644 --- a/src/Backend/AutopilotMonitor.Functions/Services/MaintenanceService.cs +++ b/src/Backend/AutopilotMonitor.Functions/Services/MaintenanceService.cs @@ -155,6 +155,10 @@ namespace AutopilotMonitor.Functions.Services // Backfill OnboardedAt for tenants that don't have it yet // TODO: Remove once all tenants have been backfilled await BackfillTenantOnboardedAtAsync(); + + // Backfill NtpServer for tenants with null/empty value + // TODO: Remove after 2026-06-01 + await BackfillNtpServerDefaultAsync(); } await RecomputePlatformStatsAsync(); @@ -406,6 +410,51 @@ namespace AutopilotMonitor.Functions.Services } } + /// + /// Backfills NtpServer for tenants that have null or empty value. + /// Sets them to the default "time.windows.com". + /// Self-healing: runs every manual maintenance cycle, no-ops once all tenants are backfilled. + /// TODO: Remove after 2026-06-01 + /// + private async Task BackfillNtpServerDefaultAsync() + { + _logger.LogInformation("Backfilling NtpServer for tenants with missing value..."); + + try + { + var allConfigs = await _tenantConfigService.GetAllConfigurationsAsync(); + var configsMissingNtp = allConfigs.Where(c => string.IsNullOrEmpty(c.NtpServer)).ToList(); + + if (configsMissingNtp.Count == 0) + { + _logger.LogInformation("All tenants already have NtpServer set"); + return; + } + + int backfilledCount = 0; + + foreach (var config in configsMissingNtp) + { + try + { + config.NtpServer = "time.windows.com"; + await _tenantConfigService.SaveConfigurationAsync(config); + backfilledCount++; + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Failed to backfill NtpServer for tenant {TenantId}", config.TenantId); + } + } + + _logger.LogInformation("NtpServer backfill completed: {Count} tenants updated", backfilledCount); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to backfill NtpServer for tenants"); + } + } + /// /// Aggregates metrics for any missed days in the last 7 days, plus yesterday. /// Checks the UsageMetrics table for existing snapshots to avoid re-aggregation. diff --git a/src/Shared/AutopilotMonitor.Shared/Models/Config/TenantConfiguration.cs b/src/Shared/AutopilotMonitor.Shared/Models/Config/TenantConfiguration.cs index 05c40ae9..5ff44286 100644 --- a/src/Shared/AutopilotMonitor.Shared/Models/Config/TenantConfiguration.cs +++ b/src/Shared/AutopilotMonitor.Shared/Models/Config/TenantConfiguration.cs @@ -545,7 +545,8 @@ namespace AutopilotMonitor.Shared.Models SelfDestructOnComplete = true, KeepLogFile = false, ShowScriptOutput = true, - OnboardedAt = DateTime.UtcNow + OnboardedAt = DateTime.UtcNow, + NtpServer = "time.windows.com" }; } }