@oneuptime/common 11.0.1 → 11.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/Alert.ts +110 -0
- package/Models/DatabaseModels/CephCluster.ts +964 -0
- package/Models/DatabaseModels/CephClusterLabelRule.ts +514 -0
- package/Models/DatabaseModels/CephClusterOwnerRule.ts +596 -0
- package/Models/DatabaseModels/CephClusterOwnerTeam.ts +487 -0
- package/Models/DatabaseModels/CephClusterOwnerUser.ts +486 -0
- package/Models/DatabaseModels/CephResource.ts +809 -0
- package/Models/DatabaseModels/Host.ts +64 -0
- package/Models/DatabaseModels/Incident.ts +110 -0
- package/Models/DatabaseModels/Index.ts +24 -0
- package/Models/DatabaseModels/ProxmoxCluster.ts +943 -0
- package/Models/DatabaseModels/ProxmoxClusterLabelRule.ts +514 -0
- package/Models/DatabaseModels/ProxmoxClusterOwnerRule.ts +596 -0
- package/Models/DatabaseModels/ProxmoxClusterOwnerTeam.ts +487 -0
- package/Models/DatabaseModels/ProxmoxClusterOwnerUser.ts +486 -0
- package/Models/DatabaseModels/ProxmoxResource.ts +726 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +110 -0
- package/Server/API/BillingInvoiceAPI.ts +47 -7
- package/Server/API/CephResourceAPI.ts +134 -0
- package/Server/API/DashboardAPI.ts +46 -0
- package/Server/API/ProjectAPI.ts +15 -0
- package/Server/API/ProxmoxResourceAPI.ts +132 -0
- package/Server/API/ResellerPlanAPI.ts +17 -0
- package/Server/Infrastructure/GlobalCache.ts +8 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781500000000-AddProxmoxAndCephClusterTables.ts +163 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781600000000-AddProxmoxCephV2Columns.ts +211 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781600000001-AddProxmoxCephActivityAndRules.ts +590 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781700000000-AddProxmoxCephV3Columns.ts +64 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Infrastructure/Redis.ts +40 -12
- package/Server/Services/AnalyticsDatabaseService.ts +1 -1
- package/Server/Services/BillingService.ts +109 -21
- package/Server/Services/CephClusterLabelRuleEngineService.ts +200 -0
- package/Server/Services/CephClusterLabelRuleService.ts +14 -0
- package/Server/Services/CephClusterOwnerRuleEngineService.ts +218 -0
- package/Server/Services/CephClusterOwnerRuleService.ts +14 -0
- package/Server/Services/CephClusterOwnerTeamService.ts +10 -0
- package/Server/Services/CephClusterOwnerUserService.ts +10 -0
- package/Server/Services/CephClusterService.ts +401 -0
- package/Server/Services/CephResourceService.ts +383 -0
- package/Server/Services/CloudResourceService.ts +11 -3
- package/Server/Services/DockerHostService.ts +11 -3
- package/Server/Services/ExceptionAggregationService.ts +2 -0
- package/Server/Services/HostService.ts +11 -3
- package/Server/Services/Index.ts +24 -0
- package/Server/Services/KubernetesClusterService.ts +11 -3
- package/Server/Services/LogAggregationService.ts +2 -0
- package/Server/Services/MetricAggregationService.ts +2 -0
- package/Server/Services/OpenTelemetryIngestService.ts +36 -0
- package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +204 -0
- package/Server/Services/ProxmoxClusterLabelRuleService.ts +14 -0
- package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +222 -0
- package/Server/Services/ProxmoxClusterOwnerRuleService.ts +14 -0
- package/Server/Services/ProxmoxClusterOwnerTeamService.ts +10 -0
- package/Server/Services/ProxmoxClusterOwnerUserService.ts +10 -0
- package/Server/Services/ProxmoxClusterService.ts +382 -0
- package/Server/Services/ProxmoxResourceService.ts +404 -0
- package/Server/Services/RumApplicationService.ts +11 -3
- package/Server/Services/ServerlessFunctionService.ts +11 -3
- package/Server/Services/TelemetryUsageBillingService.ts +41 -3
- package/Server/Services/TraceAggregationService.ts +2 -0
- package/Server/Types/AnalyticsDatabase/AggregateBy.ts +8 -23
- package/Server/Utils/Monitor/MonitorAlert.ts +45 -0
- package/Server/Utils/Monitor/MonitorClusterContext.ts +129 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +344 -4
- package/Server/Utils/Monitor/MonitorIncident.ts +130 -7
- package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +39 -6
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +3 -1
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +33 -0
- package/Server/Utils/Profiling.ts +37 -2
- package/Server/Utils/Telemetry/EntityRegistry.ts +4 -0
- package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +1096 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +85 -0
- package/Server/Utils/Telemetry.ts +8 -19
- package/Tests/Server/API/BillingInvoiceAPI.test.ts +194 -0
- package/Tests/Server/API/ProjectAPI.test.ts +91 -0
- package/Tests/Server/API/ResellerPlanAPI.test.ts +207 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +100 -0
- package/Tests/Server/Services/BillingService.test.ts +323 -0
- package/Tests/Server/Services/CephResourceService.test.ts +264 -0
- package/Tests/Server/Services/ProxmoxResourceService.test.ts +326 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +322 -0
- package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +13 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +879 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +196 -0
- package/Tests/Types/Monitor/CephAlertTemplates.test.ts +1231 -0
- package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +732 -0
- package/Tests/Utils/Telemetry/EntityRelationship.test.ts +49 -0
- package/Tests/Utils/Telemetry/HeartbeatAvailability.test.ts +423 -0
- package/Types/BaseDatabase/AggregationIntervalUtil.ts +74 -0
- package/Types/Dashboard/DashboardComponentType.ts +4 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +2 -0
- package/Types/Dashboard/DashboardComponents/DashboardCephOsdListComponent.ts +15 -0
- package/Types/Dashboard/DashboardComponents/DashboardCephPoolListComponent.ts +14 -0
- package/Types/Dashboard/DashboardComponents/DashboardProxmoxGuestListComponent.ts +17 -0
- package/Types/Dashboard/DashboardComponents/DashboardProxmoxNodeListComponent.ts +16 -0
- package/Types/Dashboard/DashboardTemplates.ts +446 -0
- package/Types/Icon/IconProp.ts +2 -0
- package/Types/Monitor/CephAlertTemplates.ts +1647 -0
- package/Types/Monitor/CephMetricCatalog.ts +409 -0
- package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +44 -0
- package/Types/Monitor/MonitorStep.ts +64 -0
- package/Types/Monitor/MonitorStepCephMonitor.ts +57 -0
- package/Types/Monitor/MonitorStepProxmoxMonitor.ts +81 -0
- package/Types/Monitor/MonitorType.ts +29 -1
- package/Types/Monitor/ProxmoxAlertTemplates.ts +899 -0
- package/Types/Monitor/ProxmoxMetricCatalog.ts +382 -0
- package/Types/Permission.ts +464 -0
- package/Types/Telemetry/EntityType.ts +11 -0
- package/Types/Telemetry/ServiceType.ts +2 -0
- package/UI/Components/Icon/Icon.tsx +84 -0
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +9 -5
- package/UI/Utils/Telemetry/Telemetry.ts +16 -21
- package/UI/Utils/TelemetryService.ts +7 -3
- package/Utils/Dashboard/Components/DashboardCephOsdListComponent.ts +63 -0
- package/Utils/Dashboard/Components/DashboardCephPoolListComponent.ts +32 -0
- package/Utils/Dashboard/Components/DashboardCephResourceListShared.ts +61 -0
- package/Utils/Dashboard/Components/DashboardProxmoxGuestListComponent.ts +69 -0
- package/Utils/Dashboard/Components/DashboardProxmoxNodeListComponent.ts +55 -0
- package/Utils/Dashboard/Components/DashboardProxmoxResourceListShared.ts +61 -0
- package/Utils/Dashboard/Components/Index.ts +28 -0
- package/Utils/Telemetry/EntityKey.ts +35 -0
- package/Utils/Telemetry/EntityRelationship.ts +6 -0
- package/Utils/Telemetry/HeartbeatAvailability.ts +262 -0
- package/build/dist/Models/DatabaseModels/Alert.js +108 -0
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js +992 -0
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -0
- package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js +522 -0
- package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js +603 -0
- package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/CephClusterOwnerTeam.js +503 -0
- package/build/dist/Models/DatabaseModels/CephClusterOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/CephClusterOwnerUser.js +502 -0
- package/build/dist/Models/DatabaseModels/CephClusterOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/CephResource.js +846 -0
- package/build/dist/Models/DatabaseModels/CephResource.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Host.js +63 -0
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +108 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +24 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +967 -0
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js +522 -0
- package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js +603 -0
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerTeam.js +503 -0
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerUser.js +502 -0
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js +761 -0
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +108 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/API/BillingInvoiceAPI.js +35 -5
- package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
- package/build/dist/Server/API/CephResourceAPI.js +98 -0
- package/build/dist/Server/API/CephResourceAPI.js.map +1 -0
- package/build/dist/Server/API/DashboardAPI.js +46 -0
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +11 -0
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/ProxmoxResourceAPI.js +95 -0
- package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -0
- package/build/dist/Server/API/ResellerPlanAPI.js +17 -3
- package/build/dist/Server/API/ResellerPlanAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +7 -2
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781500000000-AddProxmoxAndCephClusterTables.js +76 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781500000000-AddProxmoxAndCephClusterTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781600000000-AddProxmoxCephV2Columns.js +108 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781600000000-AddProxmoxCephV2Columns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781600000001-AddProxmoxCephActivityAndRules.js +253 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781600000001-AddProxmoxCephActivityAndRules.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781700000000-AddProxmoxCephV3Columns.js +43 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781700000000-AddProxmoxCephV3Columns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Redis.js +31 -8
- package/build/dist/Server/Infrastructure/Redis.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +85 -23
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +166 -0
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/CephClusterLabelRuleService.js +13 -0
- package/build/dist/Server/Services/CephClusterLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +186 -0
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/CephClusterOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/CephClusterOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/CephClusterOwnerTeamService.js +9 -0
- package/build/dist/Server/Services/CephClusterOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/CephClusterOwnerUserService.js +9 -0
- package/build/dist/Server/Services/CephClusterOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/CephClusterService.js +353 -0
- package/build/dist/Server/Services/CephClusterService.js.map +1 -0
- package/build/dist/Server/Services/CephResourceService.js +257 -0
- package/build/dist/Server/Services/CephResourceService.js.map +1 -0
- package/build/dist/Server/Services/CloudResourceService.js +10 -2
- package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +10 -2
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/ExceptionAggregationService.js +2 -0
- package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +10 -2
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +24 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +10 -2
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +2 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +2 -0
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +37 -7
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +166 -0
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleService.js +13 -0
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +186 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerTeamService.js +9 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerUserService.js +9 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/ProxmoxClusterService.js +337 -0
- package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -0
- package/build/dist/Server/Services/ProxmoxResourceService.js +285 -0
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -0
- package/build/dist/Server/Services/RumApplicationService.js +10 -2
- package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionService.js +10 -2
- package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +30 -3
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +2 -0
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +8 -25
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +36 -0
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +90 -0
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +228 -4
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +103 -8
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +23 -6
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +3 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +23 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
- package/build/dist/Server/Utils/Profiling.js +24 -3
- package/build/dist/Server/Utils/Profiling.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +4 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +854 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +62 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +8 -10
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +69 -0
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js +4 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardCephOsdListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardCephOsdListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardCephPoolListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardCephPoolListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardProxmoxGuestListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardProxmoxGuestListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardProxmoxNodeListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardProxmoxNodeListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +394 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Icon/IconProp.js +2 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/Monitor/CephAlertTemplates.js +1379 -0
- package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -0
- package/build/dist/Types/Monitor/CephMetricCatalog.js +353 -0
- package/build/dist/Types/Monitor/CephMetricCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorStep.js +46 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepCephMonitor.js +34 -0
- package/build/dist/Types/Monitor/MonitorStepCephMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorStepProxmoxMonitor.js +36 -0
- package/build/dist/Types/Monitor/MonitorStepProxmoxMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorType.js +27 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +743 -0
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -0
- package/build/dist/Types/Monitor/ProxmoxMetricCatalog.js +320 -0
- package/build/dist/Types/Monitor/ProxmoxMetricCatalog.js.map +1 -0
- package/build/dist/Types/Permission.js +408 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityType.js +11 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/ServiceType.js +2 -0
- package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +33 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +5 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Utils/Telemetry/Telemetry.js +11 -10
- package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/UI/Utils/TelemetryService.js +5 -2
- package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardCephOsdListComponent.js +50 -0
- package/build/dist/Utils/Dashboard/Components/DashboardCephOsdListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardCephPoolListComponent.js +27 -0
- package/build/dist/Utils/Dashboard/Components/DashboardCephPoolListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardCephResourceListShared.js +46 -0
- package/build/dist/Utils/Dashboard/Components/DashboardCephResourceListShared.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardProxmoxGuestListComponent.js +55 -0
- package/build/dist/Utils/Dashboard/Components/DashboardProxmoxGuestListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardProxmoxNodeListComponent.js +42 -0
- package/build/dist/Utils/Dashboard/Components/DashboardProxmoxNodeListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardProxmoxResourceListShared.js +46 -0
- package/build/dist/Utils/Dashboard/Components/DashboardProxmoxResourceListShared.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityKey.js +27 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityRelationship.js +3 -0
- package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
- package/build/dist/Utils/Telemetry/HeartbeatAvailability.js +174 -0
- package/build/dist/Utils/Telemetry/HeartbeatAvailability.js.map +1 -0
- package/package.json +29 -21
package/Server/Infrastructure/Postgres/SchemaMigrations/1781700000000-AddProxmoxCephV3Columns.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Proxmox + Ceph V3 (Internal/Roadmap/ProxmoxCephProductsV3.md):
|
|
5
|
+
*
|
|
6
|
+
* 1. WI-24 backup coverage — ProxmoxCluster.guestsWithoutBackupCount
|
|
7
|
+
* (written from pve_not_backed_up_total on the WI-3 extras path) and
|
|
8
|
+
* ProxmoxResource.isBackedUp (per-guest flag derived from
|
|
9
|
+
* pve_not_backed_up_info presence: an info series carrying the
|
|
10
|
+
* guest's id means NOT covered by any backup job). Both nullable —
|
|
11
|
+
* NULL means the exporter's cluster-level backup-info collector has
|
|
12
|
+
* not reported, which is distinct from "0 uncovered guests".
|
|
13
|
+
*
|
|
14
|
+
* 2. WI-28 hyperconverged cross-link — nullable
|
|
15
|
+
* ProxmoxCluster.cephClusterId FK (SET NULL on delete), manually
|
|
16
|
+
* linked via the cluster's Settings page. No auto-link heuristic:
|
|
17
|
+
* pve-exporter exposes no fsid, so there is no honest join signal
|
|
18
|
+
* (contrast WI-17's Host link, which had name equality). Mirrors
|
|
19
|
+
* Host.proxmoxClusterId: SET NULL, no index.
|
|
20
|
+
*
|
|
21
|
+
* Columns/FKs are derived from the model decorators in
|
|
22
|
+
* Common/Models/DatabaseModels/{ProxmoxCluster,ProxmoxResource}.ts.
|
|
23
|
+
*/
|
|
24
|
+
export class AddProxmoxCephV3Columns1781700000000
|
|
25
|
+
implements MigrationInterface
|
|
26
|
+
{
|
|
27
|
+
public name = "AddProxmoxCephV3Columns1781700000000";
|
|
28
|
+
|
|
29
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
30
|
+
// WI-24: backup coverage snapshot columns.
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "ProxmoxCluster" ADD "guestsWithoutBackupCount" integer`,
|
|
33
|
+
);
|
|
34
|
+
await queryRunner.query(
|
|
35
|
+
`ALTER TABLE "ProxmoxResource" ADD "isBackedUp" boolean`,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
// WI-28: ProxmoxCluster -> CephCluster cross-link (manual only).
|
|
39
|
+
await queryRunner.query(
|
|
40
|
+
`ALTER TABLE "ProxmoxCluster" ADD "cephClusterId" uuid`,
|
|
41
|
+
);
|
|
42
|
+
await queryRunner.query(
|
|
43
|
+
`ALTER TABLE "ProxmoxCluster" ADD CONSTRAINT "FK_proxmox_cluster_cephClusterId" FOREIGN KEY ("cephClusterId") REFERENCES "CephCluster"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
48
|
+
// WI-28: Ceph cross-link.
|
|
49
|
+
await queryRunner.query(
|
|
50
|
+
`ALTER TABLE "ProxmoxCluster" DROP CONSTRAINT "FK_proxmox_cluster_cephClusterId"`,
|
|
51
|
+
);
|
|
52
|
+
await queryRunner.query(
|
|
53
|
+
`ALTER TABLE "ProxmoxCluster" DROP COLUMN "cephClusterId"`,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// WI-24: backup coverage snapshot columns.
|
|
57
|
+
await queryRunner.query(
|
|
58
|
+
`ALTER TABLE "ProxmoxResource" DROP COLUMN "isBackedUp"`,
|
|
59
|
+
);
|
|
60
|
+
await queryRunner.query(
|
|
61
|
+
`ALTER TABLE "ProxmoxCluster" DROP COLUMN "guestsWithoutBackupCount"`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -385,6 +385,10 @@ import { AddTelemetryEntityRelationshipTable1781200000001 } from "./178120000000
|
|
|
385
385
|
import { MigrationName1781250074195 } from "./1781250074195-MigrationName";
|
|
386
386
|
import { AddTelemetryEntityLabels1781300000000 } from "./1781300000000-AddTelemetryEntityLabels";
|
|
387
387
|
import { AddServiceTelemetrySdkLanguage1781400000000 } from "./1781400000000-AddServiceTelemetrySdkLanguage";
|
|
388
|
+
import { AddProxmoxAndCephClusterTables1781500000000 } from "./1781500000000-AddProxmoxAndCephClusterTables";
|
|
389
|
+
import { AddProxmoxCephV2Columns1781600000000 } from "./1781600000000-AddProxmoxCephV2Columns";
|
|
390
|
+
import { AddProxmoxCephActivityAndRules1781600000001 } from "./1781600000001-AddProxmoxCephActivityAndRules";
|
|
391
|
+
import { AddProxmoxCephV3Columns1781700000000 } from "./1781700000000-AddProxmoxCephV3Columns";
|
|
388
392
|
|
|
389
393
|
export default [
|
|
390
394
|
InitialMigration,
|
|
@@ -774,4 +778,8 @@ export default [
|
|
|
774
778
|
AddTelemetryEntityLabels1781300000000,
|
|
775
779
|
AddServiceTelemetrySdkLanguage1781400000000,
|
|
776
780
|
MigrationName1781250074195,
|
|
781
|
+
AddProxmoxAndCephClusterTables1781500000000,
|
|
782
|
+
AddProxmoxCephV2Columns1781600000000,
|
|
783
|
+
AddProxmoxCephActivityAndRules1781600000001,
|
|
784
|
+
AddProxmoxCephV3Columns1781700000000,
|
|
777
785
|
];
|
|
@@ -100,22 +100,50 @@ export default abstract class Redis {
|
|
|
100
100
|
const connectToDatabase: ConnectToDatabaseFunction = async (
|
|
101
101
|
client: RedisClient,
|
|
102
102
|
): Promise<void> => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
logger.debug(
|
|
108
|
-
"Cannot connect to Redis. Retrying again in 5 seconds",
|
|
109
|
-
);
|
|
110
|
-
// sleep for 5 seconds.
|
|
103
|
+
// A previous attempt (or ioredis' background reconnect) already succeeded.
|
|
104
|
+
if (client.status === "ready") {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
111
107
|
|
|
112
|
-
|
|
108
|
+
/*
|
|
109
|
+
* The client is created with lazyConnect, so it starts in the "wait" state
|
|
110
|
+
* and only opens when we call connect(). If the first attempt fails, ioredis
|
|
111
|
+
* begins auto-reconnecting in the background (status "connecting" /
|
|
112
|
+
* "reconnecting"), and calling connect() again in that state throws
|
|
113
|
+
* "Redis is already connecting/connected" — which previously propagated out
|
|
114
|
+
* of init() and crashlooped the process. So only issue connect() when the
|
|
115
|
+
* client is idle; when a (re)connect is already in flight, skip the call and
|
|
116
|
+
* wait for it to settle on the next iteration.
|
|
117
|
+
*/
|
|
118
|
+
const isIdle: boolean =
|
|
119
|
+
client.status === "wait" ||
|
|
120
|
+
client.status === "end" ||
|
|
121
|
+
client.status === "close";
|
|
113
122
|
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
try {
|
|
124
|
+
if (isIdle) {
|
|
125
|
+
await client.connect();
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
} catch (err) {
|
|
129
|
+
if (retry >= 3) {
|
|
130
|
+
throw err;
|
|
116
131
|
}
|
|
117
|
-
throw err;
|
|
118
132
|
}
|
|
133
|
+
|
|
134
|
+
if (retry >= 3) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
`Unable to connect to Redis at ${RedisHostname}:${RedisPort.toNumber()} (status: ${client.status})`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
logger.debug("Cannot connect to Redis. Retrying again in 5 seconds");
|
|
141
|
+
// sleep for 5 seconds.
|
|
142
|
+
|
|
143
|
+
await Sleep.sleep(5000);
|
|
144
|
+
|
|
145
|
+
retry++;
|
|
146
|
+
return await connectToDatabase(client);
|
|
119
147
|
};
|
|
120
148
|
|
|
121
149
|
await connectToDatabase(this.client);
|
|
@@ -793,14 +793,35 @@ export class BillingService extends BaseService {
|
|
|
793
793
|
const customer: Stripe.Response<Stripe.Customer | Stripe.DeletedCustomer> =
|
|
794
794
|
await this.stripe.customers.retrieve(customerId);
|
|
795
795
|
|
|
796
|
-
|
|
796
|
+
const defaultPaymentMethod:
|
|
797
|
+
| string
|
|
798
|
+
| Stripe.PaymentMethod
|
|
799
|
+
| null
|
|
800
|
+
| undefined = (customer as Stripe.Customer).invoice_settings
|
|
801
|
+
?.default_payment_method;
|
|
802
|
+
|
|
803
|
+
const defaultPaymentMethodId: string | undefined =
|
|
804
|
+
typeof defaultPaymentMethod === "string"
|
|
805
|
+
? defaultPaymentMethod
|
|
806
|
+
: defaultPaymentMethod?.id;
|
|
807
|
+
|
|
808
|
+
if (defaultPaymentMethodId) {
|
|
809
|
+
for (const paymentMethod of paymentMethods) {
|
|
810
|
+
paymentMethod.isDefault = paymentMethod.id === defaultPaymentMethodId;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// default payment method first — it's charged first when paying invoices.
|
|
814
|
+
paymentMethods.sort((a: PaymentMethod, b: PaymentMethod) => {
|
|
815
|
+
return Number(b.isDefault) - Number(a.isDefault);
|
|
816
|
+
});
|
|
817
|
+
} else if (
|
|
797
818
|
(customer as Stripe.Customer).invoice_settings &&
|
|
798
|
-
|
|
819
|
+
paymentMethods.length > 0 &&
|
|
820
|
+
paymentMethods[0]?.id
|
|
799
821
|
) {
|
|
800
822
|
// set the first payment method as default.
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
}
|
|
823
|
+
await this.setDefaultPaymentMethod(customerId, paymentMethods[0].id);
|
|
824
|
+
paymentMethods[0].isDefault = true;
|
|
804
825
|
}
|
|
805
826
|
|
|
806
827
|
return paymentMethods;
|
|
@@ -1237,6 +1258,41 @@ export class BillingService extends BaseService {
|
|
|
1237
1258
|
return invoice;
|
|
1238
1259
|
}
|
|
1239
1260
|
|
|
1261
|
+
/*
|
|
1262
|
+
* Returns true if the error is attributable to the payment method itself
|
|
1263
|
+
* (declined, expired, unusable), meaning paying with a different payment
|
|
1264
|
+
* method may succeed.
|
|
1265
|
+
*
|
|
1266
|
+
* Not retryable:
|
|
1267
|
+
* - invoice_payment_intent_requires_action (3DS/SCA): the payment method
|
|
1268
|
+
* works but needs customer authentication — throw so the interactive
|
|
1269
|
+
* flow (BillingInvoiceAPI) surfaces the authentication prompt for the
|
|
1270
|
+
* default method instead of silently charging a backup method.
|
|
1271
|
+
* - Invoice-state or connectivity errors: another payment method would
|
|
1272
|
+
* not help, and if the outcome of the attempt is unknown a retry could
|
|
1273
|
+
* double-charge the customer.
|
|
1274
|
+
*
|
|
1275
|
+
* Note: most bank debit (ACH/SEPA/BACS) failures are asynchronous — the
|
|
1276
|
+
* pay call succeeds and the failure arrives days later via webhook — so
|
|
1277
|
+
* failover only catches the synchronous ones (unverified/unusable
|
|
1278
|
+
* accounts).
|
|
1279
|
+
*/
|
|
1280
|
+
private canRetryWithDifferentPaymentMethod(err: unknown): boolean {
|
|
1281
|
+
const stripeError: { type?: string; code?: string } = err as {
|
|
1282
|
+
type?: string;
|
|
1283
|
+
code?: string;
|
|
1284
|
+
};
|
|
1285
|
+
|
|
1286
|
+
if (stripeError?.type === "StripeCardError") {
|
|
1287
|
+
return true;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
return Boolean(
|
|
1291
|
+
stripeError?.code?.startsWith("payment_method_") ||
|
|
1292
|
+
stripeError?.code?.startsWith("bank_account_"),
|
|
1293
|
+
);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1240
1296
|
@CaptureSpan()
|
|
1241
1297
|
public async payInvoice(
|
|
1242
1298
|
customerId: string,
|
|
@@ -1250,23 +1306,55 @@ export class BillingService extends BaseService {
|
|
|
1250
1306
|
throw new BadDataException(Errors.BillingService.NO_PAYMENTS_METHODS);
|
|
1251
1307
|
}
|
|
1252
1308
|
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1309
|
+
/*
|
|
1310
|
+
* getPaymentMethods returns the default payment method first. If it is
|
|
1311
|
+
* declined, fall back to the customer's other payment methods before
|
|
1312
|
+
* giving up. Attempts are capped to bound decline traffic on unattended
|
|
1313
|
+
* retry paths (e.g. recharge-on-low-balance), which create a fresh
|
|
1314
|
+
* invoice and retry on every cycle.
|
|
1315
|
+
*/
|
|
1316
|
+
const maxPaymentMethodsToTry: number = 3;
|
|
1317
|
+
let lastError: unknown = null;
|
|
1256
1318
|
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1319
|
+
for (const paymentMethod of paymentMethods.slice(
|
|
1320
|
+
0,
|
|
1321
|
+
maxPaymentMethodsToTry,
|
|
1322
|
+
)) {
|
|
1323
|
+
try {
|
|
1324
|
+
const invoice: Stripe.Invoice = await this.stripe.invoices.pay(
|
|
1325
|
+
invoiceId,
|
|
1326
|
+
{
|
|
1327
|
+
payment_method: paymentMethod.id,
|
|
1328
|
+
},
|
|
1329
|
+
);
|
|
1330
|
+
|
|
1331
|
+
return {
|
|
1332
|
+
id: invoice.id!,
|
|
1333
|
+
amount: invoice.amount_due,
|
|
1334
|
+
currencyCode: invoice.currency,
|
|
1335
|
+
subscriptionId: invoice.subscription?.toString() || undefined,
|
|
1336
|
+
status: invoice.status?.toString() || "Unknown",
|
|
1337
|
+
downloadableLink: invoice.invoice_pdf?.toString() || "",
|
|
1338
|
+
customerId: invoice.customer?.toString() || "",
|
|
1339
|
+
invoiceDate: invoice.created
|
|
1340
|
+
? new Date(invoice.created * 1000)
|
|
1341
|
+
: OneUptimeDate.getCurrentDate(),
|
|
1342
|
+
invoiceNumber: invoice.number || undefined,
|
|
1343
|
+
};
|
|
1344
|
+
} catch (err) {
|
|
1345
|
+
logger.error(
|
|
1346
|
+
`Failed to pay invoice ${invoiceId} with payment method ${paymentMethod.type} ending in ${paymentMethod.last4Digits}: ${err}`,
|
|
1347
|
+
);
|
|
1348
|
+
|
|
1349
|
+
if (!this.canRetryWithDifferentPaymentMethod(err)) {
|
|
1350
|
+
throw err;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
lastError = err;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
throw lastError;
|
|
1270
1358
|
}
|
|
1271
1359
|
|
|
1272
1360
|
public getMeteredPlanPriceId(productType: ProductType): string {
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import Label from "../../Models/DatabaseModels/Label";
|
|
2
|
+
import CephCluster from "../../Models/DatabaseModels/CephCluster";
|
|
3
|
+
import CephClusterLabelRule from "../../Models/DatabaseModels/CephClusterLabelRule";
|
|
4
|
+
import CephClusterLabelRuleService from "./CephClusterLabelRuleService";
|
|
5
|
+
import CephClusterService from "./CephClusterService";
|
|
6
|
+
import ObjectID from "../../Types/ObjectID";
|
|
7
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
8
|
+
import logger, { LogAttributes } from "../Utils/Logger";
|
|
9
|
+
|
|
10
|
+
class CephClusterLabelRuleEngineServiceClass {
|
|
11
|
+
/**
|
|
12
|
+
* Evaluates CephClusterLabelRule rows for the given Ceph cluster and attaches matched
|
|
13
|
+
* labels to it. The union is deduped against labels already on the Ceph cluster
|
|
14
|
+
* before insert to avoid PK conflicts on the join table.
|
|
15
|
+
*/
|
|
16
|
+
@CaptureSpan()
|
|
17
|
+
public async applyRulesToCephCluster(
|
|
18
|
+
cephCluster: CephCluster,
|
|
19
|
+
): Promise<void> {
|
|
20
|
+
if (!cephCluster.id || !cephCluster.projectId) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const rules: Array<CephClusterLabelRule> =
|
|
26
|
+
await CephClusterLabelRuleService.findBy({
|
|
27
|
+
query: {
|
|
28
|
+
projectId: cephCluster.projectId,
|
|
29
|
+
isEnabled: true,
|
|
30
|
+
},
|
|
31
|
+
props: { isRoot: true },
|
|
32
|
+
select: {
|
|
33
|
+
_id: true,
|
|
34
|
+
name: true,
|
|
35
|
+
cephClusterLabels: { _id: true },
|
|
36
|
+
cephClusterNamePattern: true,
|
|
37
|
+
cephClusterDescriptionPattern: true,
|
|
38
|
+
labelsToAdd: { _id: true },
|
|
39
|
+
},
|
|
40
|
+
limit: 100,
|
|
41
|
+
skip: 0,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
if (rules.length === 0) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const cephClusterWithDetails: CephCluster | null =
|
|
49
|
+
await CephClusterService.findOneById({
|
|
50
|
+
id: cephCluster.id,
|
|
51
|
+
select: {
|
|
52
|
+
name: true,
|
|
53
|
+
description: true,
|
|
54
|
+
labels: { _id: true },
|
|
55
|
+
},
|
|
56
|
+
props: { isRoot: true },
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (!cephClusterWithDetails) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const labelIdsToAdd: Set<string> = new Set();
|
|
64
|
+
|
|
65
|
+
for (const rule of rules) {
|
|
66
|
+
const matches: boolean = this.doesCephClusterMatchRule(
|
|
67
|
+
cephClusterWithDetails,
|
|
68
|
+
rule,
|
|
69
|
+
);
|
|
70
|
+
if (!matches) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
for (const label of rule.labelsToAdd || []) {
|
|
74
|
+
if (label.id) {
|
|
75
|
+
labelIdsToAdd.add(label.id.toString());
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (labelIdsToAdd.size === 0) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const existingLabelIds: Set<string> = new Set(
|
|
85
|
+
(cephClusterWithDetails.labels || [])
|
|
86
|
+
.map((l: Label) => {
|
|
87
|
+
return l.id?.toString() || "";
|
|
88
|
+
})
|
|
89
|
+
.filter((id: string) => {
|
|
90
|
+
return id !== "";
|
|
91
|
+
}),
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const newLabelIds: Array<string> = Array.from(labelIdsToAdd).filter(
|
|
95
|
+
(id: string) => {
|
|
96
|
+
return !existingLabelIds.has(id);
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
if (newLabelIds.length === 0) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
await CephClusterService.getRepository()
|
|
104
|
+
.createQueryBuilder()
|
|
105
|
+
.relation(CephCluster, "labels")
|
|
106
|
+
.of(cephCluster.id.toString())
|
|
107
|
+
.add(newLabelIds);
|
|
108
|
+
|
|
109
|
+
/*
|
|
110
|
+
* Sync in-memory cephCluster.labels so a downstream owner-rule engine in
|
|
111
|
+
* the same onCreateSuccess chain can match on rule-added labels.
|
|
112
|
+
*/
|
|
113
|
+
const mergedLabelIds: Set<string> = new Set([
|
|
114
|
+
...existingLabelIds,
|
|
115
|
+
...newLabelIds,
|
|
116
|
+
]);
|
|
117
|
+
cephCluster.labels = Array.from(mergedLabelIds).map((id: string) => {
|
|
118
|
+
const label: Label = new Label();
|
|
119
|
+
label.id = new ObjectID(id);
|
|
120
|
+
return label;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
logger.debug(
|
|
124
|
+
`CephClusterLabelRuleEngine attached ${newLabelIds.length} labels to Ceph cluster ${cephCluster.id}`,
|
|
125
|
+
{ projectId: cephCluster.projectId.toString() } as LogAttributes,
|
|
126
|
+
);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
logger.error(`Error applying Ceph cluster label rules: ${error}`, {
|
|
129
|
+
projectId: cephCluster.projectId?.toString(),
|
|
130
|
+
cephClusterId: cephCluster.id?.toString(),
|
|
131
|
+
} as LogAttributes);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private doesCephClusterMatchRule(
|
|
136
|
+
cephCluster: CephCluster,
|
|
137
|
+
rule: CephClusterLabelRule,
|
|
138
|
+
): boolean {
|
|
139
|
+
if (rule.cephClusterLabels && rule.cephClusterLabels.length > 0) {
|
|
140
|
+
if (!cephCluster.labels || cephCluster.labels.length === 0) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const ruleLabelIds: Array<string> = rule.cephClusterLabels.map(
|
|
144
|
+
(l: Label) => {
|
|
145
|
+
return l.id?.toString() || "";
|
|
146
|
+
},
|
|
147
|
+
);
|
|
148
|
+
const labelIds: Array<string> = cephCluster.labels.map((l: Label) => {
|
|
149
|
+
return l.id?.toString() || "";
|
|
150
|
+
});
|
|
151
|
+
if (
|
|
152
|
+
!ruleLabelIds.some((id: string) => {
|
|
153
|
+
return labelIds.includes(id);
|
|
154
|
+
})
|
|
155
|
+
) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (
|
|
161
|
+
rule.cephClusterNamePattern &&
|
|
162
|
+
(!cephCluster.name ||
|
|
163
|
+
!this.testRegex(rule.cephClusterNamePattern, cephCluster.name, rule))
|
|
164
|
+
) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (
|
|
169
|
+
rule.cephClusterDescriptionPattern &&
|
|
170
|
+
(!cephCluster.description ||
|
|
171
|
+
!this.testRegex(
|
|
172
|
+
rule.cephClusterDescriptionPattern,
|
|
173
|
+
cephCluster.description,
|
|
174
|
+
rule,
|
|
175
|
+
))
|
|
176
|
+
) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
private testRegex(
|
|
184
|
+
pattern: string,
|
|
185
|
+
value: string,
|
|
186
|
+
rule: CephClusterLabelRule,
|
|
187
|
+
): boolean {
|
|
188
|
+
try {
|
|
189
|
+
const regex: RegExp = new RegExp(pattern, "i");
|
|
190
|
+
return regex.test(value);
|
|
191
|
+
} catch {
|
|
192
|
+
logger.warn(
|
|
193
|
+
`Invalid regex in Ceph cluster label rule ${rule.id}: ${pattern}`,
|
|
194
|
+
);
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export default new CephClusterLabelRuleEngineServiceClass();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import DatabaseService from "./DatabaseService";
|
|
2
|
+
import Model from "../../Models/DatabaseModels/CephClusterLabelRule";
|
|
3
|
+
import { IsBillingEnabled } from "../EnvironmentConfig";
|
|
4
|
+
|
|
5
|
+
export class Service extends DatabaseService<Model> {
|
|
6
|
+
public constructor() {
|
|
7
|
+
super(Model);
|
|
8
|
+
if (IsBillingEnabled) {
|
|
9
|
+
this.hardDeleteItemsOlderThanInDays("createdAt", 3 * 365);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default new Service();
|