using OTSSignsOrchestrator.Server.Data.Entities; namespace OTSSignsOrchestrator.Server.Health.Checks; /// /// For Pro plan BYOI customers: checks certificate expiry from . /// Alerts at 60-day (Warning), 30-day (Warning), 7-day (Critical) thresholds. /// AutoRemediate=false — customer must rotate their IdP certificate via the portal. /// public sealed class ByoiCertExpiryHealthCheck : IHealthCheck { /// Alert thresholds in days (descending). internal static readonly int[] AlertThresholdDays = [60, 30, 7]; /// Days at or below which severity escalates to Critical. internal const int CriticalThresholdDays = 7; public string CheckName => "ByoiCertExpiry"; public bool AutoRemediate => false; public Task RunAsync(Instance instance, CancellationToken ct) { // Only applies to instances with an enabled BYOI config var byoiConfig = instance.ByoiConfigs.FirstOrDefault(b => b.Enabled); if (byoiConfig is null) { return Task.FromResult(new HealthCheckResult(HealthStatus.Healthy, "No BYOI config — check not applicable")); } // Only Pro customers have BYOI if (instance.Customer.Plan != CustomerPlan.Pro) { return Task.FromResult(new HealthCheckResult(HealthStatus.Healthy, "Non-Pro plan — BYOI check not applicable")); } var daysRemaining = (byoiConfig.CertExpiry - DateTime.UtcNow).TotalDays; if (daysRemaining <= 0) { return Task.FromResult(new HealthCheckResult(HealthStatus.Critical, $"BYOI certificate has EXPIRED (expired {Math.Abs((int)daysRemaining)} days ago)", "Customer must rotate their IdP certificate via the portal immediately")); } if (daysRemaining <= CriticalThresholdDays) { return Task.FromResult(new HealthCheckResult(HealthStatus.Critical, $"BYOI certificate expires in {(int)daysRemaining} days", "Urgent: customer must rotate their IdP certificate")); } // Check warning thresholds (60 and 30 days) foreach (var threshold in AlertThresholdDays) { if (threshold <= CriticalThresholdDays) continue; if (daysRemaining <= threshold) { return Task.FromResult(new HealthCheckResult(HealthStatus.Degraded, $"BYOI certificate expires in {(int)daysRemaining} days (threshold: {threshold}d)", "Customer should plan certificate rotation")); } } return Task.FromResult(new HealthCheckResult(HealthStatus.Healthy, $"BYOI certificate valid for {(int)daysRemaining} more days")); } }