@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
|
@@ -0,0 +1,1119 @@
|
|
|
1
|
+
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
2
|
+
import CommonAPI from "./CommonAPI";
|
|
3
|
+
import Express from "../Utils/Express";
|
|
4
|
+
import Response from "../Utils/Response";
|
|
5
|
+
import OneUptimeDate from "../../Types/Date";
|
|
6
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
7
|
+
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
|
|
8
|
+
import ServiceUnavailableException from "../../Types/Exception/ServiceUnavailableException";
|
|
9
|
+
import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
|
|
10
|
+
import ObjectID from "../../Types/ObjectID";
|
|
11
|
+
import RunnerJobOrigin from "../../Types/Runbook/RunnerJobOrigin";
|
|
12
|
+
import RunnerJobStatus from "../../Types/Runbook/RunnerJobStatus";
|
|
13
|
+
import RunbookStepType from "../../Types/Runbook/RunbookStepType";
|
|
14
|
+
import AIRunType from "../../Types/AI/AIRunType";
|
|
15
|
+
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
16
|
+
import { RESOURCE_AI_ACCESS_INSIGHTS_PATH, RESOURCE_AI_ACCESS_RESET_AGENT_PATH, RESOURCE_AI_ACCESS_STATUS_PATH, RESOURCE_AI_ACCESS_TEST_PATH, RESOURCE_AI_INSIGHTS_COMMAND_WINDOW_IN_DAYS, RESOURCE_AI_INSIGHTS_LIMIT, RESOURCE_AI_INSIGHTS_RATIONALE_MAX_LENGTH, } from "../../Types/AI/ResourceAiAccessApi";
|
|
17
|
+
import { RESOURCE_AI_ACCESS_ADMIN_PERMISSIONS, getResourceAgentName, getResourceAiAgentResetRefusal, getResourceSentenceName, } from "../../Types/AI/ResourceAiAccessPermissions";
|
|
18
|
+
import AiResourceType, { AI_RESOURCE_TYPE_INFO, parseAiResourceType, } from "../../Types/ResourceAiAgent/AiResourceType";
|
|
19
|
+
import { DEFAULT_RESOURCE_COMMAND_TIMEOUT_MS, } from "../../Types/ResourceAiAgent/ResourceAiAccess";
|
|
20
|
+
import AIRun from "../../Models/DatabaseModels/AIRun";
|
|
21
|
+
import GlobalCache from "../Infrastructure/GlobalCache";
|
|
22
|
+
import Semaphore from "../Infrastructure/Semaphore";
|
|
23
|
+
import AIRunService from "../Services/AIRunService";
|
|
24
|
+
import AlertService from "../Services/AlertService";
|
|
25
|
+
import AutoRemediationSuggestionService from "../Services/AutoRemediationSuggestionService";
|
|
26
|
+
import CephClusterService from "../Services/CephClusterService";
|
|
27
|
+
import DatabaseServerService from "../Services/DatabaseServerService";
|
|
28
|
+
import DockerHostService from "../Services/DockerHostService";
|
|
29
|
+
import DockerSwarmClusterService from "../Services/DockerSwarmClusterService";
|
|
30
|
+
import HostService from "../Services/HostService";
|
|
31
|
+
import IncidentService from "../Services/IncidentService";
|
|
32
|
+
import PodmanHostService from "../Services/PodmanHostService";
|
|
33
|
+
import ProxmoxClusterService from "../Services/ProxmoxClusterService";
|
|
34
|
+
import ResourceAiAccessService from "../Services/ResourceAiAccessService";
|
|
35
|
+
import ResourceAiAgentService from "../Services/ResourceAiAgentService";
|
|
36
|
+
import RunnerJobService from "../Services/RunnerJobService";
|
|
37
|
+
import VMwareVCenterService from "../Services/VMwareVCenterService";
|
|
38
|
+
import QueryHelper from "../Types/Database/QueryHelper";
|
|
39
|
+
import logger from "../Utils/Logger";
|
|
40
|
+
import { holdsAnyUnblockedPermission } from "../Utils/Runbook/RunbookExecutePermission";
|
|
41
|
+
import ResourceCommandJobRunner, { RESOURCE_COMMAND_CLAIM_TIMEOUT_MS, } from "../Utils/AI/ResourceAccess/ResourceCommandJobRunner";
|
|
42
|
+
const router = Express.getRouter();
|
|
43
|
+
export const RESOURCE_AI_ACCESS_KINDS = {
|
|
44
|
+
[AiResourceType.DockerHost]: {
|
|
45
|
+
service: DockerHostService,
|
|
46
|
+
subjectRelation: "dockerHosts",
|
|
47
|
+
},
|
|
48
|
+
[AiResourceType.PodmanHost]: {
|
|
49
|
+
service: PodmanHostService,
|
|
50
|
+
subjectRelation: "podmanHosts",
|
|
51
|
+
},
|
|
52
|
+
[AiResourceType.DockerSwarmCluster]: {
|
|
53
|
+
service: DockerSwarmClusterService,
|
|
54
|
+
subjectRelation: "dockerSwarmClusters",
|
|
55
|
+
},
|
|
56
|
+
[AiResourceType.ProxmoxCluster]: {
|
|
57
|
+
service: ProxmoxClusterService,
|
|
58
|
+
subjectRelation: "proxmoxClusters",
|
|
59
|
+
},
|
|
60
|
+
[AiResourceType.VMwareVCenter]: {
|
|
61
|
+
service: VMwareVCenterService,
|
|
62
|
+
subjectRelation: "vmwareVCenters",
|
|
63
|
+
},
|
|
64
|
+
[AiResourceType.CephCluster]: {
|
|
65
|
+
service: CephClusterService,
|
|
66
|
+
subjectRelation: "cephClusters",
|
|
67
|
+
},
|
|
68
|
+
[AiResourceType.DatabaseServer]: {
|
|
69
|
+
service: DatabaseServerService,
|
|
70
|
+
subjectRelation: "databaseServers",
|
|
71
|
+
},
|
|
72
|
+
[AiResourceType.Host]: {
|
|
73
|
+
service: HostService,
|
|
74
|
+
subjectRelation: "hosts",
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
async function getLoggedInProps(req) {
|
|
78
|
+
const props = await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
79
|
+
CommonAPI.assertAuthenticatedUser(props);
|
|
80
|
+
return Object.assign(Object.assign({}, props), { isMultiTenantRequest: false });
|
|
81
|
+
}
|
|
82
|
+
/*
|
|
83
|
+
* The resource type a request names: an AiResourceType value (any case) or
|
|
84
|
+
* an agent alias ("docker", "db", ...). Anything else is refused before any
|
|
85
|
+
* lookup.
|
|
86
|
+
*/
|
|
87
|
+
export function readResourceType(value) {
|
|
88
|
+
const resourceType = parseAiResourceType(value);
|
|
89
|
+
if (!resourceType) {
|
|
90
|
+
throw new BadDataException(`resourceType is required and must be one of ${Object.values(AiResourceType).join(", ")}.`);
|
|
91
|
+
}
|
|
92
|
+
return resourceType;
|
|
93
|
+
}
|
|
94
|
+
/*
|
|
95
|
+
* Access check under the USER's permissions inside the tenant. Null is
|
|
96
|
+
* "does not exist OR not yours", reported identically so the route never
|
|
97
|
+
* leaks whether an id exists in another project.
|
|
98
|
+
*/
|
|
99
|
+
async function findAccessibleResource(data) {
|
|
100
|
+
const body = (data.req.body || {});
|
|
101
|
+
const resourceType = readResourceType(body["resourceType"]);
|
|
102
|
+
const resourceIdString = body["resourceId"];
|
|
103
|
+
if (!resourceIdString ||
|
|
104
|
+
typeof resourceIdString !== "string" ||
|
|
105
|
+
!ObjectID.isValidUUID(resourceIdString)) {
|
|
106
|
+
throw new BadDataException("resourceId is required.");
|
|
107
|
+
}
|
|
108
|
+
/*
|
|
109
|
+
* Read under the user's own props — so the resource's read ACL (and any
|
|
110
|
+
* label-scoped block) applies exactly as on a CRUD read — and scoped to
|
|
111
|
+
* the tenant in the query itself.
|
|
112
|
+
*/
|
|
113
|
+
const resource = (await RESOURCE_AI_ACCESS_KINDS[resourceType].service.findOneBy({
|
|
114
|
+
query: {
|
|
115
|
+
_id: resourceIdString,
|
|
116
|
+
projectId: data.tenantId,
|
|
117
|
+
},
|
|
118
|
+
select: { _id: true, projectId: true, name: true },
|
|
119
|
+
props: data.props,
|
|
120
|
+
}));
|
|
121
|
+
const record = resource;
|
|
122
|
+
const projectId = record ? record["projectId"] : undefined;
|
|
123
|
+
/*
|
|
124
|
+
* A row from another project is reported exactly like a missing one
|
|
125
|
+
* (belt and braces: the query is already tenant-scoped), so the route
|
|
126
|
+
* never confirms that an id exists somewhere else.
|
|
127
|
+
*/
|
|
128
|
+
if (!resource ||
|
|
129
|
+
!resource.id ||
|
|
130
|
+
!projectId ||
|
|
131
|
+
String(projectId) !== data.tenantId.toString()) {
|
|
132
|
+
throw new BadDataException(`${AI_RESOURCE_TYPE_INFO[resourceType].displayName} not found (or you do not have access to it).`);
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
resourceType,
|
|
136
|
+
id: resource.id,
|
|
137
|
+
name: typeof record["name"] === "string" && record["name"]
|
|
138
|
+
? record["name"]
|
|
139
|
+
: resource.id.toString(),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/*
|
|
143
|
+
* The access test is read-only, but it spends the agent's time and prints
|
|
144
|
+
* what the agent can see, so it is for the people who may EDIT this
|
|
145
|
+
* resource — decided for this row exactly as a CRUD update of it would be
|
|
146
|
+
* (ResourceAiAccessService.assertCallerMayChangeResource): the update ACL,
|
|
147
|
+
* label-scoped allow and block rows against the row's own labels, a
|
|
148
|
+
* table-wide block row, and the caller's Owned scope. Holding an edit
|
|
149
|
+
* permission somewhere in the project is not enough: an edit grant limited
|
|
150
|
+
* to "staging" does not reach the "prod" host, and a block row for "prod"
|
|
151
|
+
* refuses it. Master admins are not gated.
|
|
152
|
+
*/
|
|
153
|
+
async function assertCanEditResource(data) {
|
|
154
|
+
try {
|
|
155
|
+
await ResourceAiAccessService.assertCallerMayChangeResource({
|
|
156
|
+
props: data.props,
|
|
157
|
+
projectId: data.projectId,
|
|
158
|
+
resourceType: data.resource.resourceType,
|
|
159
|
+
resourceId: data.resource.id,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
if (error instanceof NotAuthorizedException) {
|
|
164
|
+
throw new NotAuthorizedException(`You need permission to edit this ${getResourceSentenceName(data.resource.resourceType)} to run its AI access test.`);
|
|
165
|
+
}
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/*
|
|
170
|
+
* Resetting the agent locks out whatever holds its key, and the real agent
|
|
171
|
+
* registers afresh: the same people who may loosen AI access may do it.
|
|
172
|
+
*/
|
|
173
|
+
function assertCanResetAiAgent(data) {
|
|
174
|
+
if (!holdsAnyUnblockedPermission({
|
|
175
|
+
props: data.props,
|
|
176
|
+
projectId: data.projectId,
|
|
177
|
+
allowed: RESOURCE_AI_ACCESS_ADMIN_PERMISSIONS,
|
|
178
|
+
})) {
|
|
179
|
+
throw new NotAuthorizedException(getResourceAiAgentResetRefusal(data.resourceType));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async function getStatus(data) {
|
|
183
|
+
const status = await ResourceAiAccessService.getStatusForResource({
|
|
184
|
+
projectId: data.projectId,
|
|
185
|
+
resourceType: data.resource.resourceType,
|
|
186
|
+
resourceId: data.resource.id,
|
|
187
|
+
});
|
|
188
|
+
if (!status) {
|
|
189
|
+
throw new BadDataException(`${AI_RESOURCE_TYPE_INFO[data.resource.resourceType].displayName} not found.`);
|
|
190
|
+
}
|
|
191
|
+
return status;
|
|
192
|
+
}
|
|
193
|
+
/*
|
|
194
|
+
* The access test's own limits. It enqueues real agent jobs and holds the
|
|
195
|
+
* request open while they run, so it is bounded where it is triggered and
|
|
196
|
+
* never counted against the project-wide investigation brake, so no amount
|
|
197
|
+
* of testing can starve real incident investigations:
|
|
198
|
+
*
|
|
199
|
+
* - one test at a time per resource: an atomic reservation (Redis SET NX,
|
|
200
|
+
* released when the test ends and expiring on its own after the longest
|
|
201
|
+
* a test can run), so concurrent requests cannot all read "nothing
|
|
202
|
+
* running" and all start. The per-resource counts below are read inside
|
|
203
|
+
* it, so they are exact;
|
|
204
|
+
* - a few per minute and a cumulative ceiling per hour per resource, and a
|
|
205
|
+
* few per minute per user across resources — the per-user count is read
|
|
206
|
+
* and the test's first command run under a per-user lock, so a user's
|
|
207
|
+
* concurrent requests on different resources are counted one after the
|
|
208
|
+
* other. Counted on the RunnerJob rows the test creates, which every API
|
|
209
|
+
* node shares.
|
|
210
|
+
*
|
|
211
|
+
* The numbers are a Kubernetes cluster's; the step ids, the reservation
|
|
212
|
+
* and the lock are this route's own, so testing a resource never counts
|
|
213
|
+
* against a cluster's tests or the other way round.
|
|
214
|
+
*/
|
|
215
|
+
export const MAX_RESOURCE_AI_ACCESS_TESTS_PER_RESOURCE_PER_MINUTE = 3;
|
|
216
|
+
export const MAX_RESOURCE_AI_ACCESS_TESTS_PER_RESOURCE_PER_HOUR = 30;
|
|
217
|
+
export const MAX_RESOURCE_AI_ACCESS_TESTS_PER_USER_PER_MINUTE = 6;
|
|
218
|
+
/*
|
|
219
|
+
* A test job older than this is past both of its windows (claim plus
|
|
220
|
+
* execution, twice over), so a row a crashed request left Pending never
|
|
221
|
+
* blocks the next test for good — and neither does a reservation a crashed
|
|
222
|
+
* request never released.
|
|
223
|
+
*/
|
|
224
|
+
const RESOURCE_AI_ACCESS_TEST_MAX_DURATION_MINUTES = 4;
|
|
225
|
+
export const RESOURCE_AI_ACCESS_TEST_RESERVATION_NAMESPACE = "resource-ai-access-test";
|
|
226
|
+
export const RESOURCE_AI_ACCESS_TEST_USER_LOCK_NAMESPACE = "resource-ai-access-test-user";
|
|
227
|
+
/*
|
|
228
|
+
* Held from the per-user count until the test's first command has finished.
|
|
229
|
+
* The lock refreshes itself while it is held; the timeout is how long it
|
|
230
|
+
* outlives a request that died holding it.
|
|
231
|
+
*/
|
|
232
|
+
const RESOURCE_AI_ACCESS_TEST_USER_LOCK_TIMEOUT_MS = 30000;
|
|
233
|
+
const RESOURCE_AI_ACCESS_TEST_USER_LOCK_ACQUIRE_TIMEOUT_MS = 15000;
|
|
234
|
+
/*
|
|
235
|
+
* Gaps that block both capabilities but not the access test's transport:
|
|
236
|
+
* they are about the project's AI (switched off, no provider, no credits),
|
|
237
|
+
* and the test runs the agent's commands, never a model. An agent that is
|
|
238
|
+
* online but could not reach its resource at its last probe is tested too:
|
|
239
|
+
* the test's own output is exactly what says why, and a success clears it.
|
|
240
|
+
*/
|
|
241
|
+
const NON_TRANSPORT_GAP_CODES = [
|
|
242
|
+
"ai_disabled_for_project",
|
|
243
|
+
"llm_provider_missing",
|
|
244
|
+
"ai_balance_insufficient",
|
|
245
|
+
"ai_agent_unreachable_resource",
|
|
246
|
+
];
|
|
247
|
+
/*
|
|
248
|
+
* Every access-test job's stepId starts with this; the first command's
|
|
249
|
+
* with the "-1-" form plus the user who ran it, so a test (not a command)
|
|
250
|
+
* can be counted per resource and per user from the rows alone. Distinct
|
|
251
|
+
* from a Kubernetes cluster's "ai-access-test-" prefix, which the cluster
|
|
252
|
+
* route counts with startsWith.
|
|
253
|
+
*/
|
|
254
|
+
export const RESOURCE_AI_ACCESS_TEST_STEP_ID_PREFIX = "resource-ai-access-test-";
|
|
255
|
+
export function getResourceAiAccessTestStepId(data) {
|
|
256
|
+
return `${RESOURCE_AI_ACCESS_TEST_STEP_ID_PREFIX}${data.commandNumber}-${data.userId.toString()}`;
|
|
257
|
+
}
|
|
258
|
+
function getReservationKey(resource) {
|
|
259
|
+
return `${resource.resourceType}:${resource.id.toString()}`;
|
|
260
|
+
}
|
|
261
|
+
function getAlreadyRunningMessage(resourceType) {
|
|
262
|
+
return `An AI access test is already running for this ${getResourceSentenceName(resourceType)}. Wait for it to finish, then run it again.`;
|
|
263
|
+
}
|
|
264
|
+
/*
|
|
265
|
+
* Take this resource's one access-test slot, atomically, and return the
|
|
266
|
+
* token that releases it — or refuse: 429 while another test holds it, 503
|
|
267
|
+
* when the reservation cannot be checked at all (failing closed: the
|
|
268
|
+
* reservation is what makes "one at a time" true under concurrency).
|
|
269
|
+
*/
|
|
270
|
+
async function reserveResourceForAccessTest(resource) {
|
|
271
|
+
const token = ObjectID.generate().toString();
|
|
272
|
+
let isReserved = false;
|
|
273
|
+
try {
|
|
274
|
+
isReserved = await GlobalCache.setStringIfNotExists(RESOURCE_AI_ACCESS_TEST_RESERVATION_NAMESPACE, getReservationKey(resource), token, { expiresInSeconds: RESOURCE_AI_ACCESS_TEST_MAX_DURATION_MINUTES * 60 });
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
logger.error(`ResourceAiAccessAPI: could not reserve the AI access test of ${getReservationKey(resource)}: ${error}`);
|
|
278
|
+
throw new ServiceUnavailableException("The AI access test could not start right now. Try again in a moment.");
|
|
279
|
+
}
|
|
280
|
+
if (!isReserved) {
|
|
281
|
+
throw new TooManyRequestsException(getAlreadyRunningMessage(resource.resourceType));
|
|
282
|
+
}
|
|
283
|
+
return token;
|
|
284
|
+
}
|
|
285
|
+
// Best effort: the reservation expires on its own if this fails.
|
|
286
|
+
async function releaseResourceReservation(data) {
|
|
287
|
+
try {
|
|
288
|
+
await GlobalCache.deleteKeyIfValue(RESOURCE_AI_ACCESS_TEST_RESERVATION_NAMESPACE, getReservationKey(data.resource), data.token);
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
logger.error(`ResourceAiAccessAPI: could not release the AI access test reservation of ${getReservationKey(data.resource)}; it expires on its own: ${error}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/*
|
|
295
|
+
* The per-resource limits, read while this request holds the resource's
|
|
296
|
+
* reservation — so no other test of this resource can be counting (or
|
|
297
|
+
* creating rows) at the same time.
|
|
298
|
+
*/
|
|
299
|
+
async function assertResourceAccessTestMayRun(data) {
|
|
300
|
+
const resourceQuery = {
|
|
301
|
+
projectId: data.projectId,
|
|
302
|
+
resourceType: data.resource.resourceType,
|
|
303
|
+
resourceId: data.resource.id,
|
|
304
|
+
};
|
|
305
|
+
const sentenceName = getResourceSentenceName(data.resource.resourceType);
|
|
306
|
+
const inFlight = (await RunnerJobService.countBy({
|
|
307
|
+
query: Object.assign(Object.assign({}, resourceQuery), { stepId: QueryHelper.startsWith(RESOURCE_AI_ACCESS_TEST_STEP_ID_PREFIX), status: QueryHelper.any([
|
|
308
|
+
RunnerJobStatus.Pending,
|
|
309
|
+
RunnerJobStatus.Claimed,
|
|
310
|
+
RunnerJobStatus.Running,
|
|
311
|
+
]), createdAt: QueryHelper.greaterThan(OneUptimeDate.getSomeMinutesAgo(RESOURCE_AI_ACCESS_TEST_MAX_DURATION_MINUTES)) }),
|
|
312
|
+
props: { isRoot: true },
|
|
313
|
+
})).toNumber();
|
|
314
|
+
if (inFlight > 0) {
|
|
315
|
+
throw new TooManyRequestsException(getAlreadyRunningMessage(data.resource.resourceType));
|
|
316
|
+
}
|
|
317
|
+
const testsForResource = (await RunnerJobService.countBy({
|
|
318
|
+
query: Object.assign(Object.assign({}, resourceQuery), { stepId: QueryHelper.startsWith(`${RESOURCE_AI_ACCESS_TEST_STEP_ID_PREFIX}1-`), createdAt: QueryHelper.greaterThan(OneUptimeDate.getSomeMinutesAgo(1)) }),
|
|
319
|
+
props: { isRoot: true },
|
|
320
|
+
})).toNumber();
|
|
321
|
+
if (testsForResource >= MAX_RESOURCE_AI_ACCESS_TESTS_PER_RESOURCE_PER_MINUTE) {
|
|
322
|
+
throw new TooManyRequestsException(`This ${sentenceName}'s AI access was tested ${testsForResource} times in the last minute, which is its limit (${MAX_RESOURCE_AI_ACCESS_TESTS_PER_RESOURCE_PER_MINUTE}). Try again in a minute.`);
|
|
323
|
+
}
|
|
324
|
+
/*
|
|
325
|
+
* The cumulative ceiling: access-test jobs are kept out of the project's
|
|
326
|
+
* investigation brake, so without this nothing would bound them over an
|
|
327
|
+
* hour.
|
|
328
|
+
*/
|
|
329
|
+
const testsForResourceThisHour = (await RunnerJobService.countBy({
|
|
330
|
+
query: Object.assign(Object.assign({}, resourceQuery), { stepId: QueryHelper.startsWith(`${RESOURCE_AI_ACCESS_TEST_STEP_ID_PREFIX}1-`), createdAt: QueryHelper.greaterThan(OneUptimeDate.getSomeHoursAgo(1)) }),
|
|
331
|
+
props: { isRoot: true },
|
|
332
|
+
})).toNumber();
|
|
333
|
+
if (testsForResourceThisHour >=
|
|
334
|
+
MAX_RESOURCE_AI_ACCESS_TESTS_PER_RESOURCE_PER_HOUR) {
|
|
335
|
+
throw new TooManyRequestsException(`This ${sentenceName}'s AI access was tested ${testsForResourceThisHour} times in the last hour, which is its limit (${MAX_RESOURCE_AI_ACCESS_TESTS_PER_RESOURCE_PER_HOUR}). Try again later.`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/*
|
|
339
|
+
* The per-user limit spans resources, so the resource reservation does not
|
|
340
|
+
* serialize it: the count is read and the test's first command run under a
|
|
341
|
+
* per-user lock, so a user's concurrent tests on different resources cannot
|
|
342
|
+
* all read the same count. The lock is held until that first command has
|
|
343
|
+
* finished, because ResourceCommandJobRunner.run enqueues and waits in one
|
|
344
|
+
* call and the job it creates is what the next count must see.
|
|
345
|
+
*/
|
|
346
|
+
async function lockUserForAccessTestStart(userId) {
|
|
347
|
+
try {
|
|
348
|
+
return await Semaphore.lock({
|
|
349
|
+
key: userId.toString(),
|
|
350
|
+
namespace: RESOURCE_AI_ACCESS_TEST_USER_LOCK_NAMESPACE,
|
|
351
|
+
lockTimeout: RESOURCE_AI_ACCESS_TEST_USER_LOCK_TIMEOUT_MS,
|
|
352
|
+
acquireTimeout: RESOURCE_AI_ACCESS_TEST_USER_LOCK_ACQUIRE_TIMEOUT_MS,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
logger.error(`ResourceAiAccessAPI: could not take the AI access test lock of user ${userId.toString()}: ${error}`);
|
|
357
|
+
throw new TooManyRequestsException("Another AI access test of yours is starting right now. Try again in a moment.");
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
async function releaseUserLock(mutex) {
|
|
361
|
+
try {
|
|
362
|
+
await Semaphore.release(mutex);
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
logger.error(`ResourceAiAccessAPI: could not release an AI access test user lock; it expires on its own: ${error}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
async function assertUserMayStartAccessTest(data) {
|
|
369
|
+
const testsByUser = (await RunnerJobService.countBy({
|
|
370
|
+
query: {
|
|
371
|
+
projectId: data.projectId,
|
|
372
|
+
stepId: QueryHelper.startsWith(getResourceAiAccessTestStepId({
|
|
373
|
+
commandNumber: 1,
|
|
374
|
+
userId: data.userId,
|
|
375
|
+
})),
|
|
376
|
+
createdAt: QueryHelper.greaterThan(OneUptimeDate.getSomeMinutesAgo(1)),
|
|
377
|
+
},
|
|
378
|
+
props: { isRoot: true },
|
|
379
|
+
})).toNumber();
|
|
380
|
+
if (testsByUser >= MAX_RESOURCE_AI_ACCESS_TESTS_PER_USER_PER_MINUTE) {
|
|
381
|
+
throw new TooManyRequestsException(`You ran ${testsByUser} AI access tests in the last minute, which is the limit (${MAX_RESOURCE_AI_ACCESS_TESTS_PER_USER_PER_MINUTE}). Try again in a minute.`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/*
|
|
385
|
+
* One access-test command, run the way every AI resource command is
|
|
386
|
+
* (ResourceCommandJobRunner.run): enqueued through the resource-command
|
|
387
|
+
* chokepoint as an access test — the policy, the read-only rule and the
|
|
388
|
+
* resource's current agent still apply; the investigation switch and the
|
|
389
|
+
* project's investigation brake do not — then waited on, read and recorded
|
|
390
|
+
* exactly like an investigation's command (only a success or an ACCESS
|
|
391
|
+
* failure becomes the resource's "Last verified" / "Last error").
|
|
392
|
+
*
|
|
393
|
+
* Origin AiInvestigation with no AI run: an access test has none to keep
|
|
394
|
+
* alive.
|
|
395
|
+
*/
|
|
396
|
+
async function runAccessTestCommand(data) {
|
|
397
|
+
return ResourceCommandJobRunner.run({
|
|
398
|
+
projectId: data.projectId,
|
|
399
|
+
origin: RunnerJobOrigin.AiInvestigation,
|
|
400
|
+
resourceType: data.resource.resourceType,
|
|
401
|
+
resourceId: data.resource.id,
|
|
402
|
+
targetResourceAiAgentId: data.agentId,
|
|
403
|
+
command: data.command,
|
|
404
|
+
stepId: data.stepId,
|
|
405
|
+
timeoutInMs: DEFAULT_RESOURCE_COMMAND_TIMEOUT_MS,
|
|
406
|
+
claimTimeoutInMs: RESOURCE_COMMAND_CLAIM_TIMEOUT_MS,
|
|
407
|
+
isAccessTest: true,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
/*
|
|
411
|
+
* Start the test: under this user's lock, check the per-user limit and run
|
|
412
|
+
* the first command, so the next concurrent test of this user counts its
|
|
413
|
+
* job (see lockUserForAccessTestStart). The limit refusal is thrown (the
|
|
414
|
+
* route answers 429); a refusal from the chokepoint, or a wait that broke,
|
|
415
|
+
* is returned as the first command's failure.
|
|
416
|
+
*/
|
|
417
|
+
async function startAccessTest(data) {
|
|
418
|
+
const userLock = await lockUserForAccessTestStart(data.userId);
|
|
419
|
+
try {
|
|
420
|
+
await assertUserMayStartAccessTest({
|
|
421
|
+
projectId: data.projectId,
|
|
422
|
+
userId: data.userId,
|
|
423
|
+
});
|
|
424
|
+
try {
|
|
425
|
+
const outcome = await runAccessTestCommand({
|
|
426
|
+
projectId: data.projectId,
|
|
427
|
+
resource: data.resource,
|
|
428
|
+
agentId: data.agentId,
|
|
429
|
+
command: data.command,
|
|
430
|
+
stepId: getResourceAiAccessTestStepId({
|
|
431
|
+
commandNumber: 1,
|
|
432
|
+
userId: data.userId,
|
|
433
|
+
}),
|
|
434
|
+
});
|
|
435
|
+
return { outcome };
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
return { error };
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
finally {
|
|
442
|
+
await releaseUserLock(userLock);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
function describeFailure(error) {
|
|
446
|
+
if (error === undefined || error === null) {
|
|
447
|
+
return "The command could not be started.";
|
|
448
|
+
}
|
|
449
|
+
return error instanceof Error ? error.message : String(error);
|
|
450
|
+
}
|
|
451
|
+
/*
|
|
452
|
+
* The gap that stops the access test before anything is enqueued: one that
|
|
453
|
+
* blocks both capabilities and is about the transport — no agent, or an
|
|
454
|
+
* offline one — never one about the project's AI.
|
|
455
|
+
*/
|
|
456
|
+
export function getAccessTestTransportGap(status) {
|
|
457
|
+
return status.gaps.find((gap) => {
|
|
458
|
+
return (gap.blocksInvestigation &&
|
|
459
|
+
gap.blocksRemediation &&
|
|
460
|
+
!NON_TRANSPORT_GAP_CODES.includes(gap.code));
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
router.post(RESOURCE_AI_ACCESS_STATUS_PATH, UserMiddleware.getUserMiddleware, async (req, res, next) => {
|
|
464
|
+
try {
|
|
465
|
+
const props = await getLoggedInProps(req);
|
|
466
|
+
const tenantId = CommonAPI.assertTenantScoped(props);
|
|
467
|
+
const resource = await findAccessibleResource({
|
|
468
|
+
req,
|
|
469
|
+
props,
|
|
470
|
+
tenantId,
|
|
471
|
+
});
|
|
472
|
+
const status = await getStatus({
|
|
473
|
+
projectId: tenantId,
|
|
474
|
+
resource,
|
|
475
|
+
});
|
|
476
|
+
Response.sendJsonObjectResponse(req, res, status);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
catch (err) {
|
|
480
|
+
next(err);
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
router.post(RESOURCE_AI_ACCESS_TEST_PATH, UserMiddleware.getUserMiddleware, async (req, res, next) => {
|
|
485
|
+
var _a, _b;
|
|
486
|
+
try {
|
|
487
|
+
const props = await getLoggedInProps(req);
|
|
488
|
+
const tenantId = CommonAPI.assertTenantScoped(props);
|
|
489
|
+
const resource = await findAccessibleResource({
|
|
490
|
+
req,
|
|
491
|
+
props,
|
|
492
|
+
tenantId,
|
|
493
|
+
});
|
|
494
|
+
await assertCanEditResource({
|
|
495
|
+
props,
|
|
496
|
+
projectId: tenantId,
|
|
497
|
+
resource,
|
|
498
|
+
});
|
|
499
|
+
const agentName = getResourceAgentName(resource.resourceType);
|
|
500
|
+
// One test at a time per resource: an atomic reservation, held to the end.
|
|
501
|
+
const reservation = await reserveResourceForAccessTest(resource);
|
|
502
|
+
try {
|
|
503
|
+
await assertResourceAccessTestMayRun({
|
|
504
|
+
projectId: tenantId,
|
|
505
|
+
resource,
|
|
506
|
+
});
|
|
507
|
+
const status = await getStatus({
|
|
508
|
+
projectId: tenantId,
|
|
509
|
+
resource,
|
|
510
|
+
});
|
|
511
|
+
/*
|
|
512
|
+
* The test needs a reachable agent, not the investigation switch:
|
|
513
|
+
* an operator checks access BEFORE turning AI on. Only gaps that
|
|
514
|
+
* block the transport itself stop it — never one about the
|
|
515
|
+
* project's AI (the test runs the agent's commands, not a model).
|
|
516
|
+
*/
|
|
517
|
+
const transportGap = getAccessTestTransportGap(status);
|
|
518
|
+
if (transportGap || !status.agent || !status.agent.isOnline) {
|
|
519
|
+
Response.sendJsonObjectResponse(req, res, {
|
|
520
|
+
ok: false,
|
|
521
|
+
message: transportGap
|
|
522
|
+
? `${transportGap.title}. ${transportGap.nextStep}`
|
|
523
|
+
: status.agent
|
|
524
|
+
? `The ${agentName} is offline. Check that its container is running and can reach your OneUptime URL.`
|
|
525
|
+
: `Nothing can reach this ${getResourceSentenceName(resource.resourceType)} yet: install the ${agentName}.`,
|
|
526
|
+
results: [],
|
|
527
|
+
status: status,
|
|
528
|
+
});
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const agentId = new ObjectID(status.agent.agentId);
|
|
532
|
+
const commands = AI_RESOURCE_TYPE_INFO[resource.resourceType].testCommands;
|
|
533
|
+
const results = [];
|
|
534
|
+
let allSucceeded = true;
|
|
535
|
+
const start = await startAccessTest({
|
|
536
|
+
projectId: tenantId,
|
|
537
|
+
resource,
|
|
538
|
+
userId: props.userId,
|
|
539
|
+
agentId,
|
|
540
|
+
command: commands[0],
|
|
541
|
+
});
|
|
542
|
+
for (let index = 0; index < commands.length; index++) {
|
|
543
|
+
const command = commands[index];
|
|
544
|
+
let failure = undefined;
|
|
545
|
+
let outcome = undefined;
|
|
546
|
+
if (index === 0) {
|
|
547
|
+
outcome = start.outcome;
|
|
548
|
+
failure = start.error;
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
try {
|
|
552
|
+
outcome = await runAccessTestCommand({
|
|
553
|
+
projectId: tenantId,
|
|
554
|
+
resource,
|
|
555
|
+
agentId,
|
|
556
|
+
command,
|
|
557
|
+
stepId: getResourceAiAccessTestStepId({
|
|
558
|
+
commandNumber: index + 1,
|
|
559
|
+
userId: props.userId,
|
|
560
|
+
}),
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
catch (error) {
|
|
564
|
+
failure = error;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (!outcome) {
|
|
568
|
+
allSucceeded = false;
|
|
569
|
+
results.push({
|
|
570
|
+
command,
|
|
571
|
+
succeeded: false,
|
|
572
|
+
exitCode: null,
|
|
573
|
+
output: "",
|
|
574
|
+
errorMessage: describeFailure(failure),
|
|
575
|
+
});
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
578
|
+
allSucceeded = allSucceeded && outcome.succeeded;
|
|
579
|
+
results.push({
|
|
580
|
+
command: outcome.displayCommand || command,
|
|
581
|
+
succeeded: outcome.succeeded,
|
|
582
|
+
exitCode: (_a = outcome.exitCode) !== null && _a !== void 0 ? _a : null,
|
|
583
|
+
output: outcome.output,
|
|
584
|
+
errorMessage: (_b = outcome.errorMessage) !== null && _b !== void 0 ? _b : null,
|
|
585
|
+
});
|
|
586
|
+
if (!outcome.succeeded) {
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
const refreshed = await ResourceAiAccessService.getStatusForResource({
|
|
591
|
+
projectId: tenantId,
|
|
592
|
+
resourceType: resource.resourceType,
|
|
593
|
+
resourceId: resource.id,
|
|
594
|
+
});
|
|
595
|
+
Response.sendJsonObjectResponse(req, res, {
|
|
596
|
+
ok: allSucceeded,
|
|
597
|
+
message: allSucceeded
|
|
598
|
+
? `OneUptime AI can run commands on "${resource.name}" through the ${agentName}.`
|
|
599
|
+
: `The ${agentName} could not run the test commands successfully — see the command output below.`,
|
|
600
|
+
results: results,
|
|
601
|
+
status: (refreshed || status),
|
|
602
|
+
});
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
finally {
|
|
606
|
+
await releaseResourceReservation({
|
|
607
|
+
resource,
|
|
608
|
+
token: reservation,
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
catch (err) {
|
|
613
|
+
next(err);
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
router.post(RESOURCE_AI_ACCESS_RESET_AGENT_PATH, UserMiddleware.getUserMiddleware, async (req, res, next) => {
|
|
618
|
+
try {
|
|
619
|
+
const props = await getLoggedInProps(req);
|
|
620
|
+
const tenantId = CommonAPI.assertTenantScoped(props);
|
|
621
|
+
const resource = await findAccessibleResource({
|
|
622
|
+
req,
|
|
623
|
+
props,
|
|
624
|
+
tenantId,
|
|
625
|
+
});
|
|
626
|
+
assertCanResetAiAgent({
|
|
627
|
+
props,
|
|
628
|
+
projectId: tenantId,
|
|
629
|
+
resourceType: resource.resourceType,
|
|
630
|
+
});
|
|
631
|
+
const agentName = getResourceAgentName(resource.resourceType);
|
|
632
|
+
const agent = await ResourceAiAgentService.findAgentForResource({
|
|
633
|
+
projectId: tenantId,
|
|
634
|
+
resourceType: resource.resourceType,
|
|
635
|
+
resourceId: resource.id,
|
|
636
|
+
});
|
|
637
|
+
if (!agent) {
|
|
638
|
+
throw new BadDataException(`This ${getResourceSentenceName(resource.resourceType)} has no ${agentName} to reset.`);
|
|
639
|
+
}
|
|
640
|
+
await ResourceAiAgentService.resetAgent({
|
|
641
|
+
projectId: tenantId,
|
|
642
|
+
resourceType: resource.resourceType,
|
|
643
|
+
resourceId: resource.id,
|
|
644
|
+
userId: props.userId,
|
|
645
|
+
});
|
|
646
|
+
const status = await ResourceAiAccessService.getStatusForResource({
|
|
647
|
+
projectId: tenantId,
|
|
648
|
+
resourceType: resource.resourceType,
|
|
649
|
+
resourceId: resource.id,
|
|
650
|
+
});
|
|
651
|
+
Response.sendJsonObjectResponse(req, res, Object.assign({ ok: true, message: `The ${agentName} was reset. It reconnects on its own within a few minutes.` }, (status ? { status: status } : {})));
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
catch (err) {
|
|
655
|
+
next(err);
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
/*
|
|
660
|
+
* How many of the resource's newest agent jobs the insights read to find
|
|
661
|
+
* the AI runs and suggestions that ran commands on it. Each AI run runs at
|
|
662
|
+
* most a handful, so this reaches well past the newest 25 of either.
|
|
663
|
+
*/
|
|
664
|
+
const INSIGHTS_JOB_SCAN_LIMIT = 500;
|
|
665
|
+
// How many incidents and alerts linked to the resource the insights read.
|
|
666
|
+
const INSIGHTS_LINKED_SUBJECT_LIMIT = 200;
|
|
667
|
+
function toIsoString(date) {
|
|
668
|
+
return date ? OneUptimeDate.toString(date) : undefined;
|
|
669
|
+
}
|
|
670
|
+
function newestFirst(rows) {
|
|
671
|
+
return rows.sort((a, b) => {
|
|
672
|
+
return ((b.createdAt ? new Date(b.createdAt).getTime() : 0) -
|
|
673
|
+
(a.createdAt ? new Date(a.createdAt).getTime() : 0));
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
/*
|
|
677
|
+
* The union of several newest-first reads: one row per id, newest first,
|
|
678
|
+
* at most `limit` of them (all of them without one).
|
|
679
|
+
*/
|
|
680
|
+
function mergeNewest(groups, limit) {
|
|
681
|
+
var _a;
|
|
682
|
+
const byId = new Map();
|
|
683
|
+
for (const rows of groups) {
|
|
684
|
+
for (const row of rows) {
|
|
685
|
+
const id = (_a = row.id) === null || _a === void 0 ? void 0 : _a.toString();
|
|
686
|
+
if (id && !byId.has(id)) {
|
|
687
|
+
byId.set(id, row);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
return newestFirst(Array.from(byId.values())).slice(0, limit);
|
|
692
|
+
}
|
|
693
|
+
function getIds(rows) {
|
|
694
|
+
return rows
|
|
695
|
+
.map((row) => {
|
|
696
|
+
return row.id || undefined;
|
|
697
|
+
})
|
|
698
|
+
.filter((id) => {
|
|
699
|
+
return Boolean(id);
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
function getUniqueIds(ids) {
|
|
703
|
+
const byId = new Map();
|
|
704
|
+
for (const id of ids) {
|
|
705
|
+
if (id) {
|
|
706
|
+
byId.set(id.toString(), id);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return Array.from(byId.values());
|
|
710
|
+
}
|
|
711
|
+
/*
|
|
712
|
+
* A read made under the caller's own props, which the permission layer
|
|
713
|
+
* refuses outright for a role that cannot read the table at all (a
|
|
714
|
+
* ReadDockerHost-only role reading Incident): that caller gets nothing from
|
|
715
|
+
* it, the same as a caller whose labels or private-incident membership
|
|
716
|
+
* leave no row readable.
|
|
717
|
+
*/
|
|
718
|
+
async function readIfPermitted(read) {
|
|
719
|
+
try {
|
|
720
|
+
return await read();
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
if (error instanceof NotAuthorizedException) {
|
|
724
|
+
return [];
|
|
725
|
+
}
|
|
726
|
+
throw error;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
/*
|
|
730
|
+
* What OneUptime AI investigated and changed on one resource, as summaries
|
|
731
|
+
* (ResourceAiInsights). The caller has already been checked for read
|
|
732
|
+
* access to the resource (findAccessibleResource), which is a wider
|
|
733
|
+
* audience than the incidents, alerts, AI runs and suggestions summarised
|
|
734
|
+
* here, so what is said about THOSE follows the caller's own read access to
|
|
735
|
+
* them:
|
|
736
|
+
*
|
|
737
|
+
* - incidents and alerts are read under the caller's props (tenant, labels,
|
|
738
|
+
* private incidents), both to find the ones linked to the resource and to
|
|
739
|
+
* name a run's subject; an investigation whose incident or alert the
|
|
740
|
+
* caller cannot read is left out altogether;
|
|
741
|
+
* - an investigation's TL;DR is shown with its readable incident or alert —
|
|
742
|
+
* the incident's and alert's own AI investigation panel shows the whole
|
|
743
|
+
* analysis to anyone who may read the subject — and, for a run with
|
|
744
|
+
* neither (an AI insight's triage), only to a caller who may read AIRun;
|
|
745
|
+
* - a fix's rationale is read under the caller's props, so only a caller who
|
|
746
|
+
* may read that AutoRemediationSuggestion (its ACL and its incident's or
|
|
747
|
+
* alert's privacy) gets it.
|
|
748
|
+
*
|
|
749
|
+
* The rest — which AI runs and suggestions touched the resource, their
|
|
750
|
+
* status and dates, the command counts — is about the resource itself and
|
|
751
|
+
* is read as root: AI runs, suggestions and agent jobs have narrower read
|
|
752
|
+
* ACLs of their own (an investigation run is private to its author), so
|
|
753
|
+
* reading them under the caller's props would empty the page for exactly
|
|
754
|
+
* the people it is for. Nothing here returns command output, prompts or
|
|
755
|
+
* command plans.
|
|
756
|
+
*
|
|
757
|
+
* - investigations: AI investigations that ran a command on this resource
|
|
758
|
+
* (their RunnerJob rows name it), UNION investigations of incidents and
|
|
759
|
+
* alerts linked to it — which also covers one whose access was not set
|
|
760
|
+
* up, so it never ran a command. Newest first, at most
|
|
761
|
+
* RESOURCE_AI_INSIGHTS_LIMIT.
|
|
762
|
+
* - fixes: suggestions the resource's own AI remediation setting produced
|
|
763
|
+
* (AutoRemediationSuggestion.resourceType / resourceId), UNION any
|
|
764
|
+
* suggestion whose commands ran on this resource (a rule's round, too).
|
|
765
|
+
* Newest first, same limit.
|
|
766
|
+
* - commandCounts: commands in the last
|
|
767
|
+
* RESOURCE_AI_INSIGHTS_COMMAND_WINDOW_IN_DAYS days. The AI agent page's
|
|
768
|
+
* connection tests have no AI run behind them and are not counted.
|
|
769
|
+
*/
|
|
770
|
+
export async function getResourceAiInsights(data) {
|
|
771
|
+
const { projectId, resourceType, resourceId, props } = data;
|
|
772
|
+
const limit = RESOURCE_AI_INSIGHTS_LIMIT;
|
|
773
|
+
const subjectRelation = RESOURCE_AI_ACCESS_KINDS[resourceType].subjectRelation;
|
|
774
|
+
const jobs = await RunnerJobService.findBy({
|
|
775
|
+
query: {
|
|
776
|
+
projectId,
|
|
777
|
+
resourceType,
|
|
778
|
+
resourceId,
|
|
779
|
+
stepType: RunbookStepType.ResourceCommand,
|
|
780
|
+
},
|
|
781
|
+
select: { _id: true, aiRunId: true, autoRemediationSuggestionId: true },
|
|
782
|
+
sort: { createdAt: SortOrder.Descending },
|
|
783
|
+
limit: INSIGHTS_JOB_SCAN_LIMIT,
|
|
784
|
+
skip: 0,
|
|
785
|
+
props: { isRoot: true },
|
|
786
|
+
});
|
|
787
|
+
const runIdsFromJobs = new Map();
|
|
788
|
+
const suggestionIdsFromJobs = new Map();
|
|
789
|
+
for (const job of jobs) {
|
|
790
|
+
if (job.aiRunId) {
|
|
791
|
+
runIdsFromJobs.set(job.aiRunId.toString(), job.aiRunId);
|
|
792
|
+
}
|
|
793
|
+
if (job.autoRemediationSuggestionId) {
|
|
794
|
+
suggestionIdsFromJobs.set(job.autoRemediationSuggestionId.toString(), job.autoRemediationSuggestionId);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
// Only the incidents and alerts the caller may read (see above).
|
|
798
|
+
const [linkedIncidents, linkedAlerts] = await Promise.all([
|
|
799
|
+
readIfPermitted(() => {
|
|
800
|
+
return IncidentService.findBy({
|
|
801
|
+
query: {
|
|
802
|
+
projectId,
|
|
803
|
+
[subjectRelation]: QueryHelper.inRelationArray([resourceId]),
|
|
804
|
+
},
|
|
805
|
+
select: { _id: true },
|
|
806
|
+
sort: { createdAt: SortOrder.Descending },
|
|
807
|
+
limit: INSIGHTS_LINKED_SUBJECT_LIMIT,
|
|
808
|
+
skip: 0,
|
|
809
|
+
props,
|
|
810
|
+
});
|
|
811
|
+
}),
|
|
812
|
+
readIfPermitted(() => {
|
|
813
|
+
return AlertService.findBy({
|
|
814
|
+
query: {
|
|
815
|
+
projectId,
|
|
816
|
+
[subjectRelation]: QueryHelper.inRelationArray([resourceId]),
|
|
817
|
+
},
|
|
818
|
+
select: { _id: true },
|
|
819
|
+
sort: { createdAt: SortOrder.Descending },
|
|
820
|
+
limit: INSIGHTS_LINKED_SUBJECT_LIMIT,
|
|
821
|
+
skip: 0,
|
|
822
|
+
props,
|
|
823
|
+
});
|
|
824
|
+
}),
|
|
825
|
+
]);
|
|
826
|
+
const investigations = await getInsightInvestigations({
|
|
827
|
+
projectId,
|
|
828
|
+
props,
|
|
829
|
+
runIds: Array.from(runIdsFromJobs.values()),
|
|
830
|
+
incidentIds: getIds(linkedIncidents),
|
|
831
|
+
alertIds: getIds(linkedAlerts),
|
|
832
|
+
limit,
|
|
833
|
+
});
|
|
834
|
+
const fixes = await getInsightFixes({
|
|
835
|
+
projectId,
|
|
836
|
+
props,
|
|
837
|
+
resourceType,
|
|
838
|
+
resourceId,
|
|
839
|
+
suggestionIds: Array.from(suggestionIdsFromJobs.values()),
|
|
840
|
+
limit,
|
|
841
|
+
});
|
|
842
|
+
const since = OneUptimeDate.getSomeDaysAgo(RESOURCE_AI_INSIGHTS_COMMAND_WINDOW_IN_DAYS);
|
|
843
|
+
const countCommands = async (query) => {
|
|
844
|
+
return (await RunnerJobService.countBy({
|
|
845
|
+
query: Object.assign(Object.assign({}, query), { projectId,
|
|
846
|
+
resourceType,
|
|
847
|
+
resourceId, stepType: RunbookStepType.ResourceCommand, createdAt: QueryHelper.greaterThan(since) }),
|
|
848
|
+
props: { isRoot: true },
|
|
849
|
+
})).toNumber();
|
|
850
|
+
};
|
|
851
|
+
const [investigationCommands, remediationCommands] = await Promise.all([
|
|
852
|
+
countCommands({
|
|
853
|
+
origin: RunnerJobOrigin.AiInvestigation,
|
|
854
|
+
// Connection tests have no AI run; every investigation command does.
|
|
855
|
+
aiRunId: QueryHelper.notNull(),
|
|
856
|
+
}),
|
|
857
|
+
countCommands({ origin: RunnerJobOrigin.AiRemediation }),
|
|
858
|
+
]);
|
|
859
|
+
return {
|
|
860
|
+
resourceType,
|
|
861
|
+
resourceId: resourceId.toString(),
|
|
862
|
+
investigations,
|
|
863
|
+
fixes,
|
|
864
|
+
commandCounts: {
|
|
865
|
+
investigation: investigationCommands,
|
|
866
|
+
remediation: remediationCommands,
|
|
867
|
+
},
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
const INSIGHT_RUN_SELECT = {
|
|
871
|
+
_id: true,
|
|
872
|
+
status: true,
|
|
873
|
+
analysisTldr: true,
|
|
874
|
+
createdAt: true,
|
|
875
|
+
completedAt: true,
|
|
876
|
+
triggeredByIncidentId: true,
|
|
877
|
+
triggeredByAlertId: true,
|
|
878
|
+
};
|
|
879
|
+
/*
|
|
880
|
+
* Who may read the TL;DR of a run that has no incident or alert to decide
|
|
881
|
+
* it: the people who may read that column of AIRun.
|
|
882
|
+
*/
|
|
883
|
+
function getSubjectlessRunTldrReadPermissions() {
|
|
884
|
+
var _a;
|
|
885
|
+
return ((_a = new AIRun().getColumnAccessControlFor("analysisTldr")) === null || _a === void 0 ? void 0 : _a.read) || [];
|
|
886
|
+
}
|
|
887
|
+
async function getInsightInvestigations(data) {
|
|
888
|
+
const reads = [];
|
|
889
|
+
const readRuns = (query) => {
|
|
890
|
+
return AIRunService.findBy({
|
|
891
|
+
query: Object.assign(Object.assign({}, query), { projectId: data.projectId, runType: AIRunType.Investigation }),
|
|
892
|
+
select: INSIGHT_RUN_SELECT,
|
|
893
|
+
sort: { createdAt: SortOrder.Descending },
|
|
894
|
+
limit: data.limit,
|
|
895
|
+
skip: 0,
|
|
896
|
+
props: { isRoot: true },
|
|
897
|
+
});
|
|
898
|
+
};
|
|
899
|
+
if (data.runIds.length > 0) {
|
|
900
|
+
reads.push(readRuns({ _id: QueryHelper.any(data.runIds) }));
|
|
901
|
+
}
|
|
902
|
+
if (data.incidentIds.length > 0) {
|
|
903
|
+
reads.push(readRuns({ triggeredByIncidentId: QueryHelper.any(data.incidentIds) }));
|
|
904
|
+
}
|
|
905
|
+
if (data.alertIds.length > 0) {
|
|
906
|
+
reads.push(readRuns({ triggeredByAlertId: QueryHelper.any(data.alertIds) }));
|
|
907
|
+
}
|
|
908
|
+
if (reads.length === 0) {
|
|
909
|
+
return [];
|
|
910
|
+
}
|
|
911
|
+
// Every candidate, newest first: the limit applies after the subject check.
|
|
912
|
+
const candidates = mergeNewest(await Promise.all(reads));
|
|
913
|
+
const incidentIds = getUniqueIds(candidates.map((run) => {
|
|
914
|
+
return run.triggeredByIncidentId;
|
|
915
|
+
}));
|
|
916
|
+
const alertIds = getUniqueIds(candidates.map((run) => {
|
|
917
|
+
return run.triggeredByAlertId;
|
|
918
|
+
}));
|
|
919
|
+
/*
|
|
920
|
+
* The subjects under the CALLER's props: tenant, labels and private
|
|
921
|
+
* incidents apply exactly as on a CRUD read, and a role that may not read
|
|
922
|
+
* incidents (or alerts) at all reads none.
|
|
923
|
+
*/
|
|
924
|
+
const [incidents, alerts] = await Promise.all([
|
|
925
|
+
incidentIds.length > 0
|
|
926
|
+
? readIfPermitted(() => {
|
|
927
|
+
return IncidentService.findBy({
|
|
928
|
+
query: {
|
|
929
|
+
projectId: data.projectId,
|
|
930
|
+
_id: QueryHelper.any(incidentIds),
|
|
931
|
+
},
|
|
932
|
+
select: { _id: true, title: true, incidentNumber: true },
|
|
933
|
+
limit: incidentIds.length,
|
|
934
|
+
skip: 0,
|
|
935
|
+
props: data.props,
|
|
936
|
+
});
|
|
937
|
+
})
|
|
938
|
+
: Promise.resolve([]),
|
|
939
|
+
alertIds.length > 0
|
|
940
|
+
? readIfPermitted(() => {
|
|
941
|
+
return AlertService.findBy({
|
|
942
|
+
query: {
|
|
943
|
+
projectId: data.projectId,
|
|
944
|
+
_id: QueryHelper.any(alertIds),
|
|
945
|
+
},
|
|
946
|
+
select: { _id: true, title: true },
|
|
947
|
+
limit: alertIds.length,
|
|
948
|
+
skip: 0,
|
|
949
|
+
props: data.props,
|
|
950
|
+
});
|
|
951
|
+
})
|
|
952
|
+
: Promise.resolve([]),
|
|
953
|
+
]);
|
|
954
|
+
const incidentsById = new Map(incidents.map((incident) => {
|
|
955
|
+
var _a;
|
|
956
|
+
return [((_a = incident.id) === null || _a === void 0 ? void 0 : _a.toString()) || "", incident];
|
|
957
|
+
}));
|
|
958
|
+
const alertsById = new Map(alerts.map((alert) => {
|
|
959
|
+
var _a;
|
|
960
|
+
return [((_a = alert.id) === null || _a === void 0 ? void 0 : _a.toString()) || "", alert];
|
|
961
|
+
}));
|
|
962
|
+
// A run whose incident or alert the caller cannot read is left out.
|
|
963
|
+
const runs = candidates
|
|
964
|
+
.filter((run) => {
|
|
965
|
+
if (run.triggeredByIncidentId &&
|
|
966
|
+
!incidentsById.has(run.triggeredByIncidentId.toString())) {
|
|
967
|
+
return false;
|
|
968
|
+
}
|
|
969
|
+
if (run.triggeredByAlertId &&
|
|
970
|
+
!alertsById.has(run.triggeredByAlertId.toString())) {
|
|
971
|
+
return false;
|
|
972
|
+
}
|
|
973
|
+
return true;
|
|
974
|
+
})
|
|
975
|
+
.slice(0, data.limit);
|
|
976
|
+
const mayReadSubjectlessTldr = holdsAnyUnblockedPermission({
|
|
977
|
+
props: data.props,
|
|
978
|
+
projectId: data.projectId,
|
|
979
|
+
allowed: getSubjectlessRunTldrReadPermissions(),
|
|
980
|
+
});
|
|
981
|
+
return runs.map((run) => {
|
|
982
|
+
const incident = run.triggeredByIncidentId
|
|
983
|
+
? incidentsById.get(run.triggeredByIncidentId.toString())
|
|
984
|
+
: undefined;
|
|
985
|
+
const alert = run.triggeredByAlertId
|
|
986
|
+
? alertsById.get(run.triggeredByAlertId.toString())
|
|
987
|
+
: undefined;
|
|
988
|
+
/*
|
|
989
|
+
* Every run left here with a subject has a subject the caller may read,
|
|
990
|
+
* and the subject's own AI panel shows its analysis to them.
|
|
991
|
+
*/
|
|
992
|
+
const mayReadTldr = Boolean(run.triggeredByIncidentId || run.triggeredByAlertId) ||
|
|
993
|
+
mayReadSubjectlessTldr;
|
|
994
|
+
return {
|
|
995
|
+
aiRunId: run.id.toString(),
|
|
996
|
+
status: run.status,
|
|
997
|
+
analysisTldr: mayReadTldr ? run.analysisTldr || undefined : undefined,
|
|
998
|
+
createdAt: toIsoString(run.createdAt),
|
|
999
|
+
completedAt: toIsoString(run.completedAt),
|
|
1000
|
+
incident: run.triggeredByIncidentId
|
|
1001
|
+
? {
|
|
1002
|
+
id: run.triggeredByIncidentId.toString(),
|
|
1003
|
+
title: incident === null || incident === void 0 ? void 0 : incident.title,
|
|
1004
|
+
number: incident === null || incident === void 0 ? void 0 : incident.incidentNumber,
|
|
1005
|
+
}
|
|
1006
|
+
: undefined,
|
|
1007
|
+
alert: run.triggeredByAlertId
|
|
1008
|
+
? {
|
|
1009
|
+
id: run.triggeredByAlertId.toString(),
|
|
1010
|
+
title: alert === null || alert === void 0 ? void 0 : alert.title,
|
|
1011
|
+
}
|
|
1012
|
+
: undefined,
|
|
1013
|
+
};
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
/*
|
|
1017
|
+
* Read as root, so never the rationale: that is read under the caller's
|
|
1018
|
+
* props (getInsightFixes).
|
|
1019
|
+
*/
|
|
1020
|
+
const INSIGHT_FIX_SELECT = {
|
|
1021
|
+
_id: true,
|
|
1022
|
+
status: true,
|
|
1023
|
+
executionMode: true,
|
|
1024
|
+
suggestionType: true,
|
|
1025
|
+
createdAt: true,
|
|
1026
|
+
approvedAt: true,
|
|
1027
|
+
incidentId: true,
|
|
1028
|
+
alertId: true,
|
|
1029
|
+
};
|
|
1030
|
+
async function getInsightFixes(data) {
|
|
1031
|
+
const readSuggestions = (query) => {
|
|
1032
|
+
return AutoRemediationSuggestionService.findBy({
|
|
1033
|
+
query: Object.assign(Object.assign({}, query), { projectId: data.projectId }),
|
|
1034
|
+
select: INSIGHT_FIX_SELECT,
|
|
1035
|
+
sort: { createdAt: SortOrder.Descending },
|
|
1036
|
+
limit: data.limit,
|
|
1037
|
+
skip: 0,
|
|
1038
|
+
props: { isRoot: true },
|
|
1039
|
+
});
|
|
1040
|
+
};
|
|
1041
|
+
const reads = [
|
|
1042
|
+
readSuggestions({
|
|
1043
|
+
resourceType: data.resourceType,
|
|
1044
|
+
resourceId: data.resourceId,
|
|
1045
|
+
}),
|
|
1046
|
+
];
|
|
1047
|
+
if (data.suggestionIds.length > 0) {
|
|
1048
|
+
reads.push(readSuggestions({ _id: QueryHelper.any(data.suggestionIds) }));
|
|
1049
|
+
}
|
|
1050
|
+
const suggestions = mergeNewest(await Promise.all(reads), data.limit);
|
|
1051
|
+
const ids = getIds(suggestions);
|
|
1052
|
+
/*
|
|
1053
|
+
* The rationale quotes the AI's analysis of the incident or alert, so it
|
|
1054
|
+
* is read under the CALLER's props: the suggestion's read ACL and its
|
|
1055
|
+
* subject's privacy decide it, as on a CRUD read.
|
|
1056
|
+
*/
|
|
1057
|
+
const readable = ids.length > 0
|
|
1058
|
+
? await readIfPermitted(() => {
|
|
1059
|
+
return AutoRemediationSuggestionService.findBy({
|
|
1060
|
+
query: {
|
|
1061
|
+
projectId: data.projectId,
|
|
1062
|
+
_id: QueryHelper.any(ids),
|
|
1063
|
+
},
|
|
1064
|
+
select: { _id: true, rationaleMarkdown: true },
|
|
1065
|
+
limit: ids.length,
|
|
1066
|
+
skip: 0,
|
|
1067
|
+
props: data.props,
|
|
1068
|
+
});
|
|
1069
|
+
})
|
|
1070
|
+
: [];
|
|
1071
|
+
const rationaleById = new Map();
|
|
1072
|
+
for (const suggestion of readable) {
|
|
1073
|
+
if (suggestion.id && suggestion.rationaleMarkdown) {
|
|
1074
|
+
rationaleById.set(suggestion.id.toString(), suggestion.rationaleMarkdown);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
return suggestions.map((suggestion) => {
|
|
1078
|
+
var _a, _b;
|
|
1079
|
+
const rationale = rationaleById.get(suggestion.id.toString());
|
|
1080
|
+
return {
|
|
1081
|
+
id: suggestion.id.toString(),
|
|
1082
|
+
status: suggestion.status,
|
|
1083
|
+
executionMode: suggestion.executionMode,
|
|
1084
|
+
suggestionType: suggestion.suggestionType,
|
|
1085
|
+
rationale: rationale
|
|
1086
|
+
? rationale.slice(0, RESOURCE_AI_INSIGHTS_RATIONALE_MAX_LENGTH)
|
|
1087
|
+
: undefined,
|
|
1088
|
+
createdAt: toIsoString(suggestion.createdAt),
|
|
1089
|
+
approvedAt: toIsoString(suggestion.approvedAt),
|
|
1090
|
+
incidentId: (_a = suggestion.incidentId) === null || _a === void 0 ? void 0 : _a.toString(),
|
|
1091
|
+
alertId: (_b = suggestion.alertId) === null || _b === void 0 ? void 0 : _b.toString(),
|
|
1092
|
+
};
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
router.post(RESOURCE_AI_ACCESS_INSIGHTS_PATH, UserMiddleware.getUserMiddleware, async (req, res, next) => {
|
|
1096
|
+
try {
|
|
1097
|
+
const props = await getLoggedInProps(req);
|
|
1098
|
+
const tenantId = CommonAPI.assertTenantScoped(props);
|
|
1099
|
+
const resource = await findAccessibleResource({
|
|
1100
|
+
req,
|
|
1101
|
+
props,
|
|
1102
|
+
tenantId,
|
|
1103
|
+
});
|
|
1104
|
+
const insights = await getResourceAiInsights({
|
|
1105
|
+
projectId: tenantId,
|
|
1106
|
+
resourceType: resource.resourceType,
|
|
1107
|
+
resourceId: resource.id,
|
|
1108
|
+
props,
|
|
1109
|
+
});
|
|
1110
|
+
Response.sendJsonObjectResponse(req, res, insights);
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
catch (err) {
|
|
1114
|
+
next(err);
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
export default router;
|
|
1119
|
+
//# sourceMappingURL=ResourceAiAccessAPI.js.map
|