@oneuptime/common 14.0.8 → 14.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
- package/Models/DatabaseModels/Project.ts +55 -5
- package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
- package/Models/DatabaseModels/RunnerJob.ts +75 -0
- package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
- package/Server/API/AIChatAPI.ts +6 -3
- package/Server/API/AIInvestigationAPI.ts +17 -10
- package/Server/API/AutoRemediationAPI.ts +207 -25
- package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
- package/Server/API/MicrosoftTeamsAPI.ts +93 -14
- package/Server/API/ProxmoxResourceAPI.ts +244 -14
- package/Server/Infrastructure/GlobalCache.ts +32 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/TelemetryIngest.ts +41 -18
- package/Server/Services/AIService.ts +70 -1
- package/Server/Services/AlertService.ts +352 -11
- package/Server/Services/AlertSeverityService.ts +65 -15
- package/Server/Services/AutoRemediationRuleService.ts +1 -1
- package/Server/Services/IncidentService.ts +280 -104
- package/Server/Services/IncidentSeverityService.ts +66 -15
- package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
- package/Server/Services/KubernetesAiAgentService.ts +1634 -0
- package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
- package/Server/Services/KubernetesClusterService.ts +129 -21
- package/Server/Services/ProjectService.ts +32 -0
- package/Server/Services/ProxmoxResourceService.ts +322 -5
- package/Server/Services/RunnerJobService.ts +241 -104
- package/Server/Services/RunnerService.ts +1 -1
- package/Server/Services/ScheduledMaintenanceService.ts +737 -1
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
- package/Server/Services/TeamComplianceSettingService.ts +1125 -9
- package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
- package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
- package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
- package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
- package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
- package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
- package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
- package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
- package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
- package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
- package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
- package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
- package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
- package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
- package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
- package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
- package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
- package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
- package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
- package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
- package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
- package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
- package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
- package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
- package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
- package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
- package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
- package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
- package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
- package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
- package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
- package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
- package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
- package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
- package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
- package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
- package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
- package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
- package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
- package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
- package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
- package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
- package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
- package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
- package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
- package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
- package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
- package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
- package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
- package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
- package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
- package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
- package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
- package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
- package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
- package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
- package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
- package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
- package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
- package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
- package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
- package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
- package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
- package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
- package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
- package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
- package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
- package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
- package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
- package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
- package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
- package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
- package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
- package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
- package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
- package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
- package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
- package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
- package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
- package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
- package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
- package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
- package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
- package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
- package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
- package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
- package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
- package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
- package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
- package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
- package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
- package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
- package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
- package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
- package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
- package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
- package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
- package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
- package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
- package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
- package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
- package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
- package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
- package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
- package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
- package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
- package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
- package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
- package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
- package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
- package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
- package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
- package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
- package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
- package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
- package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
- package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
- package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
- package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
- package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
- package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
- package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
- package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
- package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
- package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
- package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
- package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
- package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
- package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
- package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
- package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
- package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
- package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
- package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
- package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
- package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
- package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
- package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
- package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
- package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
- package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
- package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
- package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
- package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
- package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
- package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
- package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
- package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
- package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
- package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
- package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
- package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
- package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
- package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
- package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
- package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
- package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
- package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
- package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
- package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
- package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
- package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
- package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
- package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
- package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
- package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
- package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
- package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
- package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
- package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
- package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
- package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
- package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
- package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
- package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
- package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
- package/Tests/UI/Components/Input.test.tsx +80 -1
- package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
- package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
- package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
- package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
- package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
- package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
- package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
- package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
- package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
- package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
- package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
- package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
- package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
- package/Tests/UI/Components/Toggle.test.tsx +66 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
- package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
- package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
- package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
- package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
- package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
- package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
- package/Types/AI/AIRunType.ts +9 -4
- package/Types/AI/InvestigationNotStartedReason.ts +6 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
- package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
- package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
- package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
- package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
- package/Types/Team/ComplianceNotificationChannel.ts +22 -0
- package/Types/Team/ComplianceRule.ts +434 -0
- package/Types/Team/ComplianceRuleType.ts +21 -0
- package/Types/Team/TeamComplianceStatus.ts +81 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
- package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
- package/UI/Components/ActionButton/RowActions.tsx +238 -0
- package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
- package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
- package/UI/Components/Charts/Line/LineChart.tsx +32 -2
- package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
- package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
- package/UI/Components/Charts/Utils/XAxis.ts +75 -0
- package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
- package/UI/Components/Forms/Fields/FormField.tsx +10 -0
- package/UI/Components/Input/Input.tsx +90 -57
- package/UI/Components/List/ListRow.tsx +8 -74
- package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
- package/UI/Components/OrderedStatesList/Item.tsx +7 -72
- package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
- package/UI/Components/Table/TableBody.tsx +8 -2
- package/UI/Components/Table/TableRow.tsx +20 -140
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
- package/UI/Components/TelemetryViewer/types.ts +2 -0
- package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
- package/UI/Components/Toggle/Toggle.tsx +26 -0
- package/UI/Components/Tooltip/Tooltip.tsx +8 -1
- package/UI/Styles/Theme.css +14 -2
- package/Utils/AiRemediation/CommandPolicy.ts +1 -1
- package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
- package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +56 -5
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +6 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
- package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +59 -1
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +248 -13
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +51 -15
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +199 -72
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
- package/build/dist/Server/Services/RunnerJobService.js +178 -92
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/RunnerService.js +1 -1
- package/build/dist/Server/Services/RunnerService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIRunType.js +9 -4
- package/build/dist/Types/AI/AIRunType.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRule.js +304 -0
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
- package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
- package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
- package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
- package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +69 -54
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/List/ListRow.js +4 -39
- package/build/dist/UI/Components/List/ListRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
- package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +6 -2
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +12 -75
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
- package/package.json +1 -1
|
@@ -18,6 +18,7 @@ import Project from "../../../../Models/DatabaseModels/Project";
|
|
|
18
18
|
import AIRun from "../../../../Models/DatabaseModels/AIRun";
|
|
19
19
|
import LlmProvider from "../../../../Models/DatabaseModels/LlmProvider";
|
|
20
20
|
import ObjectID from "../../../../Types/ObjectID";
|
|
21
|
+
import logger from "../../../../Server/Utils/Logger";
|
|
21
22
|
import InvestigationNotStartedReason, {
|
|
22
23
|
InvestigationNotStartedCode,
|
|
23
24
|
} from "../../../../Types/AI/InvestigationNotStartedReason";
|
|
@@ -33,6 +34,7 @@ const codes: Array<InvestigationNotStartedCode> = [
|
|
|
33
34
|
"ai_disabled",
|
|
34
35
|
"automatic_investigation_disabled",
|
|
35
36
|
"provider_missing",
|
|
37
|
+
"insufficient_ai_balance",
|
|
36
38
|
"severity_below_threshold",
|
|
37
39
|
"monitor_cooldown",
|
|
38
40
|
"daily_budget_exhausted",
|
|
@@ -45,9 +47,29 @@ const configurationCodes: Array<InvestigationNotStartedCode> = [
|
|
|
45
47
|
"ai_disabled",
|
|
46
48
|
"automatic_investigation_disabled",
|
|
47
49
|
"provider_missing",
|
|
50
|
+
"insufficient_ai_balance",
|
|
48
51
|
"severity_below_threshold",
|
|
49
52
|
];
|
|
50
53
|
|
|
54
|
+
const BALANCE_BLOCKER: string =
|
|
55
|
+
"This project is out of AI credits. Add credits under Project Settings → AI Credits, or turn on auto-recharge.";
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
* AIService.getAiBalanceBlocker — the one AI balance predicate shared with
|
|
59
|
+
* the Kubernetes cluster's ai_balance_insufficient gap. null = no blocker.
|
|
60
|
+
*/
|
|
61
|
+
function mockBalanceBlocker(
|
|
62
|
+
outcome: string | null | Error = null,
|
|
63
|
+
): jest.SpyInstance {
|
|
64
|
+
const spy: jest.SpyInstance = jest.spyOn(AIService, "getAiBalanceBlocker");
|
|
65
|
+
if (outcome instanceof Error) {
|
|
66
|
+
spy.mockRejectedValue(outcome);
|
|
67
|
+
} else {
|
|
68
|
+
spy.mockResolvedValue(outcome);
|
|
69
|
+
}
|
|
70
|
+
return spy;
|
|
71
|
+
}
|
|
72
|
+
|
|
51
73
|
afterEach(() => {
|
|
52
74
|
jest.restoreAllMocks();
|
|
53
75
|
});
|
|
@@ -143,6 +165,7 @@ describe("investigation enablement reasons", () => {
|
|
|
143
165
|
jest
|
|
144
166
|
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
145
167
|
.mockResolvedValue(new LlmProvider());
|
|
168
|
+
mockBalanceBlocker(null);
|
|
146
169
|
expect(
|
|
147
170
|
await AIInvestigationEngine.getDisabledReason(projectId, "Incident"),
|
|
148
171
|
).toBeNull();
|
|
@@ -158,6 +181,256 @@ describe("investigation enablement reasons", () => {
|
|
|
158
181
|
});
|
|
159
182
|
});
|
|
160
183
|
|
|
184
|
+
/*
|
|
185
|
+
* On OneUptime's own billed provider, a project with no AI credits (and
|
|
186
|
+
* auto-recharge off) has every model call refused with "Insufficient AI
|
|
187
|
+
* balance". Starting an investigation then only produces a failed run that
|
|
188
|
+
* is retried once, with nothing on the incident saying why — so the gate
|
|
189
|
+
* refuses up front with a reason people can act on. It is the same
|
|
190
|
+
* predicate as the cluster's ai_balance_insufficient gap, and it fails OPEN:
|
|
191
|
+
* the model call still enforces the balance.
|
|
192
|
+
*/
|
|
193
|
+
describe("the AI balance gate (insufficient_ai_balance)", () => {
|
|
194
|
+
function mockReadyProject(): jest.SpyInstance {
|
|
195
|
+
jest
|
|
196
|
+
.spyOn(ProjectService, "findOneById")
|
|
197
|
+
.mockResolvedValue(enabledProject());
|
|
198
|
+
return jest
|
|
199
|
+
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
200
|
+
.mockResolvedValue(new LlmProvider());
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
it.each(["Alert", "Incident"] as const)(
|
|
204
|
+
"refuses a %s investigation when the project is out of AI credits",
|
|
205
|
+
async (kind: "Alert" | "Incident") => {
|
|
206
|
+
mockReadyProject();
|
|
207
|
+
mockBalanceBlocker(BALANCE_BLOCKER);
|
|
208
|
+
|
|
209
|
+
expect(
|
|
210
|
+
await AIInvestigationEngine.getDisabledReason(projectId, kind),
|
|
211
|
+
).toBe("insufficient_ai_balance");
|
|
212
|
+
expect(
|
|
213
|
+
await AIInvestigationEngine.isEnabledForProject(projectId, kind),
|
|
214
|
+
).toBe(false);
|
|
215
|
+
},
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
it("asks the shared predicate about this project, handing it the provider it already resolved", async () => {
|
|
219
|
+
const llmProvider: LlmProvider = new LlmProvider();
|
|
220
|
+
jest
|
|
221
|
+
.spyOn(ProjectService, "findOneById")
|
|
222
|
+
.mockResolvedValue(enabledProject());
|
|
223
|
+
const providerLookup: jest.SpyInstance = jest
|
|
224
|
+
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
225
|
+
.mockResolvedValue(llmProvider);
|
|
226
|
+
const blocker: jest.SpyInstance = mockBalanceBlocker(null);
|
|
227
|
+
|
|
228
|
+
await AIInvestigationEngine.getDisabledReason(projectId, "Incident");
|
|
229
|
+
|
|
230
|
+
expect(blocker).toHaveBeenCalledTimes(1);
|
|
231
|
+
expect(blocker).toHaveBeenCalledWith({ projectId, llmProvider });
|
|
232
|
+
// One provider lookup for the whole gate, not one per check.
|
|
233
|
+
expect(providerLookup).toHaveBeenCalledTimes(1);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it("lets the investigation start when there is no blocker", async () => {
|
|
237
|
+
mockReadyProject();
|
|
238
|
+
mockBalanceBlocker(null);
|
|
239
|
+
|
|
240
|
+
expect(
|
|
241
|
+
await AIInvestigationEngine.getDisabledReason(projectId, "Alert"),
|
|
242
|
+
).toBeNull();
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("an empty blocker string is not a blocker", async () => {
|
|
246
|
+
mockReadyProject();
|
|
247
|
+
mockBalanceBlocker("");
|
|
248
|
+
|
|
249
|
+
expect(
|
|
250
|
+
await AIInvestigationEngine.getDisabledReason(projectId, "Alert"),
|
|
251
|
+
).toBeNull();
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it("fails OPEN when the balance cannot be read — logged, never blocking", async () => {
|
|
255
|
+
mockReadyProject();
|
|
256
|
+
mockBalanceBlocker(new Error("billing store unavailable"));
|
|
257
|
+
const errorLog: jest.SpyInstance = jest
|
|
258
|
+
.spyOn(logger, "error")
|
|
259
|
+
.mockImplementation((): void => {
|
|
260
|
+
return undefined;
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
expect(
|
|
264
|
+
await AIInvestigationEngine.getDisabledReason(projectId, "Incident"),
|
|
265
|
+
).toBeNull();
|
|
266
|
+
expect(errorLog).toHaveBeenCalledWith(
|
|
267
|
+
expect.stringContaining("could not check the AI balance"),
|
|
268
|
+
);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it.each([
|
|
272
|
+
["AI is off", { enableAi: false }, "ai_disabled"],
|
|
273
|
+
[
|
|
274
|
+
"automatic investigation is off",
|
|
275
|
+
{ enableAutomaticIncidentInvestigation: false },
|
|
276
|
+
"automatic_investigation_disabled",
|
|
277
|
+
],
|
|
278
|
+
] as const)(
|
|
279
|
+
"is not consulted when %s — the switch is the reason, not the balance",
|
|
280
|
+
async (
|
|
281
|
+
_label: string,
|
|
282
|
+
overrides: Partial<Project>,
|
|
283
|
+
expected: InvestigationNotStartedCode,
|
|
284
|
+
) => {
|
|
285
|
+
jest
|
|
286
|
+
.spyOn(ProjectService, "findOneById")
|
|
287
|
+
.mockResolvedValue(Object.assign(enabledProject(), overrides));
|
|
288
|
+
const blocker: jest.SpyInstance = mockBalanceBlocker(BALANCE_BLOCKER);
|
|
289
|
+
|
|
290
|
+
expect(
|
|
291
|
+
await AIInvestigationEngine.getDisabledReason(projectId, "Incident"),
|
|
292
|
+
).toBe(expected);
|
|
293
|
+
expect(blocker).not.toHaveBeenCalled();
|
|
294
|
+
},
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
it("is not consulted without a provider — a missing provider is the reason", async () => {
|
|
298
|
+
jest
|
|
299
|
+
.spyOn(ProjectService, "findOneById")
|
|
300
|
+
.mockResolvedValue(enabledProject());
|
|
301
|
+
jest
|
|
302
|
+
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
303
|
+
.mockResolvedValue(null);
|
|
304
|
+
const blocker: jest.SpyInstance = mockBalanceBlocker(BALANCE_BLOCKER);
|
|
305
|
+
|
|
306
|
+
expect(
|
|
307
|
+
await AIInvestigationEngine.getDisabledReason(projectId, "Alert"),
|
|
308
|
+
).toBe("provider_missing");
|
|
309
|
+
expect(blocker).not.toHaveBeenCalled();
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
describe("getProviderOrBalanceReason — the half of the gate that is not a switch", () => {
|
|
313
|
+
it("reports a missing provider first", async () => {
|
|
314
|
+
jest
|
|
315
|
+
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
316
|
+
.mockResolvedValue(null);
|
|
317
|
+
const blocker: jest.SpyInstance = mockBalanceBlocker(BALANCE_BLOCKER);
|
|
318
|
+
|
|
319
|
+
expect(
|
|
320
|
+
await AIInvestigationEngine.getProviderOrBalanceReason(projectId),
|
|
321
|
+
).toBe("provider_missing");
|
|
322
|
+
expect(blocker).not.toHaveBeenCalled();
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it("reports an empty balance", async () => {
|
|
326
|
+
jest
|
|
327
|
+
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
328
|
+
.mockResolvedValue(new LlmProvider());
|
|
329
|
+
mockBalanceBlocker(BALANCE_BLOCKER);
|
|
330
|
+
|
|
331
|
+
expect(
|
|
332
|
+
await AIInvestigationEngine.getProviderOrBalanceReason(projectId),
|
|
333
|
+
).toBe("insufficient_ai_balance");
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it("reports nothing when a model can be called and paid for", async () => {
|
|
337
|
+
jest
|
|
338
|
+
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
339
|
+
.mockResolvedValue(new LlmProvider());
|
|
340
|
+
mockBalanceBlocker(null);
|
|
341
|
+
|
|
342
|
+
expect(
|
|
343
|
+
await AIInvestigationEngine.getProviderOrBalanceReason(projectId),
|
|
344
|
+
).toBeNull();
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it("never reads the project's switches — callers own those", async () => {
|
|
348
|
+
jest
|
|
349
|
+
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
350
|
+
.mockResolvedValue(new LlmProvider());
|
|
351
|
+
mockBalanceBlocker(null);
|
|
352
|
+
const projectRead: jest.SpyInstance = jest.spyOn(
|
|
353
|
+
ProjectService,
|
|
354
|
+
"findOneById",
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
await AIInvestigationEngine.getProviderOrBalanceReason(projectId);
|
|
358
|
+
|
|
359
|
+
expect(projectRead).not.toHaveBeenCalled();
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it.each(subjects)(
|
|
364
|
+
"explains the recorded reason in plain words for %o",
|
|
365
|
+
(subject: InvestigationSubject) => {
|
|
366
|
+
const reason: InvestigationNotStartedReason =
|
|
367
|
+
InvestigationEligibility.reason("insufficient_ai_balance", subject);
|
|
368
|
+
|
|
369
|
+
expect(reason.code).toBe("insufficient_ai_balance");
|
|
370
|
+
expect(reason.title).toBe(
|
|
371
|
+
"The project was out of AI credits at creation",
|
|
372
|
+
);
|
|
373
|
+
expect(reason.description).toBe(
|
|
374
|
+
`This project had no AI credits left when this ${
|
|
375
|
+
subject.alertId ? "alert" : "incident"
|
|
376
|
+
} was created, so its automatic investigation did not start.`,
|
|
377
|
+
);
|
|
378
|
+
expect(reason.nextStep).toContain("Project Settings → AI Credits");
|
|
379
|
+
expect(reason.nextStep).toContain("auto-recharge");
|
|
380
|
+
},
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
it.each(subjects)(
|
|
384
|
+
"explains the current condition, pointing at AI Credits, for %o",
|
|
385
|
+
async (subject: InvestigationSubject) => {
|
|
386
|
+
mockMissingDecision();
|
|
387
|
+
jest
|
|
388
|
+
.spyOn(AIInvestigationEngine, "getDisabledReason")
|
|
389
|
+
.mockResolvedValue("insufficient_ai_balance");
|
|
390
|
+
|
|
391
|
+
const reason: InvestigationNotStartedReason =
|
|
392
|
+
await InvestigationEligibility.getNotStartedReason(subject);
|
|
393
|
+
|
|
394
|
+
expect(reason.code).toBe("insufficient_ai_balance");
|
|
395
|
+
expect(reason.source).toBe("current_configuration");
|
|
396
|
+
expect(reason.title).toBe("The project is currently out of AI credits");
|
|
397
|
+
expect(reason.nextStep).toContain(
|
|
398
|
+
"Add AI credits under Project Settings → AI Credits",
|
|
399
|
+
);
|
|
400
|
+
expect(reason.nextStep).toContain("auto-recharge");
|
|
401
|
+
// The subject gate and the daily budget are never reached.
|
|
402
|
+
expect(
|
|
403
|
+
AIAlertInvestigationRunner.shouldInvestigateAlert,
|
|
404
|
+
).not.toHaveBeenCalled();
|
|
405
|
+
expect(
|
|
406
|
+
AIIncidentInvestigationRunner.shouldInvestigateIncident,
|
|
407
|
+
).not.toHaveBeenCalled();
|
|
408
|
+
expect(AIService.getAutonomousDailyBudgetStatus).not.toHaveBeenCalled();
|
|
409
|
+
},
|
|
410
|
+
);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
describe("the AI switches page is named where AI is off", () => {
|
|
414
|
+
it.each(subjects)(
|
|
415
|
+
"recorded and current ai_disabled next steps name Project Settings → AI Features for %o",
|
|
416
|
+
async (subject: InvestigationSubject) => {
|
|
417
|
+
const recorded: InvestigationNotStartedReason =
|
|
418
|
+
InvestigationEligibility.reason("ai_disabled", subject);
|
|
419
|
+
expect(recorded.nextStep).toContain("Project Settings → AI Features");
|
|
420
|
+
expect(recorded.nextStep).not.toContain("AI Credits");
|
|
421
|
+
|
|
422
|
+
mockMissingDecision();
|
|
423
|
+
jest
|
|
424
|
+
.spyOn(AIInvestigationEngine, "getDisabledReason")
|
|
425
|
+
.mockResolvedValue("ai_disabled");
|
|
426
|
+
const current: InvestigationNotStartedReason =
|
|
427
|
+
await InvestigationEligibility.getNotStartedReason(subject);
|
|
428
|
+
expect(current.nextStep).toContain("Project Settings → AI Features");
|
|
429
|
+
expect(current.nextStep).not.toContain("AI Credits");
|
|
430
|
+
},
|
|
431
|
+
);
|
|
432
|
+
});
|
|
433
|
+
|
|
161
434
|
describe.each(subjects)(
|
|
162
435
|
"recorded explanation time context for %o",
|
|
163
436
|
(subject: InvestigationSubject) => {
|
|
@@ -296,6 +569,7 @@ describe.each(subjects)(
|
|
|
296
569
|
"ai_disabled",
|
|
297
570
|
"automatic_investigation_disabled",
|
|
298
571
|
"provider_missing",
|
|
572
|
+
"insufficient_ai_balance",
|
|
299
573
|
] as const)(
|
|
300
574
|
"labels %s as current conditions, never historical proof",
|
|
301
575
|
async (code: InvestigationNotStartedCode) => {
|
|
@@ -502,6 +776,7 @@ describe.each(subjects)(
|
|
|
502
776
|
"ai_disabled",
|
|
503
777
|
"automatic_investigation_disabled",
|
|
504
778
|
"provider_missing",
|
|
779
|
+
"insufficient_ai_balance",
|
|
505
780
|
] as const)(
|
|
506
781
|
"records disabled admission %s",
|
|
507
782
|
async (code: InvestigationNotStartedCode) => {
|
|
@@ -593,6 +868,41 @@ describe.each(subjects)(
|
|
|
593
868
|
).not.toHaveBeenCalled();
|
|
594
869
|
expect(AIInvestigationQueue.processRun).toHaveBeenCalled();
|
|
595
870
|
});
|
|
871
|
+
it("records an empty AI balance through the real engine gate and never creates a run", async () => {
|
|
872
|
+
(
|
|
873
|
+
AIInvestigationEngine.getDisabledReason as unknown as jest.SpyInstance
|
|
874
|
+
).mockRestore();
|
|
875
|
+
jest
|
|
876
|
+
.spyOn(ProjectService, "findOneById")
|
|
877
|
+
.mockResolvedValue(enabledProject());
|
|
878
|
+
jest
|
|
879
|
+
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
880
|
+
.mockResolvedValue(new LlmProvider());
|
|
881
|
+
mockBalanceBlocker(BALANCE_BLOCKER);
|
|
882
|
+
|
|
883
|
+
expect(await trigger(subject)).toBe(false);
|
|
884
|
+
expectRecorded("insufficient_ai_balance");
|
|
885
|
+
expect(AIRunService.create).not.toHaveBeenCalled();
|
|
886
|
+
expect(AIInvestigationQueue.processRun).not.toHaveBeenCalled();
|
|
887
|
+
});
|
|
888
|
+
it("still starts the investigation through the real engine gate when the balance cannot be read", async () => {
|
|
889
|
+
(
|
|
890
|
+
AIInvestigationEngine.getDisabledReason as unknown as jest.SpyInstance
|
|
891
|
+
).mockRestore();
|
|
892
|
+
jest
|
|
893
|
+
.spyOn(ProjectService, "findOneById")
|
|
894
|
+
.mockResolvedValue(enabledProject());
|
|
895
|
+
jest
|
|
896
|
+
.spyOn(LlmProviderService, "getLLMProviderForProject")
|
|
897
|
+
.mockResolvedValue(new LlmProvider());
|
|
898
|
+
mockBalanceBlocker(new Error("billing store unavailable"));
|
|
899
|
+
jest.spyOn(logger, "error").mockImplementation((): void => {
|
|
900
|
+
return undefined;
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
expect(await trigger(subject)).toBe(true);
|
|
904
|
+
expect(AIRunService.create).toHaveBeenCalled();
|
|
905
|
+
});
|
|
596
906
|
it("records unexpected eligibility failures without stranding remediation", async () => {
|
|
597
907
|
jest
|
|
598
908
|
.spyOn(AIInvestigationEngine, "getDisabledReason")
|
|
@@ -91,6 +91,8 @@ function readyCluster(
|
|
|
91
91
|
posture: { inCluster: true, allowWrites: false },
|
|
92
92
|
},
|
|
93
93
|
accessMethod: "in_cluster",
|
|
94
|
+
aiAgent: null,
|
|
95
|
+
automaticInvestigation: { incidents: false, alerts: false },
|
|
94
96
|
kubectlAllowlist: [],
|
|
95
97
|
isInvestigationEnabled: true,
|
|
96
98
|
isInvestigationReady: true,
|
|
@@ -1248,6 +1250,74 @@ describe("KubectlInvestigationToolkit run_kubectl when kubectl never ran", () =>
|
|
|
1248
1250
|
expect(toolkit.getCommandsRun()).toBe(1);
|
|
1249
1251
|
});
|
|
1250
1252
|
|
|
1253
|
+
/*
|
|
1254
|
+
* The same unclaimed command on a cluster reached through its Kubernetes
|
|
1255
|
+
* AI agent: the text names the agent, never "its Runner".
|
|
1256
|
+
*/
|
|
1257
|
+
it("names the Kubernetes AI agent, not a Runner, when the agent left the command unclaimed", async () => {
|
|
1258
|
+
const toolkit: KubectlInvestigationToolkit =
|
|
1259
|
+
new KubectlInvestigationToolkit({
|
|
1260
|
+
projectId: PROJECT_ID,
|
|
1261
|
+
aiRunId: RUN_ID,
|
|
1262
|
+
clusters: [
|
|
1263
|
+
readyCluster({
|
|
1264
|
+
runner: {
|
|
1265
|
+
id: RUNNER_ID.toString(),
|
|
1266
|
+
name: "Kubernetes AI agent",
|
|
1267
|
+
kind: "ai_agent",
|
|
1268
|
+
isOnline: true,
|
|
1269
|
+
canRunAiCommands: true,
|
|
1270
|
+
posture: { inCluster: true, allowWrites: false },
|
|
1271
|
+
},
|
|
1272
|
+
}),
|
|
1273
|
+
],
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
const before: ToolCallOutcome = await getTool(
|
|
1277
|
+
toolkit,
|
|
1278
|
+
LIST_CLUSTER_ACCESS_TOOL_NAME,
|
|
1279
|
+
).execute({});
|
|
1280
|
+
expect(before.textForLlm).toContain(
|
|
1281
|
+
"read-only kubectl via the Kubernetes AI agent",
|
|
1282
|
+
);
|
|
1283
|
+
|
|
1284
|
+
const outcome: ToolCallOutcome = await runOn(toolkit);
|
|
1285
|
+
|
|
1286
|
+
expect(outcome.errorMessage).toBe(
|
|
1287
|
+
'kubectl was not run on cluster "prod-us": its Kubernetes AI agent did not pick up the command in time.',
|
|
1288
|
+
);
|
|
1289
|
+
expect(outcome.textForLlm).toContain(
|
|
1290
|
+
"its Kubernetes AI agent did not pick up",
|
|
1291
|
+
);
|
|
1292
|
+
expect(outcome.textForLlm).toContain(
|
|
1293
|
+
"the cluster's Kubernetes AI agent did not respond",
|
|
1294
|
+
);
|
|
1295
|
+
expect(outcome.textForLlm).not.toContain("Runner");
|
|
1296
|
+
|
|
1297
|
+
// The breaker speaks of the agent too.
|
|
1298
|
+
const second: ToolCallOutcome = await runOn(toolkit);
|
|
1299
|
+
expect(second.textForLlm).toMatch(/^The Kubernetes AI agent, which serves/);
|
|
1300
|
+
expect(second.errorMessage).toBe(
|
|
1301
|
+
'kubectl was not run on cluster "prod-us": its Kubernetes AI agent did not pick up an earlier command, so the cluster was unreachable for the rest of this investigation.',
|
|
1302
|
+
);
|
|
1303
|
+
|
|
1304
|
+
const list: ToolCallOutcome = await getTool(
|
|
1305
|
+
toolkit,
|
|
1306
|
+
LIST_CLUSTER_ACCESS_TOOL_NAME,
|
|
1307
|
+
).execute({});
|
|
1308
|
+
expect(list.textForLlm).toContain(
|
|
1309
|
+
"its Kubernetes AI agent did not pick up an earlier command",
|
|
1310
|
+
);
|
|
1311
|
+
|
|
1312
|
+
// The command went to the agent's row id with no credential.
|
|
1313
|
+
const data: Record<string, unknown> = enqueue.mock.calls[0]![0] as Record<
|
|
1314
|
+
string,
|
|
1315
|
+
unknown
|
|
1316
|
+
>;
|
|
1317
|
+
expect(String(data["targetAgentId"])).toBe(RUNNER_ID.toString());
|
|
1318
|
+
expect(data["credentialId"]).toBeUndefined();
|
|
1319
|
+
});
|
|
1320
|
+
|
|
1251
1321
|
it("trips a per-cluster breaker: the next command fails at once, enqueues nothing and spends nothing", async () => {
|
|
1252
1322
|
const toolkit: KubectlInvestigationToolkit = singleClusterToolkit();
|
|
1253
1323
|
|
|
@@ -230,6 +230,64 @@ describe("KubectlJobRunner.readFinishedJob", () => {
|
|
|
230
230
|
});
|
|
231
231
|
});
|
|
232
232
|
|
|
233
|
+
/*
|
|
234
|
+
* A job enqueued for the cluster's Kubernetes AI agent (the row carries
|
|
235
|
+
* targetKubernetesAiAgentId) is worded for the agent: "Runner" would send
|
|
236
|
+
* the operator looking for a Runner that does not exist.
|
|
237
|
+
*/
|
|
238
|
+
describe("KubectlJobRunner.readFinishedJob for a Kubernetes AI agent job", () => {
|
|
239
|
+
function readAgentJob(terminalJob: RunnerJob): Promise<KubectlJobOutcome> {
|
|
240
|
+
return KubectlJobRunner.readFinishedJob({
|
|
241
|
+
job: {
|
|
242
|
+
...enqueuedJob({ displayCommand: "kubectl get pods -n web" }),
|
|
243
|
+
targetKubernetesAiAgentId: ObjectID.generate(),
|
|
244
|
+
} as unknown as RunnerJob,
|
|
245
|
+
terminalJob,
|
|
246
|
+
command: "kubectl get pods -n web",
|
|
247
|
+
claimTimeoutInMs: KUBECTL_CLAIM_TIMEOUT_MS,
|
|
248
|
+
executionTimeoutInMs: EXECUTION_TIMEOUT_MS,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
it("never picked up: names the agent", async () => {
|
|
253
|
+
claimRead.mockResolvedValue(terminal({}));
|
|
254
|
+
|
|
255
|
+
const outcome: KubectlJobOutcome = await readAgentJob(
|
|
256
|
+
terminal({ status: RunnerJobStatus.TimedOut }),
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
expect(outcome.errorMessage).toMatch(
|
|
260
|
+
/^The cluster's Kubernetes AI agent did not pick up this kubectl command within \d+s/,
|
|
261
|
+
);
|
|
262
|
+
expect(outcome.runState).toBe(KubectlRunState.NotRun);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it("taken and gone silent: names the agent", async () => {
|
|
266
|
+
claimRead.mockResolvedValue(terminal({ claimedAt: new Date() }));
|
|
267
|
+
|
|
268
|
+
const outcome: KubectlJobOutcome = await readAgentJob(
|
|
269
|
+
terminal({ status: RunnerJobStatus.TimedOut }),
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
expect(outcome.errorMessage).toMatch(
|
|
273
|
+
/^The Kubernetes AI agent took this kubectl command but did not report a result in time/,
|
|
274
|
+
);
|
|
275
|
+
expect(outcome.errorMessage).not.toContain("Runner");
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("claim unreadable: names the agent", async () => {
|
|
279
|
+
claimRead.mockRejectedValue(new Error("db down"));
|
|
280
|
+
|
|
281
|
+
const outcome: KubectlJobOutcome = await readAgentJob(
|
|
282
|
+
terminal({ status: RunnerJobStatus.TimedOut }),
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
expect(outcome.errorMessage).toContain(
|
|
286
|
+
"whether the Kubernetes AI agent picked it up could not be read",
|
|
287
|
+
);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
|
|
233
291
|
describe("KubectlJobRunner.recordOutcomeOnCluster", () => {
|
|
234
292
|
let recordOutcome: jest.SpyInstance;
|
|
235
293
|
|
|
@@ -107,6 +107,8 @@ function cluster(
|
|
|
107
107
|
posture: { inCluster: true, allowWrites: true },
|
|
108
108
|
},
|
|
109
109
|
accessMethod: "in_cluster",
|
|
110
|
+
aiAgent: null,
|
|
111
|
+
automaticInvestigation: { incidents: false, alerts: false },
|
|
110
112
|
kubectlAllowlist: [],
|
|
111
113
|
isInvestigationEnabled: true,
|
|
112
114
|
isInvestigationReady: true,
|
|
@@ -79,6 +79,8 @@ function cluster(): KubernetesClusterAiAccessStatus {
|
|
|
79
79
|
posture: { inCluster: true, allowWrites: true },
|
|
80
80
|
},
|
|
81
81
|
accessMethod: "in_cluster",
|
|
82
|
+
aiAgent: null,
|
|
83
|
+
automaticInvestigation: { incidents: false, alerts: false },
|
|
82
84
|
kubectlAllowlist: [],
|
|
83
85
|
isInvestigationEnabled: true,
|
|
84
86
|
isInvestigationReady: true,
|
|
@@ -103,6 +103,8 @@ function cluster(
|
|
|
103
103
|
posture: { inCluster: true, allowWrites: true },
|
|
104
104
|
},
|
|
105
105
|
accessMethod: "in_cluster",
|
|
106
|
+
aiAgent: null,
|
|
107
|
+
automaticInvestigation: { incidents: false, alerts: false },
|
|
106
108
|
kubectlAllowlist: [],
|
|
107
109
|
isInvestigationEnabled: true,
|
|
108
110
|
isInvestigationReady: true,
|
|
@@ -111,6 +111,8 @@ function cluster(
|
|
|
111
111
|
posture: posture || undefined,
|
|
112
112
|
},
|
|
113
113
|
accessMethod: "in_cluster",
|
|
114
|
+
aiAgent: null,
|
|
115
|
+
automaticInvestigation: { incidents: false, alerts: false },
|
|
114
116
|
kubectlAllowlist: [],
|
|
115
117
|
isInvestigationEnabled: true,
|
|
116
118
|
isInvestigationReady: true,
|
|
@@ -233,7 +235,7 @@ describe("RemediationCommandToolkit.getRunnerScopeRefusal — the Runner's repor
|
|
|
233
235
|
expect(
|
|
234
236
|
refusalFor("kubectl rollout restart deployment/pay -n payments"),
|
|
235
237
|
).toContain(
|
|
236
|
-
'It only lets OneUptime AI change "web", "api" (aiAccess.remediation.namespaces on the Kubernetes agent chart).',
|
|
238
|
+
'It only lets OneUptime AI change "web", "api" (aiAccess.remediation.namespaces on the Kubernetes agent chart; after upgrading to the Kubernetes AI agent, aiAgent.remediation.namespaces).',
|
|
237
239
|
);
|
|
238
240
|
expect(refusalFor("kubectl rollout restart deployment/web")).toContain(
|
|
239
241
|
"Name the target namespace with -n <namespace>.",
|
|
@@ -1063,3 +1065,125 @@ describe("RemediationCommandToolkit tells the model the Runner's scope as the Ru
|
|
|
1063
1065
|
}
|
|
1064
1066
|
});
|
|
1065
1067
|
});
|
|
1068
|
+
|
|
1069
|
+
/*
|
|
1070
|
+
* The Kubernetes AI agent as the cluster's access target (runner.kind
|
|
1071
|
+
* "ai_agent", accessMethod "in_cluster"): the same rule as the in-cluster
|
|
1072
|
+
* Runner — a write with no -n lands in the agent pod's own namespace — in
|
|
1073
|
+
* the agent's words, naming the aiAgent.* chart values. The previous
|
|
1074
|
+
* in-cluster Runner's refusals say how to move to the agent; a credential
|
|
1075
|
+
* Runner's name its own environment.
|
|
1076
|
+
*/
|
|
1077
|
+
describe("RemediationCommandToolkit.getRunnerScopeRefusal — who sets the scope, three ways", () => {
|
|
1078
|
+
const AGENT_POSTURE: KubernetesRunnerPosture = {
|
|
1079
|
+
inCluster: true,
|
|
1080
|
+
allowWrites: true,
|
|
1081
|
+
clusterIdentifier: "prod-us",
|
|
1082
|
+
writeNamespaces: ["web", "api"],
|
|
1083
|
+
podNamespace: "oneuptime-agent",
|
|
1084
|
+
allowNodeOperations: false,
|
|
1085
|
+
};
|
|
1086
|
+
|
|
1087
|
+
function agentCluster(): KubernetesClusterAiAccessStatus {
|
|
1088
|
+
return cluster(AGENT_POSTURE, {
|
|
1089
|
+
runner: {
|
|
1090
|
+
id: RUNNER_ID.toString(),
|
|
1091
|
+
name: "Kubernetes AI agent",
|
|
1092
|
+
kind: "ai_agent",
|
|
1093
|
+
isOnline: true,
|
|
1094
|
+
canRunAiCommands: true,
|
|
1095
|
+
posture: AGENT_POSTURE,
|
|
1096
|
+
},
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
it("names the agent and aiAgent.remediation.namespaces for a write outside its scope", () => {
|
|
1101
|
+
const refusal: string | null = refusalFor(
|
|
1102
|
+
"kubectl rollout restart deployment/pay -n payments",
|
|
1103
|
+
agentCluster(),
|
|
1104
|
+
);
|
|
1105
|
+
|
|
1106
|
+
expect(refusal).toContain(
|
|
1107
|
+
'outside the namespaces the Kubernetes AI agent of cluster "prod-us" may change',
|
|
1108
|
+
);
|
|
1109
|
+
expect(refusal).toContain(
|
|
1110
|
+
"(aiAgent.remediation.namespaces on the Kubernetes agent chart)",
|
|
1111
|
+
);
|
|
1112
|
+
expect(refusal).not.toContain("aiAccess");
|
|
1113
|
+
expect(refusal).not.toContain("the Runner of cluster");
|
|
1114
|
+
});
|
|
1115
|
+
|
|
1116
|
+
it("names aiAgent.remediation.nodeOperations for a node operation", () => {
|
|
1117
|
+
const refusal: string | null = refusalFor(
|
|
1118
|
+
"kubectl cordon n1",
|
|
1119
|
+
agentCluster(),
|
|
1120
|
+
);
|
|
1121
|
+
|
|
1122
|
+
expect(refusal).toContain(
|
|
1123
|
+
"aiAgent.remediation.nodeOperations=false on the Kubernetes agent chart",
|
|
1124
|
+
);
|
|
1125
|
+
expect(refusal).not.toContain("aiAccess");
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
it("judges a write with no -n against the agent pod's own namespace, as the agent does", () => {
|
|
1129
|
+
const refusal: string | null = refusalFor(
|
|
1130
|
+
"kubectl rollout restart deployment/web",
|
|
1131
|
+
agentCluster(),
|
|
1132
|
+
);
|
|
1133
|
+
|
|
1134
|
+
expect(refusal).toContain(
|
|
1135
|
+
'names no namespace, so kubectl would run it in "oneuptime-agent"',
|
|
1136
|
+
);
|
|
1137
|
+
expect(refusal).toContain("never changes its own namespace");
|
|
1138
|
+
});
|
|
1139
|
+
|
|
1140
|
+
it("negative control: a write inside the agent's scope is not refused", () => {
|
|
1141
|
+
expect(
|
|
1142
|
+
refusalFor(
|
|
1143
|
+
"kubectl rollout restart deployment/web -n web",
|
|
1144
|
+
agentCluster(),
|
|
1145
|
+
),
|
|
1146
|
+
).toBeNull();
|
|
1147
|
+
});
|
|
1148
|
+
|
|
1149
|
+
it("getRunnerScopeSettings: the agent, the previous in-cluster Runner and a credential Runner each name their own setting", () => {
|
|
1150
|
+
expect(
|
|
1151
|
+
RemediationCommandToolkit.getRunnerScopeSettings(agentCluster()),
|
|
1152
|
+
).toEqual({
|
|
1153
|
+
namespaces:
|
|
1154
|
+
"aiAgent.remediation.namespaces on the Kubernetes agent chart",
|
|
1155
|
+
nodeOperations:
|
|
1156
|
+
"aiAgent.remediation.nodeOperations=false on the Kubernetes agent chart",
|
|
1157
|
+
});
|
|
1158
|
+
|
|
1159
|
+
const legacy: { namespaces: string; nodeOperations: string } =
|
|
1160
|
+
RemediationCommandToolkit.getRunnerScopeSettings(cluster(AGENT_POSTURE));
|
|
1161
|
+
|
|
1162
|
+
expect(legacy.namespaces).toContain(
|
|
1163
|
+
"aiAccess.remediation.namespaces on the Kubernetes agent chart",
|
|
1164
|
+
);
|
|
1165
|
+
expect(legacy.namespaces).toContain(
|
|
1166
|
+
"after upgrading to the Kubernetes AI agent, aiAgent.remediation.namespaces",
|
|
1167
|
+
);
|
|
1168
|
+
expect(legacy.nodeOperations).toContain(
|
|
1169
|
+
"after upgrading to the Kubernetes AI agent, aiAgent.remediation.nodeOperations",
|
|
1170
|
+
);
|
|
1171
|
+
|
|
1172
|
+
expect(
|
|
1173
|
+
RemediationCommandToolkit.getRunnerScopeSettings(credentialCluster()),
|
|
1174
|
+
).toEqual({
|
|
1175
|
+
namespaces: "ONEUPTIME_KUBECTL_WRITE_NAMESPACES on the Runner's host",
|
|
1176
|
+
nodeOperations:
|
|
1177
|
+
"ONEUPTIME_KUBECTL_ALLOW_NODE_OPERATIONS on the Runner's host",
|
|
1178
|
+
});
|
|
1179
|
+
});
|
|
1180
|
+
|
|
1181
|
+
it("the agent is told apart by kind only: a posture alone reads as the previous in-cluster Runner", () => {
|
|
1182
|
+
const withoutKind: KubernetesClusterAiAccessStatus = agentCluster();
|
|
1183
|
+
delete withoutKind.runner!.kind;
|
|
1184
|
+
|
|
1185
|
+
expect(
|
|
1186
|
+
RemediationCommandToolkit.getRunnerScopeSettings(withoutKind).namespaces,
|
|
1187
|
+
).toContain("aiAccess.remediation.namespaces");
|
|
1188
|
+
});
|
|
1189
|
+
});
|