@oneuptime/common 11.7.2 → 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/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
- 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/TableView.ts +40 -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/1785241000000-AddColumnsToTableView.ts +13 -0
- 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 +10 -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/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -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/JSONFunctions.test.ts +103 -1
- 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/BaseModelTableColumnCustomization.test.tsx +679 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
- package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +999 -0
- package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -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/Tests/Utils/UserPreferences.test.ts +563 -0
- package/Types/Date.ts +15 -6
- package/Types/JSONFunctions.ts +7 -2
- package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
- 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/MasterPage/MasterPage.tsx +65 -0
- package/UI/Components/Modal/Modal.tsx +16 -60
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
- package/UI/Components/ModelTable/BaseModelTable.tsx +503 -71
- package/UI/Components/ModelTable/Column.ts +17 -0
- package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +523 -0
- package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
- package/UI/Components/ModelTable/TableView.tsx +24 -2
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
- package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
- package/UI/Components/SideMenu/SideMenu.tsx +24 -4
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
- package/UI/Components/Table/Table.tsx +14 -1
- package/UI/Components/Table/TableRow.tsx +180 -175
- package/UI/Components/Table/Types/Column.ts +2 -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/Utils/UserPreferences.ts +53 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
- 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/TableView.js +40 -0
- package/build/dist/Models/DatabaseModels/TableView.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/1785241000000-AddColumnsToTableView.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
- 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 +10 -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/JSONFunctions.js +8 -3
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.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/MasterPage/MasterPage.js +50 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.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 +308 -40
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +230 -0
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
- package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
- 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/SideMenu/SideMenu.js +15 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- 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/Table/Table.js +15 -2
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +11 -6
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- 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/build/dist/Utils/UserPreferences.js +33 -0
- package/build/dist/Utils/UserPreferences.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
import MonitorRecommendationCatalog, {
|
|
2
|
+
MonitorRecommendationResourceTypeDefinition,
|
|
3
|
+
} from "../../../../Types/Monitor/Recommendation/MonitorRecommendationCatalog";
|
|
4
|
+
import MonitorRecommendationUtil from "../../../../Types/Monitor/Recommendation/MonitorRecommendationUtil";
|
|
5
|
+
import {
|
|
6
|
+
MonitorRecommendation,
|
|
7
|
+
MonitorRecommendationArgs,
|
|
8
|
+
MonitorRecommendationNotificationMode,
|
|
9
|
+
MonitorRecommendationNotificationSettings,
|
|
10
|
+
} from "../../../../Types/Monitor/Recommendation/MonitorRecommendationTypes";
|
|
11
|
+
import MonitorStep from "../../../../Types/Monitor/MonitorStep";
|
|
12
|
+
import MonitorSteps from "../../../../Types/Monitor/MonitorSteps";
|
|
13
|
+
import MonitorCriteriaInstance from "../../../../Types/Monitor/MonitorCriteriaInstance";
|
|
14
|
+
import { CriteriaIncident } from "../../../../Types/Monitor/CriteriaIncident";
|
|
15
|
+
import { CriteriaAlert } from "../../../../Types/Monitor/CriteriaAlert";
|
|
16
|
+
import ObjectID from "../../../../Types/ObjectID";
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* What the Alert / Incident / Both choice on the recommendations create form
|
|
20
|
+
* actually does to a generated monitor.
|
|
21
|
+
*
|
|
22
|
+
* The reason this file exists separately from MonitorRecommendationUtil.test.ts
|
|
23
|
+
* is that `createIncidents` / `createAlerts` are the two flags the monitor
|
|
24
|
+
* evaluator reads to decide whether a threshold breach turns into a record.
|
|
25
|
+
* They are booleans on a criteria instance, they have no UI on the
|
|
26
|
+
* recommendation card, and getting them wrong is invisible until production:
|
|
27
|
+
*
|
|
28
|
+
* - set both on a criteria that has no incidents/alerts to create, and the
|
|
29
|
+
* auto-resolve path counts that criteria as breach-producing, so a
|
|
30
|
+
* recovered monitor never closes the incident it opened;
|
|
31
|
+
* - set neither on the criteria that DOES have them, and the monitor
|
|
32
|
+
* silently watches a threshold and tells nobody;
|
|
33
|
+
* - empty the arrays instead of clearing the flag, and the user's later
|
|
34
|
+
* "actually I do want incidents" costs them re-authoring every title,
|
|
35
|
+
* description and severity by hand.
|
|
36
|
+
*
|
|
37
|
+
* None of those three failures produce an error, a validation failure, or a
|
|
38
|
+
* visible difference on the recommendations page. They only show up the next
|
|
39
|
+
* time something actually breaks.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
const ONLINE_STATUS_ID: ObjectID = ObjectID.generate();
|
|
43
|
+
const OFFLINE_STATUS_ID: ObjectID = ObjectID.generate();
|
|
44
|
+
const DEFAULT_STATUS_ID: ObjectID = ObjectID.generate();
|
|
45
|
+
const INCIDENT_SEVERITY_ID: ObjectID = ObjectID.generate();
|
|
46
|
+
const ALERT_SEVERITY_ID: ObjectID = ObjectID.generate();
|
|
47
|
+
|
|
48
|
+
function buildArgs(
|
|
49
|
+
overrides?: Partial<MonitorRecommendationArgs>,
|
|
50
|
+
): MonitorRecommendationArgs {
|
|
51
|
+
return {
|
|
52
|
+
resourceIdentifier: "prod-cluster-01",
|
|
53
|
+
onlineMonitorStatusId: ONLINE_STATUS_ID,
|
|
54
|
+
offlineMonitorStatusId: OFFLINE_STATUS_ID,
|
|
55
|
+
defaultIncidentSeverityId: INCIDENT_SEVERITY_ID,
|
|
56
|
+
defaultAlertSeverityId: ALERT_SEVERITY_ID,
|
|
57
|
+
monitorName: "Test Monitor",
|
|
58
|
+
...overrides,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getCriteriaInstances(
|
|
63
|
+
monitorStep: MonitorStep,
|
|
64
|
+
): Array<MonitorCriteriaInstance> {
|
|
65
|
+
return (
|
|
66
|
+
monitorStep.data?.monitorCriteria?.data?.monitorCriteriaInstanceArray || []
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
* The recovery ("Healthy") criteria is identified structurally — empty
|
|
72
|
+
* incidents AND empty alerts — rather than by its name, because the eight
|
|
73
|
+
* template modules name it inconsistently once a template overrides
|
|
74
|
+
* `criteriaName`. Empty-arrays IS the property that makes flipping a flag on it
|
|
75
|
+
* meaningless-at-best and harmful-at-worst, so it is the right thing to key on.
|
|
76
|
+
*/
|
|
77
|
+
function isRecoveryCriteriaInstance(
|
|
78
|
+
criteriaInstance: MonitorCriteriaInstance,
|
|
79
|
+
): boolean {
|
|
80
|
+
return (
|
|
81
|
+
(criteriaInstance.data?.incidents || []).length === 0 &&
|
|
82
|
+
(criteriaInstance.data?.alerts || []).length === 0
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function getRecoveryCriteriaInstances(
|
|
87
|
+
monitorStep: MonitorStep,
|
|
88
|
+
): Array<MonitorCriteriaInstance> {
|
|
89
|
+
return getCriteriaInstances(monitorStep).filter(isRecoveryCriteriaInstance);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/*
|
|
93
|
+
* Every criteria instance that ships something to create — the "Unhealthy"
|
|
94
|
+
* ones. Ceph's Monitor Disk template ships two of them (a CRIT tier and a LOW
|
|
95
|
+
* tier), so this is deliberately a list and not a single instance.
|
|
96
|
+
*/
|
|
97
|
+
function getBreachCriteriaInstances(
|
|
98
|
+
monitorStep: MonitorStep,
|
|
99
|
+
): Array<MonitorCriteriaInstance> {
|
|
100
|
+
return getCriteriaInstances(monitorStep).filter(
|
|
101
|
+
(criteriaInstance: MonitorCriteriaInstance) => {
|
|
102
|
+
return !isRecoveryCriteriaInstance(criteriaInstance);
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function applyMode(data: {
|
|
108
|
+
recommendation: MonitorRecommendation;
|
|
109
|
+
notificationMode: MonitorRecommendationNotificationMode | undefined;
|
|
110
|
+
}): MonitorStep {
|
|
111
|
+
return MonitorRecommendationUtil.applyNotificationSettingsToMonitorStep({
|
|
112
|
+
monitorStep: data.recommendation.getMonitorStep(buildArgs()),
|
|
113
|
+
notificationSettings: { notificationMode: data.notificationMode },
|
|
114
|
+
severity: data.recommendation.severity,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const ALL_RECOMMENDATIONS: Array<MonitorRecommendation> =
|
|
119
|
+
MonitorRecommendationCatalog.getAllRecommendations();
|
|
120
|
+
|
|
121
|
+
// One representative recommendation per resource type, for the focused tests.
|
|
122
|
+
const ONE_PER_RESOURCE_TYPE: Array<MonitorRecommendation> =
|
|
123
|
+
MonitorRecommendationCatalog.getResourceTypeDefinitions().map(
|
|
124
|
+
(definition: MonitorRecommendationResourceTypeDefinition) => {
|
|
125
|
+
return definition.getRecommendations()[0]!;
|
|
126
|
+
},
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const ALL_MODES: Array<MonitorRecommendationNotificationMode> = [
|
|
130
|
+
MonitorRecommendationNotificationMode.Alert,
|
|
131
|
+
MonitorRecommendationNotificationMode.Incident,
|
|
132
|
+
MonitorRecommendationNotificationMode.Both,
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
describe("MonitorRecommendationNotificationMode", () => {
|
|
136
|
+
describe("the shipped template baseline the modes are measured against", () => {
|
|
137
|
+
/*
|
|
138
|
+
* Everything below this describe block is a statement about how a mode
|
|
139
|
+
* CHANGES the templates. Those statements are only meaningful if the
|
|
140
|
+
* starting point is known, and the starting point lives in eight
|
|
141
|
+
* independently maintained `<X>AlertTemplates.ts` modules that nothing
|
|
142
|
+
* else forces to agree. If one of them ever ships, say, an unhealthy
|
|
143
|
+
* criteria with `createAlerts: false`, then "mode Both leaves both on"
|
|
144
|
+
* would still pass while quietly meaning something different. These two
|
|
145
|
+
* tests are the canary for that.
|
|
146
|
+
*/
|
|
147
|
+
|
|
148
|
+
it("has recommendations to test at all", () => {
|
|
149
|
+
// Guards every for-loop in this file against a vacuous pass.
|
|
150
|
+
expect(ALL_RECOMMENDATIONS.length).toBeGreaterThan(0);
|
|
151
|
+
expect(ONE_PER_RESOURCE_TYPE.length).toBe(8);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("ships every unhealthy criteria with createIncidents AND createAlerts true, and both arrays populated", () => {
|
|
155
|
+
for (const recommendation of ALL_RECOMMENDATIONS) {
|
|
156
|
+
const monitorStep: MonitorStep =
|
|
157
|
+
recommendation.getMonitorStep(buildArgs());
|
|
158
|
+
|
|
159
|
+
const breachInstances: Array<MonitorCriteriaInstance> =
|
|
160
|
+
getBreachCriteriaInstances(monitorStep);
|
|
161
|
+
|
|
162
|
+
expect(breachInstances.length).toBeGreaterThan(0);
|
|
163
|
+
|
|
164
|
+
for (const criteriaInstance of breachInstances) {
|
|
165
|
+
expect(criteriaInstance.data?.createIncidents).toBe(true);
|
|
166
|
+
expect(criteriaInstance.data?.createAlerts).toBe(true);
|
|
167
|
+
expect(
|
|
168
|
+
(criteriaInstance.data?.incidents || []).length,
|
|
169
|
+
).toBeGreaterThan(0);
|
|
170
|
+
expect((criteriaInstance.data?.alerts || []).length).toBeGreaterThan(
|
|
171
|
+
0,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("ships exactly one recovery criteria per recommendation, with both flags false and both arrays empty", () => {
|
|
178
|
+
for (const recommendation of ALL_RECOMMENDATIONS) {
|
|
179
|
+
const recoveryInstances: Array<MonitorCriteriaInstance> =
|
|
180
|
+
getRecoveryCriteriaInstances(
|
|
181
|
+
recommendation.getMonitorStep(buildArgs()),
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
expect(recoveryInstances.length).toBe(1);
|
|
185
|
+
|
|
186
|
+
expect(recoveryInstances[0]!.data?.createIncidents).toBe(false);
|
|
187
|
+
expect(recoveryInstances[0]!.data?.createAlerts).toBe(false);
|
|
188
|
+
expect(recoveryInstances[0]!.data?.incidents).toEqual([]);
|
|
189
|
+
expect(recoveryInstances[0]!.data?.alerts).toEqual([]);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("ships at least one recommendation with more than one unhealthy criteria", () => {
|
|
194
|
+
/*
|
|
195
|
+
* Ceph's monitor-disk template tiers CRIT and LOW into two unhealthy
|
|
196
|
+
* criteria on one monitor. Without a multi-criteria template in the
|
|
197
|
+
* catalog, "the mode is applied to EVERY unhealthy criteria" below could
|
|
198
|
+
* never fail — a buggy implementation that only touched the first
|
|
199
|
+
* criteria instance would pass every other test in this file.
|
|
200
|
+
*/
|
|
201
|
+
const multiCriteriaRecommendations: Array<MonitorRecommendation> =
|
|
202
|
+
ALL_RECOMMENDATIONS.filter((recommendation: MonitorRecommendation) => {
|
|
203
|
+
return (
|
|
204
|
+
getBreachCriteriaInstances(
|
|
205
|
+
recommendation.getMonitorStep(buildArgs()),
|
|
206
|
+
).length > 1
|
|
207
|
+
);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
expect(multiCriteriaRecommendations.length).toBeGreaterThan(0);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
describe("applyNotificationSettingsToMonitorStep — notification mode", () => {
|
|
215
|
+
it("mode Alert leaves alerts on and turns incidents off, on every unhealthy criteria", () => {
|
|
216
|
+
for (const recommendation of ALL_RECOMMENDATIONS) {
|
|
217
|
+
const monitorStep: MonitorStep = applyMode({
|
|
218
|
+
recommendation: recommendation,
|
|
219
|
+
notificationMode: MonitorRecommendationNotificationMode.Alert,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
for (const criteriaInstance of getBreachCriteriaInstances(
|
|
223
|
+
monitorStep,
|
|
224
|
+
)) {
|
|
225
|
+
expect(criteriaInstance.data?.createAlerts).toBe(true);
|
|
226
|
+
expect(criteriaInstance.data?.createIncidents).toBe(false);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("mode Incident leaves incidents on and turns alerts off, on every unhealthy criteria", () => {
|
|
232
|
+
for (const recommendation of ALL_RECOMMENDATIONS) {
|
|
233
|
+
const monitorStep: MonitorStep = applyMode({
|
|
234
|
+
recommendation: recommendation,
|
|
235
|
+
notificationMode: MonitorRecommendationNotificationMode.Incident,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
for (const criteriaInstance of getBreachCriteriaInstances(
|
|
239
|
+
monitorStep,
|
|
240
|
+
)) {
|
|
241
|
+
expect(criteriaInstance.data?.createIncidents).toBe(true);
|
|
242
|
+
expect(criteriaInstance.data?.createAlerts).toBe(false);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("mode Both leaves both on, on every unhealthy criteria", () => {
|
|
248
|
+
for (const recommendation of ALL_RECOMMENDATIONS) {
|
|
249
|
+
const monitorStep: MonitorStep = applyMode({
|
|
250
|
+
recommendation: recommendation,
|
|
251
|
+
notificationMode: MonitorRecommendationNotificationMode.Both,
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
for (const criteriaInstance of getBreachCriteriaInstances(
|
|
255
|
+
monitorStep,
|
|
256
|
+
)) {
|
|
257
|
+
expect(criteriaInstance.data?.createIncidents).toBe(true);
|
|
258
|
+
expect(criteriaInstance.data?.createAlerts).toBe(true);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it("an absent mode leaves the flags exactly as the template shipped them", () => {
|
|
264
|
+
/*
|
|
265
|
+
* The backwards-compatible path. `notificationMode` is optional, and any
|
|
266
|
+
* caller that predates it — older tests, MonitorRecommendationCreateUtil
|
|
267
|
+
* before the form gained the toggle, any future programmatic caller —
|
|
268
|
+
* passes settings without it. Those callers must keep creating
|
|
269
|
+
* both-incident-and-alert monitors rather than silently inheriting a
|
|
270
|
+
* default someone else picked, so `undefined` is a distinct state from
|
|
271
|
+
* `Both` and not a synonym for it.
|
|
272
|
+
*/
|
|
273
|
+
for (const recommendation of ALL_RECOMMENDATIONS) {
|
|
274
|
+
const monitorStep: MonitorStep = applyMode({
|
|
275
|
+
recommendation: recommendation,
|
|
276
|
+
notificationMode: undefined,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
for (const criteriaInstance of getBreachCriteriaInstances(
|
|
280
|
+
monitorStep,
|
|
281
|
+
)) {
|
|
282
|
+
expect(criteriaInstance.data?.createIncidents).toBe(true);
|
|
283
|
+
expect(criteriaInstance.data?.createAlerts).toBe(true);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("settings that carry no mode at all leave the flags alone too", () => {
|
|
289
|
+
/*
|
|
290
|
+
* Same guarantee as above, reached the other way: a settings object that
|
|
291
|
+
* only sets on-call policies / labels / severities must not disturb the
|
|
292
|
+
* flags as a side effect of the severity or owner writes.
|
|
293
|
+
*/
|
|
294
|
+
const settingsWithoutMode: MonitorRecommendationNotificationSettings = {
|
|
295
|
+
onCallPolicyIds: [ObjectID.generate()],
|
|
296
|
+
labelIds: [ObjectID.generate()],
|
|
297
|
+
ownerTeamIds: [ObjectID.generate()],
|
|
298
|
+
ownerUserIds: [ObjectID.generate()],
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
for (const recommendation of ONE_PER_RESOURCE_TYPE) {
|
|
302
|
+
const monitorStep: MonitorStep =
|
|
303
|
+
MonitorRecommendationUtil.applyNotificationSettingsToMonitorStep({
|
|
304
|
+
monitorStep: recommendation.getMonitorStep(buildArgs()),
|
|
305
|
+
notificationSettings: settingsWithoutMode,
|
|
306
|
+
severity: recommendation.severity,
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
for (const criteriaInstance of getBreachCriteriaInstances(
|
|
310
|
+
monitorStep,
|
|
311
|
+
)) {
|
|
312
|
+
expect(criteriaInstance.data?.createIncidents).toBe(true);
|
|
313
|
+
expect(criteriaInstance.data?.createAlerts).toBe(true);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it("never marks the recovery criteria as incident- or alert-producing, under ANY mode", () => {
|
|
319
|
+
/*
|
|
320
|
+
* The highest-value assertion in this file, and the one most likely to be
|
|
321
|
+
* broken by an innocent-looking simplification of
|
|
322
|
+
* `applyNotificationModeToCriteriaInstance` (dropping its
|
|
323
|
+
* "only if the array is non-empty" guards reads like dead code).
|
|
324
|
+
*
|
|
325
|
+
* The recovery criteria is what fires when a monitor comes back healthy.
|
|
326
|
+
* `createIncidents: true` on it means the auto-resolve path treats it as
|
|
327
|
+
* a criteria that contributes breaches, so the recovery never resolves
|
|
328
|
+
* the incident the unhealthy criteria opened. The monitor would look
|
|
329
|
+
* correct on the create form, create correctly, alert correctly — and
|
|
330
|
+
* then leave a permanently open incident behind after every recovery,
|
|
331
|
+
* with nothing in the config visibly wrong. `Both` is the dangerous mode
|
|
332
|
+
* here precisely because it is the one that turns everything else on.
|
|
333
|
+
*/
|
|
334
|
+
for (const recommendation of ALL_RECOMMENDATIONS) {
|
|
335
|
+
for (const notificationMode of ALL_MODES) {
|
|
336
|
+
const monitorStep: MonitorStep = applyMode({
|
|
337
|
+
recommendation: recommendation,
|
|
338
|
+
notificationMode: notificationMode,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
const recoveryInstances: Array<MonitorCriteriaInstance> =
|
|
342
|
+
getRecoveryCriteriaInstances(monitorStep);
|
|
343
|
+
|
|
344
|
+
expect(recoveryInstances.length).toBe(1);
|
|
345
|
+
|
|
346
|
+
for (const criteriaInstance of recoveryInstances) {
|
|
347
|
+
expect(criteriaInstance.data?.createIncidents).toBe(false);
|
|
348
|
+
expect(criteriaInstance.data?.createAlerts).toBe(false);
|
|
349
|
+
// Still nothing to create, so the flags stayed meaningful.
|
|
350
|
+
expect(criteriaInstance.data?.incidents).toEqual([]);
|
|
351
|
+
expect(criteriaInstance.data?.alerts).toEqual([]);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it("keeps the incident config intact when mode Alert switches incidents off", () => {
|
|
358
|
+
/*
|
|
359
|
+
* Turning a mode off must clear the flag and nothing else. If the
|
|
360
|
+
* implementation instead emptied `incidents`, the switch would be
|
|
361
|
+
* one-way: the user who later opens the monitor's criteria form and
|
|
362
|
+
* flips "Create Incidents" back on would find an empty incident with no
|
|
363
|
+
* title, no description and no severity — and would have to re-author by
|
|
364
|
+
* hand the exact text the template wrote for them.
|
|
365
|
+
*/
|
|
366
|
+
for (const recommendation of ONE_PER_RESOURCE_TYPE) {
|
|
367
|
+
const templateStep: MonitorStep =
|
|
368
|
+
recommendation.getMonitorStep(buildArgs());
|
|
369
|
+
const alertOnlyStep: MonitorStep = applyMode({
|
|
370
|
+
recommendation: recommendation,
|
|
371
|
+
notificationMode: MonitorRecommendationNotificationMode.Alert,
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
const templateIncidents: Array<CriteriaIncident> =
|
|
375
|
+
getBreachCriteriaInstances(templateStep).flatMap(
|
|
376
|
+
(criteriaInstance: MonitorCriteriaInstance) => {
|
|
377
|
+
return criteriaInstance.data?.incidents || [];
|
|
378
|
+
},
|
|
379
|
+
);
|
|
380
|
+
const alertOnlyIncidents: Array<CriteriaIncident> =
|
|
381
|
+
getBreachCriteriaInstances(alertOnlyStep).flatMap(
|
|
382
|
+
(criteriaInstance: MonitorCriteriaInstance) => {
|
|
383
|
+
return criteriaInstance.data?.incidents || [];
|
|
384
|
+
},
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
expect(alertOnlyIncidents.length).toBe(templateIncidents.length);
|
|
388
|
+
expect(alertOnlyIncidents.length).toBeGreaterThan(0);
|
|
389
|
+
|
|
390
|
+
alertOnlyIncidents.forEach(
|
|
391
|
+
(incident: CriteriaIncident, index: number) => {
|
|
392
|
+
expect(incident.title).toBe(templateIncidents[index]!.title);
|
|
393
|
+
expect(incident.description).toBe(
|
|
394
|
+
templateIncidents[index]!.description,
|
|
395
|
+
);
|
|
396
|
+
expect(incident.incidentSeverityId).toEqual(INCIDENT_SEVERITY_ID);
|
|
397
|
+
},
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
it("keeps the alert config intact when mode Incident switches alerts off", () => {
|
|
403
|
+
// The mirror image of the test above; the two toggles must behave alike.
|
|
404
|
+
for (const recommendation of ONE_PER_RESOURCE_TYPE) {
|
|
405
|
+
const templateStep: MonitorStep =
|
|
406
|
+
recommendation.getMonitorStep(buildArgs());
|
|
407
|
+
const incidentOnlyStep: MonitorStep = applyMode({
|
|
408
|
+
recommendation: recommendation,
|
|
409
|
+
notificationMode: MonitorRecommendationNotificationMode.Incident,
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
const templateAlerts: Array<CriteriaAlert> = getBreachCriteriaInstances(
|
|
413
|
+
templateStep,
|
|
414
|
+
).flatMap((criteriaInstance: MonitorCriteriaInstance) => {
|
|
415
|
+
return criteriaInstance.data?.alerts || [];
|
|
416
|
+
});
|
|
417
|
+
const incidentOnlyAlerts: Array<CriteriaAlert> =
|
|
418
|
+
getBreachCriteriaInstances(incidentOnlyStep).flatMap(
|
|
419
|
+
(criteriaInstance: MonitorCriteriaInstance) => {
|
|
420
|
+
return criteriaInstance.data?.alerts || [];
|
|
421
|
+
},
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
expect(incidentOnlyAlerts.length).toBe(templateAlerts.length);
|
|
425
|
+
expect(incidentOnlyAlerts.length).toBeGreaterThan(0);
|
|
426
|
+
|
|
427
|
+
incidentOnlyAlerts.forEach((alert: CriteriaAlert, index: number) => {
|
|
428
|
+
expect(alert.title).toBe(templateAlerts[index]!.title);
|
|
429
|
+
expect(alert.description).toBe(templateAlerts[index]!.description);
|
|
430
|
+
expect(alert.alertSeverityId).toEqual(ALERT_SEVERITY_ID);
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
it("applies the mode alongside on-call policies and severities rather than instead of them", () => {
|
|
436
|
+
/*
|
|
437
|
+
* The mode write and the owner/severity writes happen in the same pass
|
|
438
|
+
* over the criteria instances. A short-circuit in either direction —
|
|
439
|
+
* returning early once the mode is handled, or skipping the mode when
|
|
440
|
+
* other settings are present — would leave half of the create form's
|
|
441
|
+
* choices on the floor.
|
|
442
|
+
*/
|
|
443
|
+
const policyId: ObjectID = ObjectID.generate();
|
|
444
|
+
const criticalIncidentSeverityId: ObjectID = ObjectID.generate();
|
|
445
|
+
const warningIncidentSeverityId: ObjectID = ObjectID.generate();
|
|
446
|
+
|
|
447
|
+
for (const recommendation of ONE_PER_RESOURCE_TYPE) {
|
|
448
|
+
const monitorStep: MonitorStep =
|
|
449
|
+
MonitorRecommendationUtil.applyNotificationSettingsToMonitorStep({
|
|
450
|
+
monitorStep: recommendation.getMonitorStep(buildArgs()),
|
|
451
|
+
notificationSettings: {
|
|
452
|
+
notificationMode: MonitorRecommendationNotificationMode.Incident,
|
|
453
|
+
onCallPolicyIds: [policyId],
|
|
454
|
+
incidentSeverityIdBySeverity: {
|
|
455
|
+
Critical: criticalIncidentSeverityId,
|
|
456
|
+
Warning: warningIncidentSeverityId,
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
severity: recommendation.severity,
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
const expectedIncidentSeverityId: ObjectID =
|
|
463
|
+
recommendation.severity === "Critical"
|
|
464
|
+
? criticalIncidentSeverityId
|
|
465
|
+
: warningIncidentSeverityId;
|
|
466
|
+
|
|
467
|
+
for (const criteriaInstance of getBreachCriteriaInstances(
|
|
468
|
+
monitorStep,
|
|
469
|
+
)) {
|
|
470
|
+
expect(criteriaInstance.data?.createIncidents).toBe(true);
|
|
471
|
+
expect(criteriaInstance.data?.createAlerts).toBe(false);
|
|
472
|
+
|
|
473
|
+
for (const incident of criteriaInstance.data?.incidents || []) {
|
|
474
|
+
expect(incident.onCallPolicyIds).toEqual([policyId]);
|
|
475
|
+
expect(incident.incidentSeverityId).toEqual(
|
|
476
|
+
expectedIncidentSeverityId,
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
it("does not throw on a step with no criteria instances", () => {
|
|
484
|
+
/*
|
|
485
|
+
* The mode pass runs before anything reads a criteria instance's arrays.
|
|
486
|
+
* A hand-built or partially-deserialized step must not take the create
|
|
487
|
+
* flow down.
|
|
488
|
+
*/
|
|
489
|
+
for (const notificationMode of ALL_MODES) {
|
|
490
|
+
expect(() => {
|
|
491
|
+
MonitorRecommendationUtil.applyNotificationSettingsToMonitorStep({
|
|
492
|
+
monitorStep: new MonitorStep(),
|
|
493
|
+
notificationSettings: { notificationMode: notificationMode },
|
|
494
|
+
severity: "Critical",
|
|
495
|
+
});
|
|
496
|
+
}).not.toThrow();
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
describe("buildMonitorSteps with a notification mode", () => {
|
|
502
|
+
it("threads the mode through to the created monitor's criteria for every resource type", () => {
|
|
503
|
+
/*
|
|
504
|
+
* `buildMonitorSteps` is what the create flow actually calls;
|
|
505
|
+
* `applyNotificationSettingsToMonitorStep` is an implementation detail it
|
|
506
|
+
* happens to expose. If the wiring between them were dropped, every test
|
|
507
|
+
* above would still pass and the shipped feature would do nothing.
|
|
508
|
+
*/
|
|
509
|
+
for (const recommendation of ONE_PER_RESOURCE_TYPE) {
|
|
510
|
+
for (const notificationMode of ALL_MODES) {
|
|
511
|
+
const monitorSteps: MonitorSteps =
|
|
512
|
+
MonitorRecommendationUtil.buildMonitorSteps({
|
|
513
|
+
recommendation: recommendation,
|
|
514
|
+
args: buildArgs(),
|
|
515
|
+
defaultMonitorStatusId: DEFAULT_STATUS_ID,
|
|
516
|
+
notificationSettings: { notificationMode: notificationMode },
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
const monitorStep: MonitorStep =
|
|
520
|
+
monitorSteps.data!.monitorStepsInstanceArray[0]!;
|
|
521
|
+
|
|
522
|
+
const expectsIncidents: boolean =
|
|
523
|
+
notificationMode !== MonitorRecommendationNotificationMode.Alert;
|
|
524
|
+
const expectsAlerts: boolean =
|
|
525
|
+
notificationMode !== MonitorRecommendationNotificationMode.Incident;
|
|
526
|
+
|
|
527
|
+
for (const criteriaInstance of getBreachCriteriaInstances(
|
|
528
|
+
monitorStep,
|
|
529
|
+
)) {
|
|
530
|
+
expect(criteriaInstance.data?.createIncidents).toBe(
|
|
531
|
+
expectsIncidents,
|
|
532
|
+
);
|
|
533
|
+
expect(criteriaInstance.data?.createAlerts).toBe(expectsAlerts);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
it("still passes MonitorSteps.getValidationError under every mode, for every recommendation", () => {
|
|
540
|
+
/*
|
|
541
|
+
* `MonitorSteps.getValidationError` is the same client-side gate the
|
|
542
|
+
* monitor create form runs before POSTing, and it validates the incident
|
|
543
|
+
* and alert payloads regardless of whether their create flag is on. So a
|
|
544
|
+
* mode implementation that "disabled" a side by blanking a title or a
|
|
545
|
+
* severity id instead of clearing the flag would fail here — at submit
|
|
546
|
+
* time in production, with a message about a field the user was never
|
|
547
|
+
* shown, and only for the mode they happened to pick.
|
|
548
|
+
*/
|
|
549
|
+
for (const recommendation of ALL_RECOMMENDATIONS) {
|
|
550
|
+
for (const notificationMode of ALL_MODES) {
|
|
551
|
+
const monitorSteps: MonitorSteps =
|
|
552
|
+
MonitorRecommendationUtil.buildMonitorSteps({
|
|
553
|
+
recommendation: recommendation,
|
|
554
|
+
args: buildArgs(),
|
|
555
|
+
defaultMonitorStatusId: DEFAULT_STATUS_ID,
|
|
556
|
+
notificationSettings: { notificationMode: notificationMode },
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
expect(
|
|
560
|
+
MonitorSteps.getValidationError(
|
|
561
|
+
monitorSteps,
|
|
562
|
+
recommendation.monitorType,
|
|
563
|
+
),
|
|
564
|
+
).toBeNull();
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
it("builds independent steps, so one monitor's mode does not leak into the next", () => {
|
|
570
|
+
/*
|
|
571
|
+
* The recommendations page creates a batch of monitors in one submit, and
|
|
572
|
+
* `applyNotificationSettingsToMonitorStep` mutates the step it is given.
|
|
573
|
+
* If the template modules ever returned a shared/cached criteria instance
|
|
574
|
+
* instead of a fresh one, choosing Alert for one recommendation would
|
|
575
|
+
* silently rewrite the flags of every monitor built before it in the same
|
|
576
|
+
* batch.
|
|
577
|
+
*/
|
|
578
|
+
const recommendation: MonitorRecommendation = ONE_PER_RESOURCE_TYPE[0]!;
|
|
579
|
+
|
|
580
|
+
const incidentOnly: MonitorSteps =
|
|
581
|
+
MonitorRecommendationUtil.buildMonitorSteps({
|
|
582
|
+
recommendation: recommendation,
|
|
583
|
+
args: buildArgs(),
|
|
584
|
+
defaultMonitorStatusId: DEFAULT_STATUS_ID,
|
|
585
|
+
notificationSettings: {
|
|
586
|
+
notificationMode: MonitorRecommendationNotificationMode.Incident,
|
|
587
|
+
},
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
MonitorRecommendationUtil.buildMonitorSteps({
|
|
591
|
+
recommendation: recommendation,
|
|
592
|
+
args: buildArgs(),
|
|
593
|
+
defaultMonitorStatusId: DEFAULT_STATUS_ID,
|
|
594
|
+
notificationSettings: {
|
|
595
|
+
notificationMode: MonitorRecommendationNotificationMode.Alert,
|
|
596
|
+
},
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
for (const criteriaInstance of getBreachCriteriaInstances(
|
|
600
|
+
incidentOnly.data!.monitorStepsInstanceArray[0]!,
|
|
601
|
+
)) {
|
|
602
|
+
expect(criteriaInstance.data?.createIncidents).toBe(true);
|
|
603
|
+
expect(criteriaInstance.data?.createAlerts).toBe(false);
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
});
|
|
607
|
+
});
|