@oneuptime/common 14.0.8 → 14.0.10
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/AutoRemediationSuggestion.ts +60 -0
- package/Models/DatabaseModels/CephCluster.ts +213 -0
- package/Models/DatabaseModels/DatabaseServer.ts +213 -0
- package/Models/DatabaseModels/DockerHost.ts +213 -0
- package/Models/DatabaseModels/DockerSwarmCluster.ts +213 -0
- package/Models/DatabaseModels/GlobalConfig.ts +1 -1
- package/Models/DatabaseModels/Host.ts +213 -0
- package/Models/DatabaseModels/Index.ts +4 -0
- package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
- package/Models/DatabaseModels/PodmanHost.ts +213 -0
- package/Models/DatabaseModels/Project.ts +55 -5
- package/Models/DatabaseModels/ProxmoxCluster.ts +213 -0
- package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
- package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
- package/Models/DatabaseModels/RunnerJob.ts +219 -0
- package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
- package/Models/DatabaseModels/VMwareVCenter.ts +213 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
- package/Server/API/AIChatAPI.ts +6 -3
- package/Server/API/AIInvestigationAPI.ts +17 -10
- package/Server/API/AutoRemediationAPI.ts +598 -25
- package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
- package/Server/API/MicrosoftTeamsAPI.ts +93 -14
- package/Server/API/ProxmoxResourceAPI.ts +244 -14
- package/Server/API/ResourceAiAccessAPI.ts +1669 -0
- package/Server/Infrastructure/GlobalCache.ts +32 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Infrastructure/Semaphore.ts +22 -0
- package/Server/Middleware/TelemetryIngest.ts +51 -18
- package/Server/Services/AIService.ts +70 -1
- package/Server/Services/AlertService.ts +352 -11
- package/Server/Services/AlertSeverityService.ts +65 -15
- package/Server/Services/AnalyticsDatabaseService.ts +45 -1
- package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
- package/Server/Services/AutoRemediationRuleService.ts +1 -1
- package/Server/Services/CephClusterService.ts +109 -1
- package/Server/Services/DatabaseServerService.ts +116 -1
- package/Server/Services/DockerHostService.ts +109 -1
- package/Server/Services/DockerSwarmClusterService.ts +113 -1
- package/Server/Services/HostService.ts +126 -4
- package/Server/Services/IncidentService.ts +280 -104
- package/Server/Services/IncidentSeverityService.ts +66 -15
- package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
- package/Server/Services/KubernetesAiAgentService.ts +1634 -0
- package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
- package/Server/Services/KubernetesClusterService.ts +129 -21
- package/Server/Services/MetricRecordingRuleService.ts +47 -0
- package/Server/Services/PodmanHostService.ts +109 -1
- package/Server/Services/ProjectService.ts +32 -0
- package/Server/Services/ProxmoxClusterService.ts +110 -1
- package/Server/Services/ProxmoxResourceService.ts +322 -5
- package/Server/Services/ResourceAiAccessService.ts +1439 -0
- package/Server/Services/ResourceAiAgentJobService.ts +202 -0
- package/Server/Services/ResourceAiAgentService.ts +2432 -0
- package/Server/Services/RunnerJobService.ts +852 -108
- package/Server/Services/RunnerService.ts +1 -1
- package/Server/Services/ScheduledMaintenanceService.ts +737 -1
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
- package/Server/Services/TeamComplianceSettingService.ts +1125 -9
- package/Server/Services/TelemetryUsageBillingService.ts +28 -0
- package/Server/Services/TraceRecordingRuleService.ts +33 -0
- package/Server/Services/VMwareVCenterService.ts +110 -1
- package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1475 -51
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +1000 -43
- package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
- package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +577 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
- package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +873 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +120 -7
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +72 -5
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +72 -5
- package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
- package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
- package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +402 -14
- package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
- package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
- package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
- package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
- package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
- package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +35 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +298 -224
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +35 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +1073 -213
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.ts +163 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +396 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.ts +418 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.ts +152 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.ts +251 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.ts +214 -0
- package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
- package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
- package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
- package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
- package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
- package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
- package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
- package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
- package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
- package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
- package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
- package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
- package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
- package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
- package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
- package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +184 -19
- package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
- package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
- package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
- package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
- package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
- package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
- package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
- package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
- package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
- package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
- package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +18 -6
- package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
- package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
- package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
- package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
- package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
- package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
- package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
- package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
- package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
- package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
- package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
- package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
- package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
- package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
- package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
- package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
- package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
- package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
- package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
- package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
- package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
- package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
- package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
- package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
- package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
- package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
- package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
- package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
- package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
- package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
- package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
- package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
- package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
- package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
- package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
- package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
- package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
- package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
- package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
- package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
- package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
- package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
- package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
- package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
- package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
- package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
- package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
- package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
- package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
- package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
- package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
- package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
- package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
- package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
- package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
- package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
- package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
- package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
- package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
- package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
- package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
- package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
- package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardDescription.test.tsx +209 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
- package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
- package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
- package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +1721 -0
- package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1002 -0
- package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
- package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
- package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
- package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
- package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
- package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
- package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
- package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
- package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
- package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
- package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
- package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
- package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
- package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
- package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
- package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
- package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
- package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
- package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
- package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
- package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
- package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
- package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
- package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
- package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
- package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
- package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
- package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
- package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
- package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +33 -1
- package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
- package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
- package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
- package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
- package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
- package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
- package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
- package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
- package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
- package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
- package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
- package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
- package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +119 -4
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +196 -2
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +123 -2
- package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
- package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
- package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
- package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
- package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
- package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
- package/Tests/Server/Services/DatabaseServerService.test.ts +55 -0
- package/Tests/Server/Services/GroupTelemetryUsageExcludeNames.test.ts +299 -0
- package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +44 -0
- package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
- package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
- package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
- package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
- package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
- package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
- package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
- package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
- package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
- package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
- package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
- package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
- package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
- package/Tests/Server/Services/RecordingRuleReservedMetricName.test.ts +171 -0
- package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
- package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
- package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
- package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
- package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
- package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
- package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
- package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
- package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +153 -15
- package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
- package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
- package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
- package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
- package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
- package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
- package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
- package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
- package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
- package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
- package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
- package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
- package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
- package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +453 -0
- package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
- package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
- package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1249 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
- package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
- package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +722 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +830 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
- package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
- package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
- package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
- package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +75 -3
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsAccountNotLinked.test.ts +1093 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.test.ts +1049 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +1676 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCards.test.ts +2884 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.test.ts +2490 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmit.test.ts +2293 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmitServerTimezone.test.ts +386 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.test.ts +1477 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.test.ts +1967 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsStripHtmlTags.test.ts +92 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsSubmittedFormRemoval.test.ts +1819 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.test.ts +1033 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezoneServerZone.test.ts +610 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsBotMessageHandling.test.ts +2610 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
- package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
- package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
- package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
- package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +517 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
- package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
- package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
- package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
- package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
- package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
- package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
- package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
- package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
- package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
- package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
- package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
- package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
- package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
- package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
- package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
- package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
- package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
- package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
- package/Tests/UI/Components/Input.test.tsx +80 -1
- package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
- package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
- package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
- package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
- package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
- package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
- package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
- package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
- package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
- package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
- package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
- package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
- package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
- package/Tests/UI/Components/Toggle.test.tsx +66 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
- package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
- package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
- package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
- package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
- package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
- package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
- package/Tests/Utils/AiRemediation/Resource/CephCommandPolicy.test.ts +1653 -0
- package/Tests/Utils/AiRemediation/Resource/CephOutputRedaction.test.ts +204 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseCommandPolicy.test.ts +1077 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.test.ts +558 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseQueryRedactor.test.ts +834 -0
- package/Tests/Utils/AiRemediation/Resource/DockerCliGrammar.test.ts +747 -0
- package/Tests/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.test.ts +1259 -0
- package/Tests/Utils/AiRemediation/Resource/DockerOutputRedaction.test.ts +386 -0
- package/Tests/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.test.ts +782 -0
- package/Tests/Utils/AiRemediation/Resource/GovcCommandPolicy.test.ts +2259 -0
- package/Tests/Utils/AiRemediation/Resource/HostCommandPolicy.test.ts +2019 -0
- package/Tests/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.test.ts +2497 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicy.test.ts +1305 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.test.ts +585 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactor.test.ts +334 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactorCopyParity.test.ts +98 -0
- package/Tests/Utils/AiRemediation/Resource/ResourcePolicyImportClosure.test.ts +391 -0
- package/Tests/Utils/AiRemediation/ResourceAiAgentPolicyCopyParity.test.ts +497 -0
- package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
- package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
- package/Types/AI/AIRunType.ts +9 -4
- package/Types/AI/InvestigationNotStartedReason.ts +6 -0
- package/Types/AI/ResourceAiAccessApi.ts +140 -0
- package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +197 -18
- package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
- package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
- package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
- package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
- package/Types/Monitor/RumAlertTemplates.ts +351 -4
- package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
- package/Types/ResourceAiAgent/ResourceAiAccess.ts +574 -0
- package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
- package/Types/Runbook/RunbookStepType.ts +29 -0
- package/Types/Team/ComplianceNotificationChannel.ts +22 -0
- package/Types/Team/ComplianceRule.ts +434 -0
- package/Types/Team/ComplianceRuleType.ts +21 -0
- package/Types/Team/TeamComplianceStatus.ts +81 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +40 -0
- package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
- package/UI/Components/ActionButton/RowActions.tsx +238 -0
- package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
- package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
- package/UI/Components/Charts/Line/LineChart.tsx +32 -2
- package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
- package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
- package/UI/Components/Charts/Utils/XAxis.ts +75 -0
- package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
- package/UI/Components/Forms/Fields/FormField.tsx +10 -0
- package/UI/Components/Input/Input.tsx +90 -57
- package/UI/Components/List/ListRow.tsx +8 -74
- package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
- package/UI/Components/OrderedStatesList/Item.tsx +7 -72
- package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
- package/UI/Components/Table/TableBody.tsx +8 -2
- package/UI/Components/Table/TableRow.tsx +20 -140
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
- package/UI/Components/TelemetryViewer/types.ts +2 -0
- package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
- package/UI/Components/Toggle/Toggle.tsx +26 -0
- package/UI/Components/Tooltip/Tooltip.tsx +8 -1
- package/UI/Styles/Theme.css +14 -2
- package/Utils/AI/InvestigationReport.ts +121 -15
- package/Utils/AiRemediation/CommandPolicy.ts +1 -1
- package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
- package/Utils/AiRemediation/Resource/CephCommandPolicy.ts +1936 -0
- package/Utils/AiRemediation/Resource/DatabaseCommandPolicy.ts +166 -0
- package/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.ts +1532 -0
- package/Utils/AiRemediation/Resource/DatabaseQueryRedactor.ts +1394 -0
- package/Utils/AiRemediation/Resource/DockerCliGrammar.ts +1839 -0
- package/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.ts +490 -0
- package/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.ts +687 -0
- package/Utils/AiRemediation/Resource/GovcCommandPolicy.ts +2096 -0
- package/Utils/AiRemediation/Resource/HostCommandPolicy.ts +2982 -0
- package/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.ts +1679 -0
- package/Utils/AiRemediation/Resource/ResourceCommandPolicy.ts +851 -0
- package/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.ts +593 -0
- package/Utils/AiRemediation/Resource/ResourceOutputRedactor.ts +2812 -0
- package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
- package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js +219 -0
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseServer.js +219 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +219 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +219 -0
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +219 -0
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +4 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PodmanHost.js +219 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +56 -5
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +219 -0
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ResourceAiAgent.js +439 -0
- package/build/dist/Models/DatabaseModels/ResourceAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js +219 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js +219 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +6 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +374 -24
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
- package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
- package/build/dist/Server/API/ResourceAiAccessAPI.js +1119 -0
- package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js +168 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +41 -19
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +59 -1
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +248 -13
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +51 -15
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +26 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +601 -3
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterService.js +104 -0
- package/build/dist/Server/Services/CephClusterService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseServerService.js +99 -0
- package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +104 -0
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterService.js +104 -0
- package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +114 -2
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +199 -72
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/MetricRecordingRuleService.js +46 -0
- package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostService.js +104 -0
- package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterService.js +104 -0
- package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
- package/build/dist/Server/Services/ResourceAiAccessService.js +1028 -0
- package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -0
- package/build/dist/Server/Services/ResourceAiAgentJobService.js +173 -0
- package/build/dist/Server/Services/ResourceAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/ResourceAiAgentService.js +1687 -0
- package/build/dist/Server/Services/ResourceAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/RunnerJobService.js +522 -97
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/RunnerService.js +1 -1
- package/build/dist/Server/Services/RunnerService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +26 -0
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
- package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
- package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1056 -43
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +683 -42
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +330 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +600 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +89 -9
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +55 -4
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +55 -4
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +294 -15
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +29 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +9 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +627 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js +60 -5
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +183 -209
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +768 -152
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js +129 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +266 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js +258 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js +104 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js +183 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js +123 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js.map +1 -0
- package/build/dist/Types/AI/AIRunType.js +9 -4
- package/build/dist/Types/AI/AIRunType.js.map +1 -1
- package/build/dist/Types/AI/ResourceAiAccessApi.js +30 -0
- package/build/dist/Types/AI/ResourceAiAccessApi.js.map +1 -0
- package/build/dist/Types/AI/ResourceAiAccessPermissions.js +98 -0
- package/build/dist/Types/AI/ResourceAiAccessPermissions.js.map +1 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +126 -45
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +275 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
- package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
- package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRule.js +304 -0
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
- package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
- package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
- package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +36 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
- package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +69 -54
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/List/ListRow.js +4 -39
- package/build/dist/UI/Components/List/ListRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
- package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +6 -2
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +12 -75
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/Utils/AI/InvestigationReport.js +71 -11
- package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
- package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js +1462 -0
- package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js +122 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js +1139 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js +1060 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js +1301 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js +370 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js +498 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js +1565 -0
- package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js +2206 -0
- package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js +1129 -0
- package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js +565 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js +408 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js +1910 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js.map +1 -0
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
- package/package.json +1 -1
|
@@ -28,18 +28,48 @@ import {
|
|
|
28
28
|
KubernetesAiRemediationMode,
|
|
29
29
|
KubernetesRunnerPosture,
|
|
30
30
|
isInClusterPostureForCluster,
|
|
31
|
+
parseKubernetesAgentPosture,
|
|
31
32
|
parseKubernetesRunnerPosture,
|
|
32
33
|
} from "../../Types/Kubernetes/KubernetesClusterAiAccess";
|
|
33
34
|
import RunbookCredentialType from "../../Types/Runbook/RunbookCredentialType";
|
|
34
35
|
import AIRunType from "../../Types/AI/AIRunType";
|
|
35
36
|
import AIRun from "../../Models/DatabaseModels/AIRun";
|
|
37
|
+
import KubernetesAiAgent from "../../Models/DatabaseModels/KubernetesAiAgent";
|
|
36
38
|
import KubernetesCluster from "../../Models/DatabaseModels/KubernetesCluster";
|
|
37
39
|
import RunbookCredential from "../../Models/DatabaseModels/RunbookCredential";
|
|
38
40
|
import Runner from "../../Models/DatabaseModels/Runner";
|
|
39
41
|
import AIRunService from "./AIRunService";
|
|
42
|
+
import KubernetesClusterAiAccessService, {
|
|
43
|
+
KubernetesAiAccessExecutorKind,
|
|
44
|
+
LoadedKubernetesAiAccessTarget,
|
|
45
|
+
getKubernetesAiAccessTargetId,
|
|
46
|
+
} from "./KubernetesClusterAiAccessService";
|
|
40
47
|
import KubernetesClusterService from "./KubernetesClusterService";
|
|
41
48
|
import RunbookCredentialService from "./RunbookCredentialService";
|
|
42
49
|
import RunnerService, { Service as RunnerServiceClass } from "./RunnerService";
|
|
50
|
+
import ResourceAiAccessService, {
|
|
51
|
+
LoadedResourceAiAccessTarget,
|
|
52
|
+
ResourceAiAccessRow,
|
|
53
|
+
describeResourceNoun,
|
|
54
|
+
getResourceAiAgentInstallNextStep,
|
|
55
|
+
getResourceAiAgentPage,
|
|
56
|
+
} from "./ResourceAiAccessService";
|
|
57
|
+
import ResourceAiAgent from "../../Models/DatabaseModels/ResourceAiAgent";
|
|
58
|
+
import AiResourceType, {
|
|
59
|
+
AI_RESOURCE_TYPE_INFO,
|
|
60
|
+
AiResourceTypeInfo,
|
|
61
|
+
isAiResourceType,
|
|
62
|
+
} from "../../Types/ResourceAiAgent/AiResourceType";
|
|
63
|
+
import {
|
|
64
|
+
ResourceAiAgentPosture,
|
|
65
|
+
ResourceAiRemediationMode,
|
|
66
|
+
ResourceCommandJobPayload,
|
|
67
|
+
ResourceCommandTier,
|
|
68
|
+
parseResourceAiAgentPosture,
|
|
69
|
+
} from "../../Types/ResourceAiAgent/ResourceAiAccess";
|
|
70
|
+
import ResourceCommandPolicy from "../../Utils/AiRemediation/Resource/ResourceCommandPolicy";
|
|
71
|
+
import { ResourceCommandPolicyResult } from "../../Utils/AiRemediation/Resource/ResourceCommandPolicyCore";
|
|
72
|
+
import { redactResourceCommandOutput } from "../../Utils/AiRemediation/Resource/ResourceOutputRedactor";
|
|
43
73
|
import QueryHelper from "../Types/Database/QueryHelper";
|
|
44
74
|
|
|
45
75
|
/*
|
|
@@ -73,6 +103,69 @@ export const MAX_AI_COMMAND_JOBS_PER_PROJECT_PER_HOUR: number = 30;
|
|
|
73
103
|
* ceiling, because every call spends Runner time and LLM budget.
|
|
74
104
|
*/
|
|
75
105
|
export const MAX_AI_INVESTIGATION_COMMAND_JOBS_PER_PROJECT_PER_HOUR: number = 240;
|
|
106
|
+
|
|
107
|
+
/*
|
|
108
|
+
* The same two brakes for commands on infrastructure resources (Docker,
|
|
109
|
+
* Podman, Swarm, Proxmox, VMware, Ceph, database servers, hosts), counted
|
|
110
|
+
* on their own ResourceCommand rows so a busy hour on one kind of
|
|
111
|
+
* infrastructure never starves the cluster lane, or the other way round.
|
|
112
|
+
*/
|
|
113
|
+
export const MAX_AI_INVESTIGATION_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR: number = 240;
|
|
114
|
+
export const MAX_AI_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR: number = 30;
|
|
115
|
+
|
|
116
|
+
/*
|
|
117
|
+
* Why enqueueAiResourceCommand refused a command, for callers that act on
|
|
118
|
+
* the reason (the remediation tools tell "the agent is read-only" from "the
|
|
119
|
+
* resource's fixes were turned off" from "this hour's budget is spent"):
|
|
120
|
+
*
|
|
121
|
+
* invalid_request: the call itself is malformed (type, id, origin, run).
|
|
122
|
+
* policy_denied: the resource command policy denies the command.
|
|
123
|
+
* not_read_only: an investigation asked for a command that is not Read.
|
|
124
|
+
* hourly_limit: the project's hourly brake for resource commands.
|
|
125
|
+
* resource_not_found: the resource is not this project's.
|
|
126
|
+
* agent_not_online: the resource has no online AI agent right now.
|
|
127
|
+
* agent_changed: the agent the caller named is no longer the resource's.
|
|
128
|
+
* switch_off: the resource's investigation or fixes switch is off.
|
|
129
|
+
* credential_refused: the command named a credential (agents never get one).
|
|
130
|
+
* agent_posture_mismatch: the agent has not reported serving this resource.
|
|
131
|
+
* write_scope: the agent's own posture rules the write out.
|
|
132
|
+
*/
|
|
133
|
+
export type ResourceCommandEnqueueRefusalCode =
|
|
134
|
+
| "invalid_request"
|
|
135
|
+
| "policy_denied"
|
|
136
|
+
| "not_read_only"
|
|
137
|
+
| "hourly_limit"
|
|
138
|
+
| "resource_not_found"
|
|
139
|
+
| "agent_not_online"
|
|
140
|
+
| "agent_changed"
|
|
141
|
+
| "switch_off"
|
|
142
|
+
| "credential_refused"
|
|
143
|
+
| "agent_posture_mismatch"
|
|
144
|
+
| "write_scope";
|
|
145
|
+
|
|
146
|
+
/*
|
|
147
|
+
* A refusal of the resource command chokepoint. A BadDataException, so
|
|
148
|
+
* every caller that already handles the kubectl chokepoint's refusals
|
|
149
|
+
* handles this one the same way; `refusalCode` says which rule refused it.
|
|
150
|
+
*/
|
|
151
|
+
export class ResourceCommandEnqueueRefusedException extends BadDataException {
|
|
152
|
+
public readonly refusalCode: ResourceCommandEnqueueRefusalCode;
|
|
153
|
+
|
|
154
|
+
public constructor(
|
|
155
|
+
refusalCode: ResourceCommandEnqueueRefusalCode,
|
|
156
|
+
message: string,
|
|
157
|
+
) {
|
|
158
|
+
super(message);
|
|
159
|
+
this.refusalCode = refusalCode;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// The resource modes in which a remediation command may be enqueued at all.
|
|
164
|
+
const ENABLED_RESOURCE_REMEDIATION_MODES: Array<ResourceAiRemediationMode> = [
|
|
165
|
+
ResourceAiRemediationMode.RequireApproval,
|
|
166
|
+
ResourceAiRemediationMode.Automatic,
|
|
167
|
+
ResourceAiRemediationMode.BypassApproval,
|
|
168
|
+
];
|
|
76
169
|
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
77
170
|
import OneUptimeDate from "../../Types/Date";
|
|
78
171
|
import { JSONObject } from "../../Types/JSON";
|
|
@@ -188,7 +281,25 @@ export function describeRunnerJobTimeout(data: {
|
|
|
188
281
|
stepType: RunbookStepType | undefined;
|
|
189
282
|
claimTimeoutInMs: number;
|
|
190
283
|
executionTimeoutInMs: number;
|
|
284
|
+
/*
|
|
285
|
+
* The job was for the cluster's Kubernetes AI agent
|
|
286
|
+
* (targetKubernetesAiAgentId) rather than a Runner, so the text names it.
|
|
287
|
+
*/
|
|
288
|
+
isForKubernetesAiAgent?: boolean | undefined;
|
|
289
|
+
/*
|
|
290
|
+
* For a ResourceCommand job: the type of the resource whose AI agent
|
|
291
|
+
* (targetResourceAiAgentId) the command was for, so the text names that
|
|
292
|
+
* agent ("the Docker AI agent").
|
|
293
|
+
*/
|
|
294
|
+
resourceType?: AiResourceType | null | undefined;
|
|
191
295
|
}): string {
|
|
296
|
+
if (
|
|
297
|
+
data.stepType === RunbookStepType.ResourceCommand &&
|
|
298
|
+
AI_COMMAND_JOB_ORIGINS.includes(data.origin || RunnerJobOrigin.Runbook)
|
|
299
|
+
) {
|
|
300
|
+
return describeResourceCommandTimeout(data);
|
|
301
|
+
}
|
|
302
|
+
|
|
192
303
|
const isAiKubectl: boolean =
|
|
193
304
|
data.stepType === RunbookStepType.Kubectl &&
|
|
194
305
|
AI_COMMAND_JOB_ORIGINS.includes(data.origin || RunnerJobOrigin.Runbook);
|
|
@@ -218,15 +329,19 @@ export function describeRunnerJobTimeout(data: {
|
|
|
218
329
|
? "unclaimed"
|
|
219
330
|
: data.kind;
|
|
220
331
|
|
|
332
|
+
const executor: string = data.isForKubernetesAiAgent
|
|
333
|
+
? "The cluster's Kubernetes AI agent"
|
|
334
|
+
: "The cluster's Runner";
|
|
335
|
+
|
|
221
336
|
switch (kind) {
|
|
222
337
|
case "unclaimed":
|
|
223
|
-
return
|
|
338
|
+
return `${executor} did not pick up this kubectl command within ${describeSeconds(
|
|
224
339
|
data.claimTimeoutInMs,
|
|
225
340
|
)} — it may be offline, restarting or busy with other work. Nothing was run on the cluster.`;
|
|
226
341
|
case "lease_expired":
|
|
227
|
-
return
|
|
342
|
+
return `${executor} stopped responding while this kubectl command was running — it may have restarted or lost its connection. What the command did is unknown.${checkFirst}`;
|
|
228
343
|
default:
|
|
229
|
-
return
|
|
344
|
+
return `${executor} did not report a result for this kubectl command in time — kubectl may have outlived its ${describeSeconds(
|
|
230
345
|
data.executionTimeoutInMs,
|
|
231
346
|
)} timeout. What the command did is unknown.${checkFirst}`;
|
|
232
347
|
}
|
|
@@ -236,8 +351,59 @@ function describeSeconds(milliseconds: number): string {
|
|
|
236
351
|
return `${Math.max(1, Math.round(milliseconds / 1000))}s`;
|
|
237
352
|
}
|
|
238
353
|
|
|
354
|
+
/*
|
|
355
|
+
* The same three reasons for a command on an infrastructure resource, run
|
|
356
|
+
* by that resource's AI agent: "nobody picked it up" (nothing ran) versus
|
|
357
|
+
* "it was picked up and then went silent" (what it did is unknown), naming
|
|
358
|
+
* the agent ("the Docker AI agent") and the resource ("the Docker host").
|
|
359
|
+
*/
|
|
360
|
+
function describeResourceCommandTimeout(data: {
|
|
361
|
+
kind: RunnerJobTimeoutKind;
|
|
362
|
+
wasClaimed?: boolean | undefined;
|
|
363
|
+
origin: RunnerJobOrigin | undefined;
|
|
364
|
+
claimTimeoutInMs: number;
|
|
365
|
+
executionTimeoutInMs: number;
|
|
366
|
+
resourceType?: AiResourceType | null | undefined;
|
|
367
|
+
}): string {
|
|
368
|
+
const agentName: string = isAiResourceType(data.resourceType)
|
|
369
|
+
? AI_RESOURCE_TYPE_INFO[data.resourceType].agentDisplayName
|
|
370
|
+
: "resource's AI agent";
|
|
371
|
+
const noun: string = isAiResourceType(data.resourceType)
|
|
372
|
+
? describeResourceNoun(data.resourceType)
|
|
373
|
+
: "resource";
|
|
374
|
+
|
|
375
|
+
const checkFirst: string =
|
|
376
|
+
data.origin === RunnerJobOrigin.AiRemediation
|
|
377
|
+
? ` Check the ${noun} before running a change again.`
|
|
378
|
+
: "";
|
|
379
|
+
|
|
380
|
+
const kind: RunnerJobTimeoutKind =
|
|
381
|
+
data.kind === "overall" && data.wasClaimed === false
|
|
382
|
+
? "unclaimed"
|
|
383
|
+
: data.kind;
|
|
384
|
+
|
|
385
|
+
switch (kind) {
|
|
386
|
+
case "unclaimed":
|
|
387
|
+
return `The ${agentName} did not pick up the command in time (within ${describeSeconds(
|
|
388
|
+
data.claimTimeoutInMs,
|
|
389
|
+
)}) — it may be offline, restarting or busy with other work. Nothing was run on the ${noun}.`;
|
|
390
|
+
case "lease_expired":
|
|
391
|
+
return `The ${agentName} stopped responding while this command was running — it may have restarted or lost its connection. What the command did is unknown.${checkFirst}`;
|
|
392
|
+
default:
|
|
393
|
+
return `The ${agentName} did not report a result for this command in time — the command may have outlived its ${describeSeconds(
|
|
394
|
+
data.executionTimeoutInMs,
|
|
395
|
+
)} timeout. What the command did is unknown.${checkFirst}`;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
239
399
|
// Where a Runner's write scope is set, as a refusal words it.
|
|
240
400
|
interface RunnerWriteScopeSettings {
|
|
401
|
+
// Who runs the command, as a refusal names it ("the cluster's Runner").
|
|
402
|
+
executor: string;
|
|
403
|
+
// The same, where it is the one living in the cluster.
|
|
404
|
+
inClusterExecutor: string;
|
|
405
|
+
// The same, short ("the Runner"), for "so ... would refuse it".
|
|
406
|
+
executorShort: string;
|
|
241
407
|
// Why the Runner refuses node operations (a clause).
|
|
242
408
|
nodeOperationsOff: string;
|
|
243
409
|
// How to let it change nodes (a clause, after "To let OneUptime AI change nodes, ").
|
|
@@ -285,6 +451,13 @@ export class Service extends DatabaseService<Model> {
|
|
|
285
451
|
policy: KubectlPolicyResult;
|
|
286
452
|
posture: KubernetesRunnerPosture | undefined;
|
|
287
453
|
usesCredential: boolean;
|
|
454
|
+
/*
|
|
455
|
+
* Who runs the command, for the wording only (the rule is the same):
|
|
456
|
+
* the Kubernetes AI agent, the previous in-cluster Runner or a Runner
|
|
457
|
+
* with a credential. Absent reads from usesCredential, as before the
|
|
458
|
+
* agent existed: in-cluster means the previous in-cluster Runner.
|
|
459
|
+
*/
|
|
460
|
+
executorKind?: KubernetesAiAccessExecutorKind | undefined;
|
|
288
461
|
}): string | null {
|
|
289
462
|
const { policy, posture } = data;
|
|
290
463
|
|
|
@@ -308,26 +481,36 @@ export class Service extends DatabaseService<Model> {
|
|
|
308
481
|
return refusal
|
|
309
482
|
? Service.describeRunnerWriteScopeRefusal(
|
|
310
483
|
refusal,
|
|
311
|
-
Service.getRunnerWriteScopeSettings(
|
|
484
|
+
Service.getRunnerWriteScopeSettings(
|
|
485
|
+
data.executorKind ||
|
|
486
|
+
(data.usesCredential ? "credential_runner" : "legacy_runner"),
|
|
487
|
+
),
|
|
312
488
|
)
|
|
313
489
|
: null;
|
|
314
490
|
}
|
|
315
491
|
|
|
316
492
|
/*
|
|
317
|
-
* Where the target
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
493
|
+
* Where the target's write scope is set, in the words a refusal uses —
|
|
494
|
+
* three ways, by who runs the command:
|
|
495
|
+
*
|
|
496
|
+
* - the Kubernetes AI agent: the chart's aiAgent.remediation.* values;
|
|
497
|
+
* - the previous in-cluster Runner an older chart installed: its values
|
|
498
|
+
* are aiAccess.remediation.*, and the way to change them now is to
|
|
499
|
+
* upgrade the chart to the AI agent, which replaces the Runner;
|
|
500
|
+
* - a Runner that reaches the cluster through a Kubernetes credential: an
|
|
501
|
+
* ordinary Runner no chart configures, which reports what it was
|
|
502
|
+
* started with — ONEUPTIME_KUBECTL_WRITE_NAMESPACES and
|
|
503
|
+
* ONEUPTIME_KUBECTL_ALLOW_NODE_OPERATIONS on its own host — and picks
|
|
504
|
+
* up a change on restart.
|
|
325
505
|
*/
|
|
326
506
|
private static getRunnerWriteScopeSettings(
|
|
327
|
-
|
|
507
|
+
executorKind: KubernetesAiAccessExecutorKind,
|
|
328
508
|
): RunnerWriteScopeSettings {
|
|
329
|
-
if (
|
|
509
|
+
if (executorKind === "credential_runner") {
|
|
330
510
|
return {
|
|
511
|
+
executor: "the cluster's Runner",
|
|
512
|
+
inClusterExecutor: "the cluster's in-cluster Runner",
|
|
513
|
+
executorShort: "the Runner",
|
|
331
514
|
nodeOperationsOff: `it was started with ${KUBECTL_ALLOW_NODE_OPERATIONS_ENV} (or ${KUBECTL_ALLOW_WRITES_ENV}) set to something other than true on its host`,
|
|
332
515
|
allowNodeOperations: `set ${KUBECTL_ALLOW_NODE_OPERATIONS_ENV}=true on that Runner's host and restart it`,
|
|
333
516
|
namespaces: `${KUBECTL_WRITE_NAMESPACES_ENV} on that Runner's host`,
|
|
@@ -335,13 +518,30 @@ export class Service extends DatabaseService<Model> {
|
|
|
335
518
|
};
|
|
336
519
|
}
|
|
337
520
|
|
|
521
|
+
if (executorKind === "ai_agent") {
|
|
522
|
+
return {
|
|
523
|
+
executor: "the cluster's Kubernetes AI agent",
|
|
524
|
+
inClusterExecutor: "the cluster's Kubernetes AI agent",
|
|
525
|
+
executorShort: "the AI agent",
|
|
526
|
+
nodeOperationsOff: `it was installed with aiAgent.remediation.nodeOperations=false (${KUBECTL_ALLOW_NODE_OPERATIONS_ENV})`,
|
|
527
|
+
allowNodeOperations:
|
|
528
|
+
"upgrade the Kubernetes agent chart with --set aiAgent.remediation.nodeOperations=true",
|
|
529
|
+
namespaces: `aiAgent.remediation.namespaces on the Kubernetes agent chart, ${KUBECTL_WRITE_NAMESPACES_ENV}`,
|
|
530
|
+
addNamespace:
|
|
531
|
+
"add it to aiAgent.remediation.namespaces and upgrade the Kubernetes agent chart",
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
|
|
338
535
|
return {
|
|
536
|
+
executor: "the cluster's Runner",
|
|
537
|
+
inClusterExecutor: "the cluster's in-cluster Runner",
|
|
538
|
+
executorShort: "the Runner",
|
|
339
539
|
nodeOperationsOff: `its Kubernetes agent was installed with aiAccess.remediation.nodeOperations=false (${KUBECTL_ALLOW_NODE_OPERATIONS_ENV})`,
|
|
340
540
|
allowNodeOperations:
|
|
341
|
-
"upgrade the agent with --set
|
|
541
|
+
"upgrade the Kubernetes agent chart to the Kubernetes AI agent (it replaces the in-cluster Runner) with --set aiAgent.remediation.nodeOperations=true",
|
|
342
542
|
namespaces: `aiAccess.remediation.namespaces on the Kubernetes agent chart, ${KUBECTL_WRITE_NAMESPACES_ENV}`,
|
|
343
543
|
addNamespace:
|
|
344
|
-
"add it to
|
|
544
|
+
"upgrade the Kubernetes agent chart to the Kubernetes AI agent (it replaces the in-cluster Runner) and add it to aiAgent.remediation.namespaces",
|
|
345
545
|
};
|
|
346
546
|
}
|
|
347
547
|
|
|
@@ -351,8 +551,9 @@ export class Service extends DatabaseService<Model> {
|
|
|
351
551
|
settings: RunnerWriteScopeSettings,
|
|
352
552
|
): string {
|
|
353
553
|
const command: string = `"${refusal.displayCommand}"`;
|
|
354
|
-
const wouldRefuse: string =
|
|
355
|
-
|
|
554
|
+
const wouldRefuse: string = `so ${settings.executorShort} would refuse it. It was not enqueued.`;
|
|
555
|
+
const executor: string = settings.executor;
|
|
556
|
+
const Executor: string = `${executor.charAt(0).toUpperCase()}${executor.slice(1)}`;
|
|
356
557
|
const scopeList: string = `${refusal.writeNamespaces
|
|
357
558
|
.map((allowed: string) => {
|
|
358
559
|
return `"${allowed}"`;
|
|
@@ -366,17 +567,17 @@ export class Service extends DatabaseService<Model> {
|
|
|
366
567
|
return `${
|
|
367
568
|
refusal.uncertainty === null
|
|
368
569
|
? `${command} changes a node`
|
|
369
|
-
:
|
|
370
|
-
}, and
|
|
570
|
+
: `${Executor} cannot tell for certain whether ${command} changes a node (${refusal.uncertainty})`
|
|
571
|
+
}, and ${executor} does not allow node operations (cordon, uncordon, drain, taint, or labelling, annotating or patching a Node): ${settings.nodeOperationsOff}, ${wouldRefuse}${fix} To let OneUptime AI change nodes, ${settings.allowNodeOperations}.`;
|
|
371
572
|
case "objects_uncertain":
|
|
372
573
|
case "namespace_uncertain":
|
|
373
|
-
return
|
|
574
|
+
return `${Executor} cannot tell for certain which ${
|
|
374
575
|
refusal.code === "namespace_uncertain" ? "namespace" : "objects"
|
|
375
576
|
} ${command} changes (${refusal.uncertainty}), ${wouldRefuse}${fix}`;
|
|
376
577
|
case "verb_mismatch":
|
|
377
|
-
return
|
|
578
|
+
return `${Executor} reads the verb of ${command} as "${refusal.readVerb}", but the kubectl policy read "${refusal.policyVerb}", so it cannot tell for certain what the command changes, ${wouldRefuse}`;
|
|
378
579
|
case "unnamed_namespace_objects":
|
|
379
|
-
return `${command} would change Namespace objects without naming them (a selector, --all or no name at all), so
|
|
580
|
+
return `${command} would change Namespace objects without naming them (a selector, --all or no name at all), so ${executor} cannot tell whether one of them is ${
|
|
380
581
|
refusal.podNamespace
|
|
381
582
|
? `"${refusal.podNamespace}", the namespace it runs in`
|
|
382
583
|
: "outside the namespaces it lets OneUptime AI change"
|
|
@@ -384,19 +585,19 @@ export class Service extends DatabaseService<Model> {
|
|
|
384
585
|
case "cluster_scoped":
|
|
385
586
|
return `${command} changes ${refusal.clusterScopedKinds.join(
|
|
386
587
|
", ",
|
|
387
|
-
)} objects, which are cluster-scoped: they live outside every namespace, so outside the namespaces
|
|
588
|
+
)} objects, which are cluster-scoped: they live outside every namespace, so outside the namespaces ${executor} lets OneUptime AI change (${scopeList}) whatever -n says, ${wouldRefuse}`;
|
|
388
589
|
case "all_namespaces":
|
|
389
|
-
return `${command} would change every namespace, including ones
|
|
590
|
+
return `${command} would change every namespace, including ones ${executor} may not change, ${wouldRefuse}${fix}`;
|
|
390
591
|
case "no_namespace":
|
|
391
|
-
return `${command} names no namespace, and
|
|
592
|
+
return `${command} names no namespace, and ${executor} reported no namespace of its own for kubectl to use there, ${wouldRefuse}${fix}`;
|
|
392
593
|
case "own_namespace":
|
|
393
594
|
return refusal.namespaceSource === "namespace_object"
|
|
394
|
-
? `${command} would change the Namespace object "${namespace}", the namespace
|
|
595
|
+
? `${command} would change the Namespace object "${namespace}", the namespace ${settings.inClusterExecutor} itself runs in. OneUptime AI never changes it — a change there could reconfigure the Kubernetes agent or ${settings.executorShort} — ${wouldRefuse}`
|
|
395
596
|
: `${command} would change namespace "${namespace}"${
|
|
396
597
|
refusal.namespaceSource === "default_namespace"
|
|
397
598
|
? " (the command names none, so kubectl would use that one)"
|
|
398
599
|
: ""
|
|
399
|
-
}, the namespace
|
|
600
|
+
}, the namespace ${settings.inClusterExecutor} itself runs in. OneUptime AI never changes it — a change there could scale away the Kubernetes agent or ${settings.executorShort} — ${wouldRefuse} Name the namespace of the workload to fix with -n <namespace>.`;
|
|
400
601
|
case "outside_scope":
|
|
401
602
|
return `${command} would change ${
|
|
402
603
|
refusal.namespaceSource === "namespace_object"
|
|
@@ -406,7 +607,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
406
607
|
? " (the command names none, so kubectl would use that one)"
|
|
407
608
|
: ""
|
|
408
609
|
}`
|
|
409
|
-
}, which is outside the namespaces
|
|
610
|
+
}, which is outside the namespaces ${executor} lets OneUptime AI change (${scopeList}), ${wouldRefuse} To let OneUptime AI change "${namespace}", ${settings.addNamespace}.`;
|
|
410
611
|
default: {
|
|
411
612
|
const unhandled: never = refusal.code;
|
|
412
613
|
return unhandled;
|
|
@@ -525,6 +726,17 @@ export class Service extends DatabaseService<Model> {
|
|
|
525
726
|
);
|
|
526
727
|
}
|
|
527
728
|
|
|
729
|
+
/*
|
|
730
|
+
* A resource command runs on that resource's own AI agent, never on a
|
|
731
|
+
* Runner: this lane would target a Runner (targetAgentId), which must
|
|
732
|
+
* never be handed one.
|
|
733
|
+
*/
|
|
734
|
+
if (data.stepType === RunbookStepType.ResourceCommand) {
|
|
735
|
+
throw new BadDataException(
|
|
736
|
+
"Resource commands run on the resource's AI agent, never on a Runner, and are enqueued through enqueueAiResourceCommand.",
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
|
|
528
740
|
const command: string = (data.command || "").trim();
|
|
529
741
|
if (!command) {
|
|
530
742
|
throw new BadDataException("An AI command job needs a command.");
|
|
@@ -579,13 +791,16 @@ export class Service extends DatabaseService<Model> {
|
|
|
579
791
|
* approved-plan and rollback paths — not just the FullAuto inline tool
|
|
580
792
|
* that has its own pre-check for a friendlier message to the model.
|
|
581
793
|
* Check-then-act, so a burst of concurrent runs can overshoot slightly;
|
|
582
|
-
* the cap is a storm brake, not a quota.
|
|
794
|
+
* the cap is a storm brake, not a quota. Resource commands share the
|
|
795
|
+
* table and the origin but have their own brake, so they never count
|
|
796
|
+
* here (see MAX_AI_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR).
|
|
583
797
|
*/
|
|
584
798
|
const jobsInLastHour: number = (
|
|
585
799
|
await this.countBy({
|
|
586
800
|
query: {
|
|
587
801
|
projectId: data.projectId,
|
|
588
802
|
origin: RunnerJobOrigin.AiRemediation,
|
|
803
|
+
stepType: QueryHelper.notEquals(RunbookStepType.ResourceCommand),
|
|
589
804
|
createdAt: QueryHelper.greaterThan(OneUptimeDate.getSomeHoursAgo(1)),
|
|
590
805
|
},
|
|
591
806
|
props: { isRoot: true },
|
|
@@ -651,17 +866,24 @@ export class Service extends DatabaseService<Model> {
|
|
|
651
866
|
* the cluster), and the payload carries the cluster's identifier so the
|
|
652
867
|
* claim path and the Runner can refuse a job that reaches the wrong pod.
|
|
653
868
|
* A credential is never sent to a kubernetes-agent Runner (its identity
|
|
654
|
-
* is minted with the project's telemetry ingestion key)
|
|
869
|
+
* is minted with the project's telemetry ingestion key), nor to the
|
|
870
|
+
* cluster's Kubernetes AI agent.
|
|
871
|
+
*
|
|
872
|
+
* The target may be the cluster's Kubernetes AI agent (a KubernetesAiAgent
|
|
873
|
+
* row, never a Runner): targetAgentId then names the agent row, and the
|
|
874
|
+
* job is written with targetKubernetesAiAgentId instead, so only that
|
|
875
|
+
* agent can claim it and no Runner ever sees it.
|
|
655
876
|
*
|
|
656
877
|
* It also re-reads the cluster's CURRENT AI access configuration, because
|
|
657
878
|
* every caller acts on a snapshot (an investigation reads the cluster's
|
|
658
879
|
* status once when it starts, a remediation run when it composes): the
|
|
659
|
-
* target must still be the cluster's
|
|
660
|
-
*
|
|
661
|
-
*
|
|
662
|
-
*
|
|
663
|
-
*
|
|
664
|
-
*
|
|
880
|
+
* target must still be the cluster's access target as resolved now
|
|
881
|
+
* (KubernetesClusterAiAccessService.loadAccessTarget), a credential must
|
|
882
|
+
* still be its bound Kubernetes credential, an investigation's reads need
|
|
883
|
+
* "Investigate with kubectl" still on, and a remediation run's commands
|
|
884
|
+
* (its reads included) need the cluster's fixes still enabled. An
|
|
885
|
+
* operator who revokes or re-points access — or an agent that takes over
|
|
886
|
+
* from a Runner — therefore stops an in-flight run at its next command.
|
|
665
887
|
*/
|
|
666
888
|
@CaptureSpan()
|
|
667
889
|
public async enqueueAiKubectlCommand(data: {
|
|
@@ -676,6 +898,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
676
898
|
autoRemediationSuggestionId?: ObjectID | undefined;
|
|
677
899
|
kubernetesClusterId: ObjectID;
|
|
678
900
|
stepId: string;
|
|
901
|
+
/*
|
|
902
|
+
* The cluster's access target: a Runner id, or the id of the cluster's
|
|
903
|
+
* Kubernetes AI agent row (the status's runner.id either way).
|
|
904
|
+
*/
|
|
679
905
|
targetAgentId: ObjectID;
|
|
680
906
|
credentialId?: string | undefined;
|
|
681
907
|
command: string;
|
|
@@ -770,7 +996,9 @@ export class Service extends DatabaseService<Model> {
|
|
|
770
996
|
/*
|
|
771
997
|
* The access test is bounded by its own route limits instead, and an
|
|
772
998
|
* investigation's brake counts only rows with an AI run, so tests never
|
|
773
|
-
* spend the budget real investigations share.
|
|
999
|
+
* spend the budget real investigations share. Resource commands have
|
|
1000
|
+
* their own brake and never count here, so a busy hour on the project's
|
|
1001
|
+
* other infrastructure never starves the cluster lane.
|
|
774
1002
|
*/
|
|
775
1003
|
if (!isAccessTest) {
|
|
776
1004
|
const hourlyCap: number =
|
|
@@ -783,6 +1011,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
783
1011
|
query: {
|
|
784
1012
|
projectId: data.projectId,
|
|
785
1013
|
origin: data.origin,
|
|
1014
|
+
stepType: QueryHelper.notEquals(RunbookStepType.ResourceCommand),
|
|
786
1015
|
createdAt: QueryHelper.greaterThan(
|
|
787
1016
|
OneUptimeDate.getSomeHoursAgo(1),
|
|
788
1017
|
),
|
|
@@ -817,6 +1046,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
817
1046
|
},
|
|
818
1047
|
select: {
|
|
819
1048
|
_id: true,
|
|
1049
|
+
projectId: true,
|
|
820
1050
|
name: true,
|
|
821
1051
|
clusterIdentifier: true,
|
|
822
1052
|
aiAccessRunnerId: true,
|
|
@@ -837,9 +1067,18 @@ export class Service extends DatabaseService<Model> {
|
|
|
837
1067
|
const clusterLabel: string =
|
|
838
1068
|
cluster.name || clusterIdentifier || data.kubernetesClusterId.toString();
|
|
839
1069
|
|
|
1070
|
+
/*
|
|
1071
|
+
* The cluster's access target as it resolves NOW. A target that is not
|
|
1072
|
+
* it — a Runner the cluster was re-pointed away from, or a Runner after
|
|
1073
|
+
* the cluster's Kubernetes AI agent came online — is refused below.
|
|
1074
|
+
*/
|
|
1075
|
+
const loaded: LoadedKubernetesAiAccessTarget =
|
|
1076
|
+
await KubernetesClusterAiAccessService.loadAccessTarget({ cluster });
|
|
1077
|
+
|
|
840
1078
|
const bindingRefusal: string | null = Service.getClusterBindingRefusal({
|
|
841
1079
|
cluster,
|
|
842
1080
|
clusterLabel,
|
|
1081
|
+
resolvedTargetId: getKubernetesAiAccessTargetId(loaded.target),
|
|
843
1082
|
targetAgentId: data.targetAgentId,
|
|
844
1083
|
credentialId: data.credentialId,
|
|
845
1084
|
requiredSwitch: await this.getRequiredClusterSwitch({
|
|
@@ -854,92 +1093,138 @@ export class Service extends DatabaseService<Model> {
|
|
|
854
1093
|
throw new BadDataException(bindingRefusal);
|
|
855
1094
|
}
|
|
856
1095
|
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
projectId: data.projectId,
|
|
861
|
-
},
|
|
862
|
-
select: { _id: true, name: true, hostInfo: true },
|
|
863
|
-
props: { isRoot: true },
|
|
864
|
-
});
|
|
1096
|
+
let posture: KubernetesRunnerPosture | undefined = undefined;
|
|
1097
|
+
let executorKind: KubernetesAiAccessExecutorKind;
|
|
1098
|
+
let targetKubernetesAiAgentId: ObjectID | undefined = undefined;
|
|
865
1099
|
|
|
866
|
-
if (
|
|
867
|
-
|
|
868
|
-
"The target Runner was not found or it does not belong to this project.",
|
|
869
|
-
);
|
|
870
|
-
}
|
|
1100
|
+
if (loaded.target.type === "ai_agent") {
|
|
1101
|
+
const agent: KubernetesAiAgent = loaded.target.agent;
|
|
871
1102
|
|
|
872
|
-
if (data.credentialId) {
|
|
873
1103
|
/*
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
* anyone holding that key could come to hold the credential too. The
|
|
877
|
-
* claim path refuses it as well (by the same name-or-posture rule);
|
|
878
|
-
* refusing here keeps the job from ever existing.
|
|
1104
|
+
* The agent row was read by (project, cluster), so it is this
|
|
1105
|
+
* cluster's: checked again here so the rule reads in one place.
|
|
879
1106
|
*/
|
|
880
|
-
if (
|
|
1107
|
+
if (
|
|
1108
|
+
agent.projectId?.toString() !== data.projectId.toString() ||
|
|
1109
|
+
agent.kubernetesClusterId?.toString() !==
|
|
1110
|
+
data.kubernetesClusterId.toString()
|
|
1111
|
+
) {
|
|
881
1112
|
throw new BadDataException(
|
|
882
|
-
`
|
|
1113
|
+
`The Kubernetes AI agent this kubectl command names is not cluster "${clusterLabel}"'s, so it was not enqueued.`,
|
|
883
1114
|
);
|
|
884
1115
|
}
|
|
885
1116
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
projectId: data.projectId,
|
|
893
|
-
},
|
|
894
|
-
select: { _id: true, name: true, credentialType: true },
|
|
895
|
-
props: { isRoot: true },
|
|
896
|
-
})
|
|
897
|
-
: null;
|
|
898
|
-
|
|
899
|
-
if (
|
|
900
|
-
!credential ||
|
|
901
|
-
credential.credentialType !== RunbookCredentialType.Kubernetes
|
|
902
|
-
) {
|
|
1117
|
+
/*
|
|
1118
|
+
* The agent runs kubectl with its own ServiceAccount only and is
|
|
1119
|
+
* never handed credential material: its identity is issued with the
|
|
1120
|
+
* project's telemetry ingestion key.
|
|
1121
|
+
*/
|
|
1122
|
+
if (data.credentialId) {
|
|
903
1123
|
throw new BadDataException(
|
|
904
|
-
`
|
|
1124
|
+
`Cluster "${clusterLabel}" is reached through its Kubernetes AI agent, which runs kubectl with its own ServiceAccount and is never given a credential, so a kubectl command that needs one was not enqueued.`,
|
|
905
1125
|
);
|
|
906
1126
|
}
|
|
907
|
-
}
|
|
908
1127
|
|
|
909
|
-
|
|
910
|
-
|
|
1128
|
+
posture = parseKubernetesAgentPosture(agent.posture);
|
|
1129
|
+
executorKind = "ai_agent";
|
|
1130
|
+
targetKubernetesAiAgentId = agent.id!;
|
|
911
1131
|
|
|
912
|
-
if (!data.credentialId) {
|
|
913
1132
|
if (!isInClusterPostureForCluster(posture, clusterIdentifier)) {
|
|
914
1133
|
throw new BadDataException(
|
|
915
|
-
`
|
|
1134
|
+
`The Kubernetes AI agent has not reported that it runs in cluster "${
|
|
916
1135
|
clusterIdentifier || cluster.name || cluster.id?.toString()
|
|
917
|
-
}",
|
|
918
|
-
posture?.inCluster
|
|
919
|
-
? `is the in-cluster Runner of ${
|
|
920
|
-
posture.clusterIdentifier?.trim()
|
|
921
|
-
? `cluster "${posture.clusterIdentifier.trim()}"`
|
|
922
|
-
: "an unnamed cluster"
|
|
923
|
-
}`
|
|
924
|
-
: "runs outside the cluster"
|
|
925
|
-
}. Select a Kubernetes credential for this Runner on the cluster's AI page, or install the in-cluster Runner on this cluster.`,
|
|
1136
|
+
}", so this kubectl command was not enqueued. Wait for its next report (within a minute), or reset the agent on the cluster's AI agent page (AI → Agent).`,
|
|
926
1137
|
);
|
|
927
1138
|
}
|
|
1139
|
+
} else {
|
|
1140
|
+
/*
|
|
1141
|
+
* A Runner target: the Runner row the resolution read, which is the
|
|
1142
|
+
* cluster's bound Runner and so belongs to this project.
|
|
1143
|
+
*/
|
|
1144
|
+
const targetRunner: Runner | null =
|
|
1145
|
+
loaded.target.type === "none" ? null : loaded.target.runner;
|
|
1146
|
+
|
|
1147
|
+
if (!targetRunner) {
|
|
1148
|
+
throw new BadDataException(
|
|
1149
|
+
"The target Runner was not found or it does not belong to this project.",
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
executorKind = data.credentialId ? "credential_runner" : "legacy_runner";
|
|
1154
|
+
|
|
1155
|
+
if (data.credentialId) {
|
|
1156
|
+
/*
|
|
1157
|
+
* A kubernetes-agent Runner is never handed credential material: its
|
|
1158
|
+
* identity is issued with the project's telemetry ingestion key, so
|
|
1159
|
+
* anyone holding that key could come to hold the credential too. The
|
|
1160
|
+
* claim path refuses it as well (by the same name-or-posture rule);
|
|
1161
|
+
* refusing here keeps the job from ever existing.
|
|
1162
|
+
*/
|
|
1163
|
+
if (RunnerServiceClass.isKubernetesAgentRunnerRow(targetRunner)) {
|
|
1164
|
+
throw new BadDataException(
|
|
1165
|
+
`Runner "${targetRunner.name}" is a cluster's in-cluster Runner and is never given a credential, so a kubectl command for cluster "${clusterLabel}" that needs one cannot run on it. Create a Runner under Project Settings → Runners, assign the Kubernetes credential to it and select both on the cluster's AI agent page (AI → Agent).`,
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
const credential: RunbookCredential | null = ObjectID.isValidUUID(
|
|
1170
|
+
data.credentialId,
|
|
1171
|
+
)
|
|
1172
|
+
? await RunbookCredentialService.findOneBy({
|
|
1173
|
+
query: {
|
|
1174
|
+
_id: data.credentialId,
|
|
1175
|
+
projectId: data.projectId,
|
|
1176
|
+
},
|
|
1177
|
+
select: { _id: true, name: true, credentialType: true },
|
|
1178
|
+
props: { isRoot: true },
|
|
1179
|
+
})
|
|
1180
|
+
: null;
|
|
1181
|
+
|
|
1182
|
+
if (
|
|
1183
|
+
!credential ||
|
|
1184
|
+
credential.credentialType !== RunbookCredentialType.Kubernetes
|
|
1185
|
+
) {
|
|
1186
|
+
throw new BadDataException(
|
|
1187
|
+
`The credential this kubectl command names is not a Kubernetes credential of this project, so it was not enqueued for cluster "${clusterLabel}".`,
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
posture = parseKubernetesRunnerPosture(targetRunner.hostInfo);
|
|
1193
|
+
|
|
1194
|
+
if (!data.credentialId) {
|
|
1195
|
+
if (!isInClusterPostureForCluster(posture, clusterIdentifier)) {
|
|
1196
|
+
throw new BadDataException(
|
|
1197
|
+
`A kubectl command without a Kubernetes credential can only run on the in-cluster Runner of cluster "${
|
|
1198
|
+
clusterIdentifier || cluster.name || cluster.id?.toString()
|
|
1199
|
+
}", and Runner "${targetRunner.name}" ${
|
|
1200
|
+
posture?.inCluster
|
|
1201
|
+
? `is the in-cluster Runner of ${
|
|
1202
|
+
posture.clusterIdentifier?.trim()
|
|
1203
|
+
? `cluster "${posture.clusterIdentifier.trim()}"`
|
|
1204
|
+
: "an unnamed cluster"
|
|
1205
|
+
}`
|
|
1206
|
+
: "runs outside the cluster"
|
|
1207
|
+
}. Select a Kubernetes credential for this Runner on the cluster's AI agent page (AI → Agent), or clear the Runner there to use the cluster's Kubernetes AI agent.`,
|
|
1208
|
+
);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
928
1211
|
}
|
|
929
1212
|
|
|
930
1213
|
/*
|
|
931
|
-
* A remediation write the
|
|
1214
|
+
* A remediation write the target's own posture says it will refuse — a
|
|
932
1215
|
* namespace outside its write scope, its own namespace, or a node
|
|
933
1216
|
* operation its chart did not grant — is refused here, before it can be
|
|
934
1217
|
* approved, enqueued or counted by the cluster's circuit breaker, with
|
|
935
|
-
* the
|
|
936
|
-
*
|
|
1218
|
+
* the setting that would allow it. Reads are never refused for scope.
|
|
1219
|
+
* A job with no credential lands in the pod's own namespace when it
|
|
1220
|
+
* names none — for the agent exactly as for the in-cluster Runner.
|
|
937
1221
|
*/
|
|
938
1222
|
if (data.origin === RunnerJobOrigin.AiRemediation) {
|
|
939
1223
|
const scopeRefusal: string | null = Service.getRunnerWriteScopeRefusal({
|
|
940
1224
|
policy,
|
|
941
1225
|
posture,
|
|
942
1226
|
usesCredential: Boolean(data.credentialId),
|
|
1227
|
+
executorKind,
|
|
943
1228
|
});
|
|
944
1229
|
|
|
945
1230
|
if (scopeRefusal) {
|
|
@@ -964,7 +1249,15 @@ export class Service extends DatabaseService<Model> {
|
|
|
964
1249
|
row.kubernetesClusterId = data.kubernetesClusterId;
|
|
965
1250
|
row.stepId = data.stepId;
|
|
966
1251
|
row.stepType = RunbookStepType.Kubectl;
|
|
967
|
-
|
|
1252
|
+
/*
|
|
1253
|
+
* Exactly one target: the agent's row, or the Runner. targetAgentId has
|
|
1254
|
+
* a foreign key to Runner, so it stays empty for the agent.
|
|
1255
|
+
*/
|
|
1256
|
+
if (targetKubernetesAiAgentId) {
|
|
1257
|
+
row.targetKubernetesAiAgentId = targetKubernetesAiAgentId;
|
|
1258
|
+
} else {
|
|
1259
|
+
row.targetAgentId = data.targetAgentId;
|
|
1260
|
+
}
|
|
968
1261
|
row.script = "";
|
|
969
1262
|
row.payload = {
|
|
970
1263
|
args: policy.args,
|
|
@@ -1023,17 +1316,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
1023
1316
|
/*
|
|
1024
1317
|
* Why a kubectl job may NOT be enqueued for this cluster as it is
|
|
1025
1318
|
* configured right now, or null when it may. Pure, so the rule reads in
|
|
1026
|
-
* one place: the job must go
|
|
1027
|
-
*
|
|
1319
|
+
* one place: the job must go to the cluster's CURRENT access target
|
|
1320
|
+
* (resolvedTargetId, from resolveKubernetesAiAccessTarget), and the
|
|
1321
|
+
* capability it is for must still be switched on.
|
|
1028
1322
|
*
|
|
1029
1323
|
* A credential-less job does not require the credential binding to be
|
|
1030
|
-
* empty: the in-cluster Runner of the cluster
|
|
1031
|
-
* credential (the readiness status prefers it),
|
|
1032
|
-
* legitimate with a credential still selected.
|
|
1324
|
+
* empty: the in-cluster Runner of the cluster (or its Kubernetes AI
|
|
1325
|
+
* agent) wins over a bound credential (the readiness status prefers it),
|
|
1326
|
+
* so such a job is legitimate with a credential still selected.
|
|
1033
1327
|
*/
|
|
1034
1328
|
public static getClusterBindingRefusal(data: {
|
|
1035
1329
|
cluster: KubernetesCluster;
|
|
1036
1330
|
clusterLabel: string;
|
|
1331
|
+
// The cluster's access target as it resolves now; null when none.
|
|
1332
|
+
resolvedTargetId: string | null;
|
|
1037
1333
|
targetAgentId: ObjectID;
|
|
1038
1334
|
credentialId?: string | undefined;
|
|
1039
1335
|
// The switch that must still be on; null for the access test.
|
|
@@ -1042,10 +1338,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
1042
1338
|
const { cluster, clusterLabel } = data;
|
|
1043
1339
|
|
|
1044
1340
|
if (
|
|
1045
|
-
!
|
|
1046
|
-
|
|
1341
|
+
!data.resolvedTargetId ||
|
|
1342
|
+
data.resolvedTargetId !== data.targetAgentId.toString()
|
|
1047
1343
|
) {
|
|
1048
|
-
return `Cluster "${clusterLabel}" is no longer reached through this Runner (its AI access
|
|
1344
|
+
return `Cluster "${clusterLabel}" is no longer reached through this Runner or agent (its AI access changed on the cluster's AI agent page (AI → Agent), or its Kubernetes AI agent took over), so this kubectl command was not enqueued.`;
|
|
1049
1345
|
}
|
|
1050
1346
|
|
|
1051
1347
|
if (
|
|
@@ -1053,14 +1349,14 @@ export class Service extends DatabaseService<Model> {
|
|
|
1053
1349
|
(!cluster.aiAccessCredentialId ||
|
|
1054
1350
|
cluster.aiAccessCredentialId.toString() !== data.credentialId)
|
|
1055
1351
|
) {
|
|
1056
|
-
return `Cluster "${clusterLabel}" is no longer reached with this Kubernetes credential (its AI access
|
|
1352
|
+
return `Cluster "${clusterLabel}" is no longer reached with this Kubernetes credential (its AI access changed on the cluster's AI agent page (AI → Agent)), so this kubectl command was not enqueued.`;
|
|
1057
1353
|
}
|
|
1058
1354
|
|
|
1059
1355
|
if (
|
|
1060
1356
|
data.requiredSwitch === "investigation" &&
|
|
1061
1357
|
cluster.isAiInvestigationEnabled !== true
|
|
1062
1358
|
) {
|
|
1063
|
-
return `"
|
|
1359
|
+
return `"Investigate with kubectl" is turned off for cluster "${clusterLabel}", so this investigation command was not enqueued.`;
|
|
1064
1360
|
}
|
|
1065
1361
|
|
|
1066
1362
|
if (
|
|
@@ -1069,7 +1365,406 @@ export class Service extends DatabaseService<Model> {
|
|
|
1069
1365
|
cluster.aiRemediationMode as KubernetesAiRemediationMode,
|
|
1070
1366
|
)
|
|
1071
1367
|
) {
|
|
1072
|
-
return `AI
|
|
1368
|
+
return `AI fixes are turned off for cluster "${clusterLabel}", so this kubectl command was not enqueued.`;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
return null;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
/*
|
|
1375
|
+
* Enqueue ONE command OneUptime AI composed for an infrastructure
|
|
1376
|
+
* resource — a Docker or Podman host, a Docker Swarm, Proxmox, VMware or
|
|
1377
|
+
* Ceph cluster, a database server or a host — for that resource's AI
|
|
1378
|
+
* agent (a ResourceAiAgent row, never a Runner).
|
|
1379
|
+
*
|
|
1380
|
+
* The server-side chokepoint between an LLM's output and a resource, in
|
|
1381
|
+
* the order enqueueAiKubectlCommand checks a cluster command:
|
|
1382
|
+
*
|
|
1383
|
+
* 1. the call itself: a resource type and id, an AI origin, the
|
|
1384
|
+
* suggestion a remediation job belongs to, the run an investigation
|
|
1385
|
+
* job belongs to (the access test alone has none, and is a read);
|
|
1386
|
+
* 2. the resource command policy, re-run whatever the tool layer
|
|
1387
|
+
* checked: Denied never enqueues, and an investigation-origin job must
|
|
1388
|
+
* be Read tier — an investigation can never write;
|
|
1389
|
+
* 3. the project's hourly brake for resource commands (investigations
|
|
1390
|
+
* and remediation counted apart, on ResourceCommand rows only);
|
|
1391
|
+
* 4. the resource must be this project's;
|
|
1392
|
+
* 5. the target is re-resolved NOW: the resource's online agent
|
|
1393
|
+
* (ResourceAiAgentService.findOnlineAgentForResource), and the agent
|
|
1394
|
+
* the caller named, if any, must still be it;
|
|
1395
|
+
* 6. the switch the job needs must still be on: an investigation's reads
|
|
1396
|
+
* need the resource's investigation switch (a remediation run's reads
|
|
1397
|
+
* its fixes), and a remediation job needs its fixes (mode not
|
|
1398
|
+
* Disabled) — so an operator who turns AI off stops an in-flight run
|
|
1399
|
+
* at its next command;
|
|
1400
|
+
* 7. no credential: the agent uses only its own environment's;
|
|
1401
|
+
* 8. the agent's reported posture must be for this resource type and
|
|
1402
|
+
* name the identity it registered with (the payload carries it, and
|
|
1403
|
+
* the agent refuses a job for any other), and a write must fit it:
|
|
1404
|
+
* ONEUPTIME_AI_ALLOW_WRITES on, ONEUPTIME_AI_WRITE_TARGETS and the
|
|
1405
|
+
* agent's protected targets respected (ResourceCommandPolicy.
|
|
1406
|
+
* getWriteScopeRefusal, the rule the agent itself applies).
|
|
1407
|
+
*
|
|
1408
|
+
* The command travels as an argv (never a shell line) in a
|
|
1409
|
+
* ResourceCommandJobPayload, and the row names the agent in
|
|
1410
|
+
* targetResourceAiAgentId, so only that agent can claim it. Every
|
|
1411
|
+
* refusal is a ResourceCommandEnqueueRefusedException saying which rule.
|
|
1412
|
+
*/
|
|
1413
|
+
@CaptureSpan()
|
|
1414
|
+
public async enqueueAiResourceCommand(data: {
|
|
1415
|
+
projectId: ObjectID;
|
|
1416
|
+
/*
|
|
1417
|
+
* The AI run the command belongs to. Required for an investigation
|
|
1418
|
+
* job; absent only for the resource AI page's access test.
|
|
1419
|
+
*/
|
|
1420
|
+
aiRunId?: ObjectID | undefined;
|
|
1421
|
+
origin: RunnerJobOrigin.AiInvestigation | RunnerJobOrigin.AiRemediation;
|
|
1422
|
+
autoRemediationSuggestionId?: ObjectID | undefined;
|
|
1423
|
+
resourceType: AiResourceType;
|
|
1424
|
+
resourceId: ObjectID;
|
|
1425
|
+
stepId: string;
|
|
1426
|
+
/*
|
|
1427
|
+
* The agent the caller expects to run the command (its status's
|
|
1428
|
+
* agent.agentId). Refused when the resource's online agent is another
|
|
1429
|
+
* one now. Absent: whichever agent is the resource's online one.
|
|
1430
|
+
*/
|
|
1431
|
+
targetResourceAiAgentId?: ObjectID | undefined;
|
|
1432
|
+
command: string;
|
|
1433
|
+
timeoutInMs: number;
|
|
1434
|
+
claimTimeoutInMs?: number | undefined;
|
|
1435
|
+
/*
|
|
1436
|
+
* Never honoured: a resource's agent is never given a credential. Taken
|
|
1437
|
+
* only so a plan step that carries one is refused, never silently
|
|
1438
|
+
* dropped.
|
|
1439
|
+
*/
|
|
1440
|
+
credentialId?: string | undefined;
|
|
1441
|
+
/*
|
|
1442
|
+
* The resource AI page's "Test connection" check: a read with no AI run
|
|
1443
|
+
* behind it, exempt from the investigation switch and the brake —
|
|
1444
|
+
* never from the policy, the binding or the read-only rule.
|
|
1445
|
+
*/
|
|
1446
|
+
isAccessTest?: boolean | undefined;
|
|
1447
|
+
}): Promise<Model> {
|
|
1448
|
+
// 1. The call itself.
|
|
1449
|
+
if (!isAiResourceType(data.resourceType)) {
|
|
1450
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1451
|
+
"invalid_request",
|
|
1452
|
+
`A resource command needs a resource type; "${String(
|
|
1453
|
+
data.resourceType,
|
|
1454
|
+
)}" is not one.`,
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
const info: AiResourceTypeInfo = AI_RESOURCE_TYPE_INFO[data.resourceType];
|
|
1459
|
+
const noun: string = describeResourceNoun(data.resourceType);
|
|
1460
|
+
|
|
1461
|
+
if (!data.resourceId) {
|
|
1462
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1463
|
+
"invalid_request",
|
|
1464
|
+
`resourceId is required for a command on a ${noun}.`,
|
|
1465
|
+
);
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
if (
|
|
1469
|
+
data.origin !== RunnerJobOrigin.AiInvestigation &&
|
|
1470
|
+
data.origin !== RunnerJobOrigin.AiRemediation
|
|
1471
|
+
) {
|
|
1472
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1473
|
+
"invalid_request",
|
|
1474
|
+
`A resource command job cannot have origin "${String(data.origin)}".`,
|
|
1475
|
+
);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
if (
|
|
1479
|
+
data.origin === RunnerJobOrigin.AiRemediation &&
|
|
1480
|
+
!data.autoRemediationSuggestionId
|
|
1481
|
+
) {
|
|
1482
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1483
|
+
"invalid_request",
|
|
1484
|
+
"A resource remediation job needs its auto-remediation suggestion.",
|
|
1485
|
+
);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
const isAccessTest: boolean = data.isAccessTest === true;
|
|
1489
|
+
|
|
1490
|
+
if (
|
|
1491
|
+
isAccessTest &&
|
|
1492
|
+
(data.origin !== RunnerJobOrigin.AiInvestigation || data.aiRunId)
|
|
1493
|
+
) {
|
|
1494
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1495
|
+
"invalid_request",
|
|
1496
|
+
"An access test is a read-only check with no AI run behind it.",
|
|
1497
|
+
);
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
if (
|
|
1501
|
+
data.origin === RunnerJobOrigin.AiInvestigation &&
|
|
1502
|
+
!isAccessTest &&
|
|
1503
|
+
!data.aiRunId
|
|
1504
|
+
) {
|
|
1505
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1506
|
+
"invalid_request",
|
|
1507
|
+
"An investigation resource command job needs the AI run it belongs to.",
|
|
1508
|
+
);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// 2. The policy, whatever the tool layer decided.
|
|
1512
|
+
const policy: ResourceCommandPolicyResult =
|
|
1513
|
+
ResourceCommandPolicy.evaluateCommand({
|
|
1514
|
+
resourceType: data.resourceType,
|
|
1515
|
+
command: data.command,
|
|
1516
|
+
});
|
|
1517
|
+
|
|
1518
|
+
if (policy.tier === ResourceCommandTier.Denied) {
|
|
1519
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1520
|
+
"policy_denied",
|
|
1521
|
+
`Denied by the ${info.displayName} command policy: ${policy.reason}.`,
|
|
1522
|
+
);
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
if (
|
|
1526
|
+
data.origin === RunnerJobOrigin.AiInvestigation &&
|
|
1527
|
+
policy.tier !== ResourceCommandTier.Read
|
|
1528
|
+
) {
|
|
1529
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1530
|
+
"not_read_only",
|
|
1531
|
+
`An investigation may only run read-only commands; "${policy.displayCommand}" would change the ${noun} (${policy.tier}).`,
|
|
1532
|
+
);
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
// 3. The hourly brake, on resource commands only.
|
|
1536
|
+
if (!isAccessTest) {
|
|
1537
|
+
const hourlyCap: number =
|
|
1538
|
+
data.origin === RunnerJobOrigin.AiInvestigation
|
|
1539
|
+
? MAX_AI_INVESTIGATION_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR
|
|
1540
|
+
: MAX_AI_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR;
|
|
1541
|
+
|
|
1542
|
+
const jobsInLastHour: number = (
|
|
1543
|
+
await this.countBy({
|
|
1544
|
+
query: {
|
|
1545
|
+
projectId: data.projectId,
|
|
1546
|
+
origin: data.origin,
|
|
1547
|
+
stepType: RunbookStepType.ResourceCommand,
|
|
1548
|
+
createdAt: QueryHelper.greaterThan(
|
|
1549
|
+
OneUptimeDate.getSomeHoursAgo(1),
|
|
1550
|
+
),
|
|
1551
|
+
...(data.origin === RunnerJobOrigin.AiInvestigation
|
|
1552
|
+
? { aiRunId: QueryHelper.notNull() }
|
|
1553
|
+
: {}),
|
|
1554
|
+
},
|
|
1555
|
+
props: { isRoot: true },
|
|
1556
|
+
})
|
|
1557
|
+
).toNumber();
|
|
1558
|
+
|
|
1559
|
+
if (jobsInLastHour >= hourlyCap) {
|
|
1560
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1561
|
+
"hourly_limit",
|
|
1562
|
+
data.origin === RunnerJobOrigin.AiInvestigation
|
|
1563
|
+
? `This project has run ${jobsInLastHour} AI investigation commands on its infrastructure in the last hour, which is its limit (${hourlyCap}). No further infrastructure commands can run this hour.`
|
|
1564
|
+
: `This project has run ${jobsInLastHour} AI remediation commands on its infrastructure in the last hour, which is its limit (${hourlyCap}). No further AI commands can run on its infrastructure this hour.`,
|
|
1565
|
+
);
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
// 4 + 5. The resource, and the agent it is reached through NOW.
|
|
1570
|
+
const loaded: LoadedResourceAiAccessTarget =
|
|
1571
|
+
await ResourceAiAccessService.loadAccessTarget({
|
|
1572
|
+
projectId: data.projectId,
|
|
1573
|
+
resourceType: data.resourceType,
|
|
1574
|
+
resourceId: data.resourceId,
|
|
1575
|
+
});
|
|
1576
|
+
|
|
1577
|
+
if (!loaded.resource) {
|
|
1578
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1579
|
+
"resource_not_found",
|
|
1580
|
+
`${info.displayName} not found or it does not belong to this project.`,
|
|
1581
|
+
);
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
const bindingRefusal: {
|
|
1585
|
+
code: ResourceCommandEnqueueRefusalCode;
|
|
1586
|
+
message: string;
|
|
1587
|
+
} | null = Service.getResourceBindingRefusal({
|
|
1588
|
+
resource: loaded.resource,
|
|
1589
|
+
agent: loaded.agent,
|
|
1590
|
+
targetResourceAiAgentId: data.targetResourceAiAgentId,
|
|
1591
|
+
credentialId: data.credentialId,
|
|
1592
|
+
// 6. The switch this job needs.
|
|
1593
|
+
requiredSwitch: await this.getRequiredClusterSwitch({
|
|
1594
|
+
projectId: data.projectId,
|
|
1595
|
+
origin: data.origin,
|
|
1596
|
+
aiRunId: data.aiRunId,
|
|
1597
|
+
isAccessTest,
|
|
1598
|
+
}),
|
|
1599
|
+
});
|
|
1600
|
+
|
|
1601
|
+
if (bindingRefusal) {
|
|
1602
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1603
|
+
bindingRefusal.code,
|
|
1604
|
+
bindingRefusal.message,
|
|
1605
|
+
);
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
const agent: ResourceAiAgent = loaded.agent!;
|
|
1609
|
+
const resourceLabel: string = loaded.resource.name;
|
|
1610
|
+
|
|
1611
|
+
// 8. The agent's own posture: this resource, and room for the write.
|
|
1612
|
+
const posture: ResourceAiAgentPosture | null = parseResourceAiAgentPosture(
|
|
1613
|
+
agent.posture,
|
|
1614
|
+
);
|
|
1615
|
+
const resourceIdentifier: string = (
|
|
1616
|
+
agent.resourceIdentifier ||
|
|
1617
|
+
posture?.resourceIdentifier ||
|
|
1618
|
+
""
|
|
1619
|
+
).trim();
|
|
1620
|
+
|
|
1621
|
+
if (
|
|
1622
|
+
!posture ||
|
|
1623
|
+
posture.resourceType !== data.resourceType ||
|
|
1624
|
+
!resourceIdentifier
|
|
1625
|
+
) {
|
|
1626
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1627
|
+
"agent_posture_mismatch",
|
|
1628
|
+
`The ${info.agentDisplayName} has not reported that it serves ${noun} "${resourceLabel}", so this command was not enqueued. Wait for its next report (within a minute), or reset the agent on ${getResourceAiAgentPage(
|
|
1629
|
+
data.resourceType,
|
|
1630
|
+
)}.`,
|
|
1631
|
+
);
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
if (policy.tier !== ResourceCommandTier.Read) {
|
|
1635
|
+
const scopeRefusal: string | null =
|
|
1636
|
+
ResourceCommandPolicy.getWriteScopeRefusal({
|
|
1637
|
+
result: policy,
|
|
1638
|
+
allowWrites: posture.allowWrites === true,
|
|
1639
|
+
writeTargets: posture.writeTargets,
|
|
1640
|
+
protectedTargets: posture.protectedTargets,
|
|
1641
|
+
resourceType: data.resourceType,
|
|
1642
|
+
});
|
|
1643
|
+
|
|
1644
|
+
if (scopeRefusal) {
|
|
1645
|
+
throw new ResourceCommandEnqueueRefusedException(
|
|
1646
|
+
"write_scope",
|
|
1647
|
+
`${scopeRefusal} It was not enqueued.`,
|
|
1648
|
+
);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
const claimDeadlineAt: Date = OneUptimeDate.addRemoveSeconds(
|
|
1653
|
+
OneUptimeDate.getCurrentDate(),
|
|
1654
|
+
Math.ceil((data.claimTimeoutInMs ?? DEFAULT_CLAIM_TIMEOUT_MS) / 1000),
|
|
1655
|
+
);
|
|
1656
|
+
|
|
1657
|
+
const payload: ResourceCommandJobPayload = {
|
|
1658
|
+
resourceType: data.resourceType,
|
|
1659
|
+
resourceId: loaded.resource.id.toString(),
|
|
1660
|
+
resourceIdentifier,
|
|
1661
|
+
program: policy.program,
|
|
1662
|
+
args: policy.args,
|
|
1663
|
+
displayCommand: policy.displayCommand,
|
|
1664
|
+
tier: policy.tier,
|
|
1665
|
+
};
|
|
1666
|
+
|
|
1667
|
+
const row: Model = new Model();
|
|
1668
|
+
row.projectId = data.projectId;
|
|
1669
|
+
row.origin = data.origin;
|
|
1670
|
+
if (data.aiRunId) {
|
|
1671
|
+
row.aiRunId = data.aiRunId;
|
|
1672
|
+
}
|
|
1673
|
+
if (data.autoRemediationSuggestionId) {
|
|
1674
|
+
row.autoRemediationSuggestionId = data.autoRemediationSuggestionId;
|
|
1675
|
+
}
|
|
1676
|
+
row.stepId = data.stepId;
|
|
1677
|
+
row.stepType = RunbookStepType.ResourceCommand;
|
|
1678
|
+
/*
|
|
1679
|
+
* The one target: the resource's agent row. targetAgentId (a Runner)
|
|
1680
|
+
* and targetKubernetesAiAgentId stay empty, so no Runner and no
|
|
1681
|
+
* Kubernetes AI agent can ever claim it.
|
|
1682
|
+
*/
|
|
1683
|
+
row.targetResourceAiAgentId = agent.id!;
|
|
1684
|
+
row.resourceType = data.resourceType;
|
|
1685
|
+
row.resourceId = loaded.resource.id;
|
|
1686
|
+
row.script = "";
|
|
1687
|
+
row.payload = payload as unknown as JSONObject;
|
|
1688
|
+
row.timeoutInMs = data.timeoutInMs;
|
|
1689
|
+
row.status = RunnerJobStatus.Pending;
|
|
1690
|
+
row.claimDeadlineAt = claimDeadlineAt;
|
|
1691
|
+
|
|
1692
|
+
return this.create({ data: row, props: { isRoot: true } });
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
/*
|
|
1696
|
+
* Why a resource command may NOT be enqueued for this resource as it is
|
|
1697
|
+
* configured right now, or null when it may. Pure, so the rule reads in
|
|
1698
|
+
* one place: the resource must have an online agent (the one the caller
|
|
1699
|
+
* named, when it named one) that is this resource's, the switch the job
|
|
1700
|
+
* needs must still be on, and no credential may travel with it.
|
|
1701
|
+
*/
|
|
1702
|
+
public static getResourceBindingRefusal(data: {
|
|
1703
|
+
resource: ResourceAiAccessRow;
|
|
1704
|
+
// The resource's ONLINE agent right now, or null.
|
|
1705
|
+
agent: ResourceAiAgent | null;
|
|
1706
|
+
targetResourceAiAgentId?: ObjectID | undefined;
|
|
1707
|
+
credentialId?: string | undefined;
|
|
1708
|
+
// The switch that must still be on; null for the access test.
|
|
1709
|
+
requiredSwitch: "investigation" | "remediation" | null;
|
|
1710
|
+
}): { code: ResourceCommandEnqueueRefusalCode; message: string } | null {
|
|
1711
|
+
const { resource, agent } = data;
|
|
1712
|
+
const info: AiResourceTypeInfo =
|
|
1713
|
+
AI_RESOURCE_TYPE_INFO[resource.resourceType];
|
|
1714
|
+
const noun: string = describeResourceNoun(resource.resourceType);
|
|
1715
|
+
const label: string = resource.name;
|
|
1716
|
+
|
|
1717
|
+
if (!agent || !agent.id) {
|
|
1718
|
+
return {
|
|
1719
|
+
code: "agent_not_online",
|
|
1720
|
+
message: `${noun.charAt(0).toUpperCase()}${noun.slice(1)} "${label}" has no online ${info.agentDisplayName}, so this command was not enqueued. ${getResourceAiAgentInstallNextStep(
|
|
1721
|
+
{
|
|
1722
|
+
resourceType: resource.resourceType,
|
|
1723
|
+
resourceId: resource.id.toString(),
|
|
1724
|
+
identifier: resource.identifier,
|
|
1725
|
+
},
|
|
1726
|
+
)} Already installed? Check that its container is running and can reach your OneUptime URL.`,
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
if (
|
|
1731
|
+
agent.projectId?.toString() !== resource.projectId.toString() ||
|
|
1732
|
+
agent.resourceType !== resource.resourceType ||
|
|
1733
|
+
agent.resourceId?.toString() !== resource.id.toString() ||
|
|
1734
|
+
(data.targetResourceAiAgentId &&
|
|
1735
|
+
data.targetResourceAiAgentId.toString() !== agent.id.toString())
|
|
1736
|
+
) {
|
|
1737
|
+
return {
|
|
1738
|
+
code: "agent_changed",
|
|
1739
|
+
message: `${noun.charAt(0).toUpperCase()}${noun.slice(1)} "${label}" is no longer reached through this ${info.agentDisplayName} (the agent was reset or replaced), so this command was not enqueued.`,
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
if (
|
|
1744
|
+
data.requiredSwitch === "investigation" &&
|
|
1745
|
+
resource.isAiInvestigationEnabled !== true
|
|
1746
|
+
) {
|
|
1747
|
+
return {
|
|
1748
|
+
code: "switch_off",
|
|
1749
|
+
message: `AI investigation is turned off for ${noun} "${label}", so this investigation command was not enqueued.`,
|
|
1750
|
+
};
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
if (
|
|
1754
|
+
data.requiredSwitch === "remediation" &&
|
|
1755
|
+
!ENABLED_RESOURCE_REMEDIATION_MODES.includes(resource.aiRemediationMode)
|
|
1756
|
+
) {
|
|
1757
|
+
return {
|
|
1758
|
+
code: "switch_off",
|
|
1759
|
+
message: `AI fixes are turned off for ${noun} "${label}", so this command was not enqueued.`,
|
|
1760
|
+
};
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
if (data.credentialId) {
|
|
1764
|
+
return {
|
|
1765
|
+
code: "credential_refused",
|
|
1766
|
+
message: `${noun.charAt(0).toUpperCase()}${noun.slice(1)} "${label}" is reached through its ${info.agentDisplayName}, which uses only the credentials in its own environment and is never given one by OneUptime, so a command that names a credential was not enqueued.`,
|
|
1767
|
+
};
|
|
1073
1768
|
}
|
|
1074
1769
|
|
|
1075
1770
|
return null;
|
|
@@ -1305,6 +2000,28 @@ export class Service extends DatabaseService<Model> {
|
|
|
1305
2000
|
.text;
|
|
1306
2001
|
}
|
|
1307
2002
|
|
|
2003
|
+
/*
|
|
2004
|
+
* A resource command's text through the resource command redactor (the
|
|
2005
|
+
* program's own rules, then the generic ones), or the text unchanged
|
|
2006
|
+
* when it is not one. Pure; redactAiJobText still runs after it.
|
|
2007
|
+
*/
|
|
2008
|
+
public static redactResourceCommandText(
|
|
2009
|
+
text: string,
|
|
2010
|
+
resourceCommand?:
|
|
2011
|
+
| { resourceType: AiResourceType; program: string }
|
|
2012
|
+
| undefined,
|
|
2013
|
+
): string {
|
|
2014
|
+
if (!resourceCommand) {
|
|
2015
|
+
return text;
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
return redactResourceCommandOutput({
|
|
2019
|
+
resourceType: resourceCommand.resourceType,
|
|
2020
|
+
program: resourceCommand.program,
|
|
2021
|
+
text,
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
|
|
1308
2025
|
/*
|
|
1309
2026
|
* A Runner's text as a Postgres text column can hold it. A NUL byte is
|
|
1310
2027
|
* ordinary in what a Runner reports — `kubectl logs` of a log that was
|
|
@@ -1333,6 +2050,18 @@ export class Service extends DatabaseService<Model> {
|
|
|
1333
2050
|
output?: string | undefined;
|
|
1334
2051
|
exitCode?: number | undefined;
|
|
1335
2052
|
errorMessage?: string | undefined;
|
|
2053
|
+
/*
|
|
2054
|
+
* Set by the resource AI agent's ingress for its ResourceCommand jobs:
|
|
2055
|
+
* the job's resource type and program (payload.program). The output is
|
|
2056
|
+
* then also run through the resource command redactor (docker inspect
|
|
2057
|
+
* env values, Proxmox and govc secrets, database literals, Ceph keys)
|
|
2058
|
+
* before the AI-job redaction, so a stored row never depends on the
|
|
2059
|
+
* agent having redacted it first. Absent for every other job, whose
|
|
2060
|
+
* text is stored exactly as before.
|
|
2061
|
+
*/
|
|
2062
|
+
resourceCommand?:
|
|
2063
|
+
| { resourceType: AiResourceType; program: string }
|
|
2064
|
+
| undefined;
|
|
1336
2065
|
}): Promise<boolean> {
|
|
1337
2066
|
const dataSource: ReturnType<typeof PostgresAppInstance.getDataSource> =
|
|
1338
2067
|
PostgresAppInstance.getDataSource();
|
|
@@ -1365,11 +2094,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
1365
2094
|
* redacted text for an AI-origin row and the verbatim text otherwise.
|
|
1366
2095
|
*/
|
|
1367
2096
|
const redactedOutput: string | null =
|
|
1368
|
-
rawOutput === null
|
|
2097
|
+
rawOutput === null
|
|
2098
|
+
? null
|
|
2099
|
+
: Service.redactAiJobText(
|
|
2100
|
+
Service.redactResourceCommandText(rawOutput, data.resourceCommand),
|
|
2101
|
+
);
|
|
1369
2102
|
const redactedErrorMessage: string | null =
|
|
1370
2103
|
rawErrorMessage === null
|
|
1371
2104
|
? null
|
|
1372
|
-
: Service.redactAiJobText(
|
|
2105
|
+
: Service.redactAiJobText(
|
|
2106
|
+
Service.redactResourceCommandText(
|
|
2107
|
+
rawErrorMessage,
|
|
2108
|
+
data.resourceCommand,
|
|
2109
|
+
),
|
|
2110
|
+
);
|
|
1373
2111
|
|
|
1374
2112
|
/*
|
|
1375
2113
|
* Only the agent that holds the lease is allowed to write the terminal
|
|
@@ -1458,6 +2196,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
1458
2196
|
// The timeout reason is worded for what the job is.
|
|
1459
2197
|
origin: true,
|
|
1460
2198
|
stepType: true,
|
|
2199
|
+
targetKubernetesAiAgentId: true,
|
|
2200
|
+
// A resource command names its resource's AI agent.
|
|
2201
|
+
targetResourceAiAgentId: true,
|
|
2202
|
+
resourceType: true,
|
|
1461
2203
|
},
|
|
1462
2204
|
props: { isRoot: true },
|
|
1463
2205
|
});
|
|
@@ -1504,6 +2246,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
1504
2246
|
stepType: job.stepType,
|
|
1505
2247
|
claimTimeoutInMs: data.claimTimeoutInMs,
|
|
1506
2248
|
executionTimeoutInMs: data.executionTimeoutInMs,
|
|
2249
|
+
isForKubernetesAiAgent: Boolean(job.targetKubernetesAiAgentId),
|
|
2250
|
+
resourceType: job.resourceType,
|
|
1507
2251
|
}),
|
|
1508
2252
|
});
|
|
1509
2253
|
}
|