@oneuptime/common 14.0.9 → 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 +2 -0
- package/Models/DatabaseModels/PodmanHost.ts +213 -0
- package/Models/DatabaseModels/ProxmoxCluster.ts +213 -0
- package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
- package/Models/DatabaseModels/RunnerJob.ts +144 -0
- package/Models/DatabaseModels/VMwareVCenter.ts +213 -0
- package/Server/API/AutoRemediationAPI.ts +392 -1
- package/Server/API/ResourceAiAccessAPI.ts +1669 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Infrastructure/Semaphore.ts +22 -0
- package/Server/Middleware/TelemetryIngest.ts +15 -5
- package/Server/Services/AnalyticsDatabaseService.ts +45 -1
- package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
- 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/MetricRecordingRuleService.ts +47 -0
- package/Server/Services/PodmanHostService.ts +109 -1
- package/Server/Services/ProxmoxClusterService.ts +110 -1
- 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 +611 -4
- 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/Remediation/RemediationCommandTools.ts +1434 -32
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +935 -21
- 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 +72 -2
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +72 -5
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +72 -5
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +396 -13
- 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/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 +366 -143
- 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/Dashboard/ClusterAccessNotice.test.tsx +93 -0
- package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +18 -6
- package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -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/RunbookStepTypeMaps.test.ts +38 -7
- package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +33 -1
- package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
- package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
- package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
- package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
- package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
- package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +63 -5
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +103 -5
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +19 -1
- package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
- 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/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
- 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 +105 -0
- package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
- package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
- package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
- package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
- package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -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/RemediationCommandTools.test.ts +94 -1
- package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1249 -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/CommandPlanExecutorResource.test.ts +717 -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/TelemetryIngestionKeyGuard.test.ts +33 -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/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -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/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/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
- 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/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
- package/Types/AI/ResourceAiAccessApi.ts +140 -0
- package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +183 -2
- 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/Telemetry/TelemetryIngestSurface.ts +14 -2
- package/Utils/AI/InvestigationReport.ts +121 -15
- 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/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 +2 -0
- package/build/dist/Models/DatabaseModels/Index.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/ProxmoxCluster.js +219 -0
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.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 +145 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.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/Server/API/AutoRemediationAPI.js +231 -1
- package/build/dist/Server/API/AutoRemediationAPI.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/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 +2 -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 +12 -5
- package/build/dist/Server/Middleware/TelemetryIngest.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/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/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/ProxmoxClusterService.js +104 -0
- package/build/dist/Server/Services/ProxmoxClusterService.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 +344 -5
- package/build/dist/Server/Services/RunnerJobService.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/Remediation/RemediationCommandTools.js +1029 -30
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +633 -28
- 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 +50 -4
- 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/AutoRemediation/CommandPlanExecutor.js +290 -13
- 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/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 +263 -110
- 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/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 +116 -29
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.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/Telemetry/TelemetryIngestSurface.js +13 -2
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.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/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/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import RunnerJobService, {
|
|
2
|
+
MAX_AI_COMMAND_JOBS_PER_PROJECT_PER_HOUR,
|
|
3
|
+
} from "../../../Server/Services/RunnerJobService";
|
|
4
|
+
import RunnerService from "../../../Server/Services/RunnerService";
|
|
5
|
+
import RunnerJob from "../../../Models/DatabaseModels/RunnerJob";
|
|
6
|
+
import RunbookStepType, {
|
|
7
|
+
AI_AGENT_EXECUTED_STEP_TYPES,
|
|
8
|
+
RUNNER_EXECUTED_STEP_TYPES,
|
|
9
|
+
} from "../../../Types/Runbook/RunbookStepType";
|
|
10
|
+
import { AI_COMMAND_STEP_TYPES } from "../../../Types/AutoRemediation/AiRemediationCommandPlan";
|
|
11
|
+
import RunnerJobOrigin from "../../../Types/Runbook/RunnerJobOrigin";
|
|
12
|
+
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
13
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
14
|
+
import PositiveNumber from "../../../Types/PositiveNumber";
|
|
15
|
+
import logger from "../../../Server/Utils/Logger";
|
|
16
|
+
import {
|
|
17
|
+
fakeRunnerJobCountBy,
|
|
18
|
+
fakeRunnerJobRows,
|
|
19
|
+
} from "../TestingUtils/Services/FakeRunnerJobCount";
|
|
20
|
+
import { afterEach, beforeEach, describe, expect, it } from "@jest/globals";
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Contract under test — a ResourceCommand job never reaches a Runner.
|
|
24
|
+
*
|
|
25
|
+
* ResourceCommand is the step type of a command for an infrastructure
|
|
26
|
+
* resource's AI agent (a ResourceAiAgent row). It is an AI command step type
|
|
27
|
+
* (AI_COMMAND_STEP_TYPES), so the generic AI-command lane must refuse it
|
|
28
|
+
* explicitly: that lane writes targetAgentId — a Runner — and a Runner
|
|
29
|
+
* must never be handed a resource command. The runbook lane (enqueue)
|
|
30
|
+
* refuses it because it is not a runner-executed type. Both refusals happen
|
|
31
|
+
* before any row is written.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
const PROJECT_ID: ObjectID = new ObjectID(
|
|
35
|
+
"22222222-2222-4222-8222-222222222222",
|
|
36
|
+
);
|
|
37
|
+
const RUNNER_ID: ObjectID = new ObjectID(
|
|
38
|
+
"44444444-4444-4444-8444-444444444444",
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
describe("ResourceCommand never enters a Runner lane", () => {
|
|
42
|
+
let create: jest.SpyInstance;
|
|
43
|
+
let runnerLookup: jest.SpyInstance;
|
|
44
|
+
let countBy: jest.SpyInstance;
|
|
45
|
+
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
// @CaptureSpan logs the expected throws at error level.
|
|
48
|
+
jest.spyOn(logger, "error").mockImplementation((): void => {
|
|
49
|
+
return undefined;
|
|
50
|
+
});
|
|
51
|
+
create = jest
|
|
52
|
+
.spyOn(RunnerJobService, "create")
|
|
53
|
+
.mockImplementation(async (data: unknown): Promise<RunnerJob> => {
|
|
54
|
+
return (data as { data: RunnerJob }).data;
|
|
55
|
+
});
|
|
56
|
+
runnerLookup = jest.spyOn(RunnerService, "findOneBy").mockResolvedValue({
|
|
57
|
+
id: RUNNER_ID,
|
|
58
|
+
_id: RUNNER_ID.toString(),
|
|
59
|
+
projectId: PROJECT_ID,
|
|
60
|
+
name: "office-runner",
|
|
61
|
+
} as never);
|
|
62
|
+
countBy = jest
|
|
63
|
+
.spyOn(RunnerJobService, "countBy")
|
|
64
|
+
.mockResolvedValue(new PositiveNumber(0));
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
afterEach(() => {
|
|
68
|
+
jest.restoreAllMocks();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("is an AI command step type but not a Runner-executed one", () => {
|
|
72
|
+
expect(AI_COMMAND_STEP_TYPES).toContain(RunbookStepType.ResourceCommand);
|
|
73
|
+
expect(AI_AGENT_EXECUTED_STEP_TYPES).toContain(
|
|
74
|
+
RunbookStepType.ResourceCommand,
|
|
75
|
+
);
|
|
76
|
+
expect(RUNNER_EXECUTED_STEP_TYPES).not.toContain(
|
|
77
|
+
RunbookStepType.ResourceCommand,
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("enqueue (the runbook lane) refuses it before writing a row", async () => {
|
|
82
|
+
await expect(
|
|
83
|
+
RunnerJobService.enqueue({
|
|
84
|
+
projectId: PROJECT_ID,
|
|
85
|
+
runbookExecutionId: new ObjectID(
|
|
86
|
+
"33333333-3333-4333-8333-333333333333",
|
|
87
|
+
),
|
|
88
|
+
stepId: "step-1",
|
|
89
|
+
stepType: RunbookStepType.ResourceCommand,
|
|
90
|
+
targetAgentId: RUNNER_ID,
|
|
91
|
+
script: "",
|
|
92
|
+
payload: { program: "docker", args: ["ps"] },
|
|
93
|
+
timeoutInMs: 30000,
|
|
94
|
+
}),
|
|
95
|
+
).rejects.toThrow(
|
|
96
|
+
new BadDataException(
|
|
97
|
+
'Runner does not execute step type "ResourceCommand".',
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
expect(create).not.toHaveBeenCalled();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("enqueueAiCommand (the Runner AI-command lane) refuses it before looking anything up", async () => {
|
|
105
|
+
let caught: unknown = null;
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
await RunnerJobService.enqueueAiCommand({
|
|
109
|
+
projectId: PROJECT_ID,
|
|
110
|
+
aiRunId: new ObjectID("88888888-8888-4888-8888-888888888888"),
|
|
111
|
+
autoRemediationSuggestionId: new ObjectID(
|
|
112
|
+
"77777777-7777-4777-8777-777777777777",
|
|
113
|
+
),
|
|
114
|
+
stepId: "ai-approved-1",
|
|
115
|
+
stepType: RunbookStepType.ResourceCommand,
|
|
116
|
+
targetAgentId: RUNNER_ID,
|
|
117
|
+
command: "docker restart web",
|
|
118
|
+
timeoutInMs: 30000,
|
|
119
|
+
});
|
|
120
|
+
} catch (err) {
|
|
121
|
+
caught = err;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
expect(caught).toBeInstanceOf(BadDataException);
|
|
125
|
+
expect((caught as Error).message).toContain("never on a Runner");
|
|
126
|
+
expect((caught as Error).message).toContain("enqueueAiResourceCommand");
|
|
127
|
+
expect(runnerLookup).not.toHaveBeenCalled();
|
|
128
|
+
expect(countBy).not.toHaveBeenCalled();
|
|
129
|
+
expect(create).not.toHaveBeenCalled();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("negative control: a Bash command still goes through the same lane", async () => {
|
|
133
|
+
await RunnerJobService.enqueueAiCommand({
|
|
134
|
+
projectId: PROJECT_ID,
|
|
135
|
+
aiRunId: new ObjectID("88888888-8888-4888-8888-888888888888"),
|
|
136
|
+
autoRemediationSuggestionId: new ObjectID(
|
|
137
|
+
"77777777-7777-4777-8777-777777777777",
|
|
138
|
+
),
|
|
139
|
+
stepId: "ai-approved-1",
|
|
140
|
+
stepType: RunbookStepType.Bash,
|
|
141
|
+
targetAgentId: RUNNER_ID,
|
|
142
|
+
command: "systemctl restart nginx",
|
|
143
|
+
timeoutInMs: 30000,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
expect(create).toHaveBeenCalledTimes(1);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
/*
|
|
150
|
+
* Resource commands are braked on their own ResourceCommand rows, so the
|
|
151
|
+
* Runner lane's hourly brake must not count them: a full hour of fixes on
|
|
152
|
+
* Docker hosts or database servers leaves every Bash and SSH fix its own
|
|
153
|
+
* budget. Counted against an in-memory RunnerJob table.
|
|
154
|
+
*/
|
|
155
|
+
describe("the Runner lane's hourly brake never counts resource-command rows", () => {
|
|
156
|
+
function bashCommand(): Parameters<
|
|
157
|
+
typeof RunnerJobService.enqueueAiCommand
|
|
158
|
+
>[0] {
|
|
159
|
+
return {
|
|
160
|
+
projectId: PROJECT_ID,
|
|
161
|
+
aiRunId: new ObjectID("88888888-8888-4888-8888-888888888888"),
|
|
162
|
+
autoRemediationSuggestionId: new ObjectID(
|
|
163
|
+
"77777777-7777-4777-8777-777777777777",
|
|
164
|
+
),
|
|
165
|
+
stepId: "ai-approved-1",
|
|
166
|
+
stepType: RunbookStepType.Bash,
|
|
167
|
+
targetAgentId: RUNNER_ID,
|
|
168
|
+
command: "systemctl restart nginx",
|
|
169
|
+
timeoutInMs: 30000,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
it("runs a Bash fix after a full hour of resource fixes", async () => {
|
|
174
|
+
countBy.mockImplementation(
|
|
175
|
+
fakeRunnerJobCountBy(
|
|
176
|
+
fakeRunnerJobRows(MAX_AI_COMMAND_JOBS_PER_PROJECT_PER_HOUR, {
|
|
177
|
+
projectId: PROJECT_ID,
|
|
178
|
+
origin: RunnerJobOrigin.AiRemediation,
|
|
179
|
+
stepType: RunbookStepType.ResourceCommand,
|
|
180
|
+
}),
|
|
181
|
+
) as never,
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
await RunnerJobService.enqueueAiCommand(bashCommand());
|
|
185
|
+
|
|
186
|
+
expect(create).toHaveBeenCalledTimes(1);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("negative control: a full hour of kubectl and SSH fixes still stops it", async () => {
|
|
190
|
+
countBy.mockImplementation(
|
|
191
|
+
fakeRunnerJobCountBy([
|
|
192
|
+
...fakeRunnerJobRows(MAX_AI_COMMAND_JOBS_PER_PROJECT_PER_HOUR - 1, {
|
|
193
|
+
projectId: PROJECT_ID,
|
|
194
|
+
origin: RunnerJobOrigin.AiRemediation,
|
|
195
|
+
stepType: RunbookStepType.Kubectl,
|
|
196
|
+
}),
|
|
197
|
+
...fakeRunnerJobRows(1, {
|
|
198
|
+
projectId: PROJECT_ID,
|
|
199
|
+
origin: RunnerJobOrigin.AiRemediation,
|
|
200
|
+
stepType: RunbookStepType.SSH,
|
|
201
|
+
}),
|
|
202
|
+
]) as never,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
await expect(
|
|
206
|
+
RunnerJobService.enqueueAiCommand(bashCommand()),
|
|
207
|
+
).rejects.toThrow(/AI remediation commands in the last hour/);
|
|
208
|
+
expect(create).not.toHaveBeenCalled();
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
});
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import RunnerJobService, {
|
|
2
|
+
RunnerJobTimeoutKind,
|
|
3
|
+
Service as RunnerJobServiceClass,
|
|
4
|
+
describeRunnerJobTimeout,
|
|
5
|
+
} from "../../../Server/Services/RunnerJobService";
|
|
6
|
+
import PostgresAppInstance from "../../../Server/Infrastructure/PostgresDatabase";
|
|
7
|
+
import RunnerJob from "../../../Models/DatabaseModels/RunnerJob";
|
|
8
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
9
|
+
import AiResourceType from "../../../Types/ResourceAiAgent/AiResourceType";
|
|
10
|
+
import RunbookStepType from "../../../Types/Runbook/RunbookStepType";
|
|
11
|
+
import RunnerJobOrigin from "../../../Types/Runbook/RunnerJobOrigin";
|
|
12
|
+
import RunnerJobStatus from "../../../Types/Runbook/RunnerJobStatus";
|
|
13
|
+
import { afterEach, beforeEach, describe, expect, it } from "@jest/globals";
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Contract under test — the two RunnerJobService readings of a resource
|
|
17
|
+
* command job's row besides its enqueue:
|
|
18
|
+
*
|
|
19
|
+
* - a timed-out ResourceCommand job is worded for the resource's AI agent
|
|
20
|
+
* ("the Docker AI agent did not pick up the command in time ... Nothing
|
|
21
|
+
* was run on the Docker host"), on the row, while every Kubectl and
|
|
22
|
+
* runbook reason stays exactly what it was;
|
|
23
|
+
* - submitResult, given the job's resource type and program, stores the
|
|
24
|
+
* output through the resource command redactor as well, and without them
|
|
25
|
+
* stores exactly what it always has.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const JOB_ID: ObjectID = new ObjectID("11111111-1111-4111-8111-111111111111");
|
|
29
|
+
const AGENT_ID: ObjectID = new ObjectID("22222222-2222-4222-8222-222222222222");
|
|
30
|
+
const CLAIM_TIMEOUT_MS: number = 60_000;
|
|
31
|
+
const EXECUTION_TIMEOUT_MS: number = 30_000;
|
|
32
|
+
|
|
33
|
+
function reason(data: {
|
|
34
|
+
kind: RunnerJobTimeoutKind;
|
|
35
|
+
wasClaimed?: boolean | undefined;
|
|
36
|
+
origin?: RunnerJobOrigin | undefined;
|
|
37
|
+
stepType?: RunbookStepType | undefined;
|
|
38
|
+
resourceType?: AiResourceType | null | undefined;
|
|
39
|
+
isForKubernetesAiAgent?: boolean | undefined;
|
|
40
|
+
}): string {
|
|
41
|
+
return describeRunnerJobTimeout({
|
|
42
|
+
kind: data.kind,
|
|
43
|
+
wasClaimed: data.wasClaimed,
|
|
44
|
+
origin: data.origin ?? RunnerJobOrigin.AiInvestigation,
|
|
45
|
+
stepType: data.stepType ?? RunbookStepType.ResourceCommand,
|
|
46
|
+
claimTimeoutInMs: CLAIM_TIMEOUT_MS,
|
|
47
|
+
executionTimeoutInMs: EXECUTION_TIMEOUT_MS,
|
|
48
|
+
isForKubernetesAiAgent: data.isForKubernetesAiAgent,
|
|
49
|
+
resourceType: data.resourceType,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
describe("describeRunnerJobTimeout for a resource command", () => {
|
|
54
|
+
it("says the agent did not pick up the command in time, and that nothing ran", () => {
|
|
55
|
+
expect(
|
|
56
|
+
reason({ kind: "unclaimed", resourceType: AiResourceType.DockerHost }),
|
|
57
|
+
).toBe(
|
|
58
|
+
"The Docker AI agent did not pick up the command in time (within 60s) — it may be offline, restarting or busy with other work. Nothing was run on the Docker host.",
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("names each type's agent and resource", () => {
|
|
63
|
+
expect(
|
|
64
|
+
reason({ kind: "unclaimed", resourceType: AiResourceType.Host }),
|
|
65
|
+
).toContain("The Host AI agent did not pick up the command in time");
|
|
66
|
+
expect(
|
|
67
|
+
reason({ kind: "unclaimed", resourceType: AiResourceType.Host }),
|
|
68
|
+
).toContain("Nothing was run on the host.");
|
|
69
|
+
expect(
|
|
70
|
+
reason({
|
|
71
|
+
kind: "unclaimed",
|
|
72
|
+
resourceType: AiResourceType.DatabaseServer,
|
|
73
|
+
}),
|
|
74
|
+
).toContain("Nothing was run on the database server.");
|
|
75
|
+
expect(
|
|
76
|
+
reason({
|
|
77
|
+
kind: "unclaimed",
|
|
78
|
+
resourceType: AiResourceType.VMwareVCenter,
|
|
79
|
+
}),
|
|
80
|
+
).toContain("The VMware AI agent did not pick up the command in time");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("reads a job still Pending at the overall deadline as never picked up", () => {
|
|
84
|
+
expect(
|
|
85
|
+
reason({
|
|
86
|
+
kind: "overall",
|
|
87
|
+
wasClaimed: false,
|
|
88
|
+
resourceType: AiResourceType.CephCluster,
|
|
89
|
+
}),
|
|
90
|
+
).toContain("The Ceph AI agent did not pick up the command in time");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("says what a command the agent took did is unknown", () => {
|
|
94
|
+
expect(
|
|
95
|
+
reason({
|
|
96
|
+
kind: "lease_expired",
|
|
97
|
+
wasClaimed: true,
|
|
98
|
+
resourceType: AiResourceType.ProxmoxCluster,
|
|
99
|
+
}),
|
|
100
|
+
).toBe(
|
|
101
|
+
"The Proxmox AI agent stopped responding while this command was running — it may have restarted or lost its connection. What the command did is unknown.",
|
|
102
|
+
);
|
|
103
|
+
expect(
|
|
104
|
+
reason({
|
|
105
|
+
kind: "overall",
|
|
106
|
+
wasClaimed: true,
|
|
107
|
+
resourceType: AiResourceType.ProxmoxCluster,
|
|
108
|
+
}),
|
|
109
|
+
).toBe(
|
|
110
|
+
"The Proxmox AI agent did not report a result for this command in time — the command may have outlived its 30s timeout. What the command did is unknown.",
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("tells a remediation to check the resource before running a change again", () => {
|
|
115
|
+
for (const kind of [
|
|
116
|
+
"lease_expired",
|
|
117
|
+
"overall",
|
|
118
|
+
] as Array<RunnerJobTimeoutKind>) {
|
|
119
|
+
expect(
|
|
120
|
+
reason({
|
|
121
|
+
kind,
|
|
122
|
+
wasClaimed: true,
|
|
123
|
+
origin: RunnerJobOrigin.AiRemediation,
|
|
124
|
+
resourceType: AiResourceType.DockerSwarmCluster,
|
|
125
|
+
}),
|
|
126
|
+
).toContain(
|
|
127
|
+
"Check the Docker Swarm cluster before running a change again.",
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Nothing ran: nothing to check.
|
|
132
|
+
expect(
|
|
133
|
+
reason({
|
|
134
|
+
kind: "unclaimed",
|
|
135
|
+
origin: RunnerJobOrigin.AiRemediation,
|
|
136
|
+
resourceType: AiResourceType.DockerSwarmCluster,
|
|
137
|
+
}),
|
|
138
|
+
).not.toContain("Check the");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("falls back to generic words for a row without a readable type", () => {
|
|
142
|
+
expect(reason({ kind: "unclaimed", resourceType: null })).toBe(
|
|
143
|
+
"The resource's AI agent did not pick up the command in time (within 60s) — it may be offline, restarting or busy with other work. Nothing was run on the resource.",
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("leaves the kubectl wording exactly as it was", () => {
|
|
148
|
+
expect(
|
|
149
|
+
reason({
|
|
150
|
+
kind: "unclaimed",
|
|
151
|
+
stepType: RunbookStepType.Kubectl,
|
|
152
|
+
isForKubernetesAiAgent: true,
|
|
153
|
+
resourceType: AiResourceType.DockerHost,
|
|
154
|
+
}),
|
|
155
|
+
).toBe(
|
|
156
|
+
"The cluster's Kubernetes AI agent did not pick up this kubectl command within 60s — it may be offline, restarting or busy with other work. Nothing was run on the cluster.",
|
|
157
|
+
);
|
|
158
|
+
expect(
|
|
159
|
+
reason({ kind: "unclaimed", stepType: RunbookStepType.Kubectl }),
|
|
160
|
+
).toBe(
|
|
161
|
+
"The cluster's Runner did not pick up this kubectl command within 60s — it may be offline, restarting or busy with other work. Nothing was run on the cluster.",
|
|
162
|
+
);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("leaves a runbook step's wording as it was", () => {
|
|
166
|
+
expect(
|
|
167
|
+
reason({
|
|
168
|
+
kind: "unclaimed",
|
|
169
|
+
origin: RunnerJobOrigin.Runbook,
|
|
170
|
+
stepType: RunbookStepType.Bash,
|
|
171
|
+
}),
|
|
172
|
+
).toBe(
|
|
173
|
+
"No runbook agent picked up this step before the wait window expired. The agent may be offline — check that it is running and reachable, then try again.",
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
describe("RunnerJobService.pollUntilTerminal on a resource command", () => {
|
|
179
|
+
let row: Record<string, unknown>;
|
|
180
|
+
let findOneById: jest.SpyInstance;
|
|
181
|
+
let timeoutSpy: jest.SpyInstance;
|
|
182
|
+
|
|
183
|
+
beforeEach(() => {
|
|
184
|
+
row = {};
|
|
185
|
+
findOneById = jest
|
|
186
|
+
.spyOn(RunnerJobService, "findOneById")
|
|
187
|
+
.mockImplementation(async (): Promise<RunnerJob> => {
|
|
188
|
+
return row as unknown as RunnerJob;
|
|
189
|
+
});
|
|
190
|
+
timeoutSpy = jest
|
|
191
|
+
.spyOn(RunnerJobService, "timeoutJob")
|
|
192
|
+
.mockImplementation(
|
|
193
|
+
async (data: { reason: string }): Promise<RunnerJob> => {
|
|
194
|
+
return {
|
|
195
|
+
status: RunnerJobStatus.TimedOut,
|
|
196
|
+
errorMessage: data.reason,
|
|
197
|
+
} as unknown as RunnerJob;
|
|
198
|
+
},
|
|
199
|
+
);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
afterEach(() => {
|
|
203
|
+
jest.restoreAllMocks();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("reads the resource agent and its type off the row and words the timeout", async () => {
|
|
207
|
+
row = {
|
|
208
|
+
status: RunnerJobStatus.Pending,
|
|
209
|
+
origin: RunnerJobOrigin.AiInvestigation,
|
|
210
|
+
stepType: RunbookStepType.ResourceCommand,
|
|
211
|
+
targetResourceAiAgentId: AGENT_ID,
|
|
212
|
+
resourceType: AiResourceType.PodmanHost,
|
|
213
|
+
claimDeadlineAt: new Date(Date.now() - 1000),
|
|
214
|
+
leaseExpiresAt: new Date(Date.now() + 60_000),
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const job: RunnerJob = await RunnerJobService.pollUntilTerminal({
|
|
218
|
+
jobId: JOB_ID,
|
|
219
|
+
claimTimeoutInMs: CLAIM_TIMEOUT_MS,
|
|
220
|
+
executionTimeoutInMs: EXECUTION_TIMEOUT_MS,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const select: Record<string, unknown> = (
|
|
224
|
+
findOneById.mock.calls[0]![0] as { select: Record<string, unknown> }
|
|
225
|
+
).select;
|
|
226
|
+
|
|
227
|
+
expect(select["targetResourceAiAgentId"]).toBe(true);
|
|
228
|
+
expect(select["resourceType"]).toBe(true);
|
|
229
|
+
// The Kubernetes target is still read for kubectl rows.
|
|
230
|
+
expect(select["targetKubernetesAiAgentId"]).toBe(true);
|
|
231
|
+
expect(timeoutSpy).toHaveBeenCalledTimes(1);
|
|
232
|
+
expect(job.errorMessage).toContain(
|
|
233
|
+
"The Podman AI agent did not pick up the command in time",
|
|
234
|
+
);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it("returns a terminal resource job as it is", async () => {
|
|
238
|
+
row = {
|
|
239
|
+
status: RunnerJobStatus.Succeeded,
|
|
240
|
+
stepType: RunbookStepType.ResourceCommand,
|
|
241
|
+
output: "[stdout]\nok",
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const job: RunnerJob = await RunnerJobService.pollUntilTerminal({
|
|
245
|
+
jobId: JOB_ID,
|
|
246
|
+
claimTimeoutInMs: CLAIM_TIMEOUT_MS,
|
|
247
|
+
executionTimeoutInMs: EXECUTION_TIMEOUT_MS,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
expect(job.status).toBe(RunnerJobStatus.Succeeded);
|
|
251
|
+
expect(timeoutSpy).not.toHaveBeenCalled();
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe("RunnerJobService.submitResult with the job's resource command", () => {
|
|
256
|
+
let queries: Array<{ sql: string; params: Array<unknown> }>;
|
|
257
|
+
|
|
258
|
+
beforeEach(() => {
|
|
259
|
+
queries = [];
|
|
260
|
+
jest.spyOn(PostgresAppInstance, "getDataSource").mockReturnValue({
|
|
261
|
+
query: jest
|
|
262
|
+
.fn()
|
|
263
|
+
.mockImplementation(
|
|
264
|
+
async (sql: string, params: Array<unknown>): Promise<unknown> => {
|
|
265
|
+
queries.push({ sql, params });
|
|
266
|
+
return [[{ _id: JOB_ID.toString() }], 1];
|
|
267
|
+
},
|
|
268
|
+
),
|
|
269
|
+
} as never);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
afterEach(() => {
|
|
273
|
+
jest.restoreAllMocks();
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
const INSPECT_OUTPUT: string =
|
|
277
|
+
'[stdout]\n[{"Id":"abc","Config":{"Env":["FOO_SETTING=plainvalue42","PATH=/usr/bin"]}}]';
|
|
278
|
+
|
|
279
|
+
// $10 is the AI-origin output, $11 the AI-origin error (see the UPDATE).
|
|
280
|
+
function aiOriginOutput(): string {
|
|
281
|
+
return queries[queries.length - 1]!.params[9] as string;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function aiOriginError(): string {
|
|
285
|
+
return queries[queries.length - 1]!.params[10] as string;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function verbatimOutput(): string {
|
|
289
|
+
return queries[queries.length - 1]!.params[1] as string;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
it("masks every docker inspect environment value for a Docker host's job", async () => {
|
|
293
|
+
await RunnerJobService.submitResult({
|
|
294
|
+
jobId: JOB_ID,
|
|
295
|
+
agentId: AGENT_ID,
|
|
296
|
+
success: true,
|
|
297
|
+
exitCode: 0,
|
|
298
|
+
output: INSPECT_OUTPUT,
|
|
299
|
+
resourceCommand: {
|
|
300
|
+
resourceType: AiResourceType.DockerHost,
|
|
301
|
+
program: "docker",
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
expect(aiOriginOutput()).not.toContain("plainvalue42");
|
|
306
|
+
expect(aiOriginOutput()).toContain("FOO_SETTING=[redacted]");
|
|
307
|
+
// The runbook branch of the CASE keeps the raw text, as always.
|
|
308
|
+
expect(verbatimOutput()).toBe(INSPECT_OUTPUT);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it("redacts the error message the same way", async () => {
|
|
312
|
+
await RunnerJobService.submitResult({
|
|
313
|
+
jobId: JOB_ID,
|
|
314
|
+
agentId: AGENT_ID,
|
|
315
|
+
success: false,
|
|
316
|
+
errorMessage:
|
|
317
|
+
'{"query":"SELECT * FROM users WHERE email = \'bob@example.com\' AND pin = 1234"}',
|
|
318
|
+
resourceCommand: {
|
|
319
|
+
resourceType: AiResourceType.DatabaseServer,
|
|
320
|
+
program: "db",
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
expect(aiOriginError()).not.toContain("bob@example.com");
|
|
325
|
+
expect(aiOriginError()).not.toContain("1234");
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it("stores exactly what it always has without a resource command", async () => {
|
|
329
|
+
await RunnerJobService.submitResult({
|
|
330
|
+
jobId: JOB_ID,
|
|
331
|
+
agentId: AGENT_ID,
|
|
332
|
+
success: true,
|
|
333
|
+
exitCode: 0,
|
|
334
|
+
output: INSPECT_OUTPUT,
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
expect(aiOriginOutput()).toBe(
|
|
338
|
+
RunnerJobServiceClass.redactAiJobText(INSPECT_OUTPUT),
|
|
339
|
+
);
|
|
340
|
+
expect(aiOriginOutput()).toContain("plainvalue42");
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it("redactResourceCommandText is the identity without a resource command", () => {
|
|
344
|
+
expect(RunnerJobServiceClass.redactResourceCommandText("x=1")).toBe("x=1");
|
|
345
|
+
expect(
|
|
346
|
+
RunnerJobServiceClass.redactResourceCommandText(INSPECT_OUTPUT, {
|
|
347
|
+
resourceType: AiResourceType.PodmanHost,
|
|
348
|
+
program: "docker",
|
|
349
|
+
}),
|
|
350
|
+
).toContain("FOO_SETTING=[redacted]");
|
|
351
|
+
});
|
|
352
|
+
});
|