@oneuptime/common 14.0.1 → 14.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/AlertEpisodeMember.ts +8 -1
- package/Models/DatabaseModels/AutoRemediationSuggestion.ts +63 -0
- package/Models/DatabaseModels/IncidentEpisodeMember.ts +8 -1
- package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +9 -2
- package/Models/DatabaseModels/IncidentPublicNote.ts +9 -2
- package/Models/DatabaseModels/KubernetesCluster.ts +429 -0
- package/Models/DatabaseModels/Monitor.ts +48 -0
- package/Models/DatabaseModels/Runner.ts +5 -4
- package/Models/DatabaseModels/RunnerJob.ts +66 -0
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +10 -2
- package/Models/DatabaseModels/WorkflowVariable.ts +479 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +79 -25
- package/Server/API/AIInvestigationAPI.ts +341 -0
- package/Server/API/AutoRemediationAPI.ts +184 -2
- package/Server/API/CommonAPI.ts +70 -0
- package/Server/API/KubernetesClusterAiAccessAPI.ts +793 -0
- package/Server/API/MicrosoftTeamsAPI.ts +770 -315
- package/Server/API/MonitorAPI.ts +140 -0
- package/Server/API/OnCallScheduleTimelineAPI.ts +5 -21
- package/Server/API/SlackAPI.ts +447 -99
- package/Server/API/StatusPageAPI.ts +146 -26
- package/Server/API/TelemetryAPI.ts +216 -5
- package/Server/API/UserTwoFactorBackupCodeAPI.ts +1 -0
- package/Server/API/WorkflowVariableAPI.ts +156 -0
- package/Server/Infrastructure/GlobalCache.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.ts +97 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.ts +129 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.ts +20 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.ts +38 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/MasterAdminAuthorization.ts +28 -0
- package/Server/Middleware/TelemetryIngest.ts +47 -2
- package/Server/Middleware/UserAuthorization.ts +56 -2
- package/Server/Services/AIAgentService.ts +1 -0
- package/Server/Services/AccessTokenService.ts +121 -48
- package/Server/Services/AlertEpisodeMemberService.ts +9 -0
- package/Server/Services/AlertEpisodeService.ts +14 -1
- package/Server/Services/AlertService.ts +134 -22
- package/Server/Services/AutoRemediationRuleEngineService.ts +968 -39
- package/Server/Services/AutoRemediationRuleService.ts +118 -0
- package/Server/Services/BillingService.ts +1 -0
- package/Server/Services/InboundEmail/Providers/SendGridInboundProvider.ts +16 -22
- package/Server/Services/IncidentEpisodeMemberService.ts +9 -0
- package/Server/Services/IncidentEpisodePublicNoteService.ts +66 -0
- package/Server/Services/IncidentEpisodeRoleMemberService.ts +27 -0
- package/Server/Services/IncidentEpisodeService.ts +14 -1
- package/Server/Services/IncidentGroupingEngineService.ts +11 -0
- package/Server/Services/IncidentMemberService.ts +21 -0
- package/Server/Services/IncidentPublicNoteService.ts +63 -0
- package/Server/Services/IncidentService.ts +120 -20
- package/Server/Services/IncidentStateTimelineService.ts +15 -0
- package/Server/Services/IncidentTemplateService.ts +83 -3
- package/Server/Services/KubernetesClusterAiAccessService.ts +1943 -0
- package/Server/Services/KubernetesClusterService.ts +1570 -1
- package/Server/Services/LogAggregationService.ts +14 -6
- package/Server/Services/MonitorService.ts +651 -52
- package/Server/Services/MonitorStatusTimelineService.ts +639 -2
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +3 -0
- package/Server/Services/OnCallNotificationAlertingService.ts +36 -12
- package/Server/Services/OnCallSetupReminderService.ts +1 -0
- package/Server/Services/ProbeService.ts +7 -1
- package/Server/Services/ProjectService.ts +11 -1
- package/Server/Services/RunbookCredentialService.ts +26 -1
- package/Server/Services/RunbookSecretService.ts +36 -0
- package/Server/Services/RunnerJobService.ts +941 -23
- package/Server/Services/RunnerService.ts +439 -6
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +66 -0
- package/Server/Services/ScheduledMaintenanceService.ts +124 -19
- package/Server/Services/ScheduledMaintenanceTemplateService.ts +82 -3
- package/Server/Services/ServiceLevelObjectiveService.ts +14 -1
- package/Server/Services/StatusPagePrivateUserService.ts +1 -0
- package/Server/Services/StatusPageService.ts +301 -74
- package/Server/Services/StatusPageSubscriberService.ts +4 -0
- package/Server/Services/TeamMemberService.ts +309 -7
- package/Server/Services/TraceAggregationService.ts +10 -6
- package/Server/Services/UserEmailService.ts +1 -0
- package/Server/Services/UserNotificationMethodAdminService.ts +1 -0
- package/Server/Services/UserNotificationRuleAdminService.ts +1 -0
- package/Server/Services/UserNotificationRuleService.ts +4 -0
- package/Server/Services/UserService.ts +122 -1
- package/Server/Services/WorkflowVariableService.ts +593 -8
- package/Server/Services/WorkspaceNotificationRuleService.ts +588 -8
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +170 -1
- package/Server/Types/Database/QueryHelper.ts +22 -0
- package/Server/Types/Markdown.ts +502 -27
- package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +182 -0
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +525 -0
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +854 -0
- package/Server/Utils/AI/CodeFix/CodeFixAgentAuth.ts +22 -2
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1916 -307
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +1601 -74
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +139 -7
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +58 -1
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +54 -1
- package/Server/Utils/AI/Toolbox/AIActionTools.ts +14 -6
- package/Server/Utils/AI/Toolbox/ResourceTools.ts +4 -2
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +1341 -150
- package/Server/Utils/AutoRemediation/RemediationVerifier.ts +375 -4
- package/Server/Utils/Database/AffectedResourceRelations.ts +127 -0
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +240 -1
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +1 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +83 -9
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +5 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +104 -9
- package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +124 -7
- package/Server/Utils/Monitor/ProbeMonitorsNotification.ts +407 -0
- package/Server/Utils/OnCall/OnCallShiftReminderRunner.ts +1 -0
- package/Server/Utils/PushNotificationUtil.ts +45 -0
- package/Server/Utils/Rules/OwnerRuleAssignment.ts +40 -3
- package/Server/Utils/Runbook/RunbookExecutePermission.ts +56 -6
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +223 -33
- package/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.ts +559 -0
- package/Server/Utils/StartServer.ts +4 -3
- package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +528 -0
- package/Server/Utils/TwoFactorBackupCodeNotification.ts +1 -0
- package/Server/Utils/UserPermission/UserPermission.ts +16 -0
- package/Server/Utils/Workflow/OAuth2TokenClient.ts +704 -0
- package/Server/Utils/Workflow/WorkflowVariableOAuthToken.ts +318 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +47 -7
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +57 -16
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +193 -214
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +57 -13
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.ts +54 -17
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +179 -161
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +281 -167
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.ts +114 -0
- package/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.ts +895 -0
- package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +7 -9
- package/Server/Utils/Workspace/Slack/Actions/Alert.ts +96 -227
- package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +93 -214
- package/Server/Utils/Workspace/Slack/Actions/Auth.ts +30 -3
- package/Server/Utils/Workspace/Slack/Actions/Authorization.ts +99 -0
- package/Server/Utils/Workspace/Slack/Actions/Incident.ts +117 -283
- package/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.ts +101 -196
- package/Server/Utils/Workspace/Slack/Actions/ReactionNote.ts +329 -0
- package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +111 -287
- package/Server/Utils/Workspace/Slack/Slack.ts +86 -17
- package/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
- package/Server/Utils/Workspace/Workspace.ts +171 -54
- package/Server/Utils/Workspace/WorkspaceActionAuthorization.ts +252 -0
- package/Server/Utils/Workspace/WorkspaceBase.ts +39 -0
- package/Server/Utils/Workspace/WorkspaceOAuthState.ts +280 -0
- package/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.ts +96 -0
- package/Server/Utils/Workspace/WorkspaceReactionNote.ts +620 -0
- package/Tests/App/Dashboard/AttributesJSONDashboardSurfaces.test.tsx +496 -0
- package/Tests/App/Dashboard/AutoRemediationRulesTableCommandRunners.test.tsx +152 -0
- package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +32 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +794 -0
- package/Tests/App/Dashboard/CreateOAuthWorkflowVariableModal.test.tsx +840 -0
- package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +653 -0
- package/Tests/App/Dashboard/DatabaseMonitorStepForm.test.tsx +197 -0
- package/Tests/App/Dashboard/DatabaseMonitorView.test.tsx +376 -0
- package/Tests/App/Dashboard/DisabledWarningRobustness.test.tsx +262 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +2080 -0
- package/Tests/App/Dashboard/EventNotesPages.test.tsx +486 -0
- package/Tests/App/Dashboard/EventNotesUtil.test.ts +933 -0
- package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +218 -0
- package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +665 -0
- package/Tests/App/Dashboard/IncidentEpisodeFeedPublicNoteNotifyDefault.test.tsx +494 -0
- package/Tests/App/Dashboard/IncidentEpisodeOverviewNotifyDefault.test.tsx +706 -0
- package/Tests/App/Dashboard/IncidentFeedPublicNoteNotifyDefault.test.tsx +472 -0
- package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +858 -0
- package/Tests/App/Dashboard/IncomingEmailAddressSettings.test.tsx +567 -0
- package/Tests/App/Dashboard/InvestigationClusterToolFormat.test.ts +241 -0
- package/Tests/App/Dashboard/InvestigationEvidenceKubectl.test.tsx +322 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +12 -0
- package/Tests/App/Dashboard/InvestigationPanelClusterAccess.test.tsx +476 -0
- package/Tests/App/Dashboard/InvestigationRunDetailsKubectl.test.tsx +383 -0
- package/Tests/App/Dashboard/KubectlActivitySummary.test.tsx +366 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +2886 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +2688 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +915 -0
- package/Tests/App/Dashboard/LayerDateTimeFieldTimezoneName.test.tsx +66 -0
- package/Tests/App/Dashboard/LogMonitorPreview.test.tsx +174 -0
- package/Tests/App/Dashboard/MonitorFeedRefresh.test.tsx +279 -0
- package/Tests/App/Dashboard/MonitorMetricQueryConfig.test.ts +244 -0
- package/Tests/App/Dashboard/MonitorOpenWorkCard.test.tsx +381 -0
- package/Tests/App/Dashboard/MonitorOpenWorkHook.test.tsx +784 -0
- package/Tests/App/Dashboard/MonitorOverviewData.test.tsx +2199 -0
- package/Tests/App/Dashboard/MonitorOverviewHero.test.tsx +1169 -0
- package/Tests/App/Dashboard/MonitorOverviewInput.test.ts +1127 -0
- package/Tests/App/Dashboard/MonitorOverviewPage.test.tsx +2136 -0
- package/Tests/App/Dashboard/MonitorOverviewSelectReadable.test.ts +368 -0
- package/Tests/App/Dashboard/MonitorOverviewStatBar.test.tsx +526 -0
- package/Tests/App/Dashboard/MonitorOverviewSupportingCards.test.tsx +542 -0
- package/Tests/App/Dashboard/MonitorOwnersCombine.test.ts +299 -0
- package/Tests/App/Dashboard/MonitorProbesCard.test.tsx +602 -0
- package/Tests/App/Dashboard/MonitorResponseTimeCard.test.tsx +386 -0
- package/Tests/App/Dashboard/MonitorSetupAndConnectionCards.test.tsx +612 -0
- package/Tests/App/Dashboard/MonitorStatusChangesCard.test.tsx +257 -0
- package/Tests/App/Dashboard/MonitorSummaryTestMonitorButton.test.tsx +360 -1
- package/Tests/App/Dashboard/MonitorUptimeHistoryCard.test.tsx +835 -0
- package/Tests/App/Dashboard/MonitorUptimeSummaryHook.test.tsx +971 -0
- package/Tests/App/Dashboard/MonitorViewLayout.test.tsx +580 -0
- package/Tests/App/Dashboard/OnCallLayerRestrictionTimesPreserved.test.tsx +441 -0
- package/Tests/App/Dashboard/OnCallNavbar.test.tsx +214 -0
- package/Tests/App/Dashboard/OnCallSchedulePreviewCalendarDisplay.test.tsx +1389 -0
- package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +205 -1
- package/Tests/App/Dashboard/OnCallScheduleTimeInputsSettingsZone.test.tsx +198 -0
- package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +524 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardApproval.test.tsx +702 -0
- package/Tests/App/Dashboard/RemoveUserFromProject.test.tsx +427 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +4 -0
- package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +3 -1
- package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +166 -0
- package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +622 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceChangeStateNotifyDefault.test.tsx +1491 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceFeedPublicNoteNotifyDefault.test.tsx +489 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewNotifyDefault.test.tsx +909 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +14 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceWindowStatsTranslation.test.tsx +307 -0
- package/Tests/App/Dashboard/SecurityEventAttributeColumnPicker.test.tsx +542 -0
- package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +174 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +973 -212
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +491 -52
- package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +301 -0
- package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +158 -1
- package/Tests/App/Dashboard/SecurityEventProviderTile.test.tsx +869 -0
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +959 -94
- package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +2 -0
- package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +274 -1
- package/Tests/App/Dashboard/TeamMembershipRemoval.test.ts +900 -0
- package/Tests/App/Dashboard/TeamMembershipRemovalPages.test.tsx +460 -0
- package/Tests/App/Dashboard/TimezoneElements.test.tsx +321 -0
- package/Tests/App/Dashboard/TimezoneSelectButton.test.tsx +634 -0
- package/Tests/App/Dashboard/TraceExplorer.test.tsx +260 -0
- package/Tests/App/Dashboard/TraceMonitorPreview.test.tsx +182 -0
- package/Tests/App/Dashboard/UserTimezoneInit.test.tsx +544 -0
- package/Tests/App/Dashboard/WorkflowVariableModals.test.tsx +1630 -0
- package/Tests/App/Dashboard/WorkflowVariableRoutes.test.tsx +603 -0
- package/Tests/App/Dashboard/WorkflowVariableTokenStatus.test.tsx +589 -0
- package/Tests/App/Dashboard/WorkflowVariableUtil.test.ts +1543 -0
- package/Tests/App/Dashboard/WorkflowVariableView.test.tsx +3227 -0
- package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +1277 -395
- package/Tests/App/StatusPage/StatusPageOverviewMonitorGroupUptime.test.tsx +714 -0
- package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.NewYork.test.tsx +1009 -0
- package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.test.tsx +1092 -0
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +5 -0
- package/Tests/Models/DatabaseModels/KubernetesClusterAiAccessColumns.test.ts +520 -0
- package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +66 -2
- package/Tests/Models/DatabaseModels/WorkspaceProjectAuthTokenAccessControl.test.ts +236 -0
- package/Tests/Models/IncidentEpisodePublicNoteNotifyColumnContract.test.ts +103 -0
- package/Tests/Models/IncidentPublicNoteNotifyColumnContract.test.ts +96 -0
- package/Tests/Models/ScheduledMaintenancePublicNoteNotifyColumnContract.test.ts +111 -0
- package/Tests/Server/API/AIInvestigationAPI.test.ts +976 -0
- package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +836 -0
- package/Tests/Server/API/CommonAPIAssertCanCreateTable.test.ts +565 -0
- package/Tests/Server/API/CommonAPIAssertCanReadTable.test.ts +282 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +1744 -0
- package/Tests/Server/API/LogHistogramAPI.test.ts +371 -0
- package/Tests/Server/API/MicrosoftTeamsLegacyWebhookRemoval.test.ts +125 -30
- package/Tests/Server/API/MicrosoftTeamsOAuthState.test.ts +1121 -0
- package/Tests/Server/API/MonitorUptimeSummaryAPI.test.ts +685 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +602 -1
- package/Tests/Server/API/SlackChannelCacheAPI.test.ts +358 -0
- package/Tests/Server/API/SlackOAuthState.test.ts +688 -0
- package/Tests/Server/API/StatusPageOverviewMonitorGroupUptime.test.ts +527 -0
- package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +2 -0
- package/Tests/Server/API/StatusPageUptimeAPI.test.ts +427 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +4 -0
- package/Tests/Server/API/WorkflowVariableAPI.test.ts +404 -0
- package/Tests/Server/API/WorkspaceOAuthTestHelpers.ts +289 -0
- package/Tests/Server/API/WorkspaceSendTestNotificationRoutes.test.ts +2064 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +86 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +589 -0
- package/Tests/Server/Infrastructure/Postgres/AddOAuth2WorkflowVariablesMigration.test.ts +254 -0
- package/Tests/Server/Middleware/BlockedUserMiddleware.test.ts +403 -0
- package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +13 -0
- package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +2 -0
- package/Tests/Server/Middleware/RemovedProjectMemberAuthorization.test.ts +469 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +77 -1
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +211 -0
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +358 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +97 -0
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +2 -0
- package/Tests/Server/Services/AccessTokenProjectUserGrant.test.ts +14 -2
- package/Tests/Server/Services/AccessTokenRemovedMemberAccess.test.ts +1044 -0
- package/Tests/Server/Services/AddOwnersIdempotency.test.ts +5 -0
- package/Tests/Server/Services/AlertEpisodeMemberCreatePermission.test.ts +139 -0
- package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +1361 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +375 -0
- package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +2384 -0
- package/Tests/Server/Services/FindOwnersProjectMembership.test.ts +267 -0
- package/Tests/Server/Services/InboundEmail/SendGridInboundProviderAddress.test.ts +90 -0
- package/Tests/Server/Services/IncidentEpisodeMemberCreatePermission.test.ts +143 -0
- package/Tests/Server/Services/IncidentEpisodePublicNoteNotifyDefault.test.ts +805 -0
- package/Tests/Server/Services/IncidentPublicNoteNotifyDefault.test.ts +724 -0
- package/Tests/Server/Services/IncidentRoleProjectMembership.test.ts +233 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessAgentRunnerAssignments.test.ts +372 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessBindingGuard.test.ts +1876 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +620 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +421 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +3662 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessSubjectClusters.test.ts +405 -0
- package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +975 -0
- package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +497 -0
- package/Tests/Server/Services/KubernetesClusterServiceDeleteSettlesRemediation.test.ts +328 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +99 -0
- package/Tests/Server/Services/MonitorServiceIncomingEmailCustomAddress.test.ts +447 -0
- package/Tests/Server/Services/MonitorServiceProbeFlagSync.test.ts +1334 -0
- package/Tests/Server/Services/MonitorServiceProbeStatusGrouping.test.ts +1640 -0
- package/Tests/Server/Services/MonitorServiceRefreshCurrentStatus.test.ts +225 -0
- package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +8 -8
- package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +264 -1
- package/Tests/Server/Services/MonitorStatusTimelineMergedDowntime.test.ts +284 -0
- package/Tests/Server/Services/MonitorUptimeSummaryService.test.ts +1043 -0
- package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +5 -0
- package/Tests/Server/Services/OnCallUndeliverablePageOwnerMembership.test.ts +359 -0
- package/Tests/Server/Services/ProbeServiceDashboardLink.test.ts +191 -0
- package/Tests/Server/Services/ProjectOwnersProjectMembership.test.ts +221 -0
- package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +5 -0
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +28 -0
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +9 -1
- package/Tests/Server/Services/RunnerJobEnqueueAiCommandAgentRunner.test.ts +230 -0
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +978 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +866 -0
- package/Tests/Server/Services/RunnerJobSubmitResultRedaction.test.ts +322 -0
- package/Tests/Server/Services/RunnerJobSubmitResultUnstorableText.test.ts +357 -0
- package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +227 -0
- package/Tests/Server/Services/RunnerServiceAgentName.test.ts +581 -0
- package/Tests/Server/Services/ScheduledMaintenancePublicNoteNotifyDefault.test.ts +802 -0
- package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +53 -0
- package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +5 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +12 -0
- package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +1176 -1
- package/Tests/Server/Services/TeamMemberBillingSeatSync.test.ts +9 -0
- package/Tests/Server/Services/TeamMemberOnCallCleanup.test.ts +18 -0
- package/Tests/Server/Services/TeamMemberProjectMembership.test.ts +255 -0
- package/Tests/Server/Services/TeamMemberRemovalRevokesProjectAccess.test.ts +600 -0
- package/Tests/Server/Services/TeamMemberResourceCleanup.test.ts +731 -0
- package/Tests/Server/Services/TeamMemberWorkspaceAccountCleanup.test.ts +164 -0
- package/Tests/Server/Services/TraceAggregationService.test.ts +64 -0
- package/Tests/Server/Services/UserServiceBlockedUser.test.ts +293 -0
- package/Tests/Server/Services/WorkflowVariableOAuthHooks.test.ts +1016 -0
- package/Tests/Server/Services/WorkflowVariableOAuthPostgres.test.ts +543 -0
- package/Tests/Server/Services/WorkflowVariableRenameUniqueness.test.ts +16 -5
- package/Tests/Server/Services/WorkspaceNotificationRuleNoteDelivery.test.ts +473 -0
- package/Tests/Server/Services/WorkspaceNotificationRuleSendTestNotification.test.ts +3690 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenMiscDataSecrets.test.ts +374 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenSlackChannelCache.test.ts +143 -0
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableOAuthColumnPermission.test.ts +250 -0
- package/Tests/Server/Types/Database/QueryHelperJsonContains.test.ts +96 -0
- package/Tests/Server/Types/Markdown.test.ts +1033 -0
- package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +285 -0
- package/Tests/Server/Utils/AI/CodeFix/CodeFixAgentAuth.test.ts +159 -1
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +752 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +1840 -0
- package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +1067 -0
- package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +355 -0
- package/Tests/Server/Utils/AI/PostIncidentStatusUpdateTool.test.ts +496 -0
- package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +305 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +1365 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +639 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +1585 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +1065 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +2138 -1
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +1035 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +517 -0
- package/Tests/Server/Utils/AI/ResourceTools.test.ts +27 -1
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +1371 -24
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorRollbackRace.test.ts +962 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +518 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +939 -2
- package/Tests/Server/Utils/Database/ProjectScopedRelationReferences.test.ts +371 -0
- package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +64 -0
- package/Tests/Server/Utils/Monitor/DatabaseMetricObservationRemediation.test.ts +102 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +362 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +55 -0
- package/Tests/Server/Utils/Monitor/MonitorEmailAddressRedaction.test.ts +255 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +347 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +203 -0
- package/Tests/Server/Utils/Monitor/ProbeMonitorsNotification.test.ts +1147 -0
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +79 -0
- package/Tests/Server/Utils/ResourceFeed/ResourceFeedUtil.test.ts +21 -1
- package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +155 -1
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +288 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.test.ts +304 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +40 -3
- package/Tests/Server/Utils/Workflow/OAuth2TokenClient.test.ts +702 -0
- package/Tests/Server/Utils/Workflow/OAuth2TokenClientHttpIntegration.test.ts +507 -0
- package/Tests/Server/Utils/Workflow/WorkflowVariableOAuthToken.test.ts +831 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsActionAuthorization.test.ts +63 -1
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsAppAccessToken.test.ts +256 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +60 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChatActionAuthorization.test.ts +442 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +44 -2
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +55 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsReactionNoteSync.test.ts +1522 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsServiceUrl.test.ts +130 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +4 -4
- package/Tests/Server/Utils/Workspace/Slack/SlackActionAuthorization.test.ts +691 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackMessageByTimestamp.test.ts +253 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackReactionNote.test.ts +574 -0
- package/Tests/Server/Utils/Workspace/WorkspaceActionAuthorization.test.ts +488 -0
- package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +861 -0
- package/Tests/Server/Utils/Workspace/WorkspaceMessageAuthor.test.ts +635 -0
- package/Tests/Server/Utils/Workspace/WorkspaceOAuthState.test.ts +548 -0
- package/Tests/Server/Utils/Workspace/WorkspaceReactionNote.test.ts +839 -0
- package/Tests/Server/Utils/Workspace/WorkspaceSendErrorMessage.test.ts +725 -0
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +283 -9
- package/Tests/Types/DateBrowserLocalWallClock.test.ts +280 -0
- package/Tests/Types/DateLocalShortMonthNameFallback.test.ts +389 -0
- package/Tests/Types/DateUserTimezone.test.ts +177 -4
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +306 -0
- package/Tests/Types/Kubernetes/KubernetesClusterAiAccess.test.ts +283 -0
- package/Tests/Types/Kubernetes/KubernetesRunnerPostureWriteScope.test.ts +68 -0
- package/Tests/Types/Monitor/DatabaseMonitor/SqlServerPlatform.test.ts +144 -0
- package/Tests/Types/Monitor/MonitorStepExceptionMonitor.test.ts +160 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +53 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +91 -16
- package/Tests/Types/Runner/RunnerLiveStatus.test.ts +14 -3
- package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +15 -0
- package/Tests/Types/StatusPage/PublicNoteSubscriberNotificationDefault.test.ts +1868 -0
- package/Tests/Types/Timezone.test.ts +5 -0
- package/Tests/Types/TimezoneAlias.test.ts +1034 -0
- package/Tests/Types/Workflow/JiraTemplateFixtures.ts +833 -0
- package/Tests/Types/Workflow/JiraTemplateScripts.test.ts +5414 -0
- package/Tests/Types/Workflow/JiraTemplateSimulation.test.ts +4803 -0
- package/Tests/Types/Workflow/JiraTemplates.test.ts +5429 -0
- package/Tests/Types/Workflow/Templates.test.ts +79 -4
- package/Tests/Types/Workflow/WorkflowVariableOAuth.test.ts +520 -0
- package/Tests/Types/Workspace/WorkspaceNoteReaction.test.ts +177 -0
- package/Tests/UI/Components/AttributesJSON/AttributesJSONView.test.tsx +390 -0
- package/Tests/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.test.tsx +566 -0
- package/Tests/UI/Components/AttributesJSON/JSONHighlight.test.ts +131 -0
- package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +276 -1
- package/Tests/UI/Components/Calendar/Calendar.test.tsx +1611 -0
- package/Tests/UI/Components/Calendar/CalendarDayLayout.test.ts +1486 -0
- package/Tests/UI/Components/Calendar/CalendarDayLayoutDst.test.ts +632 -0
- package/Tests/UI/Components/Calendar/CalendarDst.test.tsx +388 -0
- package/Tests/UI/Components/Charts/ChartGroupPlotFloor.test.tsx +170 -0
- package/Tests/UI/Components/Charts/HistogramSelection.test.ts +282 -0
- package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +6 -0
- package/Tests/UI/Components/CustomTimeRangeModalTimezoneTranslation.test.tsx +285 -0
- package/Tests/UI/Components/Dropdown.test.tsx +999 -2
- package/Tests/UI/Components/Forms/FormFieldCheckboxTranslation.test.tsx +216 -0
- package/Tests/UI/Components/Forms/FormFieldTimezoneDescriptionTranslation.test.tsx +461 -0
- package/Tests/UI/Components/Forms/IncidentEpisodePublicNoteNotifyPayload.test.tsx +641 -0
- package/Tests/UI/Components/Forms/IncidentPublicNoteNotifyPayload.test.tsx +346 -0
- package/Tests/UI/Components/Forms/ScheduledMaintenancePublicNoteNotifyPayload.test.tsx +493 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +911 -2
- package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.NewYork.test.tsx +730 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.Tokyo.test.tsx +506 -0
- package/Tests/UI/Components/HistogramClickToZoom.test.tsx +619 -0
- package/Tests/UI/Components/LogDetailsPanelAttributesJSON.test.tsx +248 -0
- package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +47 -1
- package/Tests/UI/Components/LogsViewerSmallScreens.test.tsx +620 -0
- package/Tests/UI/Components/ModelPageModelChange.test.tsx +242 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableDeleteConfirmation.test.tsx +521 -0
- package/Tests/UI/Components/MonitorGraphs/Uptime.test.tsx +406 -2
- package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +169 -2
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +266 -0
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerSmallScreens.test.tsx +439 -0
- package/Tests/UI/Components/TimezoneDropdownLegacyValues.test.tsx +704 -0
- package/Tests/UI/Components/UseHistogramZoom.test.tsx +89 -1
- package/Tests/UI/Components/UseLogsHistogram.test.tsx +175 -0
- package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +5 -5
- package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +28 -0
- package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +51 -0
- package/Tests/UI/Utils/Timezone.test.ts +747 -33
- package/Tests/UI/Workspace/SendTestNotificationButton.test.tsx +1854 -0
- package/Tests/UI/Workspace/WorkspaceCardsSendTestNotification.test.tsx +1864 -0
- package/Tests/Utils/AI/InvestigationReport.test.ts +435 -7
- package/Tests/Utils/AiRemediation/KubectlAllowlistValidatorParity.test.ts +1084 -0
- package/Tests/Utils/AiRemediation/KubectlOutputRedactor.test.ts +2531 -0
- package/Tests/Utils/AiRemediation/KubectlPolicy.test.ts +1895 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyAllowlist.test.ts +428 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +828 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyCustomResourceScope.test.ts +573 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyDenials.test.ts +1525 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyExposeOverrides.test.ts +275 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyNodePatch.test.ts +428 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyObjectWords.test.ts +195 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyPatchParents.test.ts +637 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyPodSecurityBaseline.test.ts +322 -0
- package/Tests/Utils/AiRemediation/KubectlPolicySafeWriteScope.test.ts +1026 -0
- package/Tests/Utils/AiRemediation/KubectlWaitBudget.test.ts +267 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScope.test.ts +390 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +777 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeClusterScoped.test.ts +613 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeEntryPoint.test.ts +576 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeKubectlSpellings.test.ts +752 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeObjectWords.test.ts +358 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeOverrides.test.ts +293 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopeParityCases.ts +598 -0
- package/Tests/Utils/AiRemediation/KubectlWriteScopePolicyParity.test.ts +403 -0
- package/Tests/Utils/Dashboard/DashboardClockComponent.test.ts +154 -5
- package/Tests/Utils/Monitor/IncomingEmailMonitorAddress.test.ts +478 -0
- package/Tests/Utils/Monitor/MonitorCheckScheduleUtil.test.ts +646 -0
- package/Tests/Utils/Monitor/MonitorOverviewCriteriaUtil.test.ts +292 -0
- package/Tests/Utils/Monitor/MonitorOverviewFamily.test.ts +274 -0
- package/Tests/Utils/Monitor/MonitorOverviewPresentationUtil.test.ts +3100 -0
- package/Tests/Utils/Monitor/MonitorOverviewProbeUtil.test.ts +1412 -0
- package/Tests/Utils/Monitor/MonitorOverviewTargetUtil.test.ts +374 -0
- package/Tests/Utils/Monitor/MonitorStatusHistoryUtil.test.ts +332 -0
- package/Tests/Utils/Monitor/MonitorUptimeSummaryUtil.test.ts +946 -0
- package/Tests/Utils/Rum/SessionIdentity.test.ts +94 -0
- package/Tests/Utils/Rum/SessionReplayWafCompatibility.test.ts +840 -0
- package/Tests/Utils/Rum/SessionReplayWireEncoding.test.ts +208 -0
- package/Tests/Utils/Rum/UserFlow.test.ts +1010 -0
- package/Tests/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.test.ts +217 -0
- package/Tests/Utils/StatusPage/ResourceUptime.test.ts +1272 -1
- package/Tests/Utils/StatusPage/UptimeDailyAggregateTotals.test.ts +298 -0
- package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +649 -1
- package/Tests/Utils/StatusPage/UptimeDailyAggregateWindow.test.ts +314 -0
- package/Tests/Utils/Telemetry/AttributesJSON.test.ts +454 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +418 -2
- package/Tests/Utils/Uptime/DayUptimeGraphUtilMidnightDst.test.ts +160 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Auckland.test.ts +45 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Kolkata.test.ts +40 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.London.test.ts +147 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.NewYork.test.ts +48 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Tokyo.test.ts +39 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezoneCases.ts +1015 -0
- package/Tests/Utils/Uptime/UptimeUtil.test.ts +75 -0
- package/Tests/Utils/Uptime/UptimeUtilChronologicalOrder.test.ts +1279 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +203 -5
- package/Types/Date.ts +121 -7
- package/Types/Email/EmailMessage.ts +8 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Exception/ExceptionMessages.ts +1 -0
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +488 -0
- package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +54 -0
- package/Types/Kubernetes/KubernetesClusterAiAccessToolNames.ts +17 -0
- package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +9 -0
- package/Types/Monitor/DatabaseMonitor/SqlServerPlatform.ts +117 -0
- package/Types/Monitor/KubernetesAlertTemplates.ts +6 -5
- package/Types/Monitor/MonitorStepExceptionMonitor.ts +56 -0
- package/Types/Monitor/MonitorUptimeSummary.ts +113 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +11 -0
- package/Types/Rum/SessionReplay.ts +55 -2
- package/Types/Rum/SessionReplayApi.ts +44 -1
- package/Types/Rum/UserFlow.ts +187 -0
- package/Types/Runbook/RunbookStepType.ts +10 -0
- package/Types/Runbook/RunnerJobOrigin.ts +15 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +6 -2
- package/Types/StatusPage/MergedDowntimeTotals.ts +17 -0
- package/Types/StatusPage/PublicNoteSubscriberNotificationDefault.ts +148 -0
- package/Types/StatusPage/UptimeDailyAggregate.ts +15 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +9 -0
- package/Types/Timezone.ts +5 -0
- package/Types/TimezoneAlias.ts +385 -0
- package/Types/Workflow/Templates.ts +3041 -2
- package/Types/Workflow/WorkflowVariableOAuth.ts +476 -0
- package/Types/Workspace/WorkspaceNoteReaction.ts +132 -0
- package/Typings/Index.d.ts +24 -0
- package/UI/Components/AttributesJSON/AttributesJSONPreferences.ts +175 -0
- package/UI/Components/AttributesJSON/AttributesJSONView.tsx +138 -0
- package/UI/Components/AttributesJSON/AttributesViewToggle.tsx +79 -0
- package/UI/Components/AttributesJSON/BracesGlyph.tsx +30 -0
- package/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.tsx +491 -0
- package/UI/Components/AttributesJSON/JSONHighlight.ts +77 -0
- package/UI/Components/Calendar/Calendar.css +83 -0
- package/UI/Components/Calendar/Calendar.tsx +136 -7
- package/UI/Components/Calendar/CalendarDayLayout.ts +236 -0
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +23 -1
- package/UI/Components/Charts/Utils/HistogramSelection.ts +117 -0
- package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +269 -0
- package/UI/Components/Charts/Utils/useHistogramZoom.ts +26 -2
- package/UI/Components/Date/CustomTimeRangeModal.tsx +26 -3
- package/UI/Components/Dropdown/Dropdown.tsx +58 -9
- package/UI/Components/Forms/Fields/FormField.tsx +49 -14
- package/UI/Components/Graphs/DayUptimeGraph.tsx +166 -25
- package/UI/Components/Graphs/UptimeBarTooltip.tsx +10 -2
- package/UI/Components/Graphs/UptimeDaySummary.tsx +8 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +52 -5
- package/UI/Components/LogsViewer/components/ColumnSelector.tsx +13 -2
- package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +13 -1
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +91 -76
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +15 -1
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +28 -106
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +54 -6
- package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +8 -2
- package/UI/Components/LogsViewer/useLogsHistogram.ts +39 -6
- package/UI/Components/ModelTable/BaseModelTable.tsx +66 -14
- package/UI/Components/MonitorGraphs/Uptime.tsx +12 -0
- package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +10 -2
- package/UI/Components/Page/ModelPage.tsx +59 -3
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +69 -5
- package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +12 -1
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +15 -1
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +36 -104
- package/UI/Components/TelemetryViewer/components/TelemetrySearchBar.tsx +9 -1
- package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +19 -1
- package/UI/Utils/Timezone.ts +69 -28
- package/Utils/AI/InvestigationReport.ts +195 -25
- package/Utils/AiRemediation/KubectlOutputRedactor.ts +1724 -0
- package/Utils/AiRemediation/KubectlPolicy.ts +4136 -0
- package/Utils/AiRemediation/KubectlWaitBudget.ts +156 -0
- package/Utils/AiRemediation/KubectlWriteScope.ts +1964 -0
- package/Utils/Dashboard/Components/DashboardClockComponent.ts +7 -6
- package/Utils/Monitor/IncomingEmailMonitorAddress.ts +292 -0
- package/Utils/Monitor/MonitorCheckScheduleUtil.ts +654 -0
- package/Utils/Monitor/MonitorOverviewCriteriaUtil.ts +188 -0
- package/Utils/Monitor/MonitorOverviewFamily.ts +263 -0
- package/Utils/Monitor/MonitorOverviewPresentationUtil.ts +1958 -0
- package/Utils/Monitor/MonitorOverviewProbeUtil.ts +979 -0
- package/Utils/Monitor/MonitorOverviewTargetUtil.ts +299 -0
- package/Utils/Monitor/MonitorStatusHistoryUtil.ts +201 -0
- package/Utils/Monitor/MonitorUptimeSummaryUtil.ts +638 -0
- package/Utils/Rum/SessionIdentity.ts +44 -0
- package/Utils/Rum/SessionReplayWireEncoding.ts +137 -0
- package/Utils/Rum/UserFlow.ts +1527 -0
- package/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.ts +107 -0
- package/Utils/StatusPage/ResourceUptime.ts +99 -0
- package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +197 -0
- package/Utils/Telemetry/AttributesJSON.ts +367 -0
- package/Utils/Uptime/DayUptimeGraphUtil.ts +165 -0
- package/Utils/Uptime/UptimeUtil.ts +122 -38
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +8 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +8 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +10 -3
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +10 -3
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +434 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +49 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Runner.js +4 -4
- package/build/dist/Models/DatabaseModels/Runner.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +66 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +11 -3
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +487 -3
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js +64 -16
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +205 -0
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +115 -2
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +49 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +564 -0
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -0
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +465 -176
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorAPI.js +107 -1
- package/build/dist/Server/API/MonitorAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +5 -16
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +322 -78
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +123 -17
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +144 -5
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js +1 -0
- package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js.map +1 -1
- package/build/dist/Server/API/WorkflowVariableAPI.js +109 -0
- package/build/dist/Server/API/WorkflowVariableAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js +54 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js +32 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.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/Middleware/MasterAdminAuthorization.js +21 -0
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +32 -2
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +39 -6
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AIAgentService.js +1 -0
- package/build/dist/Server/Services/AIAgentService.js.map +1 -1
- package/build/dist/Server/Services/AccessTokenService.js +87 -42
- package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeMemberService.js +4 -0
- package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeService.js +12 -1
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +110 -23
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +716 -30
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js +100 -0
- package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +1 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js +11 -16
- package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js +4 -0
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +48 -0
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js +21 -0
- package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +12 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +8 -0
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentMemberService.js +14 -0
- package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +48 -0
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +99 -21
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +12 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +68 -4
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +1470 -0
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesClusterService.js +1097 -0
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +14 -6
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +487 -48
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +540 -3
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +3 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js +29 -7
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -1
- package/build/dist/Server/Services/OnCallSetupReminderService.js +1 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +7 -1
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +11 -1
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RunbookCredentialService.js +24 -0
- package/build/dist/Server/Services/RunbookCredentialService.js.map +1 -1
- package/build/dist/Server/Services/RunbookSecretService.js +44 -0
- package/build/dist/Server/Services/RunbookSecretService.js.map +1 -1
- package/build/dist/Server/Services/RunnerJobService.js +641 -21
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/RunnerService.js +344 -5
- package/build/dist/Server/Services/RunnerService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +48 -0
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +102 -20
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +67 -4
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +12 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -0
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +230 -32
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +4 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +270 -11
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +10 -6
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +1 -0
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +1 -0
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +4 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +107 -1
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowVariableService.js +396 -7
- package/build/dist/Server/Services/WorkflowVariableService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +463 -7
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +144 -2
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +20 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +394 -27
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +123 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +344 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +587 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js +18 -2
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1380 -239
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +1099 -68
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +88 -6
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +45 -11
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +41 -11
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +11 -4
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +4 -2
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +997 -141
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +299 -4
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +120 -0
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +160 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +59 -12
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +5 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +84 -22
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +70 -5
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js +249 -0
- package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js.map +1 -1
- package/build/dist/Server/Utils/PushNotificationUtil.js +27 -0
- package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +26 -3
- package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -1
- package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js +38 -3
- package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +143 -23
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js +406 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +4 -3
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +382 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -0
- package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js +1 -0
- package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js.map +1 -1
- package/build/dist/Server/Utils/UserPermission/UserPermission.js +10 -0
- package/build/dist/Server/Utils/UserPermission/UserPermission.js.map +1 -1
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +447 -0
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -0
- package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js +202 -0
- package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +39 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +44 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +150 -191
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +44 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js +39 -17
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +151 -145
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +221 -127
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js +91 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js +673 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +3 -9
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +65 -166
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +63 -157
- package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +23 -3
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js +92 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +81 -210
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js +68 -138
- package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js +240 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +85 -212
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +60 -17
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
- package/build/dist/Server/Utils/Workspace/Workspace.js +134 -41
- package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js +197 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +32 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js +199 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js +91 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js +450 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js.map +1 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +103 -5
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/Date.js +97 -7
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Exception/ExceptionMessages.js +1 -0
- package/build/dist/Types/Exception/ExceptionMessages.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +245 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +49 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js +16 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js.map +1 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js +104 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js.map +1 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +6 -5
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +32 -0
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorUptimeSummary.js +52 -0
- package/build/dist/Types/Monitor/MonitorUptimeSummary.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +9 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplay.js +52 -2
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js +11 -0
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
- package/build/dist/Types/Rum/UserFlow.js +115 -0
- package/build/dist/Types/Rum/UserFlow.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepType.js +10 -0
- package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
- package/build/dist/Types/Runbook/RunnerJobOrigin.js +14 -0
- package/build/dist/Types/Runbook/RunnerJobOrigin.js.map +1 -1
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +2 -2
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -1
- package/build/dist/Types/StatusPage/MergedDowntimeTotals.js +2 -0
- package/build/dist/Types/StatusPage/MergedDowntimeTotals.js.map +1 -0
- package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js +65 -0
- package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +8 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/Types/Timezone.js +5 -0
- package/build/dist/Types/Timezone.js.map +1 -1
- package/build/dist/Types/TimezoneAlias.js +340 -0
- package/build/dist/Types/TimezoneAlias.js.map +1 -0
- package/build/dist/Types/Workflow/Templates.js +2694 -2
- package/build/dist/Types/Workflow/Templates.js.map +1 -1
- package/build/dist/Types/Workflow/WorkflowVariableOAuth.js +314 -0
- package/build/dist/Types/Workflow/WorkflowVariableOAuth.js.map +1 -0
- package/build/dist/Types/Workspace/WorkspaceNoteReaction.js +98 -0
- package/build/dist/Types/Workspace/WorkspaceNoteReaction.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js +95 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js +44 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js +27 -0
- package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js +9 -0
- package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js +260 -0
- package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js.map +1 -0
- package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js +56 -0
- package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js.map +1 -0
- package/build/dist/UI/Components/Calendar/Calendar.js +94 -7
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/Calendar/CalendarDayLayout.js +136 -0
- package/build/dist/UI/Components/Calendar/CalendarDayLayout.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js +72 -0
- package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +178 -0
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js +13 -1
- package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js.map +1 -1
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +20 -4
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -9
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +36 -13
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +117 -11
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +36 -8
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js +10 -2
- package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +9 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +16 -15
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +14 -74
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +22 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +9 -2
- package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +16 -5
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +23 -8
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +7 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +5 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +37 -3
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +27 -6
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +7 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +17 -77
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js +10 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +15 -1
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/Timezone.js +52 -17
- package/build/dist/UI/Utils/Timezone.js.map +1 -1
- package/build/dist/Utils/AI/InvestigationReport.js +116 -21
- package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
- package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js +1209 -0
- package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js.map +1 -0
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js +2973 -0
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js +99 -0
- package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js.map +1 -0
- package/build/dist/Utils/AiRemediation/KubectlWriteScope.js +1429 -0
- package/build/dist/Utils/AiRemediation/KubectlWriteScope.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js +7 -6
- package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js.map +1 -1
- package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js +214 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js +471 -0
- package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js +107 -0
- package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewFamily.js +191 -0
- package/build/dist/Utils/Monitor/MonitorOverviewFamily.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js +1259 -0
- package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js +593 -0
- package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js +195 -0
- package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js +127 -0
- package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js +464 -0
- package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js.map +1 -0
- package/build/dist/Utils/Rum/SessionIdentity.js +31 -1
- package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayWireEncoding.js +128 -0
- package/build/dist/Utils/Rum/SessionReplayWireEncoding.js.map +1 -0
- package/build/dist/Utils/Rum/UserFlow.js +941 -0
- package/build/dist/Utils/Rum/UserFlow.js.map +1 -0
- package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js +82 -0
- package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js +46 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/AttributesJSON.js +245 -0
- package/build/dist/Utils/Telemetry/AttributesJSON.js.map +1 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +103 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -1
- package/build/dist/Utils/Uptime/UptimeUtil.js +91 -27
- package/build/dist/Utils/Uptime/UptimeUtil.js.map +1 -1
- package/jest.config.json +2 -1
- package/package.json +2 -1
- package/tsconfig.tests.json +36 -0
- package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +0 -337
- package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +0 -124
- package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +0 -47
- package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +0 -1
|
@@ -14,15 +14,24 @@ import { IncidentFeedEventType } from "../../../Models/DatabaseModels/IncidentFe
|
|
|
14
14
|
import AutoRemediationSuggestionStatus from "../../../Types/AutoRemediation/AutoRemediationSuggestionStatus";
|
|
15
15
|
import AutoRemediationSuggestionType from "../../../Types/AutoRemediation/AutoRemediationSuggestionType";
|
|
16
16
|
import AutoRemediationVerificationStatus from "../../../Types/AutoRemediation/AutoRemediationVerificationStatus";
|
|
17
|
-
import { AiRemediationCommandExecutionStatus, AiRemediationCommandPlanUtil, AiRemediationPlanExecutionStatus, AiRemediationRollbackStatus, } from "../../../Types/AutoRemediation/AiRemediationCommandPlan";
|
|
17
|
+
import { AiRemediationCommandExecutionStatus, AiRemediationCommandPlanUtil, AiRemediationCommandPolicyVerdict, AiRemediationPlanExecutionStatus, AiRemediationRollbackStatus, getForwardCommandStepId, getRollbackCommandStepId, isSettledCommandExecutionStatus, } from "../../../Types/AutoRemediation/AiRemediationCommandPlan";
|
|
18
|
+
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
|
18
19
|
import CommandPolicy from "../../../Utils/AiRemediation/CommandPolicy";
|
|
20
|
+
import KubectlPolicy from "../../../Utils/AiRemediation/KubectlPolicy";
|
|
21
|
+
import { KubectlCommandTier, KubernetesAiRemediationMode, } from "../../../Types/Kubernetes/KubernetesClusterAiAccess";
|
|
22
|
+
import RunbookStepType from "../../../Types/Runbook/RunbookStepType";
|
|
23
|
+
import RunnerJobOrigin from "../../../Types/Runbook/RunnerJobOrigin";
|
|
19
24
|
import { Green500, Red500 } from "../../../Types/BrandColors";
|
|
20
25
|
import AlertFeedService from "../../Services/AlertFeedService";
|
|
21
26
|
import AutoRemediationSuggestionService from "../../Services/AutoRemediationSuggestionService";
|
|
22
27
|
import IncidentFeedService from "../../Services/IncidentFeedService";
|
|
28
|
+
import KubernetesClusterAiAccessService from "../../Services/KubernetesClusterAiAccessService";
|
|
23
29
|
import RunnerJobService, { isTerminalAgentJobStatus, } from "../../Services/RunnerJobService";
|
|
24
30
|
import RunnerJobStatus from "../../../Types/Runbook/RunnerJobStatus";
|
|
31
|
+
import Semaphore from "../../Infrastructure/Semaphore";
|
|
25
32
|
import ToolResultSerializer from "../AI/Toolbox/Serializer";
|
|
33
|
+
import KubectlJobRunner, { KubectlRunState, } from "../AI/ClusterAccess/KubectlJobRunner";
|
|
34
|
+
import RemediationCommandToolkit from "../AI/Remediation/RemediationCommandTools";
|
|
26
35
|
import logger from "../Logger";
|
|
27
36
|
import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
28
37
|
/*
|
|
@@ -40,10 +49,66 @@ import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
|
40
49
|
* executed command that carried a rollbackCommand is undone, in reverse
|
|
41
50
|
* order. Rollback commands were visible on the approval card (or, for
|
|
42
51
|
* FullAuto, passed the same policy the forward command did) and are
|
|
43
|
-
* re-checked against the hard denylist here anyway.
|
|
52
|
+
* re-checked against the hard denylist here anyway. A command that may
|
|
53
|
+
* have run without saying so — its record still Pending, or a kubectl
|
|
54
|
+
* command recorded as failed whose job a Runner took with no result back
|
|
55
|
+
* (KubectlJobRunner's Unknown run state) — is never treated as never run:
|
|
56
|
+
* its undo is not run blind either, a human is told to check and undo it.
|
|
57
|
+
*
|
|
58
|
+
* Kubectl commands — forward and rollback — are additionally re-checked
|
|
59
|
+
* against the cluster's AI page AS IT IS NOW, right before they are
|
|
60
|
+
* enqueued: an approval can be clicked hours after the plan was composed,
|
|
61
|
+
* and a rollback fires at the end of the verification window. The
|
|
62
|
+
* operator's current choice (remediation off, a different Runner bound, a
|
|
63
|
+
* mode that no longer bypasses approvals) wins over the frozen plan.
|
|
64
|
+
*
|
|
65
|
+
* The two arms can overlap: verification fails a plan that overran its
|
|
66
|
+
* window while the executor is still waiting on a command. Three rules keep
|
|
67
|
+
* them from undoing each other:
|
|
68
|
+
* - the executor starts each command (its stand-down check, the enqueue,
|
|
69
|
+
* and the write that names the job) under a per-plan lock, and the
|
|
70
|
+
* rollback arm reads the plan under the same lock — so every forward
|
|
71
|
+
* job that will ever exist is either on the record the rollback arm
|
|
72
|
+
* reads, or its command stands down;
|
|
73
|
+
* - the rollback arm WAITS for a forward job still in flight and rolls it
|
|
74
|
+
* back once it succeeds, instead of skipping it;
|
|
75
|
+
* - both write the plan read-modify-write under that lock, each writing
|
|
76
|
+
* only its own fields (the executor: forward executions and the plan's
|
|
77
|
+
* execution lifecycle; the rollback arm: rollbacks and rollbackStatus),
|
|
78
|
+
* so neither erases the other's record.
|
|
79
|
+
*
|
|
80
|
+
* A Worker restart mid-rollback leaves the plan's rollbackStatus unset with
|
|
81
|
+
* a heartbeat that goes stale; the verifier's recovery sweep resumes it
|
|
82
|
+
* (executeRollback settles rollbacks already handed to a Runner from their
|
|
83
|
+
* jobs, and never re-runs one that ran). The resumed rollback's outcome is
|
|
84
|
+
* the WHOLE plan's: an undo the interrupted attempt already settled as
|
|
85
|
+
* failed, or left for a human, keeps the rollback Failed — the verifier
|
|
86
|
+
* forces the follow-up round to ask first on exactly that.
|
|
44
87
|
*/
|
|
45
88
|
const AI_COMMAND_CLAIM_TIMEOUT_MS = 60000;
|
|
46
89
|
const MAX_STORED_OUTPUT_CHARS = 6000;
|
|
90
|
+
const MAX_FEED_REASON_CHARS = 400;
|
|
91
|
+
/*
|
|
92
|
+
* The per-plan lock covers database writes and one enqueue — never a wait
|
|
93
|
+
* on a Runner. It expires on its own if the pod dies holding it.
|
|
94
|
+
*/
|
|
95
|
+
const PLAN_LOCK_NAMESPACE = "AutoRemediationCommandPlan";
|
|
96
|
+
const PLAN_LOCK_TIMEOUT_MS = 30000;
|
|
97
|
+
const PLAN_LOCK_ACQUIRE_TIMEOUT_MS = 15000;
|
|
98
|
+
// What the rollback arm needs from a RunnerJob to settle its command.
|
|
99
|
+
const RECONCILE_JOB_SELECT = {
|
|
100
|
+
_id: true,
|
|
101
|
+
status: true,
|
|
102
|
+
output: true,
|
|
103
|
+
exitCode: true,
|
|
104
|
+
errorMessage: true,
|
|
105
|
+
};
|
|
106
|
+
/*
|
|
107
|
+
* What the rollback arm needs from a kubectl RunnerJob to tell whether
|
|
108
|
+
* kubectl ran (KubectlJobRunner.getRunStateOfJobRow): the outcome, and
|
|
109
|
+
* whether a Runner ever claimed or started the job.
|
|
110
|
+
*/
|
|
111
|
+
const RUN_STATE_JOB_SELECT = Object.assign(Object.assign({}, RECONCILE_JOB_SELECT), { claimedAt: true, startedAt: true, assignedAgentId: true });
|
|
47
112
|
export default class CommandPlanExecutor {
|
|
48
113
|
/*
|
|
49
114
|
* Execute an Approved plan end-to-end. Detached-callable (the approve API
|
|
@@ -87,8 +152,12 @@ export default class CommandPlanExecutor {
|
|
|
87
152
|
}
|
|
88
153
|
plan.executionStatus = AiRemediationPlanExecutionStatus.Running;
|
|
89
154
|
plan.executionStartedAt = OneUptimeDate.getCurrentDate().toISOString();
|
|
90
|
-
await this.persistPlan(suggestion, plan);
|
|
155
|
+
await this.persistPlan(suggestion, plan, "executor");
|
|
91
156
|
let failed = false;
|
|
157
|
+
// What stopped the plan, for the feed: the first non-Succeeded outcome.
|
|
158
|
+
let firstFailure = null;
|
|
159
|
+
// Verification settled the remediation while the plan was executing.
|
|
160
|
+
let settledMidPlan = false;
|
|
92
161
|
for (const command of plan.commands) {
|
|
93
162
|
// FullAuto-executed entries never appear in approved Suggest plans.
|
|
94
163
|
if (command.execution) {
|
|
@@ -102,51 +171,90 @@ export default class CommandPlanExecutor {
|
|
|
102
171
|
continue;
|
|
103
172
|
}
|
|
104
173
|
/*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* undo end up fighting each other, so the executor stops the moment
|
|
111
|
-
* verification is no longer Pending or a human moved the
|
|
112
|
-
* suggestion off Approved.
|
|
174
|
+
* Start the command under the plan lock: the stand-down check, the
|
|
175
|
+
* Pending marker, the enqueue and the write that names the job. The
|
|
176
|
+
* rollback arm reads the plan under the same lock, so it either sees
|
|
177
|
+
* this command's job (and waits for it) or this command sees the
|
|
178
|
+
* settled verification and never starts.
|
|
113
179
|
*/
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
180
|
+
const mutex = await this.lockPlan(suggestion.id);
|
|
181
|
+
let started = null;
|
|
182
|
+
try {
|
|
183
|
+
/*
|
|
184
|
+
* Abort check between commands. Verification runs on its own
|
|
185
|
+
* sweep and can fail this remediation while the plan is still
|
|
186
|
+
* executing (a slow Runner, a long command); once it does, it
|
|
187
|
+
* rolls the executed commands back. Continuing to push NEW
|
|
188
|
+
* forward commands into a rollback that is already under way is
|
|
189
|
+
* how a plan and its undo end up fighting each other, so the
|
|
190
|
+
* executor stops the moment verification is no longer Pending or
|
|
191
|
+
* a human moved the suggestion off Approved.
|
|
192
|
+
*/
|
|
193
|
+
if (!(await this.isStillExecutable(suggestion.id))) {
|
|
194
|
+
command.execution = {
|
|
195
|
+
status: AiRemediationCommandExecutionStatus.Skipped,
|
|
196
|
+
errorMessage: "Skipped: this remediation was settled (verified, failed, or actioned by a human) before the command ran.",
|
|
197
|
+
};
|
|
198
|
+
failed = true;
|
|
199
|
+
settledMidPlan = true;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
/*
|
|
203
|
+
* Persist the Pending marker BEFORE the side effect: a pod death
|
|
204
|
+
* mid-command must leave a record that this command may have
|
|
205
|
+
* run.
|
|
206
|
+
*/
|
|
207
|
+
command.execution = {
|
|
208
|
+
status: AiRemediationCommandExecutionStatus.Pending,
|
|
209
|
+
startedAt: OneUptimeDate.getCurrentDate().toISOString(),
|
|
210
|
+
};
|
|
211
|
+
await this.persistPlan(suggestion, plan, "executor", {
|
|
212
|
+
planLocked: true,
|
|
213
|
+
});
|
|
214
|
+
started = await this.startOneCommand({ suggestion, plan, command });
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
await this.unlockPlan(mutex);
|
|
219
|
+
}
|
|
220
|
+
if (!started) {
|
|
120
221
|
continue;
|
|
121
222
|
}
|
|
122
|
-
|
|
123
|
-
* Persist the Pending marker BEFORE the side effect: a pod death
|
|
124
|
-
* mid-command must leave a record that this command may have run.
|
|
125
|
-
*/
|
|
126
|
-
command.execution = {
|
|
127
|
-
status: AiRemediationCommandExecutionStatus.Pending,
|
|
128
|
-
startedAt: OneUptimeDate.getCurrentDate().toISOString(),
|
|
129
|
-
};
|
|
130
|
-
await this.persistPlan(suggestion, plan);
|
|
131
|
-
const state = await this.executeOneCommand({ suggestion, command });
|
|
223
|
+
const state = await this.finishOneCommand({ command, started });
|
|
132
224
|
command.execution = state;
|
|
133
|
-
await this.persistPlan(suggestion, plan);
|
|
225
|
+
await this.persistPlan(suggestion, plan, "executor");
|
|
134
226
|
if (state.status !== AiRemediationCommandExecutionStatus.Succeeded) {
|
|
135
227
|
failed = true;
|
|
228
|
+
firstFailure =
|
|
229
|
+
firstFailure ||
|
|
230
|
+
`command ${command.sequence} ${state.errorMessage
|
|
231
|
+
? `failed: ${this.capForFeed(state.errorMessage)}`
|
|
232
|
+
: "failed"}`;
|
|
136
233
|
}
|
|
137
234
|
}
|
|
138
235
|
plan.executionStatus = failed
|
|
139
236
|
? AiRemediationPlanExecutionStatus.Failed
|
|
140
237
|
: AiRemediationPlanExecutionStatus.Completed;
|
|
141
238
|
plan.executionCompletedAt = OneUptimeDate.getCurrentDate().toISOString();
|
|
142
|
-
await this.persistPlan(suggestion, plan);
|
|
239
|
+
await this.persistPlan(suggestion, plan, "executor");
|
|
240
|
+
/*
|
|
241
|
+
* The last command can still be running when verification concludes
|
|
242
|
+
* (a plan that overran its window). "Verification is watching" would
|
|
243
|
+
* then contradict the verification and rollback notes already on the
|
|
244
|
+
* feed.
|
|
245
|
+
*/
|
|
246
|
+
if (!settledMidPlan && !(await this.isStillExecutable(suggestion.id))) {
|
|
247
|
+
settledMidPlan = true;
|
|
248
|
+
}
|
|
143
249
|
await this.postFeedItem({
|
|
144
250
|
suggestion,
|
|
145
|
-
markdown:
|
|
146
|
-
? `⚠️ **Approved AI command plan
|
|
147
|
-
:
|
|
148
|
-
|
|
149
|
-
|
|
251
|
+
markdown: settledMidPlan
|
|
252
|
+
? `⚠️ **Approved AI command plan finished after its verification had already concluded**${firstFailure ? ` — ${firstFailure}` : ""}. Commands that had not started yet were skipped; the verification and rollback notes on this suggestion say what was judged and what was undone. Review the per-command record.`
|
|
253
|
+
: failed
|
|
254
|
+
? `⚠️ **Approved AI command plan did not complete** — ${firstFailure || "a command failed"}; the remaining commands were skipped. Review the per-command output on the suggestion. Verification will judge (and roll back) what ran.`
|
|
255
|
+
: `⚡ **Approved AI command plan executed** (${plan.commands.length} command(s)). Verification is watching the monitors for recovery.`,
|
|
256
|
+
pingWorkspace: failed || settledMidPlan,
|
|
257
|
+
displayColor: failed || settledMidPlan ? Red500 : Green500,
|
|
150
258
|
});
|
|
151
259
|
}
|
|
152
260
|
catch (error) {
|
|
@@ -156,29 +264,115 @@ export default class CommandPlanExecutor {
|
|
|
156
264
|
/*
|
|
157
265
|
* Undo a failed remediation: run the rollbackCommand of every command
|
|
158
266
|
* that executed successfully, in REVERSE order. Called by the verifier
|
|
159
|
-
* after it wins the Failed verification transition
|
|
160
|
-
*
|
|
267
|
+
* after it wins the Failed verification transition, and by its recovery
|
|
268
|
+
* sweep for a rollback a Worker restart interrupted. Never throws.
|
|
161
269
|
*/
|
|
162
270
|
static async executeRollback(data) {
|
|
163
271
|
var _a, _b;
|
|
164
272
|
const { suggestion } = data;
|
|
273
|
+
let plan = null;
|
|
165
274
|
try {
|
|
166
|
-
|
|
275
|
+
/*
|
|
276
|
+
* Read the plan as stored NOW, under the plan lock — not the copy the
|
|
277
|
+
* verifier read before it won the verification transition. An
|
|
278
|
+
* approved plan's executor may have enqueued a command since; the
|
|
279
|
+
* lock guarantees its job is on this read, or that the command stands
|
|
280
|
+
* down and never starts.
|
|
281
|
+
*/
|
|
282
|
+
plan = await this.readPlanForRollback(suggestion);
|
|
167
283
|
if (!plan) {
|
|
168
|
-
return;
|
|
284
|
+
return this.describeRollbackOutcome(null);
|
|
169
285
|
}
|
|
170
286
|
if (plan.rollbackStatus &&
|
|
171
287
|
plan.rollbackStatus !== AiRemediationRollbackStatus.NotAttempted) {
|
|
172
|
-
|
|
288
|
+
// Already rolled back (or judged not applicable).
|
|
289
|
+
return this.describeRollbackOutcome(plan);
|
|
173
290
|
}
|
|
291
|
+
plan.rollbackHeartbeatAt = OneUptimeDate.getCurrentDate().toISOString();
|
|
292
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
174
293
|
/*
|
|
175
294
|
* A command whose record still says Pending may nonetheless have run:
|
|
176
295
|
* the executor persists Pending, enqueues, and can die before writing
|
|
177
|
-
* the outcome
|
|
178
|
-
*
|
|
179
|
-
*
|
|
296
|
+
* the outcome — or it is simply still waiting on the job. The
|
|
297
|
+
* RunnerJob row is the authority on what actually happened, so
|
|
298
|
+
* resolve those first, WAITING for a job still in flight: skipping it
|
|
299
|
+
* would leave a change that is about to land exempt from its undo.
|
|
300
|
+
*/
|
|
301
|
+
await this.reconcilePendingExecutions(suggestion, plan, {
|
|
302
|
+
waitForInFlight: true,
|
|
303
|
+
});
|
|
304
|
+
/*
|
|
305
|
+
* A resumed rollback: undos an interrupted attempt already handed to
|
|
306
|
+
* a Runner are settled from their jobs, never run twice.
|
|
307
|
+
*/
|
|
308
|
+
await this.reconcilePendingRollbacks(suggestion, plan);
|
|
309
|
+
let anyFailed = false;
|
|
310
|
+
// Rollbacks nobody may run unattended now — a human undoes them.
|
|
311
|
+
const leftForHuman = [];
|
|
312
|
+
/*
|
|
313
|
+
* A resumed rollback reports the WHOLE plan, not just what this
|
|
314
|
+
* attempt does: an undo the interrupted attempt already settled as
|
|
315
|
+
* Failed — or that reconcilePendingRollbacks just settled Failed from
|
|
316
|
+
* its job — keeps the rollback Failed, and one it left for a human is
|
|
317
|
+
* named again on the feed. Otherwise a resumed rollback whose earlier
|
|
318
|
+
* undo failed would report "completed" (or "nothing to roll back"),
|
|
319
|
+
* and the follow-up round would run unattended on top of a change
|
|
320
|
+
* that is still applied.
|
|
180
321
|
*/
|
|
181
|
-
|
|
322
|
+
for (const command of plan.commands) {
|
|
323
|
+
const earlier = command.rollbackExecution;
|
|
324
|
+
if ((earlier === null || earlier === void 0 ? void 0 : earlier.status) === AiRemediationCommandExecutionStatus.Failed) {
|
|
325
|
+
anyFailed = true;
|
|
326
|
+
}
|
|
327
|
+
else if ((earlier === null || earlier === void 0 ? void 0 : earlier.status) === AiRemediationCommandExecutionStatus.Skipped) {
|
|
328
|
+
anyFailed = true;
|
|
329
|
+
leftForHuman.push(command);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/*
|
|
333
|
+
* A forward command whose job could not be resolved even after
|
|
334
|
+
* waiting may or may not have run. Its undo is not run blind; a human
|
|
335
|
+
* is told to check.
|
|
336
|
+
*/
|
|
337
|
+
for (const command of plan.commands) {
|
|
338
|
+
const execution = command.execution;
|
|
339
|
+
if (execution &&
|
|
340
|
+
!isSettledCommandExecutionStatus(execution.status) &&
|
|
341
|
+
execution.runnerJobId &&
|
|
342
|
+
command.rollbackCommand &&
|
|
343
|
+
!command.rollbackExecution) {
|
|
344
|
+
command.rollbackExecution = {
|
|
345
|
+
status: AiRemediationCommandExecutionStatus.Skipped,
|
|
346
|
+
errorMessage: `Rollback not run: whether the command ran could not be confirmed from its job. If it ran, undo it manually: ${command.rollbackCommand}`,
|
|
347
|
+
};
|
|
348
|
+
leftForHuman.push(command);
|
|
349
|
+
anyFailed = true;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/*
|
|
353
|
+
* A kubectl command recorded as failed may still have changed the
|
|
354
|
+
* cluster: a Runner took it and no result came back, the wait for it
|
|
355
|
+
* broke while the job ran on, or kubectl was stopped before it
|
|
356
|
+
* finished. Its job is read again: one that succeeded after all is
|
|
357
|
+
* rolled back like any other, and one that may have changed the
|
|
358
|
+
* cluster gets the same answer as an unresolved one above — its undo
|
|
359
|
+
* is not run blind, a human is told to check.
|
|
360
|
+
*/
|
|
361
|
+
for (const command of await this.reconcileFailedKubectlExecutions(suggestion, plan)) {
|
|
362
|
+
command.rollbackExecution = {
|
|
363
|
+
status: AiRemediationCommandExecutionStatus.Skipped,
|
|
364
|
+
errorMessage: `Rollback not run: the command reached the cluster's Runner but kubectl did not report a finished result, so whether it changed the cluster is unknown. If it did, undo it manually: ${command.rollbackCommand}`,
|
|
365
|
+
};
|
|
366
|
+
leftForHuman.push(command);
|
|
367
|
+
anyFailed = true;
|
|
368
|
+
}
|
|
369
|
+
if (plan.commands.some((command) => {
|
|
370
|
+
return (command.rollbackExecution !== undefined &&
|
|
371
|
+
!isSettledCommandExecutionStatus(command.rollbackExecution.status));
|
|
372
|
+
})) {
|
|
373
|
+
// A rollback of an interrupted attempt whose outcome is unknown.
|
|
374
|
+
anyFailed = true;
|
|
375
|
+
}
|
|
182
376
|
const rollbackTargets = plan.commands
|
|
183
377
|
.filter((command) => {
|
|
184
378
|
var _a;
|
|
@@ -188,60 +382,87 @@ export default class CommandPlanExecutor {
|
|
|
188
382
|
!command.rollbackExecution);
|
|
189
383
|
})
|
|
190
384
|
.reverse();
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
385
|
+
/*
|
|
386
|
+
* Nothing to run and nothing that went wrong, now or in an
|
|
387
|
+
* interrupted attempt: Completed when some undo ran, NotApplicable
|
|
388
|
+
* when none was ever needed. Anything else goes through the end of
|
|
389
|
+
* this method, which settles the status from the whole plan and says
|
|
390
|
+
* so on the feed.
|
|
391
|
+
*/
|
|
392
|
+
if (rollbackTargets.length === 0 && !anyFailed) {
|
|
393
|
+
plan.rollbackStatus = plan.commands.some((command) => {
|
|
394
|
+
var _a;
|
|
395
|
+
return (((_a = command.rollbackExecution) === null || _a === void 0 ? void 0 : _a.status) ===
|
|
396
|
+
AiRemediationCommandExecutionStatus.Succeeded);
|
|
397
|
+
})
|
|
398
|
+
? AiRemediationRollbackStatus.Completed
|
|
399
|
+
: AiRemediationRollbackStatus.NotApplicable;
|
|
400
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
401
|
+
return this.describeRollbackOutcome(plan);
|
|
195
402
|
}
|
|
196
|
-
let anyFailed = false;
|
|
197
403
|
for (const command of rollbackTargets) {
|
|
198
404
|
const rollbackCommand = command.rollbackCommand;
|
|
199
|
-
const denyReason =
|
|
405
|
+
const denyReason = this.getDenyReason({
|
|
406
|
+
stepType: command.stepType,
|
|
407
|
+
command: rollbackCommand,
|
|
408
|
+
});
|
|
200
409
|
if (denyReason) {
|
|
201
410
|
command.rollbackExecution = {
|
|
202
411
|
status: AiRemediationCommandExecutionStatus.Failed,
|
|
203
412
|
errorMessage: `Rollback refused by the command policy: ${denyReason}.`,
|
|
204
413
|
};
|
|
205
414
|
anyFailed = true;
|
|
206
|
-
await this.persistPlan(suggestion, plan);
|
|
415
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
/*
|
|
419
|
+
* A rollback runs with nobody watching, so it has to be allowed
|
|
420
|
+
* unattended by the cluster as it is configured NOW — not as it was
|
|
421
|
+
* when the plan accepted the rollback. A RiskyWrite undo accepted
|
|
422
|
+
* while the operator bypassed approvals must not run once they
|
|
423
|
+
* stopped bypassing them; a cluster whose remediation was turned
|
|
424
|
+
* off must not be changed at all. Left for a human, and said so.
|
|
425
|
+
*/
|
|
426
|
+
const clusterRefusal = await this.getClusterExecutionRefusal({
|
|
427
|
+
suggestion,
|
|
428
|
+
command,
|
|
429
|
+
commandText: rollbackCommand,
|
|
430
|
+
purpose: "rollback",
|
|
431
|
+
});
|
|
432
|
+
if (clusterRefusal) {
|
|
433
|
+
command.rollbackExecution = {
|
|
434
|
+
status: AiRemediationCommandExecutionStatus.Skipped,
|
|
435
|
+
errorMessage: `Rollback not run: ${clusterRefusal}. Undo it manually: ${rollbackCommand}`,
|
|
436
|
+
};
|
|
437
|
+
leftForHuman.push(command);
|
|
438
|
+
anyFailed = true;
|
|
439
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
207
440
|
continue;
|
|
208
441
|
}
|
|
209
442
|
command.rollbackExecution = {
|
|
210
443
|
status: AiRemediationCommandExecutionStatus.Pending,
|
|
211
444
|
startedAt: OneUptimeDate.getCurrentDate().toISOString(),
|
|
212
445
|
};
|
|
213
|
-
|
|
446
|
+
plan.rollbackHeartbeatAt = OneUptimeDate.getCurrentDate().toISOString();
|
|
447
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
214
448
|
try {
|
|
215
|
-
const job = await
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
stepId:
|
|
220
|
-
stepType: command.stepType,
|
|
221
|
-
targetAgentId: new ObjectID(command.runnerId),
|
|
222
|
-
command: rollbackCommand,
|
|
223
|
-
credentialId: command.credentialId,
|
|
224
|
-
timeoutInMs: command.timeoutInMs,
|
|
225
|
-
claimTimeoutInMs: AI_COMMAND_CLAIM_TIMEOUT_MS,
|
|
449
|
+
const job = await this.enqueue({
|
|
450
|
+
suggestion,
|
|
451
|
+
command,
|
|
452
|
+
commandText: rollbackCommand,
|
|
453
|
+
stepId: getRollbackCommandStepId(command),
|
|
226
454
|
});
|
|
455
|
+
// The job id lands before the wait — see startOneCommand.
|
|
227
456
|
command.rollbackExecution.runnerJobId = (_a = job.id) === null || _a === void 0 ? void 0 : _a.toString();
|
|
457
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
228
458
|
const terminalJob = await RunnerJobService.pollUntilTerminal({
|
|
229
459
|
jobId: job.id,
|
|
230
460
|
claimTimeoutInMs: AI_COMMAND_CLAIM_TIMEOUT_MS,
|
|
231
461
|
executionTimeoutInMs: command.timeoutInMs,
|
|
232
462
|
});
|
|
233
|
-
|
|
234
|
-
command.rollbackExecution.status
|
|
235
|
-
|
|
236
|
-
: AiRemediationCommandExecutionStatus.Failed;
|
|
237
|
-
command.rollbackExecution.completedAt =
|
|
238
|
-
OneUptimeDate.getCurrentDate().toISOString();
|
|
239
|
-
command.rollbackExecution.exitCode = terminalJob.exitCode;
|
|
240
|
-
command.rollbackExecution.output = this.capOutput(terminalJob.output || "");
|
|
241
|
-
if (!succeeded) {
|
|
242
|
-
command.rollbackExecution.errorMessage =
|
|
243
|
-
terminalJob.errorMessage ||
|
|
244
|
-
`Rollback ended with status ${terminalJob.status}.`;
|
|
463
|
+
this.settleFromJob(command.rollbackExecution, terminalJob, "Rollback");
|
|
464
|
+
if (command.rollbackExecution.status !==
|
|
465
|
+
AiRemediationCommandExecutionStatus.Succeeded) {
|
|
245
466
|
anyFailed = true;
|
|
246
467
|
}
|
|
247
468
|
}
|
|
@@ -252,38 +473,102 @@ export default class CommandPlanExecutor {
|
|
|
252
473
|
error instanceof Error ? error.message : String(error);
|
|
253
474
|
anyFailed = true;
|
|
254
475
|
}
|
|
255
|
-
await this.persistPlan(suggestion, plan);
|
|
476
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
256
477
|
}
|
|
257
478
|
plan.rollbackStatus = anyFailed
|
|
258
479
|
? AiRemediationRollbackStatus.Failed
|
|
259
480
|
: AiRemediationRollbackStatus.Completed;
|
|
260
|
-
await this.persistPlan(suggestion, plan);
|
|
481
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
482
|
+
const failedUndos = plan.commands.filter((command) => {
|
|
483
|
+
var _a;
|
|
484
|
+
return (((_a = command.rollbackExecution) === null || _a === void 0 ? void 0 : _a.status) ===
|
|
485
|
+
AiRemediationCommandExecutionStatus.Failed);
|
|
486
|
+
}).length;
|
|
261
487
|
await this.postFeedItem({
|
|
262
488
|
suggestion,
|
|
263
|
-
markdown:
|
|
264
|
-
? `⚠️ **Auto-remediation rollback
|
|
265
|
-
|
|
489
|
+
markdown: leftForHuman.length > 0
|
|
490
|
+
? `⚠️ **Auto-remediation rollback was not run for ${leftForHuman.length} command(s)** — the cluster no longer allows them unattended, or whether they ran could not be confirmed, so a human has to undo them. ${leftForHuman
|
|
491
|
+
.map((command) => {
|
|
492
|
+
var _a;
|
|
493
|
+
return this.capForFeed(((_a = command.rollbackExecution) === null || _a === void 0 ? void 0 : _a.errorMessage) || "");
|
|
494
|
+
})
|
|
495
|
+
.join(" ")}${failedUndos > 0
|
|
496
|
+
? ` ${failedUndos} other rollback command(s) failed.`
|
|
497
|
+
: ""} Review the suggestion's per-command record; manual intervention is needed.`
|
|
498
|
+
: anyFailed
|
|
499
|
+
? `⚠️ **Auto-remediation rollback did not fully complete** — at least one rollback command failed, or its outcome is not known. Review the suggestion's per-command record; manual intervention may be needed.`
|
|
500
|
+
: `↩️ **Auto-remediation rolled back** — the executed commands' rollback commands ran after verification failed. Escalation continues as normal.`,
|
|
266
501
|
pingWorkspace: true,
|
|
267
502
|
displayColor: anyFailed ? Red500 : Green500,
|
|
268
503
|
});
|
|
504
|
+
return this.describeRollbackOutcome(plan);
|
|
269
505
|
}
|
|
270
506
|
catch (error) {
|
|
271
507
|
logger.error(`CommandPlanExecutor: rollback failed for suggestion ${(_b = suggestion.id) === null || _b === void 0 ? void 0 : _b.toString()}: ${error}`);
|
|
508
|
+
/*
|
|
509
|
+
* Settle it as Failed so nobody assumes it was undone — and so the
|
|
510
|
+
* recovery sweep does not retry a rollback that throws every time.
|
|
511
|
+
*/
|
|
512
|
+
if (plan) {
|
|
513
|
+
plan.rollbackStatus = AiRemediationRollbackStatus.Failed;
|
|
514
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
515
|
+
await this.postFeedItem({
|
|
516
|
+
suggestion,
|
|
517
|
+
markdown: `⚠️ **Auto-remediation rollback could not complete** — an unexpected error stopped it. Review the suggestion's per-command record; manual intervention may be needed.`,
|
|
518
|
+
pingWorkspace: true,
|
|
519
|
+
displayColor: Red500,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
return this.describeRollbackOutcome(plan);
|
|
272
523
|
}
|
|
273
524
|
}
|
|
274
525
|
// ------------------------------------------------------------------
|
|
275
|
-
|
|
526
|
+
/*
|
|
527
|
+
* Everything up to and including the enqueue: the execution-time policy
|
|
528
|
+
* floor, the cluster re-check, the enqueue, and the write that names the
|
|
529
|
+
* job. Runs under the plan lock (see executeApprovedPlan).
|
|
530
|
+
*/
|
|
531
|
+
static async startOneCommand(data) {
|
|
276
532
|
var _a, _b;
|
|
277
|
-
const { suggestion, command } = data;
|
|
533
|
+
const { suggestion, plan, command } = data;
|
|
278
534
|
/*
|
|
279
535
|
* Execution-time denylist re-check: the plan was validated when it was
|
|
280
536
|
* composed, but the policy may have been tightened since.
|
|
281
537
|
*/
|
|
282
|
-
const denyReason =
|
|
538
|
+
const denyReason = this.getDenyReason({
|
|
539
|
+
stepType: command.stepType,
|
|
540
|
+
command: command.command,
|
|
541
|
+
});
|
|
283
542
|
if (denyReason) {
|
|
284
543
|
return {
|
|
285
|
-
|
|
286
|
-
|
|
544
|
+
state: {
|
|
545
|
+
status: AiRemediationCommandExecutionStatus.Failed,
|
|
546
|
+
errorMessage: `Refused by the remediation command policy at execution time: ${denyReason}.`,
|
|
547
|
+
},
|
|
548
|
+
job: null,
|
|
549
|
+
recordsClusterOutcome: false,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
/*
|
|
553
|
+
* Execution-time cluster re-check: the approve API re-checks the
|
|
554
|
+
* project switches, this re-checks the cluster's own AI page. An
|
|
555
|
+
* operator who turned remediation off, or bound a different Runner,
|
|
556
|
+
* after the plan was composed expects that to stop the plan too.
|
|
557
|
+
*/
|
|
558
|
+
const clusterRefusal = await this.getClusterExecutionRefusal({
|
|
559
|
+
suggestion,
|
|
560
|
+
command,
|
|
561
|
+
commandText: command.command,
|
|
562
|
+
purpose: "command",
|
|
563
|
+
});
|
|
564
|
+
if (clusterRefusal) {
|
|
565
|
+
return {
|
|
566
|
+
state: {
|
|
567
|
+
status: AiRemediationCommandExecutionStatus.Failed,
|
|
568
|
+
errorMessage: `Refused at execution time: ${clusterRefusal}.`,
|
|
569
|
+
},
|
|
570
|
+
job: null,
|
|
571
|
+
recordsClusterOutcome: false,
|
|
287
572
|
};
|
|
288
573
|
}
|
|
289
574
|
const state = {
|
|
@@ -292,99 +577,534 @@ export default class CommandPlanExecutor {
|
|
|
292
577
|
OneUptimeDate.getCurrentDate().toISOString(),
|
|
293
578
|
};
|
|
294
579
|
try {
|
|
295
|
-
const job = await
|
|
580
|
+
const job = await this.enqueue({
|
|
581
|
+
suggestion,
|
|
582
|
+
command,
|
|
583
|
+
commandText: command.command,
|
|
584
|
+
// Approved plans never hold inline-executed commands (skipped above).
|
|
585
|
+
stepId: getForwardCommandStepId(command),
|
|
586
|
+
});
|
|
587
|
+
/*
|
|
588
|
+
* The job id lands on the record BEFORE the wait: a pod death while
|
|
589
|
+
* polling must leave a Pending command that names its RunnerJob, so
|
|
590
|
+
* the rollback arm can resolve what really happened instead of
|
|
591
|
+
* treating the command as one that never reached the Runner.
|
|
592
|
+
*/
|
|
593
|
+
state.runnerJobId = (_b = job.id) === null || _b === void 0 ? void 0 : _b.toString();
|
|
594
|
+
command.execution = state;
|
|
595
|
+
await this.persistPlan(suggestion, plan, "executor", {
|
|
596
|
+
planLocked: true,
|
|
597
|
+
});
|
|
598
|
+
return { state, job, recordsClusterOutcome: true };
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
state.status = AiRemediationCommandExecutionStatus.Failed;
|
|
602
|
+
state.completedAt = OneUptimeDate.getCurrentDate().toISOString();
|
|
603
|
+
state.errorMessage =
|
|
604
|
+
error instanceof Error ? error.message : String(error);
|
|
605
|
+
return { state, job: null, recordsClusterOutcome: true };
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
// The wait (outside the plan lock) and the outcome.
|
|
609
|
+
static async finishOneCommand(data) {
|
|
610
|
+
const { command, started } = data;
|
|
611
|
+
const state = started.state;
|
|
612
|
+
/*
|
|
613
|
+
* What the job's end says about the cluster's ACCESS. A job that never
|
|
614
|
+
* reached a Runner (the enqueue refused it) is an access failure; a
|
|
615
|
+
* wait that threw says nothing about the cluster.
|
|
616
|
+
*/
|
|
617
|
+
let facts = started.job
|
|
618
|
+
? null
|
|
619
|
+
: { status: RunnerJobStatus.Failed, errorMessage: state.errorMessage };
|
|
620
|
+
if (started.job) {
|
|
621
|
+
try {
|
|
622
|
+
const terminalJob = await RunnerJobService.pollUntilTerminal({
|
|
623
|
+
jobId: started.job.id,
|
|
624
|
+
claimTimeoutInMs: AI_COMMAND_CLAIM_TIMEOUT_MS,
|
|
625
|
+
executionTimeoutInMs: command.timeoutInMs,
|
|
626
|
+
});
|
|
627
|
+
if (!isTerminalAgentJobStatus(terminalJob.status)) {
|
|
628
|
+
throw new Error("Command job did not reach a terminal state.");
|
|
629
|
+
}
|
|
630
|
+
this.settleFromJob(state, terminalJob, "Command");
|
|
631
|
+
facts = {
|
|
632
|
+
status: terminalJob.status,
|
|
633
|
+
exitCode: terminalJob.exitCode,
|
|
634
|
+
output: terminalJob.output,
|
|
635
|
+
errorMessage: terminalJob.errorMessage,
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
catch (error) {
|
|
639
|
+
state.status = AiRemediationCommandExecutionStatus.Failed;
|
|
640
|
+
state.completedAt = OneUptimeDate.getCurrentDate().toISOString();
|
|
641
|
+
state.errorMessage =
|
|
642
|
+
error instanceof Error ? error.message : String(error);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
/*
|
|
646
|
+
* The cluster's "Last error" is about its AI ACCESS: a success proves
|
|
647
|
+
* the access works, and a failure is recorded only when it is about
|
|
648
|
+
* the access (never claimed, refused, timed out, unauthorized,
|
|
649
|
+
* unreachable). A deployment the plan named wrong must neither become
|
|
650
|
+
* the cluster's last error nor clear a real one.
|
|
651
|
+
*/
|
|
652
|
+
const succeeded = state.status === AiRemediationCommandExecutionStatus.Succeeded;
|
|
653
|
+
const recordsOutcome = succeeded || (facts !== null && KubectlJobRunner.isAccessFailure(facts));
|
|
654
|
+
if (started.recordsClusterOutcome &&
|
|
655
|
+
recordsOutcome &&
|
|
656
|
+
command.stepType === RunbookStepType.Kubectl &&
|
|
657
|
+
command.kubernetesClusterId &&
|
|
658
|
+
ObjectID.isValidUUID(command.kubernetesClusterId)) {
|
|
659
|
+
await KubernetesClusterAiAccessService.recordCommandOutcome({
|
|
660
|
+
clusterId: new ObjectID(command.kubernetesClusterId),
|
|
661
|
+
succeeded: state.status === AiRemediationCommandExecutionStatus.Succeeded,
|
|
662
|
+
errorMessage: state.errorMessage,
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
return state;
|
|
666
|
+
}
|
|
667
|
+
// Copy a terminal job's outcome onto an execution record.
|
|
668
|
+
static settleFromJob(state, job, label) {
|
|
669
|
+
const succeeded = job.status === RunnerJobStatus.Succeeded;
|
|
670
|
+
state.status = succeeded
|
|
671
|
+
? AiRemediationCommandExecutionStatus.Succeeded
|
|
672
|
+
: AiRemediationCommandExecutionStatus.Failed;
|
|
673
|
+
state.completedAt = OneUptimeDate.getCurrentDate().toISOString();
|
|
674
|
+
state.exitCode = job.exitCode;
|
|
675
|
+
state.output = this.capOutput(job.output || "");
|
|
676
|
+
state.errorMessage = succeeded
|
|
677
|
+
? undefined
|
|
678
|
+
: job.errorMessage || `${label} ended with status ${job.status}.`;
|
|
679
|
+
}
|
|
680
|
+
/*
|
|
681
|
+
* One enqueue for both lanes. Bash/SSH go through enqueueAiCommand
|
|
682
|
+
* (script or SSH payload); Kubectl goes through enqueueAiKubectlCommand
|
|
683
|
+
* (argv + cluster + optional credential), whose policy is re-run there.
|
|
684
|
+
*/
|
|
685
|
+
static async enqueue(data) {
|
|
686
|
+
const { suggestion, command } = data;
|
|
687
|
+
if (command.stepType === RunbookStepType.Kubectl) {
|
|
688
|
+
if (!command.kubernetesClusterId ||
|
|
689
|
+
!ObjectID.isValidUUID(command.kubernetesClusterId)) {
|
|
690
|
+
throw new Error("The kubectl command names no cluster.");
|
|
691
|
+
}
|
|
692
|
+
return RunnerJobService.enqueueAiKubectlCommand({
|
|
296
693
|
projectId: suggestion.projectId,
|
|
297
694
|
aiRunId: suggestion.aiRunId,
|
|
695
|
+
origin: RunnerJobOrigin.AiRemediation,
|
|
298
696
|
autoRemediationSuggestionId: suggestion.id,
|
|
299
|
-
|
|
300
|
-
|
|
697
|
+
kubernetesClusterId: new ObjectID(command.kubernetesClusterId),
|
|
698
|
+
stepId: data.stepId,
|
|
301
699
|
targetAgentId: new ObjectID(command.runnerId),
|
|
302
|
-
command: command.command,
|
|
303
700
|
credentialId: command.credentialId,
|
|
701
|
+
command: data.commandText,
|
|
304
702
|
timeoutInMs: command.timeoutInMs,
|
|
305
703
|
claimTimeoutInMs: AI_COMMAND_CLAIM_TIMEOUT_MS,
|
|
306
704
|
});
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
705
|
+
}
|
|
706
|
+
return RunnerJobService.enqueueAiCommand({
|
|
707
|
+
projectId: suggestion.projectId,
|
|
708
|
+
aiRunId: suggestion.aiRunId,
|
|
709
|
+
autoRemediationSuggestionId: suggestion.id,
|
|
710
|
+
stepId: data.stepId,
|
|
711
|
+
stepType: command.stepType,
|
|
712
|
+
targetAgentId: new ObjectID(command.runnerId),
|
|
713
|
+
command: data.commandText,
|
|
714
|
+
credentialId: command.credentialId,
|
|
715
|
+
timeoutInMs: command.timeoutInMs,
|
|
716
|
+
claimTimeoutInMs: AI_COMMAND_CLAIM_TIMEOUT_MS,
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
/*
|
|
720
|
+
* Why a kubectl command may NOT run on its cluster right now, or null.
|
|
721
|
+
*
|
|
722
|
+
* The plan froze the cluster, the Runner and the credential the cluster's
|
|
723
|
+
* AI page bound when the plan was composed. Before anything is enqueued
|
|
724
|
+
* the page is read again: remediation must still be enabled and ready
|
|
725
|
+
* (Disabled means "AI never runs a change on this cluster", whatever was
|
|
726
|
+
* approved earlier), and the bound Runner and credential must still be
|
|
727
|
+
* the ones on the plan — a re-bound cluster never receives a job meant
|
|
728
|
+
* for its previous access path. A rollback must ALSO be allowed
|
|
729
|
+
* unattended under the cluster's CURRENT mode and allowlist: nothing
|
|
730
|
+
* shows a rollback to a human when it fires.
|
|
731
|
+
*
|
|
732
|
+
* Fails closed: a status that cannot be read is a refusal. Bash/SSH
|
|
733
|
+
* commands have no cluster and pass through.
|
|
734
|
+
*/
|
|
735
|
+
static async getClusterExecutionRefusal(data) {
|
|
736
|
+
const { suggestion, command } = data;
|
|
737
|
+
if (command.stepType !== RunbookStepType.Kubectl) {
|
|
738
|
+
return null;
|
|
739
|
+
}
|
|
740
|
+
const clusterLabel = command.kubernetesClusterNameSnapshot ||
|
|
741
|
+
command.kubernetesClusterId ||
|
|
742
|
+
"(unknown)";
|
|
743
|
+
if (!command.kubernetesClusterId ||
|
|
744
|
+
!ObjectID.isValidUUID(command.kubernetesClusterId) ||
|
|
745
|
+
!suggestion.projectId) {
|
|
746
|
+
return `the kubectl command names no valid cluster`;
|
|
747
|
+
}
|
|
748
|
+
let status;
|
|
749
|
+
try {
|
|
750
|
+
status = await KubernetesClusterAiAccessService.getStatusForCluster({
|
|
751
|
+
clusterId: new ObjectID(command.kubernetesClusterId),
|
|
752
|
+
projectId: suggestion.projectId,
|
|
312
753
|
});
|
|
313
|
-
if (!isTerminalAgentJobStatus(terminalJob.status)) {
|
|
314
|
-
throw new Error("Command job did not reach a terminal state.");
|
|
315
|
-
}
|
|
316
|
-
const succeeded = terminalJob.status === RunnerJobStatus.Succeeded;
|
|
317
|
-
state.status = succeeded
|
|
318
|
-
? AiRemediationCommandExecutionStatus.Succeeded
|
|
319
|
-
: AiRemediationCommandExecutionStatus.Failed;
|
|
320
|
-
state.completedAt = OneUptimeDate.getCurrentDate().toISOString();
|
|
321
|
-
state.exitCode = terminalJob.exitCode;
|
|
322
|
-
state.output = this.capOutput(terminalJob.output || "");
|
|
323
|
-
if (!succeeded) {
|
|
324
|
-
state.errorMessage =
|
|
325
|
-
terminalJob.errorMessage ||
|
|
326
|
-
`Command ended with status ${terminalJob.status}.`;
|
|
327
|
-
}
|
|
328
754
|
}
|
|
329
755
|
catch (error) {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
state.errorMessage =
|
|
333
|
-
error instanceof Error ? error.message : String(error);
|
|
756
|
+
logger.error(`CommandPlanExecutor: could not read the AI access status of cluster ${command.kubernetesClusterId} before a ${data.purpose}: ${error}`);
|
|
757
|
+
return `could not confirm that cluster "${clusterLabel}" still allows AI remediation`;
|
|
334
758
|
}
|
|
335
|
-
|
|
759
|
+
if (!status) {
|
|
760
|
+
return `cluster "${clusterLabel}" no longer exists in this project`;
|
|
761
|
+
}
|
|
762
|
+
if (!status.isRemediationReady) {
|
|
763
|
+
const gap = status.gaps.find((candidate) => {
|
|
764
|
+
return candidate.blocks !== "investigation";
|
|
765
|
+
});
|
|
766
|
+
return `cluster "${status.clusterName}" no longer allows AI remediation${gap ? ` (${gap.title})` : ""}`;
|
|
767
|
+
}
|
|
768
|
+
if (!status.runner || status.runner.id !== command.runnerId) {
|
|
769
|
+
return `cluster "${status.clusterName}" is no longer reached through Runner "${command.runnerNameSnapshot}", which this plan was composed for`;
|
|
770
|
+
}
|
|
771
|
+
if ((status.credentialId || undefined) !== (command.credentialId || undefined)) {
|
|
772
|
+
return `cluster "${status.clusterName}" is no longer reached with the credential this plan was composed for`;
|
|
773
|
+
}
|
|
774
|
+
/*
|
|
775
|
+
* The Runner's write scope as it reports it now: a write it would
|
|
776
|
+
* refuse is not enqueued (or, for a rollback, is left for a human with
|
|
777
|
+
* the reason) — never sent only to be refused.
|
|
778
|
+
*/
|
|
779
|
+
const scopeRefusal = RemediationCommandToolkit.getRunnerScopeRefusal({
|
|
780
|
+
cluster: status,
|
|
781
|
+
command: data.commandText,
|
|
782
|
+
});
|
|
783
|
+
if (scopeRefusal) {
|
|
784
|
+
// The callers end the sentence themselves.
|
|
785
|
+
return `the cluster's Runner would refuse it: ${scopeRefusal.endsWith(".") ? scopeRefusal.slice(0, -1) : scopeRefusal}`;
|
|
786
|
+
}
|
|
787
|
+
if (data.purpose === "rollback") {
|
|
788
|
+
const verdict = KubectlPolicy.evaluateForAutoExecution({
|
|
789
|
+
command: data.commandText,
|
|
790
|
+
allowlistPatterns: status.kubectlAllowlist,
|
|
791
|
+
bypassApproval: status.remediationMode ===
|
|
792
|
+
KubernetesAiRemediationMode.BypassApproval,
|
|
793
|
+
});
|
|
794
|
+
if (verdict.verdict !== AiRemediationCommandPolicyVerdict.AutoApproved) {
|
|
795
|
+
return `cluster "${status.clusterName}" no longer allows this change unattended (its AI remediation mode is now ${status.remediationMode}): ${verdict.reason}`;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return null;
|
|
799
|
+
}
|
|
800
|
+
/*
|
|
801
|
+
* The job a command's step ran under, when its record never got the job
|
|
802
|
+
* id. The enqueue and the write that names the job are two steps; a pod
|
|
803
|
+
* death or a failed write between them leaves a Pending record for a job
|
|
804
|
+
* the Runner was nonetheless handed. (suggestion, stepId) is unique per
|
|
805
|
+
* forward command — a plan executes at most once and a retried run never
|
|
806
|
+
* re-executes — and per rollback; the newest row wins should that ever
|
|
807
|
+
* change.
|
|
808
|
+
*/
|
|
809
|
+
static async findJobByStepId(data) {
|
|
810
|
+
if (!data.suggestion.id) {
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
const jobs = await RunnerJobService.findBy({
|
|
814
|
+
query: Object.assign(Object.assign({}, (data.suggestion.projectId
|
|
815
|
+
? { projectId: data.suggestion.projectId }
|
|
816
|
+
: {})), { autoRemediationSuggestionId: data.suggestion.id, origin: RunnerJobOrigin.AiRemediation, stepId: data.stepId }),
|
|
817
|
+
select: RECONCILE_JOB_SELECT,
|
|
818
|
+
sort: { createdAt: SortOrder.Descending },
|
|
819
|
+
limit: 1,
|
|
820
|
+
skip: 0,
|
|
821
|
+
props: { isRoot: true },
|
|
822
|
+
});
|
|
823
|
+
return jobs[0] || null;
|
|
824
|
+
}
|
|
825
|
+
static capForFeed(text) {
|
|
826
|
+
const collapsed = text.trim().replace(/\s+/g, " ");
|
|
827
|
+
return collapsed.length > MAX_FEED_REASON_CHARS
|
|
828
|
+
? `${collapsed.slice(0, MAX_FEED_REASON_CHARS)}…`
|
|
829
|
+
: collapsed;
|
|
830
|
+
}
|
|
831
|
+
/*
|
|
832
|
+
* Execution-time policy floor per lane: the bash denylist for Bash/SSH,
|
|
833
|
+
* the Denied tier for Kubectl. Null when the command may run.
|
|
834
|
+
*/
|
|
835
|
+
static getDenyReason(data) {
|
|
836
|
+
if (data.stepType === RunbookStepType.Kubectl) {
|
|
837
|
+
const policy = KubectlPolicy.evaluateCommand(data.command);
|
|
838
|
+
return policy.tier === KubectlCommandTier.Denied ? policy.reason : null;
|
|
839
|
+
}
|
|
840
|
+
return CommandPolicy.getDenyReason(data.command);
|
|
336
841
|
}
|
|
337
842
|
/*
|
|
338
843
|
* Settle commands left in Pending/Running by reading their RunnerJob. A
|
|
339
844
|
* job that reached Succeeded really ran, so the command becomes Succeeded
|
|
340
|
-
* (and therefore rollback-eligible); any other terminal state
|
|
341
|
-
*
|
|
845
|
+
* (and therefore rollback-eligible); any other terminal state becomes
|
|
846
|
+
* Failed. A job still in flight is WAITED for when `waitForInFlight` is
|
|
847
|
+
* set (the rollback arm: the change is about to land, and its undo must
|
|
848
|
+
* not be skipped); otherwise it is left alone.
|
|
849
|
+
*
|
|
850
|
+
* The job is found by the id on the record, or — when the record never
|
|
851
|
+
* got one, because the pod died or the write failed between the enqueue
|
|
852
|
+
* and the persist that names the job — by the (suggestion, stepId) pair
|
|
853
|
+
* the lane enqueued it under. A command with neither never reached the
|
|
854
|
+
* Runner and is left alone.
|
|
342
855
|
*/
|
|
343
|
-
static async reconcilePendingExecutions(suggestion, plan) {
|
|
344
|
-
var _a
|
|
856
|
+
static async reconcilePendingExecutions(suggestion, plan, options) {
|
|
857
|
+
var _a;
|
|
345
858
|
let changed = false;
|
|
346
859
|
for (const command of plan.commands) {
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
860
|
+
const execution = command.execution;
|
|
861
|
+
if (!execution) {
|
|
862
|
+
continue;
|
|
863
|
+
}
|
|
864
|
+
const isUnsettled = execution.status === AiRemediationCommandExecutionStatus.Pending ||
|
|
865
|
+
execution.status === AiRemediationCommandExecutionStatus.Running;
|
|
866
|
+
if (!isUnsettled) {
|
|
351
867
|
continue;
|
|
352
868
|
}
|
|
353
869
|
try {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
if (!job || !isTerminalAgentJobStatus(job.status)) {
|
|
870
|
+
let job = execution.runnerJobId
|
|
871
|
+
? await RunnerJobService.findOneById({
|
|
872
|
+
id: new ObjectID(execution.runnerJobId),
|
|
873
|
+
select: RECONCILE_JOB_SELECT,
|
|
874
|
+
props: { isRoot: true },
|
|
875
|
+
})
|
|
876
|
+
: await this.findJobByStepId({
|
|
877
|
+
suggestion,
|
|
878
|
+
stepId: getForwardCommandStepId(command),
|
|
879
|
+
});
|
|
880
|
+
if (!job) {
|
|
366
881
|
continue;
|
|
367
882
|
}
|
|
883
|
+
// Recovered by stepId: name the job so the record stays resolvable.
|
|
884
|
+
if (!execution.runnerJobId && job.id) {
|
|
885
|
+
execution.runnerJobId = job.id.toString();
|
|
886
|
+
changed = true;
|
|
887
|
+
}
|
|
888
|
+
if (!isTerminalAgentJobStatus(job.status)) {
|
|
889
|
+
if (!options.waitForInFlight || !job.id) {
|
|
890
|
+
continue;
|
|
891
|
+
}
|
|
892
|
+
// Say where the rollback stands before a wait that can take minutes.
|
|
893
|
+
if (changed) {
|
|
894
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
895
|
+
changed = false;
|
|
896
|
+
}
|
|
897
|
+
plan.rollbackHeartbeatAt =
|
|
898
|
+
OneUptimeDate.getCurrentDate().toISOString();
|
|
899
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
900
|
+
job = await RunnerJobService.pollUntilTerminal({
|
|
901
|
+
jobId: job.id,
|
|
902
|
+
claimTimeoutInMs: AI_COMMAND_CLAIM_TIMEOUT_MS,
|
|
903
|
+
executionTimeoutInMs: command.timeoutInMs,
|
|
904
|
+
});
|
|
905
|
+
if (!isTerminalAgentJobStatus(job.status)) {
|
|
906
|
+
continue;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
368
909
|
const succeeded = job.status === RunnerJobStatus.Succeeded;
|
|
369
|
-
|
|
910
|
+
execution.status = succeeded
|
|
370
911
|
? AiRemediationCommandExecutionStatus.Succeeded
|
|
371
912
|
: AiRemediationCommandExecutionStatus.Failed;
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
913
|
+
execution.exitCode = job.exitCode;
|
|
914
|
+
execution.output = this.capOutput(job.output || "");
|
|
915
|
+
execution.errorMessage = succeeded
|
|
375
916
|
? undefined
|
|
376
917
|
: job.errorMessage ||
|
|
377
918
|
`Command ended with status ${job.status} (recovered from the job record).`;
|
|
378
919
|
changed = true;
|
|
379
920
|
}
|
|
380
921
|
catch (error) {
|
|
381
|
-
logger.error(`CommandPlanExecutor: could not reconcile command ${command.sequence} of suggestion ${(
|
|
922
|
+
logger.error(`CommandPlanExecutor: could not reconcile command ${command.sequence} of suggestion ${(_a = suggestion.id) === null || _a === void 0 ? void 0 : _a.toString()}: ${error}`);
|
|
382
923
|
}
|
|
383
924
|
}
|
|
384
925
|
if (changed) {
|
|
385
|
-
await this.persistPlan(suggestion, plan);
|
|
926
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
386
927
|
}
|
|
387
928
|
}
|
|
929
|
+
/*
|
|
930
|
+
* A rollback resumed after a Worker restart: settle the undos the
|
|
931
|
+
* interrupted attempt had already started. One with a job — on the record
|
|
932
|
+
* or found under its rollback step id — is settled from that job
|
|
933
|
+
* (waiting for it when it is still running): it is never run a second
|
|
934
|
+
* time, because running an undo twice (a second `rollout undo`) can put
|
|
935
|
+
* the bad change right back. One that never reached a Runner is cleared,
|
|
936
|
+
* so it runs now. One whose job cannot be looked up stays unsettled, and
|
|
937
|
+
* the rollback is not reported complete.
|
|
938
|
+
*/
|
|
939
|
+
static async reconcilePendingRollbacks(suggestion, plan) {
|
|
940
|
+
var _a;
|
|
941
|
+
let changed = false;
|
|
942
|
+
for (const command of plan.commands) {
|
|
943
|
+
const rollback = command.rollbackExecution;
|
|
944
|
+
if (!rollback || isSettledCommandExecutionStatus(rollback.status)) {
|
|
945
|
+
continue;
|
|
946
|
+
}
|
|
947
|
+
try {
|
|
948
|
+
let job = rollback.runnerJobId
|
|
949
|
+
? await RunnerJobService.findOneById({
|
|
950
|
+
id: new ObjectID(rollback.runnerJobId),
|
|
951
|
+
select: RECONCILE_JOB_SELECT,
|
|
952
|
+
props: { isRoot: true },
|
|
953
|
+
})
|
|
954
|
+
: await this.findJobByStepId({
|
|
955
|
+
suggestion,
|
|
956
|
+
stepId: getRollbackCommandStepId(command),
|
|
957
|
+
});
|
|
958
|
+
if (!job) {
|
|
959
|
+
// Never reached a Runner: run it now.
|
|
960
|
+
command.rollbackExecution = undefined;
|
|
961
|
+
changed = true;
|
|
962
|
+
continue;
|
|
963
|
+
}
|
|
964
|
+
if (!rollback.runnerJobId && job.id) {
|
|
965
|
+
rollback.runnerJobId = job.id.toString();
|
|
966
|
+
changed = true;
|
|
967
|
+
}
|
|
968
|
+
if (!isTerminalAgentJobStatus(job.status) && job.id) {
|
|
969
|
+
plan.rollbackHeartbeatAt =
|
|
970
|
+
OneUptimeDate.getCurrentDate().toISOString();
|
|
971
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
972
|
+
job = await RunnerJobService.pollUntilTerminal({
|
|
973
|
+
jobId: job.id,
|
|
974
|
+
claimTimeoutInMs: AI_COMMAND_CLAIM_TIMEOUT_MS,
|
|
975
|
+
executionTimeoutInMs: command.timeoutInMs,
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
if (isTerminalAgentJobStatus(job.status)) {
|
|
979
|
+
this.settleFromJob(rollback, job, "Rollback");
|
|
980
|
+
changed = true;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
catch (error) {
|
|
984
|
+
logger.error(`CommandPlanExecutor: could not reconcile the rollback of command ${command.sequence} of suggestion ${(_a = suggestion.id) === null || _a === void 0 ? void 0 : _a.toString()}: ${error}`);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
if (changed) {
|
|
988
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
/*
|
|
992
|
+
* The kubectl commands recorded as Failed that may nonetheless have
|
|
993
|
+
* changed the cluster, read from their jobs the way KubectlJobRunner
|
|
994
|
+
* reads every kubectl job (KubectlJobRunner.getRunStateOfJobRow). Only a
|
|
995
|
+
* command that carries a rollbackCommand and has no rollback yet is read
|
|
996
|
+
* — nothing else has an undo to owe.
|
|
997
|
+
*
|
|
998
|
+
* - A job that Succeeded after all (the wait for it broke, and the
|
|
999
|
+
* record said Failed) is settled from the job: it becomes Succeeded,
|
|
1000
|
+
* and so a rollback target like any other.
|
|
1001
|
+
* - A job whose run is Unknown — a Runner took it and no result came
|
|
1002
|
+
* back, it is still in flight, or its row cannot be read — is
|
|
1003
|
+
* returned: whether it changed the cluster is not known. So is one
|
|
1004
|
+
* where kubectl ran but never finished (the Runner killed it at its
|
|
1005
|
+
* timeout, or it left output but no exit code): it may have applied
|
|
1006
|
+
* its change before it was stopped.
|
|
1007
|
+
* - A job that certainly never ran, or whose kubectl finished and
|
|
1008
|
+
* reported a failure (an exit code), owes no undo, as before.
|
|
1009
|
+
*/
|
|
1010
|
+
static async reconcileFailedKubectlExecutions(suggestion, plan) {
|
|
1011
|
+
var _a;
|
|
1012
|
+
const mayHaveRun = [];
|
|
1013
|
+
let changed = false;
|
|
1014
|
+
for (const command of plan.commands) {
|
|
1015
|
+
const execution = command.execution;
|
|
1016
|
+
if (command.stepType !== RunbookStepType.Kubectl ||
|
|
1017
|
+
!execution ||
|
|
1018
|
+
execution.status !== AiRemediationCommandExecutionStatus.Failed ||
|
|
1019
|
+
!execution.runnerJobId ||
|
|
1020
|
+
!command.rollbackCommand ||
|
|
1021
|
+
command.rollbackExecution) {
|
|
1022
|
+
continue;
|
|
1023
|
+
}
|
|
1024
|
+
let runState = KubectlRunState.Unknown;
|
|
1025
|
+
let job = null;
|
|
1026
|
+
try {
|
|
1027
|
+
job = ObjectID.isValidUUID(execution.runnerJobId)
|
|
1028
|
+
? await RunnerJobService.findOneById({
|
|
1029
|
+
id: new ObjectID(execution.runnerJobId),
|
|
1030
|
+
select: RUN_STATE_JOB_SELECT,
|
|
1031
|
+
props: { isRoot: true },
|
|
1032
|
+
})
|
|
1033
|
+
: null;
|
|
1034
|
+
if (job) {
|
|
1035
|
+
runState = KubectlJobRunner.getRunStateOfJobRow(job);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
catch (error) {
|
|
1039
|
+
logger.error(`CommandPlanExecutor: could not read whether command ${command.sequence} of suggestion ${(_a = suggestion.id) === null || _a === void 0 ? void 0 : _a.toString()} ran: ${error}`);
|
|
1040
|
+
}
|
|
1041
|
+
if (job && job.status === RunnerJobStatus.Succeeded) {
|
|
1042
|
+
this.settleFromJob(execution, job, "Command");
|
|
1043
|
+
changed = true;
|
|
1044
|
+
continue;
|
|
1045
|
+
}
|
|
1046
|
+
const kubectlFinished = runState === KubectlRunState.Ran && typeof (job === null || job === void 0 ? void 0 : job.exitCode) === "number";
|
|
1047
|
+
if (runState !== KubectlRunState.NotRun && !kubectlFinished) {
|
|
1048
|
+
mayHaveRun.push(command);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
if (changed) {
|
|
1052
|
+
await this.persistPlan(suggestion, plan, "rollback");
|
|
1053
|
+
}
|
|
1054
|
+
return mayHaveRun;
|
|
1055
|
+
}
|
|
1056
|
+
static describeRollbackOutcome(plan) {
|
|
1057
|
+
var _a;
|
|
1058
|
+
let rolledBack = 0;
|
|
1059
|
+
let failed = 0;
|
|
1060
|
+
let leftForHuman = 0;
|
|
1061
|
+
for (const command of (plan === null || plan === void 0 ? void 0 : plan.commands) || []) {
|
|
1062
|
+
switch ((_a = command.rollbackExecution) === null || _a === void 0 ? void 0 : _a.status) {
|
|
1063
|
+
case AiRemediationCommandExecutionStatus.Succeeded:
|
|
1064
|
+
rolledBack += 1;
|
|
1065
|
+
break;
|
|
1066
|
+
case AiRemediationCommandExecutionStatus.Failed:
|
|
1067
|
+
failed += 1;
|
|
1068
|
+
break;
|
|
1069
|
+
case AiRemediationCommandExecutionStatus.Skipped:
|
|
1070
|
+
leftForHuman += 1;
|
|
1071
|
+
break;
|
|
1072
|
+
default:
|
|
1073
|
+
break;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
const storedStatus = (plan === null || plan === void 0 ? void 0 : plan.rollbackStatus) &&
|
|
1077
|
+
plan.rollbackStatus !== AiRemediationRollbackStatus.NotAttempted
|
|
1078
|
+
? plan.rollbackStatus
|
|
1079
|
+
: undefined;
|
|
1080
|
+
/*
|
|
1081
|
+
* A status and its counts never contradict each other: an undo that
|
|
1082
|
+
* failed or was left for a human makes a settled rollback Failed, even
|
|
1083
|
+
* one recorded "completed" before resumed rollbacks carried earlier
|
|
1084
|
+
* failures forward.
|
|
1085
|
+
*/
|
|
1086
|
+
const rollbackStatus = storedStatus !== undefined && failed + leftForHuman > 0
|
|
1087
|
+
? AiRemediationRollbackStatus.Failed
|
|
1088
|
+
: storedStatus;
|
|
1089
|
+
let summary;
|
|
1090
|
+
switch (rollbackStatus) {
|
|
1091
|
+
case AiRemediationRollbackStatus.Completed:
|
|
1092
|
+
summary = `Rollback completed: ${rolledBack} command(s) undone.`;
|
|
1093
|
+
break;
|
|
1094
|
+
case AiRemediationRollbackStatus.NotApplicable:
|
|
1095
|
+
summary =
|
|
1096
|
+
"Nothing was rolled back: no executed command carried a rollback command.";
|
|
1097
|
+
break;
|
|
1098
|
+
case AiRemediationRollbackStatus.Failed:
|
|
1099
|
+
summary = `Rollback did NOT fully complete: ${rolledBack} command(s) undone, ${failed} rollback(s) failed, ${leftForHuman} left for a human to undo — the change may still be applied.`;
|
|
1100
|
+
break;
|
|
1101
|
+
default:
|
|
1102
|
+
summary =
|
|
1103
|
+
"The rollback did not finish; whatever it did not undo may still be applied.";
|
|
1104
|
+
break;
|
|
1105
|
+
}
|
|
1106
|
+
return { rollbackStatus, rolledBack, failed, leftForHuman, summary };
|
|
1107
|
+
}
|
|
388
1108
|
/*
|
|
389
1109
|
* Whether the suggestion is still an Approved remediation whose
|
|
390
1110
|
* verification window is open. False means someone (the verifier, or a
|
|
@@ -429,13 +1149,70 @@ export default class CommandPlanExecutor {
|
|
|
429
1149
|
return true;
|
|
430
1150
|
}
|
|
431
1151
|
}
|
|
432
|
-
|
|
1152
|
+
/*
|
|
1153
|
+
* The plan the rollback arm works from: the stored one, read under the
|
|
1154
|
+
* plan lock. Falls back to the copy the caller holds when the stored plan
|
|
1155
|
+
* cannot be read.
|
|
1156
|
+
*/
|
|
1157
|
+
static async readPlanForRollback(suggestion) {
|
|
1158
|
+
const mutex = suggestion.id
|
|
1159
|
+
? await this.lockPlan(suggestion.id)
|
|
1160
|
+
: null;
|
|
1161
|
+
try {
|
|
1162
|
+
const stored = suggestion.id
|
|
1163
|
+
? await this.readStoredPlan(suggestion.id)
|
|
1164
|
+
: null;
|
|
1165
|
+
return (stored || AiRemediationCommandPlanUtil.parse(suggestion.commandPlan));
|
|
1166
|
+
}
|
|
1167
|
+
finally {
|
|
1168
|
+
await this.unlockPlan(mutex);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
// The plan as stored right now, or null when it cannot be read.
|
|
1172
|
+
static async readStoredPlan(suggestionId) {
|
|
1173
|
+
try {
|
|
1174
|
+
/*
|
|
1175
|
+
* findOneBy, not findOneById: this is the column read for a merge,
|
|
1176
|
+
* not a status re-check, and it must not be mistaken for one.
|
|
1177
|
+
*/
|
|
1178
|
+
const stored = await AutoRemediationSuggestionService.findOneBy({
|
|
1179
|
+
query: { _id: suggestionId.toString() },
|
|
1180
|
+
select: { _id: true, commandPlan: true },
|
|
1181
|
+
props: { isRoot: true },
|
|
1182
|
+
});
|
|
1183
|
+
return AiRemediationCommandPlanUtil.parse(stored === null || stored === void 0 ? void 0 : stored.commandPlan);
|
|
1184
|
+
}
|
|
1185
|
+
catch (error) {
|
|
1186
|
+
logger.warn(`CommandPlanExecutor: could not read the stored plan of suggestion ${suggestionId.toString()} to merge into; writing this writer's copy as is: ${error}`);
|
|
1187
|
+
return null;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
/*
|
|
1191
|
+
* Persist the plan without erasing what the OTHER arm wrote. The stored
|
|
1192
|
+
* plan is re-read (under the plan lock) and only this writer's fields are
|
|
1193
|
+
* taken from its copy: the executor owns forward executions and the
|
|
1194
|
+
* plan's execution lifecycle; the rollback arm owns rollbacks,
|
|
1195
|
+
* rollbackStatus and the rollback heartbeat. A forward execution the
|
|
1196
|
+
* rollback arm settled from its job is kept over a stale unsettled copy
|
|
1197
|
+
* either way. When the stored plan cannot be read, this writer's copy is
|
|
1198
|
+
* written as is — the record must still land.
|
|
1199
|
+
*/
|
|
1200
|
+
static async persistPlan(suggestion, plan, writer, options) {
|
|
433
1201
|
var _a;
|
|
1202
|
+
const mutex = (options === null || options === void 0 ? void 0 : options.planLocked) || !suggestion.id
|
|
1203
|
+
? null
|
|
1204
|
+
: await this.lockPlan(suggestion.id);
|
|
434
1205
|
try {
|
|
1206
|
+
const stored = suggestion.id
|
|
1207
|
+
? await this.readStoredPlan(suggestion.id)
|
|
1208
|
+
: null;
|
|
1209
|
+
const toWrite = stored
|
|
1210
|
+
? this.mergePlans({ mine: plan, stored, writer })
|
|
1211
|
+
: plan;
|
|
435
1212
|
await AutoRemediationSuggestionService.updateOneById({
|
|
436
1213
|
id: suggestion.id,
|
|
437
1214
|
data: {
|
|
438
|
-
commandPlan: AiRemediationCommandPlanUtil.toJSON(
|
|
1215
|
+
commandPlan: AiRemediationCommandPlanUtil.toJSON(toWrite),
|
|
439
1216
|
},
|
|
440
1217
|
props: { isRoot: true },
|
|
441
1218
|
});
|
|
@@ -443,6 +1220,85 @@ export default class CommandPlanExecutor {
|
|
|
443
1220
|
catch (error) {
|
|
444
1221
|
logger.error(`CommandPlanExecutor: failed to persist plan progress for suggestion ${(_a = suggestion.id) === null || _a === void 0 ? void 0 : _a.toString()}: ${error}`);
|
|
445
1222
|
}
|
|
1223
|
+
finally {
|
|
1224
|
+
await this.unlockPlan(mutex);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
static mergePlans(data) {
|
|
1228
|
+
var _a, _b;
|
|
1229
|
+
const { mine, stored } = data;
|
|
1230
|
+
if (data.writer === "executor") {
|
|
1231
|
+
const storedBySequence = new Map(stored.commands.map((command) => {
|
|
1232
|
+
return [command.sequence, command];
|
|
1233
|
+
}));
|
|
1234
|
+
return Object.assign(Object.assign({}, mine), { commands: mine.commands.map((command) => {
|
|
1235
|
+
const storedCommand = storedBySequence.get(command.sequence);
|
|
1236
|
+
return Object.assign(Object.assign({}, command), { execution: this.pickExecution(command.execution, storedCommand === null || storedCommand === void 0 ? void 0 : storedCommand.execution), rollbackExecution: storedCommand === null || storedCommand === void 0 ? void 0 : storedCommand.rollbackExecution });
|
|
1237
|
+
}), rollbackStatus: stored.rollbackStatus, rollbackHeartbeatAt: stored.rollbackHeartbeatAt });
|
|
1238
|
+
}
|
|
1239
|
+
const mineBySequence = new Map(mine.commands.map((command) => {
|
|
1240
|
+
return [command.sequence, command];
|
|
1241
|
+
}));
|
|
1242
|
+
return Object.assign(Object.assign({}, stored), { commands: stored.commands.map((storedCommand) => {
|
|
1243
|
+
const command = mineBySequence.get(storedCommand.sequence);
|
|
1244
|
+
if (!command) {
|
|
1245
|
+
return storedCommand;
|
|
1246
|
+
}
|
|
1247
|
+
return Object.assign(Object.assign({}, storedCommand), { execution: this.pickExecution(command.execution, storedCommand.execution), rollbackExecution: command.rollbackExecution });
|
|
1248
|
+
}), rollbackStatus: (_a = mine.rollbackStatus) !== null && _a !== void 0 ? _a : stored.rollbackStatus, rollbackHeartbeatAt: (_b = mine.rollbackHeartbeatAt) !== null && _b !== void 0 ? _b : stored.rollbackHeartbeatAt });
|
|
1249
|
+
}
|
|
1250
|
+
/*
|
|
1251
|
+
* The more settled of two records of one command's forward execution: a
|
|
1252
|
+
* record with an outcome beats one still waiting for it; with both
|
|
1253
|
+
* settled (or both not) the writer's own wins, keeping any job id either
|
|
1254
|
+
* of them knows.
|
|
1255
|
+
*/
|
|
1256
|
+
static pickExecution(mine, stored) {
|
|
1257
|
+
if (!mine) {
|
|
1258
|
+
return stored;
|
|
1259
|
+
}
|
|
1260
|
+
if (!stored) {
|
|
1261
|
+
return mine;
|
|
1262
|
+
}
|
|
1263
|
+
if (isSettledCommandExecutionStatus(mine.status)) {
|
|
1264
|
+
return mine;
|
|
1265
|
+
}
|
|
1266
|
+
if (isSettledCommandExecutionStatus(stored.status)) {
|
|
1267
|
+
return stored;
|
|
1268
|
+
}
|
|
1269
|
+
return mine.runnerJobId || !stored.runnerJobId
|
|
1270
|
+
? mine
|
|
1271
|
+
: Object.assign(Object.assign({}, mine), { runnerJobId: stored.runnerJobId });
|
|
1272
|
+
}
|
|
1273
|
+
/*
|
|
1274
|
+
* The per-plan lock, or null when it cannot be had (Redis unavailable):
|
|
1275
|
+
* the plan's writes then proceed unserialized rather than not at all — a
|
|
1276
|
+
* remediation must never be stranded half-recorded for want of a lock.
|
|
1277
|
+
*/
|
|
1278
|
+
static async lockPlan(suggestionId) {
|
|
1279
|
+
try {
|
|
1280
|
+
return await Semaphore.lock({
|
|
1281
|
+
key: suggestionId.toString(),
|
|
1282
|
+
namespace: PLAN_LOCK_NAMESPACE,
|
|
1283
|
+
lockTimeout: PLAN_LOCK_TIMEOUT_MS,
|
|
1284
|
+
acquireTimeout: PLAN_LOCK_ACQUIRE_TIMEOUT_MS,
|
|
1285
|
+
});
|
|
1286
|
+
}
|
|
1287
|
+
catch (error) {
|
|
1288
|
+
logger.warn(`CommandPlanExecutor: could not take the plan lock of suggestion ${suggestionId.toString()}; continuing unserialized: ${error}`);
|
|
1289
|
+
return null;
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
static async unlockPlan(mutex) {
|
|
1293
|
+
if (!mutex) {
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
try {
|
|
1297
|
+
await Semaphore.release(mutex);
|
|
1298
|
+
}
|
|
1299
|
+
catch (error) {
|
|
1300
|
+
logger.error(`CommandPlanExecutor: failed to release the plan lock: ${error}`);
|
|
1301
|
+
}
|
|
446
1302
|
}
|
|
447
1303
|
static capOutput(output) {
|
|
448
1304
|
const redacted = ToolResultSerializer.redact(output).text;
|