@oneuptime/common 11.7.3 → 11.7.4
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/AlertEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
- package/Models/DatabaseModels/Index.ts +5 -0
- package/Models/DatabaseModels/LogDropFilter.ts +89 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +13 -3
- package/Models/DatabaseModels/RecommendationDismissal.ts +463 -0
- package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
- package/Models/DatabaseModels/StatusPageGroup.ts +95 -0
- package/Models/DatabaseModels/TraceDropFilter.ts +89 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +5 -1
- package/Server/API/AlertAPI.ts +32 -17
- package/Server/API/BaseAPI.ts +31 -2
- package/Server/API/BaseAnalyticsAPI.ts +36 -2
- package/Server/API/CommonAPI.ts +57 -0
- package/Server/API/IncidentAPI.ts +60 -33
- package/Server/API/IncidentEpisodeAPI.ts +31 -16
- package/Server/API/MonitorAPI.ts +30 -0
- package/Server/API/MonitorTemplateAPI.ts +8 -0
- package/Server/API/ProbeAPI.ts +196 -15
- package/Server/API/ProjectAPI.ts +79 -1
- package/Server/API/ScheduledMaintenanceAPI.ts +33 -18
- package/Server/API/StatusPageAPI.ts +74 -37
- package/Server/API/WorkspaceNotificationRuleAPI.ts +34 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.ts +527 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.ts +53 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Services/AlertEpisodeService.ts +47 -0
- package/Server/Services/AlertService.ts +125 -0
- package/Server/Services/BillingService.ts +98 -0
- package/Server/Services/DatabaseService.ts +184 -20
- package/Server/Services/IncidentEpisodeService.ts +47 -0
- package/Server/Services/IncidentService.ts +123 -0
- package/Server/Services/IncidentTemplateService.ts +123 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/LogDropFilterService.ts +133 -0
- package/Server/Services/MonitorProbeService.ts +94 -4
- package/Server/Services/MonitorService.ts +48 -43
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +70 -0
- package/Server/Services/ProbeService.ts +66 -0
- package/Server/Services/ProjectService.ts +131 -7
- package/Server/Services/RecommendationDismissalService.ts +52 -0
- package/Server/Services/RunbookAgentJobService.ts +68 -7
- package/Server/Services/ScheduledMaintenanceService.ts +103 -0
- package/Server/Services/ScheduledMaintenanceTemplateService.ts +90 -0
- package/Server/Services/StatusPageGroupService.ts +186 -0
- package/Server/Services/TraceDropFilterService.ts +133 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +12 -0
- package/Server/Types/Workflow/Components/API/Get.ts +12 -0
- package/Server/Types/Workflow/Components/API/Patch.ts +12 -0
- package/Server/Types/Workflow/Components/API/Post.ts +12 -0
- package/Server/Types/Workflow/Components/API/Put.ts +13 -0
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +212 -0
- package/Server/Utils/DropFilterValidation.ts +127 -0
- package/Server/Utils/Errors.ts +5 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +31 -2
- package/Server/Utils/Telemetry/AppMetrics.ts +31 -0
- package/Tests/Models/DatabaseModels/MonitorProbeColumnAccessControl.test.ts +196 -0
- package/Tests/Models/RecommendationDismissalModel.test.ts +269 -0
- package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +320 -0
- package/Tests/Server/API/BaseAnalyticsAPIUpdatePayloadValidation.test.ts +293 -0
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +164 -0
- package/Tests/Server/API/ProbeAPI.test.ts +422 -53
- package/Tests/Server/API/ProjectAPI.test.ts +180 -0
- package/Tests/Server/API/ProjectAPIExtendTrialBillingDisabled.test.ts +138 -0
- package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +458 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +359 -0
- package/Tests/Server/Infrastructure/ProcessSignalDelivery.test.ts +427 -0
- package/Tests/Server/Services/BillingServiceExtendTrial.test.ts +439 -0
- package/Tests/Server/Services/CrossProjectReferenceWriteGuard.test.ts +810 -0
- package/Tests/Server/Services/DatabaseServiceAtomicAddToColumns.test.ts +269 -0
- package/Tests/Server/Services/DatabaseServiceEmptyUpdate.test.ts +277 -0
- package/Tests/Server/Services/DatabaseServiceSortColumnSelect.test.ts +201 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +81 -23
- package/Tests/Server/Services/DropFilterSaveValidation.test.ts +398 -0
- package/Tests/Server/Services/MonitorProbeDeleteHooks.test.ts +280 -0
- package/Tests/Server/Services/MonitorProbeServiceProbeTenancy.test.ts +304 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +262 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +614 -0
- package/Tests/Server/Services/RecommendationDismissalService.test.ts +306 -0
- package/Tests/Server/Services/RepairCrossProjectIncidentReferencesMigration.test.ts +528 -0
- package/Tests/Server/Services/StatusPageGroupNesting.test.ts +395 -0
- package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +26 -21
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +227 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +285 -0
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +463 -0
- package/Tests/Server/Utils/DropFilterValidation.test.ts +269 -0
- package/Tests/Server/Utils/Telemetry/SpanUtil.test.ts +94 -0
- package/Tests/Types/DateUserTimezone.test.ts +52 -0
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +177 -9
- package/Tests/Types/Monitor/MonitorStepDnsMonitor.test.ts +105 -0
- package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +131 -0
- package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +60 -0
- package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +82 -0
- package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +268 -0
- package/Tests/Types/Monitor/MonitorStepMetricMonitor.test.ts +386 -0
- package/Tests/Types/Monitor/MonitorStepProfileMonitor.test.ts +185 -0
- package/Tests/Types/Monitor/MonitorStepSnmpMonitor.test.ts +156 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +371 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +901 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +607 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +754 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +960 -0
- package/Tests/Types/RollingTime/RollingTimeUtil.test.ts +186 -0
- package/Tests/Types/Runbook/RunbookStepTimeout.test.ts +410 -0
- package/Tests/Types/Telemetry/DropFilterSampling.test.ts +241 -0
- package/Tests/Types/Workspace/NotificationRuleConditionUtil.test.ts +353 -0
- package/Tests/Types/Workspace/NotificationRuleUtil.test.ts +566 -0
- package/Tests/UI/Components/CodeEditor.test.tsx +174 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +555 -24
- package/Tests/UI/Components/InfoCard.test.tsx +358 -0
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +138 -0
- package/Tests/UI/Components/Modal.test.tsx +43 -5
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
- package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +427 -0
- package/Tests/UI/Components/Runbook/StepTimeoutInput.test.tsx +386 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +671 -0
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +404 -0
- package/Tests/UI/Utils/DropdownAlignment.test.ts +306 -0
- package/Tests/UI/Utils/TableFilterUrlState.test.ts +292 -0
- package/Tests/Utils/Monitor/MonitorSummaryProbeUtil.test.ts +263 -0
- package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +583 -0
- package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +1072 -0
- package/Tests/Utils/StatusPage/GroupTree.test.ts +583 -0
- package/Tests/Utils/StatusPage/ResourceUptime.test.ts +411 -0
- package/Types/Date.ts +15 -6
- package/Types/Monitor/KubernetesAlertTemplates.ts +205 -0
- package/Types/Monitor/MonitorStep.ts +10 -1
- package/Types/Monitor/MonitorStepMetricMonitor.ts +46 -1
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +413 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +168 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +175 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +743 -0
- package/Types/Permission.ts +45 -0
- package/Types/Recommendation/RecommendationType.ts +20 -0
- package/Types/Runbook/RunbookExecutionDeadline.ts +129 -0
- package/Types/Runbook/RunbookStepTimeout.ts +202 -0
- package/Types/Telemetry/DropFilterSampling.ts +92 -0
- package/UI/Components/AI/GenerateFromAIModal.tsx +0 -2
- package/UI/Components/Accordion/Accordion.tsx +10 -2
- package/UI/Components/BulkUpdate/BulkLabelActions.tsx +0 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +34 -20
- package/UI/Components/Date/RangeStartAndEndDateView.tsx +0 -1
- package/UI/Components/EditionLabel/EditionLabel.tsx +1 -27
- package/UI/Components/Error/PageError.tsx +0 -4
- package/UI/Components/ErrorBoundary.tsx +252 -15
- package/UI/Components/InfoCard/InfoCard.tsx +58 -1
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +34 -1
- package/UI/Components/Modal/Modal.tsx +16 -60
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
- package/UI/Components/ModelTable/BaseModelTable.tsx +116 -67
- package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +150 -47
- package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +34 -1
- package/UI/Utils/DropdownAlignment.ts +162 -0
- package/UI/Utils/TableFilterUrlState.ts +59 -20
- package/Utils/API.ts +106 -2
- package/Utils/Monitor/MonitorSummaryProbeUtil.ts +130 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +434 -0
- package/Utils/StatusPage/GroupNestingLayout.ts +343 -0
- package/Utils/StatusPage/GroupTree.ts +307 -0
- package/Utils/StatusPage/ResourceUptime.ts +90 -17
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +14 -4
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js +484 -0
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js +94 -0
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +5 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AlertAPI.js +22 -13
- package/build/dist/Server/API/AlertAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +22 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js +24 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +42 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +43 -26
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js +21 -12
- package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorAPI.js +23 -0
- package/build/dist/Server/API/MonitorAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorTemplateAPI.js +4 -0
- package/build/dist/Server/API/MonitorTemplateAPI.js.map +1 -1
- package/build/dist/Server/API/ProbeAPI.js +131 -15
- package/build/dist/Server/API/ProbeAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +62 -3
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js +23 -14
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +61 -33
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js +26 -2
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js +397 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.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/Services/AlertEpisodeService.js +39 -0
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +95 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +71 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +140 -17
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +39 -0
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +100 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +97 -0
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LogDropFilterService.js +93 -0
- package/build/dist/Server/Services/LogDropFilterService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +73 -5
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +34 -39
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +71 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +64 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +103 -7
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RecommendationDismissalService.js +50 -0
- package/build/dist/Server/Services/RecommendationDismissalService.js.map +1 -0
- package/build/dist/Server/Services/RunbookAgentJobService.js +63 -5
- package/build/dist/Server/Services/RunbookAgentJobService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +83 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +65 -0
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageGroupService.js +136 -0
- package/build/dist/Server/Services/StatusPageGroupService.js.map +1 -1
- package/build/dist/Server/Services/TraceDropFilterService.js +93 -0
- package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +12 -0
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +132 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/DropFilterValidation.js +80 -0
- package/build/dist/Server/Utils/DropFilterValidation.js.map +1 -0
- package/build/dist/Server/Utils/Errors.js +3 -0
- package/build/dist/Server/Utils/Errors.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +30 -12
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +38 -18
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js +26 -0
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
- package/build/dist/Types/Date.js +14 -4
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +192 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +6 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +32 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +294 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +110 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +58 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +451 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -0
- package/build/dist/Types/Permission.js +40 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Recommendation/RecommendationType.js +21 -0
- package/build/dist/Types/Recommendation/RecommendationType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js +93 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js +142 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js.map +1 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js +75 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js.map +1 -0
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -2
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
- package/build/dist/UI/Components/Accordion/Accordion.js +9 -2
- package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +27 -14
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +2 -20
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/Error/PageError.js +1 -3
- package/build/dist/UI/Components/Error/PageError.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +145 -11
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +28 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +4 -32
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +69 -33
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +73 -32
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -1
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js +101 -0
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js.map +1 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +73 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Utils/DropdownAlignment.js +98 -0
- package/build/dist/UI/Utils/DropdownAlignment.js.map +1 -0
- package/build/dist/UI/Utils/TableFilterUrlState.js +48 -15
- package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
- package/build/dist/Utils/API.js +39 -2
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js +97 -0
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +330 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js +280 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupTree.js +214 -0
- package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js +60 -16
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
2
|
+
import MonitorStepSnmpMonitor, {
|
|
3
|
+
MonitorStepSnmpMonitorUtil,
|
|
4
|
+
} from "../../../Types/Monitor/MonitorStepSnmpMonitor";
|
|
5
|
+
import SnmpAuthProtocol from "../../../Types/Monitor/SnmpMonitor/SnmpAuthProtocol";
|
|
6
|
+
import SnmpPrivProtocol from "../../../Types/Monitor/SnmpMonitor/SnmpPrivProtocol";
|
|
7
|
+
import SnmpSecurityLevel from "../../../Types/Monitor/SnmpMonitor/SnmpSecurityLevel";
|
|
8
|
+
import SnmpVersion from "../../../Types/Monitor/SnmpMonitor/SnmpVersion";
|
|
9
|
+
|
|
10
|
+
describe("MonitorStepSnmpMonitorUtil", () => {
|
|
11
|
+
describe("getDefault", () => {
|
|
12
|
+
test("returns a v2c community-string monitor on port 161", () => {
|
|
13
|
+
const def: MonitorStepSnmpMonitor =
|
|
14
|
+
MonitorStepSnmpMonitorUtil.getDefault();
|
|
15
|
+
|
|
16
|
+
expect(def.snmpVersion).toBe(SnmpVersion.V2c);
|
|
17
|
+
expect(def.hostname).toBe("");
|
|
18
|
+
expect(def.port).toBe(161);
|
|
19
|
+
expect(def.communityString).toBe("public");
|
|
20
|
+
expect(def.oids).toEqual([]);
|
|
21
|
+
expect(def.timeout).toBe(5000);
|
|
22
|
+
expect(def.retries).toBe(3);
|
|
23
|
+
expect(def.monitorInterfaces).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe("fromJSON defaults", () => {
|
|
28
|
+
test("fills in defaults for an empty object and leaves v3 auth undefined", () => {
|
|
29
|
+
const parsed: MonitorStepSnmpMonitor =
|
|
30
|
+
MonitorStepSnmpMonitorUtil.fromJSON({});
|
|
31
|
+
|
|
32
|
+
expect(parsed.snmpVersion).toBe(SnmpVersion.V2c);
|
|
33
|
+
expect(parsed.port).toBe(161);
|
|
34
|
+
// An empty/missing community string collapses to undefined.
|
|
35
|
+
expect(parsed.communityString).toBeUndefined();
|
|
36
|
+
expect(parsed.snmpV3Auth).toBeUndefined();
|
|
37
|
+
expect(parsed.oids).toEqual([]);
|
|
38
|
+
expect(parsed.monitorInterfaces).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("coerces monitorInterfaces to a real boolean", () => {
|
|
42
|
+
expect(
|
|
43
|
+
MonitorStepSnmpMonitorUtil.fromJSON({ monitorInterfaces: 1 })
|
|
44
|
+
.monitorInterfaces,
|
|
45
|
+
).toBe(true);
|
|
46
|
+
expect(
|
|
47
|
+
MonitorStepSnmpMonitorUtil.fromJSON({ monitorInterfaces: 0 })
|
|
48
|
+
.monitorInterfaces,
|
|
49
|
+
).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe("fromJSON OID parsing", () => {
|
|
54
|
+
test("maps each OID and defaults optional name/description to undefined", () => {
|
|
55
|
+
const parsed: MonitorStepSnmpMonitor =
|
|
56
|
+
MonitorStepSnmpMonitorUtil.fromJSON({
|
|
57
|
+
oids: [
|
|
58
|
+
{ oid: "1.3.6.1.2.1.1.3.0", name: "sysUpTime", description: "Up" },
|
|
59
|
+
{ oid: "1.3.6.1.2.1.1.5.0" },
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
expect(parsed.oids).toEqual([
|
|
64
|
+
{
|
|
65
|
+
oid: "1.3.6.1.2.1.1.3.0",
|
|
66
|
+
name: "sysUpTime",
|
|
67
|
+
description: "Up",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
oid: "1.3.6.1.2.1.1.5.0",
|
|
71
|
+
name: undefined,
|
|
72
|
+
description: undefined,
|
|
73
|
+
},
|
|
74
|
+
]);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe("fromJSON v3 auth parsing", () => {
|
|
79
|
+
test("parses a full authPriv v3 configuration", () => {
|
|
80
|
+
const parsed: MonitorStepSnmpMonitor =
|
|
81
|
+
MonitorStepSnmpMonitorUtil.fromJSON({
|
|
82
|
+
snmpVersion: SnmpVersion.V3,
|
|
83
|
+
hostname: "10.0.0.1",
|
|
84
|
+
snmpV3Auth: {
|
|
85
|
+
securityLevel: SnmpSecurityLevel.AuthPriv,
|
|
86
|
+
username: "monitor",
|
|
87
|
+
authProtocol: SnmpAuthProtocol.SHA,
|
|
88
|
+
authKey: "{{monitorSecrets.authKey}}",
|
|
89
|
+
privProtocol: SnmpPrivProtocol.AES,
|
|
90
|
+
privKey: "{{monitorSecrets.privKey}}",
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
expect(parsed.snmpV3Auth).toEqual({
|
|
95
|
+
securityLevel: SnmpSecurityLevel.AuthPriv,
|
|
96
|
+
username: "monitor",
|
|
97
|
+
authProtocol: SnmpAuthProtocol.SHA,
|
|
98
|
+
authKey: "{{monitorSecrets.authKey}}",
|
|
99
|
+
privProtocol: SnmpPrivProtocol.AES,
|
|
100
|
+
privKey: "{{monitorSecrets.privKey}}",
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("defaults the security level to NoAuthNoPriv when auth is present but empty", () => {
|
|
105
|
+
const parsed: MonitorStepSnmpMonitor =
|
|
106
|
+
MonitorStepSnmpMonitorUtil.fromJSON({
|
|
107
|
+
snmpVersion: SnmpVersion.V3,
|
|
108
|
+
snmpV3Auth: {},
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
expect(parsed.snmpV3Auth).toEqual({
|
|
112
|
+
securityLevel: SnmpSecurityLevel.NoAuthNoPriv,
|
|
113
|
+
username: "",
|
|
114
|
+
authProtocol: undefined,
|
|
115
|
+
authKey: undefined,
|
|
116
|
+
privProtocol: undefined,
|
|
117
|
+
privKey: undefined,
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe("round-trip", () => {
|
|
123
|
+
test("fromJSON(toJSON(x)) preserves a fully populated v3 monitor", () => {
|
|
124
|
+
const monitor: MonitorStepSnmpMonitor = {
|
|
125
|
+
snmpVersion: SnmpVersion.V3,
|
|
126
|
+
hostname: "10.0.0.5",
|
|
127
|
+
port: 1610,
|
|
128
|
+
communityString: undefined,
|
|
129
|
+
snmpV3Auth: {
|
|
130
|
+
securityLevel: SnmpSecurityLevel.AuthNoPriv,
|
|
131
|
+
username: "reader",
|
|
132
|
+
authProtocol: SnmpAuthProtocol.MD5,
|
|
133
|
+
authKey: "secret",
|
|
134
|
+
privProtocol: undefined,
|
|
135
|
+
privKey: undefined,
|
|
136
|
+
},
|
|
137
|
+
oids: [
|
|
138
|
+
{
|
|
139
|
+
oid: "1.3.6.1.2.1.1.1.0",
|
|
140
|
+
name: "sysDescr",
|
|
141
|
+
description: undefined,
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
timeout: 8000,
|
|
145
|
+
retries: 2,
|
|
146
|
+
monitorInterfaces: true,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const json: JSONObject = MonitorStepSnmpMonitorUtil.toJSON(monitor);
|
|
150
|
+
const roundTripped: MonitorStepSnmpMonitor =
|
|
151
|
+
MonitorStepSnmpMonitorUtil.fromJSON(json);
|
|
152
|
+
|
|
153
|
+
expect(roundTripped).toEqual(monitor);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import MonitorRecommendationCatalog, {
|
|
2
|
+
MonitorRecommendationResourceTypeDefinition,
|
|
3
|
+
} from "../../../../Types/Monitor/Recommendation/MonitorRecommendationCatalog";
|
|
4
|
+
import {
|
|
5
|
+
MonitorRecommendation,
|
|
6
|
+
MonitorRecommendationResourceType,
|
|
7
|
+
buildRecommendationId,
|
|
8
|
+
} from "../../../../Types/Monitor/Recommendation/MonitorRecommendationTypes";
|
|
9
|
+
import MonitorType from "../../../../Types/Monitor/MonitorType";
|
|
10
|
+
|
|
11
|
+
import { getAllCephAlertTemplates } from "../../../../Types/Monitor/CephAlertTemplates";
|
|
12
|
+
import { getAllDockerAlertTemplates } from "../../../../Types/Monitor/DockerAlertTemplates";
|
|
13
|
+
import { getAllDockerSwarmAlertTemplates } from "../../../../Types/Monitor/DockerSwarmAlertTemplates";
|
|
14
|
+
import { getAllHostAlertTemplates } from "../../../../Types/Monitor/HostAlertTemplates";
|
|
15
|
+
import { getAllIoTAlertTemplates } from "../../../../Types/Monitor/IotAlertTemplates";
|
|
16
|
+
import { getAllKubernetesAlertTemplates } from "../../../../Types/Monitor/KubernetesAlertTemplates";
|
|
17
|
+
import { getAllPodmanAlertTemplates } from "../../../../Types/Monitor/PodmanAlertTemplates";
|
|
18
|
+
import { getAllProxmoxAlertTemplates } from "../../../../Types/Monitor/ProxmoxAlertTemplates";
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* The catalog is the seam between eight independently-maintained alert-template
|
|
22
|
+
* modules and one Recommendations UI. Everything it can silently get wrong is
|
|
23
|
+
* a wiring mistake that produces a page that looks fine and creates broken or
|
|
24
|
+
* duplicated monitors:
|
|
25
|
+
*
|
|
26
|
+
* 1. A resource type declared in the enum but never adapted -> its section
|
|
27
|
+
* renders empty and the user concludes we ship no templates for it.
|
|
28
|
+
* 2. A recommendation id that is not globally unique -> selecting the Docker
|
|
29
|
+
* "high CPU" card also selects the Podman one, because THREE modules ship
|
|
30
|
+
* a template whose local id ends in `-high-cpu`. This is not
|
|
31
|
+
* hypothetical; see the `templateId collisions` test below, which asserts
|
|
32
|
+
* the collision exists so the prefix can never be "simplified" away.
|
|
33
|
+
* 3. A monitorType that disagrees with the resource type -> the created
|
|
34
|
+
* monitor is evaluated by the wrong criteria evaluator.
|
|
35
|
+
*
|
|
36
|
+
* These tests are deliberately written against the underlying modules'
|
|
37
|
+
* `getAll<X>AlertTemplates()` rather than against hardcoded counts, so adding
|
|
38
|
+
* a template to any module does not break them — but adding a MODULE without
|
|
39
|
+
* wiring it here does.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
interface ModuleExpectation {
|
|
43
|
+
resourceType: MonitorRecommendationResourceType;
|
|
44
|
+
monitorType: MonitorType;
|
|
45
|
+
templateCount: number;
|
|
46
|
+
identifierFieldName:
|
|
47
|
+
| "clusterIdentifier"
|
|
48
|
+
| "hostIdentifier"
|
|
49
|
+
| "fleetIdentifier";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const MODULE_EXPECTATIONS: Array<ModuleExpectation> = [
|
|
53
|
+
{
|
|
54
|
+
resourceType: MonitorRecommendationResourceType.Kubernetes,
|
|
55
|
+
monitorType: MonitorType.Kubernetes,
|
|
56
|
+
templateCount: getAllKubernetesAlertTemplates().length,
|
|
57
|
+
identifierFieldName: "clusterIdentifier",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
resourceType: MonitorRecommendationResourceType.Host,
|
|
61
|
+
monitorType: MonitorType.Host,
|
|
62
|
+
templateCount: getAllHostAlertTemplates().length,
|
|
63
|
+
identifierFieldName: "hostIdentifier",
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
resourceType: MonitorRecommendationResourceType.Docker,
|
|
67
|
+
monitorType: MonitorType.Docker,
|
|
68
|
+
templateCount: getAllDockerAlertTemplates().length,
|
|
69
|
+
identifierFieldName: "hostIdentifier",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
resourceType: MonitorRecommendationResourceType.DockerSwarm,
|
|
73
|
+
monitorType: MonitorType.DockerSwarm,
|
|
74
|
+
templateCount: getAllDockerSwarmAlertTemplates().length,
|
|
75
|
+
identifierFieldName: "clusterIdentifier",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
resourceType: MonitorRecommendationResourceType.Podman,
|
|
79
|
+
monitorType: MonitorType.Podman,
|
|
80
|
+
templateCount: getAllPodmanAlertTemplates().length,
|
|
81
|
+
identifierFieldName: "hostIdentifier",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
resourceType: MonitorRecommendationResourceType.Proxmox,
|
|
85
|
+
monitorType: MonitorType.Proxmox,
|
|
86
|
+
templateCount: getAllProxmoxAlertTemplates().length,
|
|
87
|
+
identifierFieldName: "clusterIdentifier",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
resourceType: MonitorRecommendationResourceType.Ceph,
|
|
91
|
+
monitorType: MonitorType.Ceph,
|
|
92
|
+
templateCount: getAllCephAlertTemplates().length,
|
|
93
|
+
identifierFieldName: "clusterIdentifier",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
resourceType: MonitorRecommendationResourceType.IoTDevice,
|
|
97
|
+
monitorType: MonitorType.IoTDevice,
|
|
98
|
+
templateCount: getAllIoTAlertTemplates().length,
|
|
99
|
+
identifierFieldName: "fleetIdentifier",
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
describe("MonitorRecommendationCatalog", () => {
|
|
104
|
+
describe("completeness", () => {
|
|
105
|
+
it("has a definition for every resource type in the enum", () => {
|
|
106
|
+
const enumMembers: Array<MonitorRecommendationResourceType> =
|
|
107
|
+
Object.values(MonitorRecommendationResourceType);
|
|
108
|
+
|
|
109
|
+
const definedTypes: Array<MonitorRecommendationResourceType> =
|
|
110
|
+
MonitorRecommendationCatalog.getResourceTypeDefinitions().map(
|
|
111
|
+
(definition: MonitorRecommendationResourceTypeDefinition) => {
|
|
112
|
+
return definition.resourceType;
|
|
113
|
+
},
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
expect(definedTypes.sort()).toEqual(enumMembers.sort());
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("has exactly one definition per resource type", () => {
|
|
120
|
+
const definedTypes: Array<MonitorRecommendationResourceType> =
|
|
121
|
+
MonitorRecommendationCatalog.getResourceTypeDefinitions().map(
|
|
122
|
+
(definition: MonitorRecommendationResourceTypeDefinition) => {
|
|
123
|
+
return definition.resourceType;
|
|
124
|
+
},
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
expect(new Set(definedTypes).size).toBe(definedTypes.length);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("covers every alert-template module and loses no templates", () => {
|
|
131
|
+
/*
|
|
132
|
+
* A dropped `.map` or a filtered adapter would show up here as a count
|
|
133
|
+
* mismatch rather than as a quietly shorter list in the UI.
|
|
134
|
+
*/
|
|
135
|
+
for (const expectation of MODULE_EXPECTATIONS) {
|
|
136
|
+
const recommendations: Array<MonitorRecommendation> =
|
|
137
|
+
MonitorRecommendationCatalog.getRecommendations(
|
|
138
|
+
expectation.resourceType,
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
expect(expectation.templateCount).toBeGreaterThan(0);
|
|
142
|
+
expect(recommendations.length).toBe(expectation.templateCount);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("getAllRecommendations returns the sum of every module", () => {
|
|
147
|
+
const expectedTotal: number = MODULE_EXPECTATIONS.reduce(
|
|
148
|
+
(total: number, expectation: ModuleExpectation) => {
|
|
149
|
+
return total + expectation.templateCount;
|
|
150
|
+
},
|
|
151
|
+
0,
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
expect(MonitorRecommendationCatalog.getAllRecommendations().length).toBe(
|
|
155
|
+
expectedTotal,
|
|
156
|
+
);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe("recommendation identity", () => {
|
|
161
|
+
it("mints globally unique recommendation ids", () => {
|
|
162
|
+
const ids: Array<string> =
|
|
163
|
+
MonitorRecommendationCatalog.getAllRecommendations().map(
|
|
164
|
+
(recommendation: MonitorRecommendation) => {
|
|
165
|
+
return recommendation.recommendationId;
|
|
166
|
+
},
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
expect(new Set(ids).size).toBe(ids.length);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("composes the recommendation id as resourceType:templateId", () => {
|
|
173
|
+
for (const recommendation of MonitorRecommendationCatalog.getAllRecommendations()) {
|
|
174
|
+
expect(recommendation.recommendationId).toBe(
|
|
175
|
+
buildRecommendationId(
|
|
176
|
+
recommendation.resourceType,
|
|
177
|
+
recommendation.templateId,
|
|
178
|
+
),
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("canary: raw templateIds happen to be globally unique today", () => {
|
|
184
|
+
/*
|
|
185
|
+
* Every module self-prefixes (`host-high-cpu`, `docker-high-cpu`,
|
|
186
|
+
* `podman-high-cpu`), so no two of the 76 collide right now. That is a
|
|
187
|
+
* convention across eight independently maintained files, not a
|
|
188
|
+
* contract — each module only promises uniqueness within itself.
|
|
189
|
+
*
|
|
190
|
+
* This test is a canary, NOT a requirement the registry depends on. If
|
|
191
|
+
* it fails, nothing is broken: `recommendationId` is prefixed precisely
|
|
192
|
+
* so a collision stays harmless (see the test below). Update this
|
|
193
|
+
* expectation and move on.
|
|
194
|
+
*/
|
|
195
|
+
const templateIds: Array<string> =
|
|
196
|
+
MonitorRecommendationCatalog.getAllRecommendations().map(
|
|
197
|
+
(recommendation: MonitorRecommendation) => {
|
|
198
|
+
return recommendation.templateId;
|
|
199
|
+
},
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
expect(new Set(templateIds).size).toBe(templateIds.length);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("keeps colliding templateIds distinct once prefixed", () => {
|
|
206
|
+
/*
|
|
207
|
+
* The property the registry actually relies on: two modules picking the
|
|
208
|
+
* same local id still produce different recommendation ids, so selecting
|
|
209
|
+
* a Docker card can never also select the Podman one.
|
|
210
|
+
*/
|
|
211
|
+
expect(
|
|
212
|
+
buildRecommendationId(
|
|
213
|
+
MonitorRecommendationResourceType.Docker,
|
|
214
|
+
"high-cpu",
|
|
215
|
+
),
|
|
216
|
+
).not.toBe(
|
|
217
|
+
buildRecommendationId(
|
|
218
|
+
MonitorRecommendationResourceType.Podman,
|
|
219
|
+
"high-cpu",
|
|
220
|
+
),
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("round-trips every recommendation through getRecommendationById", () => {
|
|
225
|
+
for (const recommendation of MonitorRecommendationCatalog.getAllRecommendations()) {
|
|
226
|
+
const found: MonitorRecommendation | undefined =
|
|
227
|
+
MonitorRecommendationCatalog.getRecommendationById(
|
|
228
|
+
recommendation.recommendationId,
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
expect(found).toBeDefined();
|
|
232
|
+
expect(found?.templateId).toBe(recommendation.templateId);
|
|
233
|
+
expect(found?.resourceType).toBe(recommendation.resourceType);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it("returns undefined for an unknown recommendation id", () => {
|
|
238
|
+
expect(
|
|
239
|
+
MonitorRecommendationCatalog.getRecommendationById(
|
|
240
|
+
"Nope:does-not-exist",
|
|
241
|
+
),
|
|
242
|
+
).toBeUndefined();
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
describe("resource type definitions", () => {
|
|
247
|
+
it("maps each resource type to the correct MonitorType", () => {
|
|
248
|
+
for (const expectation of MODULE_EXPECTATIONS) {
|
|
249
|
+
const definition:
|
|
250
|
+
| MonitorRecommendationResourceTypeDefinition
|
|
251
|
+
| undefined = MonitorRecommendationCatalog.getResourceTypeDefinition(
|
|
252
|
+
expectation.resourceType,
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
expect(definition?.monitorType).toBe(expectation.monitorType);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it("documents the identifier field name each module actually uses", () => {
|
|
260
|
+
/*
|
|
261
|
+
* `identifierFieldName` is the only place the args rename is written
|
|
262
|
+
* down. If a template module renames e.g. `clusterIdentifier` ->
|
|
263
|
+
* `clusterId`, its adapter stops threading the identifier and every
|
|
264
|
+
* generated monitor silently scopes to undefined. This test pins the
|
|
265
|
+
* expectation; MonitorRecommendationUtil.test.ts proves the value
|
|
266
|
+
* actually arrives in the built step.
|
|
267
|
+
*/
|
|
268
|
+
for (const expectation of MODULE_EXPECTATIONS) {
|
|
269
|
+
const definition:
|
|
270
|
+
| MonitorRecommendationResourceTypeDefinition
|
|
271
|
+
| undefined = MonitorRecommendationCatalog.getResourceTypeDefinition(
|
|
272
|
+
expectation.resourceType,
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
expect(definition?.identifierFieldName).toBe(
|
|
276
|
+
expectation.identifierFieldName,
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it("stamps every recommendation with its definition's monitorType and resourceType", () => {
|
|
282
|
+
for (const definition of MonitorRecommendationCatalog.getResourceTypeDefinitions()) {
|
|
283
|
+
for (const recommendation of definition.getRecommendations()) {
|
|
284
|
+
expect(recommendation.monitorType).toBe(definition.monitorType);
|
|
285
|
+
expect(recommendation.resourceType).toBe(definition.resourceType);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it("gives every definition a non-empty human label", () => {
|
|
291
|
+
for (const definition of MonitorRecommendationCatalog.getResourceTypeDefinitions()) {
|
|
292
|
+
expect(definition.resourceLabel.trim().length).toBeGreaterThan(0);
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it("returns an empty list for an unknown resource type", () => {
|
|
297
|
+
expect(
|
|
298
|
+
MonitorRecommendationCatalog.getRecommendations(
|
|
299
|
+
"NotAResourceType" as MonitorRecommendationResourceType,
|
|
300
|
+
),
|
|
301
|
+
).toEqual([]);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it("returns undefined for an unknown resource type definition", () => {
|
|
305
|
+
expect(
|
|
306
|
+
MonitorRecommendationCatalog.getResourceTypeDefinition(
|
|
307
|
+
"NotAResourceType" as MonitorRecommendationResourceType,
|
|
308
|
+
),
|
|
309
|
+
).toBeUndefined();
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it("does not leak its internal definitions array to callers", () => {
|
|
313
|
+
const first: Array<MonitorRecommendationResourceTypeDefinition> =
|
|
314
|
+
MonitorRecommendationCatalog.getResourceTypeDefinitions();
|
|
315
|
+
first.pop();
|
|
316
|
+
|
|
317
|
+
expect(
|
|
318
|
+
MonitorRecommendationCatalog.getResourceTypeDefinitions().length,
|
|
319
|
+
).toBe(MODULE_EXPECTATIONS.length);
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
describe("recommendation content", () => {
|
|
324
|
+
it("gives every recommendation a name, description, category and valid severity", () => {
|
|
325
|
+
for (const recommendation of MonitorRecommendationCatalog.getAllRecommendations()) {
|
|
326
|
+
expect(recommendation.name.trim().length).toBeGreaterThan(0);
|
|
327
|
+
expect(recommendation.description.trim().length).toBeGreaterThan(0);
|
|
328
|
+
expect(recommendation.category.trim().length).toBeGreaterThan(0);
|
|
329
|
+
expect(["Critical", "Warning"]).toContain(recommendation.severity);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
describe("getCategories", () => {
|
|
335
|
+
it("returns distinct categories in first-declaration order", () => {
|
|
336
|
+
for (const expectation of MODULE_EXPECTATIONS) {
|
|
337
|
+
const recommendations: Array<MonitorRecommendation> =
|
|
338
|
+
MonitorRecommendationCatalog.getRecommendations(
|
|
339
|
+
expectation.resourceType,
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const categories: Array<string> =
|
|
343
|
+
MonitorRecommendationCatalog.getCategories(expectation.resourceType);
|
|
344
|
+
|
|
345
|
+
expect(new Set(categories).size).toBe(categories.length);
|
|
346
|
+
|
|
347
|
+
// Every category is real, and every recommendation's category is listed.
|
|
348
|
+
for (const recommendation of recommendations) {
|
|
349
|
+
expect(categories).toContain(recommendation.category);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Order matches first appearance in the module's own declaration order.
|
|
353
|
+
const firstAppearanceOrder: Array<string> = [];
|
|
354
|
+
for (const recommendation of recommendations) {
|
|
355
|
+
if (!firstAppearanceOrder.includes(recommendation.category)) {
|
|
356
|
+
firstAppearanceOrder.push(recommendation.category);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
expect(categories).toEqual(firstAppearanceOrder);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("returns an empty list for an unknown resource type", () => {
|
|
364
|
+
expect(
|
|
365
|
+
MonitorRecommendationCatalog.getCategories(
|
|
366
|
+
"NotAResourceType" as MonitorRecommendationResourceType,
|
|
367
|
+
),
|
|
368
|
+
).toEqual([]);
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
});
|