@oneuptime/common 14.0.8 → 14.0.9
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/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
- package/Models/DatabaseModels/Project.ts +55 -5
- package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
- package/Models/DatabaseModels/RunnerJob.ts +75 -0
- package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
- package/Server/API/AIChatAPI.ts +6 -3
- package/Server/API/AIInvestigationAPI.ts +17 -10
- package/Server/API/AutoRemediationAPI.ts +207 -25
- package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
- package/Server/API/MicrosoftTeamsAPI.ts +93 -14
- package/Server/API/ProxmoxResourceAPI.ts +244 -14
- package/Server/Infrastructure/GlobalCache.ts +32 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/TelemetryIngest.ts +41 -18
- package/Server/Services/AIService.ts +70 -1
- package/Server/Services/AlertService.ts +352 -11
- package/Server/Services/AlertSeverityService.ts +65 -15
- package/Server/Services/AutoRemediationRuleService.ts +1 -1
- package/Server/Services/IncidentService.ts +280 -104
- package/Server/Services/IncidentSeverityService.ts +66 -15
- package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
- package/Server/Services/KubernetesAiAgentService.ts +1634 -0
- package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
- package/Server/Services/KubernetesClusterService.ts +129 -21
- package/Server/Services/ProjectService.ts +32 -0
- package/Server/Services/ProxmoxResourceService.ts +322 -5
- package/Server/Services/RunnerJobService.ts +241 -104
- package/Server/Services/RunnerService.ts +1 -1
- package/Server/Services/ScheduledMaintenanceService.ts +737 -1
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
- package/Server/Services/TeamComplianceSettingService.ts +1125 -9
- package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
- package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
- package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
- package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
- package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
- package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
- package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
- package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
- package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
- package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
- package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
- package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
- package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
- package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
- package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
- package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
- package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
- package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
- package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
- package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
- package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
- package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
- package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
- package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
- package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
- package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
- package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
- package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
- package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
- package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
- package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
- package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
- package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
- package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
- package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
- package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
- package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
- package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
- package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
- package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
- package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
- package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
- package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
- package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
- package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
- package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
- package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
- package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
- package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
- package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
- package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
- package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
- package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
- package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
- package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
- package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
- package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
- package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
- package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
- package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
- package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
- package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
- package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
- package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
- package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
- package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
- package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
- package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
- package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
- package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
- package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
- package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
- package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
- package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
- package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
- package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
- package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
- package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
- package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
- package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
- package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
- package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
- package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
- package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
- package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
- package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
- package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
- package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
- package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
- package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
- package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
- package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
- package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
- package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
- package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
- package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
- package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
- package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
- package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
- package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
- package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
- package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
- package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
- package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
- package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
- package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
- package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
- package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
- package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
- package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
- package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
- package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
- package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
- package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
- package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
- package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
- package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
- package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
- package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
- package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
- package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
- package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
- package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
- package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
- package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
- package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
- package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
- package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
- package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
- package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
- package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
- package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
- package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
- package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
- package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
- package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
- package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
- package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
- package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
- package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
- package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
- package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
- package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
- package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
- package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
- package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
- package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
- package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
- package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
- package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
- package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
- package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
- package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
- package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
- package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
- package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
- package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
- package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
- package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
- package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
- package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
- package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
- package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
- package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
- package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
- package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
- package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
- package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
- package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
- package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
- package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
- package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
- package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
- package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
- package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
- package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
- package/Tests/UI/Components/Input.test.tsx +80 -1
- package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
- package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
- package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
- package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
- package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
- package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
- package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
- package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
- package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
- package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
- package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
- package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
- package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
- package/Tests/UI/Components/Toggle.test.tsx +66 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
- package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
- package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
- package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
- package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
- package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
- package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
- package/Types/AI/AIRunType.ts +9 -4
- package/Types/AI/InvestigationNotStartedReason.ts +6 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
- package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
- package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
- package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
- package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
- package/Types/Team/ComplianceNotificationChannel.ts +22 -0
- package/Types/Team/ComplianceRule.ts +434 -0
- package/Types/Team/ComplianceRuleType.ts +21 -0
- package/Types/Team/TeamComplianceStatus.ts +81 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
- package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
- package/UI/Components/ActionButton/RowActions.tsx +238 -0
- package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
- package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
- package/UI/Components/Charts/Line/LineChart.tsx +32 -2
- package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
- package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
- package/UI/Components/Charts/Utils/XAxis.ts +75 -0
- package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
- package/UI/Components/Forms/Fields/FormField.tsx +10 -0
- package/UI/Components/Input/Input.tsx +90 -57
- package/UI/Components/List/ListRow.tsx +8 -74
- package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
- package/UI/Components/OrderedStatesList/Item.tsx +7 -72
- package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
- package/UI/Components/Table/TableBody.tsx +8 -2
- package/UI/Components/Table/TableRow.tsx +20 -140
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
- package/UI/Components/TelemetryViewer/types.ts +2 -0
- package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
- package/UI/Components/Toggle/Toggle.tsx +26 -0
- package/UI/Components/Tooltip/Tooltip.tsx +8 -1
- package/UI/Styles/Theme.css +14 -2
- package/Utils/AiRemediation/CommandPolicy.ts +1 -1
- package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
- package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +56 -5
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +6 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
- package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +59 -1
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +248 -13
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +51 -15
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +199 -72
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
- package/build/dist/Server/Services/RunnerJobService.js +178 -92
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/RunnerService.js +1 -1
- package/build/dist/Server/Services/RunnerService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIRunType.js +9 -4
- package/build/dist/Types/AI/AIRunType.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRule.js +304 -0
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
- package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
- package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
- package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
- package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +69 -54
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/List/ListRow.js +4 -39
- package/build/dist/UI/Components/List/ListRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
- package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +6 -2
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +12 -75
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
- package/package.json +1 -1
|
@@ -96,6 +96,77 @@ import SafeHtml from "../../Types/SafeHtml";
|
|
|
96
96
|
import StatusPageSubscriberNotificationTemplate from "../../Models/DatabaseModels/StatusPageSubscriberNotificationTemplate";
|
|
97
97
|
import StatusPageSubscriberNotificationEventType from "../../Types/StatusPage/StatusPageSubscriberNotificationEventType";
|
|
98
98
|
import StatusPageSubscriberNotificationMethod from "../../Types/StatusPage/StatusPageSubscriberNotificationMethod";
|
|
99
|
+
import NetworkSite from "../../Models/DatabaseModels/NetworkSite";
|
|
100
|
+
import Select from "../Types/Database/Select";
|
|
101
|
+
|
|
102
|
+
/*
|
|
103
|
+
* The attachments whose membership an ongoing event acts on. Monitors are
|
|
104
|
+
* put into maintenance by a flag and a status written onto them, and network
|
|
105
|
+
* sites by re-rolling the chains above them, so an edit to either list while
|
|
106
|
+
* the window runs has to do what the state transition did for the old list.
|
|
107
|
+
*/
|
|
108
|
+
type AttachmentColumn = "monitors" | "networkSites";
|
|
109
|
+
|
|
110
|
+
const ATTACHMENT_COLUMNS: Array<AttachmentColumn> = [
|
|
111
|
+
"monitors",
|
|
112
|
+
"networkSites",
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
/*
|
|
116
|
+
* Enough of a state to tell which kind it is. A project can add its own
|
|
117
|
+
* states between the built-in ones, and those are none of the four kinds.
|
|
118
|
+
*/
|
|
119
|
+
const STATE_KIND_SELECT: Select<ScheduledMaintenanceState> = {
|
|
120
|
+
_id: true,
|
|
121
|
+
isScheduledState: true,
|
|
122
|
+
isOngoingState: true,
|
|
123
|
+
isEndedState: true,
|
|
124
|
+
isResolvedState: true,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/*
|
|
128
|
+
* What onBeforeUpdate hands to onUpdateSuccess for one event the update
|
|
129
|
+
* matched: the lists the event held just before the write, and what its
|
|
130
|
+
* state meant for them. The state after the write can differ - the same
|
|
131
|
+
* update can move the event, and so can the ChangeStateToOngoing job or
|
|
132
|
+
* another request between this read and the write - so
|
|
133
|
+
* applyAttachmentChangeToEvent weighs both.
|
|
134
|
+
*
|
|
135
|
+
* Only the ids the event held are kept, not the ids the payload asked for.
|
|
136
|
+
* The write drops list entries it cannot read as an id (see
|
|
137
|
+
* DatabaseService.sanitizeCreateOrUpdate), so the payload can name a
|
|
138
|
+
* monitor that never gets attached, or leave out one it seems to keep. What
|
|
139
|
+
* changed is read back from the event after the write instead.
|
|
140
|
+
*/
|
|
141
|
+
type AttachmentsBeforeUpdate = {
|
|
142
|
+
projectId: ObjectID | undefined;
|
|
143
|
+
// Live ongoing: what suppresses the event's network sites.
|
|
144
|
+
wasOngoingBeforeUpdate: boolean;
|
|
145
|
+
// Ongoing, or past it without having ended: what keeps monitors disabled.
|
|
146
|
+
wasHoldingMonitorsBeforeUpdate: boolean;
|
|
147
|
+
// Undefined when the update does not write that list.
|
|
148
|
+
monitorIdsBeforeUpdate: Array<ObjectID> | undefined;
|
|
149
|
+
networkSiteIdsBeforeUpdate: Array<ObjectID> | undefined;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Keyed by event id.
|
|
153
|
+
type UpdateCarryForward = Dictionary<AttachmentsBeforeUpdate>;
|
|
154
|
+
|
|
155
|
+
/*
|
|
156
|
+
* What the write actually attached to and detached from one event, from its
|
|
157
|
+
* lists before and after.
|
|
158
|
+
*/
|
|
159
|
+
type AttachmentChange = {
|
|
160
|
+
monitorsAdded: Array<ObjectID>;
|
|
161
|
+
monitorsRemoved: Array<ObjectID>;
|
|
162
|
+
// Attached or detached - both edges re-roll the same way.
|
|
163
|
+
networkSitesChanged: Array<ObjectID>;
|
|
164
|
+
/*
|
|
165
|
+
* The event as read back with its monitors, carrying the state it is in
|
|
166
|
+
* now and the status it applies. Null when the monitors were not written.
|
|
167
|
+
*/
|
|
168
|
+
eventAfterUpdate: Model | null;
|
|
169
|
+
};
|
|
99
170
|
|
|
100
171
|
export class Service extends DatabaseService<Model> {
|
|
101
172
|
public constructor() {
|
|
@@ -703,6 +774,13 @@ ${resourcesAffected ? `**Resources Affected:** ${resourcesAffected}` : ""}
|
|
|
703
774
|
|
|
704
775
|
await this.validateProjectScopedReferences(updateBy);
|
|
705
776
|
|
|
777
|
+
/*
|
|
778
|
+
* Read before the write, because afterwards the detached monitors are no
|
|
779
|
+
* longer on the event and nothing else remembers them.
|
|
780
|
+
*/
|
|
781
|
+
const carryForward: UpdateCarryForward | null =
|
|
782
|
+
await this.getAttachmentsBeforeUpdate(updateBy);
|
|
783
|
+
|
|
706
784
|
/*
|
|
707
785
|
* Re-apply mapped custom field values. Covers the Custom Fields modal
|
|
708
786
|
* saving the whole bag back over a mapped value, and the event's monitors
|
|
@@ -716,10 +794,161 @@ ${resourcesAffected ? `**Resources Affected:** ${resourcesAffected}` : ""}
|
|
|
716
794
|
|
|
717
795
|
return {
|
|
718
796
|
updateBy,
|
|
719
|
-
carryForward:
|
|
797
|
+
carryForward: carryForward,
|
|
720
798
|
};
|
|
721
799
|
}
|
|
722
800
|
|
|
801
|
+
/*
|
|
802
|
+
* The monitors and network sites each event the update matches holds just
|
|
803
|
+
* before the write, for onUpdateSuccess to compare with what it holds
|
|
804
|
+
* after. Null, with nothing read, unless the payload writes one of those
|
|
805
|
+
* lists.
|
|
806
|
+
*
|
|
807
|
+
* Read as root but held to the tenant's project, like the other update
|
|
808
|
+
* reads here; the permission checks that narrow the write run after this
|
|
809
|
+
* hook, so an event read here that the write then skips is simply never
|
|
810
|
+
* looked up again (onUpdateSuccess only visits the rows actually written).
|
|
811
|
+
*/
|
|
812
|
+
private async getAttachmentsBeforeUpdate(
|
|
813
|
+
updateBy: UpdateBy<Model>,
|
|
814
|
+
): Promise<UpdateCarryForward | null> {
|
|
815
|
+
const columns: Array<AttachmentColumn> = ATTACHMENT_COLUMNS.filter(
|
|
816
|
+
(column: AttachmentColumn): boolean => {
|
|
817
|
+
/*
|
|
818
|
+
* Only a list that is left out is left alone. Null or an empty list
|
|
819
|
+
* can clear it, and whatever the write makes of any payload is read
|
|
820
|
+
* back afterwards, so every written list is remembered here.
|
|
821
|
+
*/
|
|
822
|
+
return (updateBy.data as Dictionary<unknown>)[column] !== undefined;
|
|
823
|
+
},
|
|
824
|
+
);
|
|
825
|
+
|
|
826
|
+
if (columns.length === 0) {
|
|
827
|
+
return null;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
const carryForward: UpdateCarryForward = {};
|
|
831
|
+
|
|
832
|
+
/*
|
|
833
|
+
* One read per list. A find that selects two many-to-many relations
|
|
834
|
+
* returns a row for every combination of their ids. See
|
|
835
|
+
* ProjectScopedReferenceValidator.getHeldRelationIds.
|
|
836
|
+
*/
|
|
837
|
+
for (const column of columns) {
|
|
838
|
+
const select: Select<Model> = {
|
|
839
|
+
_id: true,
|
|
840
|
+
projectId: true,
|
|
841
|
+
currentScheduledMaintenanceState: STATE_KIND_SELECT,
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
if (column === "monitors") {
|
|
845
|
+
select.monitors = {
|
|
846
|
+
_id: true,
|
|
847
|
+
};
|
|
848
|
+
} else {
|
|
849
|
+
select.networkSites = {
|
|
850
|
+
_id: true,
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
const scheduledMaintenanceEvents: Array<Model> = await this.findBy({
|
|
855
|
+
query: updateBy.props.tenantId
|
|
856
|
+
? { ...updateBy.query, projectId: updateBy.props.tenantId }
|
|
857
|
+
: updateBy.query,
|
|
858
|
+
select: select,
|
|
859
|
+
limit: LIMIT_MAX,
|
|
860
|
+
skip: 0,
|
|
861
|
+
props: {
|
|
862
|
+
isRoot: true,
|
|
863
|
+
},
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
for (const scheduledMaintenanceEvent of scheduledMaintenanceEvents) {
|
|
867
|
+
if (!scheduledMaintenanceEvent.id) {
|
|
868
|
+
continue;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
const eventKey: string = scheduledMaintenanceEvent.id.toString();
|
|
872
|
+
|
|
873
|
+
const attachmentsBeforeUpdate: AttachmentsBeforeUpdate = carryForward[
|
|
874
|
+
eventKey
|
|
875
|
+
] || {
|
|
876
|
+
projectId: undefined,
|
|
877
|
+
wasOngoingBeforeUpdate: false,
|
|
878
|
+
wasHoldingMonitorsBeforeUpdate: false,
|
|
879
|
+
monitorIdsBeforeUpdate: undefined,
|
|
880
|
+
networkSiteIdsBeforeUpdate: undefined,
|
|
881
|
+
};
|
|
882
|
+
|
|
883
|
+
attachmentsBeforeUpdate.projectId = scheduledMaintenanceEvent.projectId;
|
|
884
|
+
attachmentsBeforeUpdate.wasOngoingBeforeUpdate = Boolean(
|
|
885
|
+
scheduledMaintenanceEvent.currentScheduledMaintenanceState
|
|
886
|
+
?.isOngoingState,
|
|
887
|
+
);
|
|
888
|
+
|
|
889
|
+
if (column === "monitors") {
|
|
890
|
+
attachmentsBeforeUpdate.monitorIdsBeforeUpdate = this.getIdsNotIn({
|
|
891
|
+
ids: resolveReferenceIds(scheduledMaintenanceEvent.monitors),
|
|
892
|
+
exclude: [],
|
|
893
|
+
});
|
|
894
|
+
|
|
895
|
+
// Only monitors are held; sites follow the live state.
|
|
896
|
+
attachmentsBeforeUpdate.wasHoldingMonitorsBeforeUpdate =
|
|
897
|
+
await ScheduledMaintenanceStateTimelineService.isScheduledMaintenanceHoldingMonitors(
|
|
898
|
+
{
|
|
899
|
+
scheduledMaintenanceId: scheduledMaintenanceEvent.id,
|
|
900
|
+
projectId: scheduledMaintenanceEvent.projectId,
|
|
901
|
+
currentState:
|
|
902
|
+
scheduledMaintenanceEvent.currentScheduledMaintenanceState,
|
|
903
|
+
},
|
|
904
|
+
);
|
|
905
|
+
} else {
|
|
906
|
+
attachmentsBeforeUpdate.networkSiteIdsBeforeUpdate = this.getIdsNotIn(
|
|
907
|
+
{
|
|
908
|
+
ids: resolveReferenceIds(scheduledMaintenanceEvent.networkSites),
|
|
909
|
+
exclude: [],
|
|
910
|
+
},
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
carryForward[eventKey] = attachmentsBeforeUpdate;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
return carryForward;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/*
|
|
922
|
+
* The ids in `ids` that `exclude` does not hold, each once and lower-cased
|
|
923
|
+
* (with nothing to exclude, a list read the same way). Compared case-blind,
|
|
924
|
+
* so an id that reached one side in another case is never reported as
|
|
925
|
+
* both removed and added.
|
|
926
|
+
*/
|
|
927
|
+
private getIdsNotIn(data: {
|
|
928
|
+
ids: Array<ObjectID | string>;
|
|
929
|
+
exclude: Array<ObjectID | string>;
|
|
930
|
+
}): Array<ObjectID> {
|
|
931
|
+
const excludedKeys: Set<string> = new Set<string>(
|
|
932
|
+
data.exclude.map((id: ObjectID | string): string => {
|
|
933
|
+
return id.toString().trim().toLowerCase();
|
|
934
|
+
}),
|
|
935
|
+
);
|
|
936
|
+
|
|
937
|
+
const result: Map<string, ObjectID> = new Map<string, ObjectID>();
|
|
938
|
+
|
|
939
|
+
for (const id of data.ids) {
|
|
940
|
+
const key: string = id.toString().trim().toLowerCase();
|
|
941
|
+
|
|
942
|
+
if (!key || excludedKeys.has(key) || result.has(key)) {
|
|
943
|
+
continue;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
result.set(key, new ObjectID(key));
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
return Array.from(result.values());
|
|
950
|
+
}
|
|
951
|
+
|
|
723
952
|
/*
|
|
724
953
|
* An update can repoint a scheduled maintenance event at another project's
|
|
725
954
|
* state or monitor status just as easily as a create can, and the result is
|
|
@@ -1755,6 +1984,443 @@ ${scheduledMaintenance.description || "No description provided."}
|
|
|
1755
1984
|
}
|
|
1756
1985
|
}
|
|
1757
1986
|
|
|
1987
|
+
/*
|
|
1988
|
+
* What the write actually changed on one event: its lists as read back
|
|
1989
|
+
* now, against the ones onBeforeUpdate read before the write. Comparing
|
|
1990
|
+
* with the payload instead would trust entries the write may have dropped
|
|
1991
|
+
* (see AttachmentsBeforeUpdate) - a monitor put into maintenance without
|
|
1992
|
+
* being attached could never be restored, since ending or deleting the
|
|
1993
|
+
* event only reaches the monitors it holds.
|
|
1994
|
+
*
|
|
1995
|
+
* The monitors are read back whenever they were written, because the feed
|
|
1996
|
+
* names the change on any event. The sites are only needed by an event
|
|
1997
|
+
* that was suppressing them.
|
|
1998
|
+
*/
|
|
1999
|
+
private async getAttachmentChange(data: {
|
|
2000
|
+
scheduledMaintenanceId: ObjectID;
|
|
2001
|
+
attachmentsBeforeUpdate: AttachmentsBeforeUpdate;
|
|
2002
|
+
}): Promise<AttachmentChange> {
|
|
2003
|
+
const attachmentsBeforeUpdate: AttachmentsBeforeUpdate =
|
|
2004
|
+
data.attachmentsBeforeUpdate;
|
|
2005
|
+
|
|
2006
|
+
const change: AttachmentChange = {
|
|
2007
|
+
monitorsAdded: [],
|
|
2008
|
+
monitorsRemoved: [],
|
|
2009
|
+
networkSitesChanged: [],
|
|
2010
|
+
eventAfterUpdate: null,
|
|
2011
|
+
};
|
|
2012
|
+
|
|
2013
|
+
const monitorIdsBeforeUpdate: Array<ObjectID> | undefined =
|
|
2014
|
+
attachmentsBeforeUpdate.monitorIdsBeforeUpdate;
|
|
2015
|
+
|
|
2016
|
+
if (monitorIdsBeforeUpdate) {
|
|
2017
|
+
const eventAfterUpdate: Model | null = await this.findOneById({
|
|
2018
|
+
id: data.scheduledMaintenanceId,
|
|
2019
|
+
select: {
|
|
2020
|
+
_id: true,
|
|
2021
|
+
changeMonitorStatusToId: true,
|
|
2022
|
+
currentScheduledMaintenanceState: STATE_KIND_SELECT,
|
|
2023
|
+
monitors: {
|
|
2024
|
+
_id: true,
|
|
2025
|
+
},
|
|
2026
|
+
},
|
|
2027
|
+
props: {
|
|
2028
|
+
isRoot: true,
|
|
2029
|
+
},
|
|
2030
|
+
});
|
|
2031
|
+
|
|
2032
|
+
/*
|
|
2033
|
+
* An event that cannot be read back was deleted since the write, and
|
|
2034
|
+
* its delete hook deals with whatever it held.
|
|
2035
|
+
*/
|
|
2036
|
+
if (eventAfterUpdate) {
|
|
2037
|
+
const monitorIdsAfterUpdate: Array<ObjectID | string> =
|
|
2038
|
+
resolveReferenceIds(eventAfterUpdate.monitors);
|
|
2039
|
+
|
|
2040
|
+
change.monitorsAdded = this.getIdsNotIn({
|
|
2041
|
+
ids: monitorIdsAfterUpdate,
|
|
2042
|
+
exclude: monitorIdsBeforeUpdate,
|
|
2043
|
+
});
|
|
2044
|
+
change.monitorsRemoved = this.getIdsNotIn({
|
|
2045
|
+
ids: monitorIdsBeforeUpdate,
|
|
2046
|
+
exclude: monitorIdsAfterUpdate,
|
|
2047
|
+
});
|
|
2048
|
+
change.eventAfterUpdate = eventAfterUpdate;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
const networkSiteIdsBeforeUpdate: Array<ObjectID> | undefined =
|
|
2053
|
+
attachmentsBeforeUpdate.networkSiteIdsBeforeUpdate;
|
|
2054
|
+
|
|
2055
|
+
if (
|
|
2056
|
+
networkSiteIdsBeforeUpdate &&
|
|
2057
|
+
attachmentsBeforeUpdate.wasOngoingBeforeUpdate
|
|
2058
|
+
) {
|
|
2059
|
+
// A read of its own, for the same reason as in onBeforeUpdate.
|
|
2060
|
+
const eventAfterUpdate: Model | null = await this.findOneById({
|
|
2061
|
+
id: data.scheduledMaintenanceId,
|
|
2062
|
+
select: {
|
|
2063
|
+
_id: true,
|
|
2064
|
+
networkSites: {
|
|
2065
|
+
_id: true,
|
|
2066
|
+
},
|
|
2067
|
+
},
|
|
2068
|
+
props: {
|
|
2069
|
+
isRoot: true,
|
|
2070
|
+
},
|
|
2071
|
+
});
|
|
2072
|
+
|
|
2073
|
+
if (eventAfterUpdate) {
|
|
2074
|
+
const networkSiteIdsAfterUpdate: Array<ObjectID | string> =
|
|
2075
|
+
resolveReferenceIds(eventAfterUpdate.networkSites);
|
|
2076
|
+
|
|
2077
|
+
change.networkSitesChanged = [
|
|
2078
|
+
...this.getIdsNotIn({
|
|
2079
|
+
ids: networkSiteIdsAfterUpdate,
|
|
2080
|
+
exclude: networkSiteIdsBeforeUpdate,
|
|
2081
|
+
}),
|
|
2082
|
+
...this.getIdsNotIn({
|
|
2083
|
+
ids: networkSiteIdsBeforeUpdate,
|
|
2084
|
+
exclude: networkSiteIdsAfterUpdate,
|
|
2085
|
+
}),
|
|
2086
|
+
];
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
return change;
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
/*
|
|
2094
|
+
* Moving to ongoing puts the attached monitors into maintenance (the flag
|
|
2095
|
+
* that stops probing, and the configured status) and ending restores the
|
|
2096
|
+
* ones attached at that moment. Both read the list only at the transition,
|
|
2097
|
+
* so a monitor detached mid-window would stay disabled for good - ending
|
|
2098
|
+
* or deleting the event no longer reaches it, and the flag is not
|
|
2099
|
+
* user-editable - and one attached mid-window would keep being probed and
|
|
2100
|
+
* alerting. This does for the edited part of the list what the
|
|
2101
|
+
* transitions did for the rest.
|
|
2102
|
+
*
|
|
2103
|
+
* Monitors are acted on while the event holds them (see
|
|
2104
|
+
* ScheduledMaintenanceStateTimelineService.isScheduledMaintenanceHoldingMonitors):
|
|
2105
|
+
* a scheduled event picks up its list when it starts, and an ended one
|
|
2106
|
+
* has nothing held. Network sites are suppressed only while the event is
|
|
2107
|
+
* live in an ongoing state.
|
|
2108
|
+
*
|
|
2109
|
+
* The write has already committed, so nothing here may undo it or turn it
|
|
2110
|
+
* into an error. Each step fails on its own, and each monitor within a
|
|
2111
|
+
* step, logged; the steps after it still run.
|
|
2112
|
+
*/
|
|
2113
|
+
private async applyAttachmentChangeToEvent(data: {
|
|
2114
|
+
scheduledMaintenanceId: ObjectID;
|
|
2115
|
+
attachmentsBeforeUpdate: AttachmentsBeforeUpdate;
|
|
2116
|
+
change: AttachmentChange;
|
|
2117
|
+
}): Promise<void> {
|
|
2118
|
+
const attachmentsBeforeUpdate: AttachmentsBeforeUpdate =
|
|
2119
|
+
data.attachmentsBeforeUpdate;
|
|
2120
|
+
const change: AttachmentChange = data.change;
|
|
2121
|
+
const projectId: ObjectID | undefined = attachmentsBeforeUpdate.projectId;
|
|
2122
|
+
|
|
2123
|
+
if (!projectId) {
|
|
2124
|
+
return;
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
const logAttributes: LogAttributes = {
|
|
2128
|
+
projectId: projectId.toString(),
|
|
2129
|
+
scheduledMaintenanceId: data.scheduledMaintenanceId.toString(),
|
|
2130
|
+
} as LogAttributes;
|
|
2131
|
+
|
|
2132
|
+
const wasHoldingMonitorsBeforeUpdate: boolean =
|
|
2133
|
+
attachmentsBeforeUpdate.wasHoldingMonitorsBeforeUpdate;
|
|
2134
|
+
|
|
2135
|
+
/*
|
|
2136
|
+
* Whether the event holds its monitors now, as read back after the write
|
|
2137
|
+
* and after any state change the same update made. The state can also
|
|
2138
|
+
* move between onBeforeUpdate's read and the write - the
|
|
2139
|
+
* ChangeStateToOngoing job starting the event, or another request
|
|
2140
|
+
* changing its state - so the state before the write cannot decide
|
|
2141
|
+
* either list alone. Read only when it can change what happens.
|
|
2142
|
+
*
|
|
2143
|
+
* If it cannot be read, nothing new is held: a monitor probed through
|
|
2144
|
+
* the window is better than one disabled with nothing to restore it.
|
|
2145
|
+
*/
|
|
2146
|
+
let isHoldingMonitorsAfterUpdate: boolean = false;
|
|
2147
|
+
|
|
2148
|
+
if (
|
|
2149
|
+
change.eventAfterUpdate &&
|
|
2150
|
+
(change.monitorsAdded.length > 0 ||
|
|
2151
|
+
(change.monitorsRemoved.length > 0 && !wasHoldingMonitorsBeforeUpdate))
|
|
2152
|
+
) {
|
|
2153
|
+
try {
|
|
2154
|
+
isHoldingMonitorsAfterUpdate =
|
|
2155
|
+
await ScheduledMaintenanceStateTimelineService.isScheduledMaintenanceHoldingMonitors(
|
|
2156
|
+
{
|
|
2157
|
+
scheduledMaintenanceId: data.scheduledMaintenanceId,
|
|
2158
|
+
projectId: projectId,
|
|
2159
|
+
currentState:
|
|
2160
|
+
change.eventAfterUpdate.currentScheduledMaintenanceState,
|
|
2161
|
+
},
|
|
2162
|
+
);
|
|
2163
|
+
} catch (err) {
|
|
2164
|
+
logger.error(
|
|
2165
|
+
`ScheduledMaintenanceService.applyAttachmentChangeToEvent: could not read whether scheduled maintenance ${data.scheduledMaintenanceId.toString()} holds its monitors after the update; holding none of the monitors it attached.`,
|
|
2166
|
+
logAttributes,
|
|
2167
|
+
);
|
|
2168
|
+
logger.error(err, logAttributes);
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
/*
|
|
2173
|
+
* A detached monitor is released if the event held its monitors on
|
|
2174
|
+
* either side of the write: before it, or after it when the event
|
|
2175
|
+
* started in between and the transition flagged the list it read then,
|
|
2176
|
+
* which may still have had this monitor on it. Only the monitors
|
|
2177
|
+
* actually flagged are released (see restoreMonitorsDetachedFromEvent).
|
|
2178
|
+
*/
|
|
2179
|
+
if (
|
|
2180
|
+
change.monitorsRemoved.length > 0 &&
|
|
2181
|
+
(wasHoldingMonitorsBeforeUpdate || isHoldingMonitorsAfterUpdate)
|
|
2182
|
+
) {
|
|
2183
|
+
try {
|
|
2184
|
+
await this.restoreMonitorsDetachedFromEvent({
|
|
2185
|
+
scheduledMaintenanceId: data.scheduledMaintenanceId,
|
|
2186
|
+
projectId: projectId,
|
|
2187
|
+
monitorIds: change.monitorsRemoved,
|
|
2188
|
+
});
|
|
2189
|
+
} catch (err) {
|
|
2190
|
+
logger.error(
|
|
2191
|
+
`ScheduledMaintenanceService.applyAttachmentChangeToEvent: could not restore the monitors detached from scheduled maintenance ${data.scheduledMaintenanceId.toString()}.`,
|
|
2192
|
+
logAttributes,
|
|
2193
|
+
);
|
|
2194
|
+
logger.error(err, logAttributes);
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
/*
|
|
2199
|
+
* An attached monitor is held when the event holds its monitors after
|
|
2200
|
+
* the write, whatever it was doing before: the job (or another request)
|
|
2201
|
+
* can have started it between onBeforeUpdate's read and the write,
|
|
2202
|
+
* flagging the list without this monitor. A transition that ran after
|
|
2203
|
+
* the write - the same update started the event, or the job did just
|
|
2204
|
+
* after - has reached this monitor already, and holding it again
|
|
2205
|
+
* changes nothing. An event the same update ended has had its whole list
|
|
2206
|
+
* restored by the transition, and holds nothing.
|
|
2207
|
+
*/
|
|
2208
|
+
if (
|
|
2209
|
+
change.monitorsAdded.length > 0 &&
|
|
2210
|
+
isHoldingMonitorsAfterUpdate &&
|
|
2211
|
+
change.eventAfterUpdate
|
|
2212
|
+
) {
|
|
2213
|
+
await this.holdMonitorsAttachedToEvent({
|
|
2214
|
+
scheduledMaintenanceId: data.scheduledMaintenanceId,
|
|
2215
|
+
projectId: projectId,
|
|
2216
|
+
monitorIds: change.monitorsAdded,
|
|
2217
|
+
changeMonitorStatusToId:
|
|
2218
|
+
change.eventAfterUpdate.changeMonitorStatusToId,
|
|
2219
|
+
});
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
/*
|
|
2223
|
+
* Sites are suppressed by the live attachment, so the edit itself has
|
|
2224
|
+
* already taken effect; this only re-rolls the chains now rather than at
|
|
2225
|
+
* the next stale sweep, as the state transition does. Detached sites
|
|
2226
|
+
* need it as much as attached ones: they were suppressed until now.
|
|
2227
|
+
* recomputeNetworkSiteRollups logs its own failures.
|
|
2228
|
+
*/
|
|
2229
|
+
if (
|
|
2230
|
+
attachmentsBeforeUpdate.wasOngoingBeforeUpdate &&
|
|
2231
|
+
change.networkSitesChanged.length > 0
|
|
2232
|
+
) {
|
|
2233
|
+
const eventWithChangedSites: Model = new Model(
|
|
2234
|
+
data.scheduledMaintenanceId,
|
|
2235
|
+
);
|
|
2236
|
+
eventWithChangedSites.projectId = projectId;
|
|
2237
|
+
eventWithChangedSites.networkSites = change.networkSitesChanged.map(
|
|
2238
|
+
(siteId: ObjectID): NetworkSite => {
|
|
2239
|
+
return new NetworkSite(siteId);
|
|
2240
|
+
},
|
|
2241
|
+
);
|
|
2242
|
+
|
|
2243
|
+
await ScheduledMaintenanceStateTimelineService.recomputeNetworkSiteRollups(
|
|
2244
|
+
eventWithChangedSites,
|
|
2245
|
+
);
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
/*
|
|
2250
|
+
* Releases the monitors an edit detached from an event that was holding
|
|
2251
|
+
* them, exactly as ending the event releases its list:
|
|
2252
|
+
* enableActiveMonitoringForMonitors clears the flag and puts each back in
|
|
2253
|
+
* the operational status, skipping a monitor another event still holds
|
|
2254
|
+
* and carrying on past one that fails. This event no longer counts as
|
|
2255
|
+
* holding them: the write has already removed them from it.
|
|
2256
|
+
*
|
|
2257
|
+
* Only a monitor whose flag is set is released. That the event held its
|
|
2258
|
+
* monitors says it held the list it read when it started, not that it
|
|
2259
|
+
* held this monitor: an event the same update (or the job, just after the
|
|
2260
|
+
* write) started never flagged a monitor the write had already detached,
|
|
2261
|
+
* and one ended by another request just before the write has released it
|
|
2262
|
+
* already. Released anyway, that monitor would be forced into the
|
|
2263
|
+
* operational status over the one it is really in.
|
|
2264
|
+
*/
|
|
2265
|
+
private async restoreMonitorsDetachedFromEvent(data: {
|
|
2266
|
+
scheduledMaintenanceId: ObjectID;
|
|
2267
|
+
projectId: ObjectID;
|
|
2268
|
+
monitorIds: Array<ObjectID>;
|
|
2269
|
+
}): Promise<void> {
|
|
2270
|
+
const heldMonitors: Array<Monitor> = await MonitorService.findBy({
|
|
2271
|
+
query: {
|
|
2272
|
+
_id: QueryHelper.any(data.monitorIds),
|
|
2273
|
+
projectId: data.projectId,
|
|
2274
|
+
disableActiveMonitoringBecauseOfScheduledMaintenanceEvent: true,
|
|
2275
|
+
},
|
|
2276
|
+
select: {
|
|
2277
|
+
_id: true,
|
|
2278
|
+
},
|
|
2279
|
+
limit: LIMIT_MAX,
|
|
2280
|
+
skip: 0,
|
|
2281
|
+
props: {
|
|
2282
|
+
isRoot: true,
|
|
2283
|
+
},
|
|
2284
|
+
});
|
|
2285
|
+
|
|
2286
|
+
if (heldMonitors.length === 0) {
|
|
2287
|
+
return;
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
const eventWithRemovedMonitors: Model = new Model(
|
|
2291
|
+
data.scheduledMaintenanceId,
|
|
2292
|
+
);
|
|
2293
|
+
eventWithRemovedMonitors.projectId = data.projectId;
|
|
2294
|
+
eventWithRemovedMonitors.monitors = this.getIdsNotIn({
|
|
2295
|
+
ids: resolveReferenceIds(heldMonitors),
|
|
2296
|
+
exclude: [],
|
|
2297
|
+
}).map((monitorId: ObjectID): Monitor => {
|
|
2298
|
+
return new Monitor(monitorId);
|
|
2299
|
+
});
|
|
2300
|
+
|
|
2301
|
+
await ScheduledMaintenanceStateTimelineService.enableActiveMonitoringForMonitors(
|
|
2302
|
+
eventWithRemovedMonitors,
|
|
2303
|
+
);
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
/*
|
|
2307
|
+
* Puts the monitors an edit attached into maintenance, as entering ongoing
|
|
2308
|
+
* does for the list (ScheduledMaintenanceStateTimelineService): the flag
|
|
2309
|
+
* that stops probing, then the status the event applies, if any. Both are
|
|
2310
|
+
* idempotent, so a monitor the transition has reached as well - the event
|
|
2311
|
+
* started just after the write - is left as it is.
|
|
2312
|
+
*
|
|
2313
|
+
* One monitor at a time, as the release is: one that fails must not leave
|
|
2314
|
+
* the rest of what the edit attached probed and alerting through the
|
|
2315
|
+
* window.
|
|
2316
|
+
*/
|
|
2317
|
+
private async holdMonitorsAttachedToEvent(data: {
|
|
2318
|
+
scheduledMaintenanceId: ObjectID;
|
|
2319
|
+
projectId: ObjectID;
|
|
2320
|
+
monitorIds: Array<ObjectID>;
|
|
2321
|
+
changeMonitorStatusToId: ObjectID | undefined;
|
|
2322
|
+
}): Promise<void> {
|
|
2323
|
+
for (const monitorId of data.monitorIds) {
|
|
2324
|
+
try {
|
|
2325
|
+
await MonitorService.updateOneById({
|
|
2326
|
+
id: monitorId,
|
|
2327
|
+
data: {
|
|
2328
|
+
disableActiveMonitoringBecauseOfScheduledMaintenanceEvent: true, /// This will stop active monitoring.
|
|
2329
|
+
},
|
|
2330
|
+
props: {
|
|
2331
|
+
isRoot: true,
|
|
2332
|
+
},
|
|
2333
|
+
});
|
|
2334
|
+
|
|
2335
|
+
const eventWithAddedMonitor: Model = new Model(
|
|
2336
|
+
data.scheduledMaintenanceId,
|
|
2337
|
+
);
|
|
2338
|
+
eventWithAddedMonitor.projectId = data.projectId;
|
|
2339
|
+
eventWithAddedMonitor.monitors = [new Monitor(monitorId)];
|
|
2340
|
+
|
|
2341
|
+
if (data.changeMonitorStatusToId) {
|
|
2342
|
+
eventWithAddedMonitor.changeMonitorStatusToId =
|
|
2343
|
+
data.changeMonitorStatusToId;
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
// A no-op when the event does not change monitor status.
|
|
2347
|
+
await this.changeAttachedMonitorStates(eventWithAddedMonitor, {
|
|
2348
|
+
isRoot: true,
|
|
2349
|
+
});
|
|
2350
|
+
} catch (err) {
|
|
2351
|
+
const logAttributes: LogAttributes = {
|
|
2352
|
+
projectId: data.projectId.toString(),
|
|
2353
|
+
scheduledMaintenanceId: data.scheduledMaintenanceId.toString(),
|
|
2354
|
+
monitorId: monitorId.toString(),
|
|
2355
|
+
} as LogAttributes;
|
|
2356
|
+
|
|
2357
|
+
logger.error(
|
|
2358
|
+
`ScheduledMaintenanceService.holdMonitorsAttachedToEvent: could not put monitor ${monitorId.toString()} into maintenance; continuing with the remaining monitors.`,
|
|
2359
|
+
logAttributes,
|
|
2360
|
+
);
|
|
2361
|
+
logger.error(err, logAttributes);
|
|
2362
|
+
continue;
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
/*
|
|
2368
|
+
* "Monitors Removed" / "Monitors Added" for the updated feed item, worded
|
|
2369
|
+
* as the incident feed words them. The names are read back held to the
|
|
2370
|
+
* project, so an id that is not this project's monitor is never named.
|
|
2371
|
+
*/
|
|
2372
|
+
private async getMonitorChangesFeedMarkdown(data: {
|
|
2373
|
+
projectId: ObjectID;
|
|
2374
|
+
change: AttachmentChange;
|
|
2375
|
+
}): Promise<string> {
|
|
2376
|
+
const sections: Array<{ title: string; monitorIds: Array<ObjectID> }> = [
|
|
2377
|
+
{
|
|
2378
|
+
title: "🗑️ Monitors Removed",
|
|
2379
|
+
monitorIds: data.change.monitorsRemoved,
|
|
2380
|
+
},
|
|
2381
|
+
{
|
|
2382
|
+
title: "🌎 Monitors Added",
|
|
2383
|
+
monitorIds: data.change.monitorsAdded,
|
|
2384
|
+
},
|
|
2385
|
+
];
|
|
2386
|
+
|
|
2387
|
+
let markdown: string = "";
|
|
2388
|
+
|
|
2389
|
+
for (const section of sections) {
|
|
2390
|
+
if (section.monitorIds.length === 0) {
|
|
2391
|
+
continue;
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
const monitors: Array<Monitor> = await MonitorService.findBy({
|
|
2395
|
+
query: {
|
|
2396
|
+
_id: QueryHelper.any(section.monitorIds),
|
|
2397
|
+
projectId: data.projectId,
|
|
2398
|
+
},
|
|
2399
|
+
select: {
|
|
2400
|
+
_id: true,
|
|
2401
|
+
name: true,
|
|
2402
|
+
},
|
|
2403
|
+
limit: LIMIT_PER_PROJECT,
|
|
2404
|
+
skip: 0,
|
|
2405
|
+
props: {
|
|
2406
|
+
isRoot: true,
|
|
2407
|
+
},
|
|
2408
|
+
});
|
|
2409
|
+
|
|
2410
|
+
if (monitors.length === 0) {
|
|
2411
|
+
continue;
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
markdown += `\n\n**${section.title}**:\n`;
|
|
2415
|
+
|
|
2416
|
+
for (const monitor of monitors) {
|
|
2417
|
+
markdown += `- [${monitor.name}](${(await MonitorService.getMonitorLinkInDashboard(data.projectId, monitor.id!)).toString()})\n`;
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
return markdown;
|
|
2422
|
+
}
|
|
2423
|
+
|
|
1758
2424
|
@CaptureSpan()
|
|
1759
2425
|
protected override async onUpdateSuccess(
|
|
1760
2426
|
onUpdate: OnUpdate<Model>,
|
|
@@ -1822,6 +2488,44 @@ ${scheduledMaintenance.description || "No description provided."}
|
|
|
1822
2488
|
const createdByUserId: ObjectID | undefined | null =
|
|
1823
2489
|
onUpdate.updateBy.props.userId;
|
|
1824
2490
|
|
|
2491
|
+
const attachmentsBeforeUpdate: AttachmentsBeforeUpdate | undefined = (
|
|
2492
|
+
onUpdate.carryForward as UpdateCarryForward | null | undefined
|
|
2493
|
+
)?.[scheduledMaintenanceId.toString()];
|
|
2494
|
+
|
|
2495
|
+
let attachmentChange: AttachmentChange | null = null;
|
|
2496
|
+
|
|
2497
|
+
if (attachmentsBeforeUpdate) {
|
|
2498
|
+
/*
|
|
2499
|
+
* The update is saved by now. Whatever fails here is logged, and
|
|
2500
|
+
* the feed item and the other events of a bulk update still
|
|
2501
|
+
* follow - with the change named in the feed, when it was read
|
|
2502
|
+
* back before the failure.
|
|
2503
|
+
*/
|
|
2504
|
+
try {
|
|
2505
|
+
attachmentChange = await this.getAttachmentChange({
|
|
2506
|
+
scheduledMaintenanceId: scheduledMaintenanceId,
|
|
2507
|
+
attachmentsBeforeUpdate: attachmentsBeforeUpdate,
|
|
2508
|
+
});
|
|
2509
|
+
|
|
2510
|
+
await this.applyAttachmentChangeToEvent({
|
|
2511
|
+
scheduledMaintenanceId: scheduledMaintenanceId,
|
|
2512
|
+
attachmentsBeforeUpdate: attachmentsBeforeUpdate,
|
|
2513
|
+
change: attachmentChange,
|
|
2514
|
+
});
|
|
2515
|
+
} catch (err) {
|
|
2516
|
+
const logAttributes: LogAttributes = {
|
|
2517
|
+
projectId: attachmentsBeforeUpdate.projectId?.toString(),
|
|
2518
|
+
scheduledMaintenanceId: scheduledMaintenanceId.toString(),
|
|
2519
|
+
} as LogAttributes;
|
|
2520
|
+
|
|
2521
|
+
logger.error(
|
|
2522
|
+
`ScheduledMaintenanceService.onUpdateSuccess: could not apply the edit of the monitors or network sites of scheduled maintenance ${scheduledMaintenanceId.toString()}; the update itself is saved.`,
|
|
2523
|
+
logAttributes,
|
|
2524
|
+
);
|
|
2525
|
+
logger.error(err, logAttributes);
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
|
|
1825
2529
|
if (onUpdate.updateBy.data.title) {
|
|
1826
2530
|
// add scheduledMaintenance feed.
|
|
1827
2531
|
|
|
@@ -1921,6 +2625,38 @@ ${LinkedAffectedResources.getMarkdownLines({
|
|
|
1921
2625
|
}
|
|
1922
2626
|
}
|
|
1923
2627
|
|
|
2628
|
+
/*
|
|
2629
|
+
* The list above is what the event affects now; these say what the
|
|
2630
|
+
* edit changed. Removing every monitor leaves no list to show, and
|
|
2631
|
+
* without this the feed would not record the edit at all.
|
|
2632
|
+
*/
|
|
2633
|
+
if (attachmentChange && onUpdate.updateBy.props.tenantId) {
|
|
2634
|
+
// A line the names could not be read for is left out, not the item.
|
|
2635
|
+
try {
|
|
2636
|
+
const monitorChangesMarkdown: string =
|
|
2637
|
+
await this.getMonitorChangesFeedMarkdown({
|
|
2638
|
+
projectId: onUpdate.updateBy.props.tenantId as ObjectID,
|
|
2639
|
+
change: attachmentChange,
|
|
2640
|
+
});
|
|
2641
|
+
|
|
2642
|
+
if (monitorChangesMarkdown) {
|
|
2643
|
+
feedInfoInMarkdown += monitorChangesMarkdown;
|
|
2644
|
+
shouldAddScheduledMaintenanceFeed = true;
|
|
2645
|
+
}
|
|
2646
|
+
} catch (err) {
|
|
2647
|
+
const logAttributes: LogAttributes = {
|
|
2648
|
+
projectId: onUpdate.updateBy.props.tenantId?.toString(),
|
|
2649
|
+
scheduledMaintenanceId: scheduledMaintenanceId.toString(),
|
|
2650
|
+
} as LogAttributes;
|
|
2651
|
+
|
|
2652
|
+
logger.error(
|
|
2653
|
+
`ScheduledMaintenanceService.onUpdateSuccess: could not name the monitors added to or removed from scheduled maintenance ${scheduledMaintenanceId.toString()} in its feed.`,
|
|
2654
|
+
logAttributes,
|
|
2655
|
+
);
|
|
2656
|
+
logger.error(err, logAttributes);
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
|
|
1924
2660
|
if (
|
|
1925
2661
|
onUpdate.updateBy.data.statusPages &&
|
|
1926
2662
|
onUpdate.updateBy.data.statusPages.length > 0 &&
|