@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.
Files changed (383) hide show
  1. package/Models/DatabaseModels/AutoRemediationSuggestion.ts +60 -0
  2. package/Models/DatabaseModels/CephCluster.ts +213 -0
  3. package/Models/DatabaseModels/DatabaseServer.ts +213 -0
  4. package/Models/DatabaseModels/DockerHost.ts +213 -0
  5. package/Models/DatabaseModels/DockerSwarmCluster.ts +213 -0
  6. package/Models/DatabaseModels/GlobalConfig.ts +1 -1
  7. package/Models/DatabaseModels/Host.ts +213 -0
  8. package/Models/DatabaseModels/Index.ts +2 -0
  9. package/Models/DatabaseModels/PodmanHost.ts +213 -0
  10. package/Models/DatabaseModels/ProxmoxCluster.ts +213 -0
  11. package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
  12. package/Models/DatabaseModels/RunnerJob.ts +144 -0
  13. package/Models/DatabaseModels/VMwareVCenter.ts +213 -0
  14. package/Server/API/AutoRemediationAPI.ts +392 -1
  15. package/Server/API/ResourceAiAccessAPI.ts +1669 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  18. package/Server/Infrastructure/Semaphore.ts +22 -0
  19. package/Server/Middleware/TelemetryIngest.ts +15 -5
  20. package/Server/Services/AnalyticsDatabaseService.ts +45 -1
  21. package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
  22. package/Server/Services/CephClusterService.ts +109 -1
  23. package/Server/Services/DatabaseServerService.ts +116 -1
  24. package/Server/Services/DockerHostService.ts +109 -1
  25. package/Server/Services/DockerSwarmClusterService.ts +113 -1
  26. package/Server/Services/HostService.ts +126 -4
  27. package/Server/Services/MetricRecordingRuleService.ts +47 -0
  28. package/Server/Services/PodmanHostService.ts +109 -1
  29. package/Server/Services/ProxmoxClusterService.ts +110 -1
  30. package/Server/Services/ResourceAiAccessService.ts +1439 -0
  31. package/Server/Services/ResourceAiAgentJobService.ts +202 -0
  32. package/Server/Services/ResourceAiAgentService.ts +2432 -0
  33. package/Server/Services/RunnerJobService.ts +611 -4
  34. package/Server/Services/TelemetryUsageBillingService.ts +28 -0
  35. package/Server/Services/TraceRecordingRuleService.ts +33 -0
  36. package/Server/Services/VMwareVCenterService.ts +110 -1
  37. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1434 -32
  38. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +935 -21
  39. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
  40. package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +577 -0
  41. package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
  42. package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
  43. package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
  44. package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
  45. package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +873 -0
  46. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +72 -2
  47. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +72 -5
  48. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +72 -5
  49. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +396 -13
  50. package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
  51. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
  52. package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
  53. package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
  54. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +35 -15
  55. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
  56. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
  57. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +298 -224
  58. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +35 -15
  59. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
  60. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +366 -143
  61. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.ts +163 -0
  62. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +396 -0
  63. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.ts +418 -0
  64. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.ts +152 -0
  65. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.ts +251 -0
  66. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.ts +214 -0
  67. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +93 -0
  68. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +18 -6
  69. package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
  70. package/Tests/App/Dashboard/RemediationSuggestionCardDescription.test.tsx +209 -0
  71. package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
  72. package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
  73. package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
  74. package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +1721 -0
  75. package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1002 -0
  76. package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
  77. package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
  78. package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
  79. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +33 -1
  80. package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
  81. package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
  82. package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
  83. package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
  84. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
  85. package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
  86. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
  87. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +63 -5
  88. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +103 -5
  89. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +19 -1
  90. package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
  91. package/Tests/Server/Services/DatabaseServerService.test.ts +55 -0
  92. package/Tests/Server/Services/GroupTelemetryUsageExcludeNames.test.ts +299 -0
  93. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +44 -0
  94. package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
  95. package/Tests/Server/Services/RecordingRuleReservedMetricName.test.ts +171 -0
  96. package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
  97. package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
  98. package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
  99. package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
  100. package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
  101. package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
  102. package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
  103. package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
  104. package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
  105. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +105 -0
  106. package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
  107. package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
  108. package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
  109. package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
  110. package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
  111. package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +453 -0
  112. package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
  113. package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
  114. package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
  115. package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1249 -0
  116. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
  117. package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
  118. package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +722 -0
  119. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
  120. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
  121. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
  122. package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +830 -0
  123. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
  124. package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
  125. package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
  126. package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
  127. package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
  128. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +33 -3
  129. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsAccountNotLinked.test.ts +1093 -0
  130. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.test.ts +1049 -0
  131. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +1676 -0
  132. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCards.test.ts +2884 -0
  133. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.test.ts +2490 -0
  134. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmit.test.ts +2293 -0
  135. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmitServerTimezone.test.ts +386 -0
  136. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.test.ts +1477 -0
  137. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.test.ts +1967 -0
  138. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsStripHtmlTags.test.ts +92 -0
  139. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsSubmittedFormRemoval.test.ts +1819 -0
  140. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.test.ts +1033 -0
  141. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezoneServerZone.test.ts +610 -0
  142. package/Tests/Server/Utils/Workspace/MicrosoftTeamsBotMessageHandling.test.ts +2610 -0
  143. package/Tests/Server/Utils/Workspace/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
  144. package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
  145. package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
  146. package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
  147. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
  148. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
  149. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
  150. package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
  151. package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +517 -0
  152. package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
  153. package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
  154. package/Tests/Utils/AiRemediation/Resource/CephCommandPolicy.test.ts +1653 -0
  155. package/Tests/Utils/AiRemediation/Resource/CephOutputRedaction.test.ts +204 -0
  156. package/Tests/Utils/AiRemediation/Resource/DatabaseCommandPolicy.test.ts +1077 -0
  157. package/Tests/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.test.ts +558 -0
  158. package/Tests/Utils/AiRemediation/Resource/DatabaseQueryRedactor.test.ts +834 -0
  159. package/Tests/Utils/AiRemediation/Resource/DockerCliGrammar.test.ts +747 -0
  160. package/Tests/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.test.ts +1259 -0
  161. package/Tests/Utils/AiRemediation/Resource/DockerOutputRedaction.test.ts +386 -0
  162. package/Tests/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.test.ts +782 -0
  163. package/Tests/Utils/AiRemediation/Resource/GovcCommandPolicy.test.ts +2259 -0
  164. package/Tests/Utils/AiRemediation/Resource/HostCommandPolicy.test.ts +2019 -0
  165. package/Tests/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.test.ts +2497 -0
  166. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicy.test.ts +1305 -0
  167. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.test.ts +585 -0
  168. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactor.test.ts +334 -0
  169. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactorCopyParity.test.ts +98 -0
  170. package/Tests/Utils/AiRemediation/Resource/ResourcePolicyImportClosure.test.ts +391 -0
  171. package/Tests/Utils/AiRemediation/ResourceAiAgentPolicyCopyParity.test.ts +497 -0
  172. package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
  173. package/Types/AI/ResourceAiAccessApi.ts +140 -0
  174. package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
  175. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +183 -2
  176. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
  177. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
  178. package/Types/Monitor/RumAlertTemplates.ts +351 -4
  179. package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
  180. package/Types/ResourceAiAgent/ResourceAiAccess.ts +574 -0
  181. package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
  182. package/Types/Runbook/RunbookStepType.ts +29 -0
  183. package/Types/Telemetry/TelemetryIngestSurface.ts +14 -2
  184. package/Utils/AI/InvestigationReport.ts +121 -15
  185. package/Utils/AiRemediation/Resource/CephCommandPolicy.ts +1936 -0
  186. package/Utils/AiRemediation/Resource/DatabaseCommandPolicy.ts +166 -0
  187. package/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.ts +1532 -0
  188. package/Utils/AiRemediation/Resource/DatabaseQueryRedactor.ts +1394 -0
  189. package/Utils/AiRemediation/Resource/DockerCliGrammar.ts +1839 -0
  190. package/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.ts +490 -0
  191. package/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.ts +687 -0
  192. package/Utils/AiRemediation/Resource/GovcCommandPolicy.ts +2096 -0
  193. package/Utils/AiRemediation/Resource/HostCommandPolicy.ts +2982 -0
  194. package/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.ts +1679 -0
  195. package/Utils/AiRemediation/Resource/ResourceCommandPolicy.ts +851 -0
  196. package/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.ts +593 -0
  197. package/Utils/AiRemediation/Resource/ResourceOutputRedactor.ts +2812 -0
  198. package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
  199. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
  200. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
  201. package/build/dist/Models/DatabaseModels/CephCluster.js +219 -0
  202. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  203. package/build/dist/Models/DatabaseModels/DatabaseServer.js +219 -0
  204. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
  205. package/build/dist/Models/DatabaseModels/DockerHost.js +219 -0
  206. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  207. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +219 -0
  208. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
  209. package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
  210. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  211. package/build/dist/Models/DatabaseModels/Host.js +219 -0
  212. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  213. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  214. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  215. package/build/dist/Models/DatabaseModels/PodmanHost.js +219 -0
  216. package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
  217. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +219 -0
  218. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  219. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js +439 -0
  220. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js.map +1 -0
  221. package/build/dist/Models/DatabaseModels/RunnerJob.js +145 -0
  222. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  223. package/build/dist/Models/DatabaseModels/VMwareVCenter.js +219 -0
  224. package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
  225. package/build/dist/Server/API/AutoRemediationAPI.js +231 -1
  226. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  227. package/build/dist/Server/API/ResourceAiAccessAPI.js +1119 -0
  228. package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js +168 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  233. package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
  234. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  235. package/build/dist/Server/Middleware/TelemetryIngest.js +12 -5
  236. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  237. package/build/dist/Server/Services/AnalyticsDatabaseService.js +26 -1
  238. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  239. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +601 -3
  240. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  241. package/build/dist/Server/Services/CephClusterService.js +104 -0
  242. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  243. package/build/dist/Server/Services/DatabaseServerService.js +99 -0
  244. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
  245. package/build/dist/Server/Services/DockerHostService.js +104 -0
  246. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  247. package/build/dist/Server/Services/DockerSwarmClusterService.js +104 -0
  248. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  249. package/build/dist/Server/Services/HostService.js +114 -2
  250. package/build/dist/Server/Services/HostService.js.map +1 -1
  251. package/build/dist/Server/Services/MetricRecordingRuleService.js +46 -0
  252. package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
  253. package/build/dist/Server/Services/PodmanHostService.js +104 -0
  254. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  255. package/build/dist/Server/Services/ProxmoxClusterService.js +104 -0
  256. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  257. package/build/dist/Server/Services/ResourceAiAccessService.js +1028 -0
  258. package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -0
  259. package/build/dist/Server/Services/ResourceAiAgentJobService.js +173 -0
  260. package/build/dist/Server/Services/ResourceAiAgentJobService.js.map +1 -0
  261. package/build/dist/Server/Services/ResourceAiAgentService.js +1687 -0
  262. package/build/dist/Server/Services/ResourceAiAgentService.js.map +1 -0
  263. package/build/dist/Server/Services/RunnerJobService.js +344 -5
  264. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  265. package/build/dist/Server/Services/TelemetryUsageBillingService.js +26 -0
  266. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  267. package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
  268. package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
  269. package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
  270. package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
  271. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1029 -30
  272. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  273. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +633 -28
  274. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  275. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
  276. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  277. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +330 -0
  278. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
  279. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
  280. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
  281. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
  282. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
  283. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
  284. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
  285. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
  286. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
  287. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +600 -0
  288. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
  289. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +50 -4
  290. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  291. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +55 -4
  292. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  293. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +55 -4
  294. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  295. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +290 -13
  296. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  297. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +29 -1
  298. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
  299. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +9 -1
  300. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  301. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +627 -0
  302. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js.map +1 -0
  303. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js +60 -5
  304. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js.map +1 -1
  305. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +19 -15
  306. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  307. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
  308. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  309. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
  310. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
  311. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +183 -209
  312. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  313. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +19 -15
  314. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  315. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
  316. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
  317. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +263 -110
  318. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  319. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js +129 -0
  320. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js.map +1 -0
  321. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +266 -0
  322. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -0
  323. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js +258 -0
  324. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js.map +1 -0
  325. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js +104 -0
  326. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js.map +1 -0
  327. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js +183 -0
  328. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js.map +1 -0
  329. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js +123 -0
  330. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js.map +1 -0
  331. package/build/dist/Types/AI/ResourceAiAccessApi.js +30 -0
  332. package/build/dist/Types/AI/ResourceAiAccessApi.js.map +1 -0
  333. package/build/dist/Types/AI/ResourceAiAccessPermissions.js +98 -0
  334. package/build/dist/Types/AI/ResourceAiAccessPermissions.js.map +1 -0
  335. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +116 -29
  336. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  337. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
  338. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  339. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
  340. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  341. package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
  342. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  343. package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
  344. package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
  345. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +275 -0
  346. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
  347. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
  348. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
  349. package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
  350. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  351. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +13 -2
  352. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  353. package/build/dist/Utils/AI/InvestigationReport.js +71 -11
  354. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
  355. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js +1462 -0
  356. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js.map +1 -0
  357. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js +122 -0
  358. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js.map +1 -0
  359. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js +1139 -0
  360. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js.map +1 -0
  361. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js +1060 -0
  362. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js.map +1 -0
  363. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js +1301 -0
  364. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js.map +1 -0
  365. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js +370 -0
  366. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js.map +1 -0
  367. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js +498 -0
  368. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js.map +1 -0
  369. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js +1565 -0
  370. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js.map +1 -0
  371. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js +2206 -0
  372. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js.map +1 -0
  373. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js +1129 -0
  374. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js.map +1 -0
  375. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js +565 -0
  376. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js.map +1 -0
  377. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js +408 -0
  378. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js.map +1 -0
  379. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js +1910 -0
  380. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js.map +1 -0
  381. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
  382. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
  383. package/package.json +1 -1
@@ -0,0 +1,569 @@
1
+ import ResourceAiDeleteCleanup, {
2
+ ResourceAiDeleteCarryForward,
3
+ getResourceAiDeleteCarryForward,
4
+ } from "../../../../../Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup";
5
+ import AutoRemediationSuggestionService from "../../../../../Server/Services/AutoRemediationSuggestionService";
6
+ import DatabaseService from "../../../../../Server/Services/DatabaseService";
7
+ import ResourceAiAgentService from "../../../../../Server/Services/ResourceAiAgentService";
8
+ import DeleteBy from "../../../../../Server/Types/Database/DeleteBy";
9
+ import { OnDelete } from "../../../../../Server/Types/Database/Hooks";
10
+ import logger from "../../../../../Server/Utils/Logger";
11
+ import AutoRemediationSuggestion from "../../../../../Models/DatabaseModels/AutoRemediationSuggestion";
12
+ import BaseModel from "../../../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
13
+ import AutoRemediationSuggestionStatus from "../../../../../Types/AutoRemediation/AutoRemediationSuggestionStatus";
14
+ import DatabaseCommonInteractionProps from "../../../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
15
+ import { JSONObject } from "../../../../../Types/JSON";
16
+ import ObjectID from "../../../../../Types/ObjectID";
17
+ import AiResourceType, {
18
+ ALL_AI_RESOURCE_TYPES,
19
+ } from "../../../../../Types/ResourceAiAgent/AiResourceType";
20
+ import { afterEach, beforeEach, describe, expect, it } from "@jest/globals";
21
+
22
+ /*
23
+ * What deleting an infrastructure resource a resource AI agent serves does
24
+ * to its OneUptime AI state (ResourceAiDeleteCleanup), through a stand-in
25
+ * service — the resource-level twin of
26
+ * KubernetesClusterServiceDeleteSettlesRemediation.test.ts:
27
+ *
28
+ * - the resource's in-flight rounds (Planning, or waiting in Suggested) are
29
+ * read BEFORE the delete, scoped to the resources the delete matches in
30
+ * the caller's project;
31
+ * - they are settled only for the resources that were actually deleted,
32
+ * through the same conditional status transition a human dismissal uses,
33
+ * with a note naming the resource — and, for a round that already ran
34
+ * commands, that those ran and nothing was rolled back;
35
+ * - the deleted resources' AI agents are deleted, whatever happened to
36
+ * the rounds;
37
+ * - nothing here ever fails the delete.
38
+ *
39
+ * The eight services' wiring is pinned in
40
+ * Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts.
41
+ */
42
+
43
+ const PROJECT_ID: ObjectID = new ObjectID(
44
+ "11111111-1111-4111-8111-111111111111",
45
+ );
46
+ const RESOURCE_ID: ObjectID = new ObjectID(
47
+ "22222222-2222-4222-8222-222222222222",
48
+ );
49
+ const OTHER_RESOURCE_ID: ObjectID = new ObjectID(
50
+ "33333333-3333-4333-8333-333333333333",
51
+ );
52
+ const USER_ID: ObjectID = new ObjectID("44444444-4444-4444-8444-444444444444");
53
+ const PLANNING_ID: ObjectID = new ObjectID(
54
+ "55555555-5555-4555-8555-555555555555",
55
+ );
56
+ const SUGGESTED_ID: ObjectID = new ObjectID(
57
+ "66666666-6666-4666-8666-666666666666",
58
+ );
59
+
60
+ // A stand-in for a resource's DatabaseService: the read is all it is asked.
61
+ interface FakeService {
62
+ findBy: jest.Mock;
63
+ }
64
+
65
+ function fakeService(
66
+ rows: Array<Record<string, unknown>> = [
67
+ { id: RESOURCE_ID, _id: RESOURCE_ID.toString(), name: "web-1" },
68
+ ],
69
+ ): FakeService {
70
+ return { findBy: jest.fn().mockResolvedValue(rows) };
71
+ }
72
+
73
+ function asService(service: FakeService): DatabaseService<BaseModel> {
74
+ return service as unknown as DatabaseService<BaseModel>;
75
+ }
76
+
77
+ function userProps(): DatabaseCommonInteractionProps {
78
+ return {
79
+ userId: USER_ID,
80
+ tenantId: PROJECT_ID,
81
+ } as DatabaseCommonInteractionProps;
82
+ }
83
+
84
+ function deleteBy(
85
+ props: DatabaseCommonInteractionProps = userProps(),
86
+ ): DeleteBy<BaseModel> {
87
+ return {
88
+ query: { _id: RESOURCE_ID.toString() },
89
+ limit: 1,
90
+ skip: 0,
91
+ props,
92
+ } as unknown as DeleteBy<BaseModel>;
93
+ }
94
+
95
+ function commandPlan(executedCommands: number): JSONObject {
96
+ const commands: Array<JSONObject> = [];
97
+
98
+ for (let i: number = 0; i < 3; i++) {
99
+ commands.push({
100
+ sequence: i + 1,
101
+ stepType: "ResourceCommand",
102
+ command: `docker restart web-${i}`,
103
+ runnerId: ObjectID.generate().toString(),
104
+ resourceType: AiResourceType.DockerHost,
105
+ resourceId: RESOURCE_ID.toString(),
106
+ resourceNameSnapshot: "web-1",
107
+ resourceCommandTier: "SafeWrite",
108
+ policyVerdict: "AutoApproved",
109
+ rationale: "restart",
110
+ ...(i < executedCommands
111
+ ? {
112
+ execution: {
113
+ status: "Succeeded",
114
+ runnerJobId: ObjectID.generate().toString(),
115
+ },
116
+ }
117
+ : i === 2
118
+ ? // A command skipped after an earlier one failed never ran.
119
+ { execution: { status: "Skipped" } }
120
+ : {}),
121
+ });
122
+ }
123
+
124
+ return { commands, summary: "restart web" } as JSONObject;
125
+ }
126
+
127
+ function round(data: {
128
+ id: ObjectID;
129
+ status: AutoRemediationSuggestionStatus;
130
+ resourceId?: ObjectID | undefined;
131
+ rationaleMarkdown?: string | undefined;
132
+ commandPlan?: JSONObject | undefined;
133
+ }): AutoRemediationSuggestion {
134
+ return {
135
+ id: data.id,
136
+ _id: data.id.toString(),
137
+ status: data.status,
138
+ resourceType: AiResourceType.DockerHost,
139
+ resourceId: data.resourceId || RESOURCE_ID,
140
+ rationaleMarkdown: data.rationaleMarkdown,
141
+ commandPlan: data.commandPlan,
142
+ } as unknown as AutoRemediationSuggestion;
143
+ }
144
+
145
+ interface Transition {
146
+ suggestionId: ObjectID;
147
+ fromStatus: AutoRemediationSuggestionStatus;
148
+ set: Record<string, unknown>;
149
+ }
150
+
151
+ describe("ResourceAiDeleteCleanup", () => {
152
+ let service: FakeService;
153
+ let suggestionFind: jest.SpyInstance;
154
+ let transition: jest.SpyInstance;
155
+ let deleteAgents: jest.SpyInstance;
156
+ let loggedError: jest.SpyInstance;
157
+
158
+ beforeEach(() => {
159
+ loggedError = jest.spyOn(logger, "error").mockImplementation((): void => {
160
+ return undefined;
161
+ });
162
+ service = fakeService();
163
+ suggestionFind = jest
164
+ .spyOn(AutoRemediationSuggestionService, "findBy")
165
+ .mockResolvedValue([
166
+ round({
167
+ id: PLANNING_ID,
168
+ status: AutoRemediationSuggestionStatus.Planning,
169
+ }),
170
+ round({
171
+ id: SUGGESTED_ID,
172
+ status: AutoRemediationSuggestionStatus.Suggested,
173
+ rationaleMarkdown: "The web container leaks memory; restart it.",
174
+ commandPlan: commandPlan(0),
175
+ }),
176
+ ]);
177
+ transition = jest
178
+ .spyOn(AutoRemediationSuggestionService, "attemptStatusTransition")
179
+ .mockResolvedValue(1);
180
+ deleteAgents = jest
181
+ .spyOn(ResourceAiAgentService, "deleteAgentsForResources")
182
+ .mockResolvedValue(1);
183
+ });
184
+
185
+ afterEach(() => {
186
+ jest.restoreAllMocks();
187
+ });
188
+
189
+ async function deleteResource(
190
+ deletedItemIds: Array<ObjectID> = [RESOURCE_ID],
191
+ props: DatabaseCommonInteractionProps = userProps(),
192
+ resourceType: AiResourceType = AiResourceType.DockerHost,
193
+ ): Promise<void> {
194
+ const request: DeleteBy<BaseModel> = deleteBy(props);
195
+ const carryForward: ResourceAiDeleteCarryForward =
196
+ await ResourceAiDeleteCleanup.beforeDelete({
197
+ resourceType,
198
+ service: asService(service),
199
+ deleteBy: request,
200
+ });
201
+
202
+ await ResourceAiDeleteCleanup.afterDelete({
203
+ resourceType,
204
+ onDelete: { deleteBy: request, carryForward } as OnDelete<BaseModel>,
205
+ deletedItemIds,
206
+ });
207
+ }
208
+
209
+ function transitions(): Array<Transition> {
210
+ return transition.mock.calls.map((call: Array<unknown>): Transition => {
211
+ return call[0] as Transition;
212
+ });
213
+ }
214
+
215
+ describe("beforeDelete", () => {
216
+ it("reads the matched resources in the caller's project, then their in-flight rounds of that type", async () => {
217
+ const carryForward: ResourceAiDeleteCarryForward =
218
+ await ResourceAiDeleteCleanup.beforeDelete({
219
+ resourceType: AiResourceType.DockerHost,
220
+ service: asService(service),
221
+ deleteBy: deleteBy(),
222
+ });
223
+
224
+ const resourceRead: {
225
+ query: Record<string, unknown>;
226
+ select: Record<string, unknown>;
227
+ props: Record<string, unknown>;
228
+ } = service.findBy.mock.calls[0]![0] as {
229
+ query: Record<string, unknown>;
230
+ select: Record<string, unknown>;
231
+ props: Record<string, unknown>;
232
+ };
233
+ expect(resourceRead.query["_id"]).toBe(RESOURCE_ID.toString());
234
+ expect(resourceRead.query["projectId"]).toBe(PROJECT_ID);
235
+ expect(resourceRead.select["name"]).toBe(true);
236
+ expect(resourceRead.props["isRoot"]).toBe(true);
237
+
238
+ const suggestionQuery: Record<string, unknown> = (
239
+ suggestionFind.mock.calls[0]![0] as { query: Record<string, unknown> }
240
+ ).query;
241
+ expect(suggestionQuery["resourceType"]).toBe(AiResourceType.DockerHost);
242
+ expect(JSON.stringify(suggestionQuery["resourceId"])).toContain(
243
+ RESOURCE_ID.toString(),
244
+ );
245
+ expect(JSON.stringify(suggestionQuery["status"])).toContain("Planning");
246
+ expect(JSON.stringify(suggestionQuery["status"])).toContain("Suggested");
247
+
248
+ expect(carryForward.resourceType).toBe(AiResourceType.DockerHost);
249
+ expect(carryForward.inFlightRounds).toHaveLength(2);
250
+ expect(carryForward.resourceNames).toEqual({
251
+ [RESOURCE_ID.toString()]: "web-1",
252
+ });
253
+
254
+ // Nothing is settled or deleted before the delete has happened.
255
+ expect(transition).not.toHaveBeenCalled();
256
+ expect(deleteAgents).not.toHaveBeenCalled();
257
+ });
258
+
259
+ it("a root delete (no project) reads by the delete's own query", async () => {
260
+ await ResourceAiDeleteCleanup.beforeDelete({
261
+ resourceType: AiResourceType.DockerHost,
262
+ service: asService(service),
263
+ deleteBy: deleteBy({ isRoot: true } as DatabaseCommonInteractionProps),
264
+ });
265
+
266
+ const query: Record<string, unknown> = (
267
+ service.findBy.mock.calls[0]![0] as { query: Record<string, unknown> }
268
+ ).query;
269
+ expect(query).toEqual({ _id: RESOURCE_ID.toString() });
270
+ });
271
+
272
+ it("negative control: a delete that matches no resource reads no round", async () => {
273
+ service.findBy.mockResolvedValue([]);
274
+
275
+ const carryForward: ResourceAiDeleteCarryForward =
276
+ await ResourceAiDeleteCleanup.beforeDelete({
277
+ resourceType: AiResourceType.DockerHost,
278
+ service: asService(service),
279
+ deleteBy: deleteBy(),
280
+ });
281
+
282
+ expect(suggestionFind).not.toHaveBeenCalled();
283
+ expect(carryForward.inFlightRounds).toEqual([]);
284
+ });
285
+
286
+ it("never blocks the delete: a failed read is logged and hands over nothing", async () => {
287
+ service.findBy.mockRejectedValue(new Error("db down"));
288
+
289
+ const carryForward: ResourceAiDeleteCarryForward =
290
+ await ResourceAiDeleteCleanup.beforeDelete({
291
+ resourceType: AiResourceType.CephCluster,
292
+ service: asService(service),
293
+ deleteBy: deleteBy(),
294
+ });
295
+
296
+ expect(carryForward).toEqual({
297
+ resourceType: AiResourceType.CephCluster,
298
+ inFlightRounds: [],
299
+ resourceNames: {},
300
+ });
301
+ expect(String(loggedError.mock.calls[0]![0])).toContain(
302
+ "could not read the in-flight AI remediation rounds of the Ceph cluster(s) being deleted",
303
+ );
304
+ });
305
+ });
306
+
307
+ describe("afterDelete", () => {
308
+ it("dismisses Planning and Suggested rounds with a note naming the deleted resource", async () => {
309
+ await deleteResource();
310
+
311
+ expect(transitions()).toHaveLength(2);
312
+
313
+ const [planning, suggested] = transitions();
314
+
315
+ expect(planning!.suggestionId).toBe(PLANNING_ID);
316
+ expect(planning!.fromStatus).toBe(
317
+ AutoRemediationSuggestionStatus.Planning,
318
+ );
319
+ expect(planning!.set["status"]).toBe(
320
+ AutoRemediationSuggestionStatus.Dismissed,
321
+ );
322
+ expect(planning!.set["dismissedByUserId"]).toBe(USER_ID.toString());
323
+ expect(planning!.set["dismissedAt"]).toBeInstanceOf(Date);
324
+ expect(planning!.set["rationaleMarkdown"]).toBe(
325
+ '**Dismissed: the Docker host "web-1" this remediation was for was deleted.** None of its commands ran, and none will.',
326
+ );
327
+
328
+ expect(suggested!.suggestionId).toBe(SUGGESTED_ID);
329
+ expect(suggested!.fromStatus).toBe(
330
+ AutoRemediationSuggestionStatus.Suggested,
331
+ );
332
+ // The AI's own reasoning is kept, after the note.
333
+ expect(String(suggested!.set["rationaleMarkdown"])).toMatch(
334
+ /was deleted\.\*\* None of its commands ran, and none will\.\n\nThe web container leaks memory; restart it\.$/,
335
+ );
336
+ });
337
+
338
+ it("says so when the round had already run commands, and that nothing was rolled back", async () => {
339
+ suggestionFind.mockResolvedValue([
340
+ round({
341
+ id: PLANNING_ID,
342
+ status: AutoRemediationSuggestionStatus.Planning,
343
+ commandPlan: commandPlan(2),
344
+ }),
345
+ ]);
346
+
347
+ await deleteResource();
348
+
349
+ const note: string = String(transitions()[0]!.set["rationaleMarkdown"]);
350
+ // Two ran; the Skipped third one never did.
351
+ expect(note).toContain("2 command(s) had already run on it before");
352
+ expect(note).toContain("nothing was rolled back");
353
+ expect(note).not.toContain("None of its commands ran");
354
+ });
355
+
356
+ it("settles only the rounds of resources that were actually deleted, and deletes only their agents", async () => {
357
+ service.findBy.mockResolvedValue([
358
+ { id: RESOURCE_ID, name: "web-1" },
359
+ { id: OTHER_RESOURCE_ID, name: "web-2" },
360
+ ]);
361
+ suggestionFind.mockResolvedValue([
362
+ round({
363
+ id: PLANNING_ID,
364
+ status: AutoRemediationSuggestionStatus.Planning,
365
+ resourceId: OTHER_RESOURCE_ID,
366
+ }),
367
+ round({
368
+ id: SUGGESTED_ID,
369
+ status: AutoRemediationSuggestionStatus.Suggested,
370
+ }),
371
+ ]);
372
+
373
+ // Only RESOURCE_ID was deleted (the other was refused by permissions).
374
+ await deleteResource([RESOURCE_ID]);
375
+
376
+ expect(
377
+ transitions().map((call: Transition): string => {
378
+ return call.suggestionId.toString();
379
+ }),
380
+ ).toEqual([SUGGESTED_ID.toString()]);
381
+ expect(deleteAgents).toHaveBeenCalledTimes(1);
382
+ expect(deleteAgents).toHaveBeenCalledWith({
383
+ resourceType: AiResourceType.DockerHost,
384
+ resourceIds: [RESOURCE_ID],
385
+ });
386
+ });
387
+
388
+ it("deletes the agents after settling the rounds", async () => {
389
+ const order: Array<string> = [];
390
+ transition.mockImplementation(async (): Promise<number> => {
391
+ order.push("settle");
392
+ return 1;
393
+ });
394
+ deleteAgents.mockImplementation(async (): Promise<number> => {
395
+ order.push("agents");
396
+ return 1;
397
+ });
398
+
399
+ await deleteResource();
400
+
401
+ expect(order).toEqual(["settle", "settle", "agents"]);
402
+ });
403
+
404
+ it("negative control: a delete that removed nothing settles and deletes nothing", async () => {
405
+ await deleteResource([]);
406
+
407
+ expect(transition).not.toHaveBeenCalled();
408
+ expect(deleteAgents).not.toHaveBeenCalled();
409
+ });
410
+
411
+ it("negative control: a resource with no in-flight round still loses its agents", async () => {
412
+ suggestionFind.mockResolvedValue([]);
413
+
414
+ await deleteResource();
415
+
416
+ expect(transition).not.toHaveBeenCalled();
417
+ expect(deleteAgents).toHaveBeenCalledWith({
418
+ resourceType: AiResourceType.DockerHost,
419
+ resourceIds: [RESOURCE_ID],
420
+ });
421
+ });
422
+
423
+ it("still deletes the agents when the rounds could not be read before the delete", async () => {
424
+ suggestionFind.mockRejectedValue(new Error("db down"));
425
+
426
+ await expect(deleteResource()).resolves.toBeUndefined();
427
+
428
+ expect(transition).not.toHaveBeenCalled();
429
+ expect(deleteAgents).toHaveBeenCalledTimes(1);
430
+ });
431
+
432
+ it("still deletes the agents when no carry-forward was handed over", async () => {
433
+ await ResourceAiDeleteCleanup.afterDelete({
434
+ resourceType: AiResourceType.Host,
435
+ onDelete: {
436
+ deleteBy: deleteBy(),
437
+ carryForward: null,
438
+ } as OnDelete<BaseModel>,
439
+ deletedItemIds: [RESOURCE_ID],
440
+ });
441
+
442
+ expect(transition).not.toHaveBeenCalled();
443
+ expect(deleteAgents).toHaveBeenCalledWith({
444
+ resourceType: AiResourceType.Host,
445
+ resourceIds: [RESOURCE_ID],
446
+ });
447
+ });
448
+
449
+ it("never fails the delete: a failed settle is logged, the next round and the agents still go", async () => {
450
+ transition
451
+ .mockRejectedValueOnce(new Error("db down"))
452
+ .mockResolvedValueOnce(1);
453
+
454
+ await expect(deleteResource()).resolves.toBeUndefined();
455
+
456
+ expect(transition).toHaveBeenCalledTimes(2);
457
+ expect(deleteAgents).toHaveBeenCalledTimes(1);
458
+ expect(String(loggedError.mock.calls[0]![0])).toContain(
459
+ `could not settle AI remediation suggestion ${PLANNING_ID.toString()} of a deleted Docker host`,
460
+ );
461
+ });
462
+
463
+ it("never fails the delete: a failed agent delete is only logged", async () => {
464
+ deleteAgents.mockRejectedValue(new Error("db down"));
465
+
466
+ await expect(deleteResource()).resolves.toBeUndefined();
467
+
468
+ expect(String(loggedError.mock.calls[0]![0])).toContain(
469
+ "could not delete the AI agent(s) of the deleted Docker host(s)",
470
+ );
471
+ });
472
+
473
+ it("a root delete (no user) settles without naming anyone", async () => {
474
+ await deleteResource([RESOURCE_ID], {
475
+ isRoot: true,
476
+ } as DatabaseCommonInteractionProps);
477
+
478
+ expect(transitions()[0]!.set).not.toHaveProperty("dismissedByUserId");
479
+ expect(transitions()[0]!.set["status"]).toBe(
480
+ AutoRemediationSuggestionStatus.Dismissed,
481
+ );
482
+ });
483
+
484
+ it("a resource without a name is still named by its type", async () => {
485
+ service.findBy.mockResolvedValue([{ id: RESOURCE_ID, name: " " }]);
486
+
487
+ await deleteResource();
488
+
489
+ expect(String(transitions()[0]!.set["rationaleMarkdown"])).toMatch(
490
+ /^\*\*Dismissed: the Docker host this remediation was for was deleted\.\*\*/,
491
+ );
492
+ });
493
+ });
494
+
495
+ describe("getResourceAiDeleteCarryForward", () => {
496
+ it("reads back only a resource delete carry-forward of the same type", () => {
497
+ const carryForward: ResourceAiDeleteCarryForward = {
498
+ resourceType: AiResourceType.PodmanHost,
499
+ inFlightRounds: [],
500
+ resourceNames: {},
501
+ };
502
+
503
+ expect(
504
+ getResourceAiDeleteCarryForward(
505
+ carryForward,
506
+ AiResourceType.PodmanHost,
507
+ ),
508
+ ).toBe(carryForward);
509
+ expect(
510
+ getResourceAiDeleteCarryForward(
511
+ carryForward,
512
+ AiResourceType.DockerHost,
513
+ ),
514
+ ).toBeNull();
515
+ expect(
516
+ getResourceAiDeleteCarryForward(null, AiResourceType.PodmanHost),
517
+ ).toBeNull();
518
+ expect(
519
+ getResourceAiDeleteCarryForward([], AiResourceType.PodmanHost),
520
+ ).toBeNull();
521
+ // A Kubernetes cluster's carry-forward is not one.
522
+ expect(
523
+ getResourceAiDeleteCarryForward(
524
+ { inFlightRounds: [], clusterNames: {} },
525
+ AiResourceType.PodmanHost,
526
+ ),
527
+ ).toBeNull();
528
+ });
529
+ });
530
+
531
+ describe("getDeletedResourceNote", () => {
532
+ it("names every resource type in a sentence", () => {
533
+ const expected: Record<AiResourceType, string> = {
534
+ [AiResourceType.DockerHost]: 'the Docker host "x"',
535
+ [AiResourceType.PodmanHost]: 'the Podman host "x"',
536
+ [AiResourceType.DockerSwarmCluster]: 'the Docker Swarm cluster "x"',
537
+ [AiResourceType.ProxmoxCluster]: 'the Proxmox cluster "x"',
538
+ [AiResourceType.VMwareVCenter]: 'the VMware vCenter "x"',
539
+ [AiResourceType.CephCluster]: 'the Ceph cluster "x"',
540
+ [AiResourceType.DatabaseServer]: 'the database server "x"',
541
+ [AiResourceType.Host]: 'the host "x"',
542
+ };
543
+
544
+ for (const resourceType of ALL_AI_RESOURCE_TYPES) {
545
+ expect(
546
+ ResourceAiDeleteCleanup.getDeletedResourceNote({
547
+ resourceType,
548
+ resourceName: "x",
549
+ executedCount: 0,
550
+ }),
551
+ ).toBe(
552
+ `**Dismissed: ${expected[resourceType]} this remediation was for was deleted.** None of its commands ran, and none will.`,
553
+ );
554
+ }
555
+ });
556
+
557
+ it("says how many commands had run", () => {
558
+ expect(
559
+ ResourceAiDeleteCleanup.getDeletedResourceNote({
560
+ resourceType: AiResourceType.Host,
561
+ resourceName: "web-2",
562
+ executedCount: 3,
563
+ }),
564
+ ).toBe(
565
+ '**Dismissed: the host "web-2" this remediation was for was deleted.** 3 command(s) had already run on it before; nothing was rolled back and no further command will run.',
566
+ );
567
+ });
568
+ });
569
+ });