@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,747 @@
1
+ import {
2
+ DOCKER_COMMAND_REFUSALS,
3
+ DOCKER_ENGINE_READ_COMMANDS,
4
+ DOCKER_ENGINE_WRITE_PATHS,
5
+ DOCKER_SWARM_GROUPS,
6
+ DockerCommandPath,
7
+ DockerCommandSpec,
8
+ DockerFlagKind,
9
+ DockerFlagSpec,
10
+ DockerJudgement,
11
+ DockerParsedArgs,
12
+ DockerProfile,
13
+ describeAllowedDockerFlags,
14
+ dockerFlagValue,
15
+ dockerFlagValues,
16
+ evaluateDockerArgv,
17
+ evaluateDockerArgvSafely,
18
+ findBadDockerFilter,
19
+ findBadDockerFormat,
20
+ findBadDockerName,
21
+ isDockerCpuCount,
22
+ isDockerFlagGiven,
23
+ isDockerImageReference,
24
+ isDockerMemorySize,
25
+ isDockerObjectName,
26
+ isDockerSwitchOn,
27
+ isDockerTimeValue,
28
+ isGoDuration,
29
+ mergeDockerCommands,
30
+ parseDockerCount,
31
+ parseDockerFlags,
32
+ parseDockerRelativeTimeSeconds,
33
+ resolveDockerCommandPath,
34
+ uniqueDockerTargets,
35
+ } from "../../../../Utils/AiRemediation/Resource/DockerCliGrammar";
36
+ import { DOCKER_ENGINE_PROFILE } from "../../../../Utils/AiRemediation/Resource/DockerEngineCommandPolicy";
37
+ import { DOCKER_SWARM_PROFILE } from "../../../../Utils/AiRemediation/Resource/DockerSwarmCommandPolicy";
38
+ import { ResourceCommandPolicyResult } from "../../../../Utils/AiRemediation/Resource/ResourceCommandPolicyCore";
39
+ import { ResourceCommandTier } from "../../../../Types/ResourceAiAgent/ResourceAiAccess";
40
+ import { describe, expect, test } from "@jest/globals";
41
+
42
+ /*
43
+ * Contract under test — the docker CLI grammar both docker policies share:
44
+ * command lookup (no flag before the command), a flag parser that reads an
45
+ * argv exactly the way pflag does (so nothing can hide in what we took for
46
+ * a flag value), fail-closed extras (unknown flags, repeats, value checks),
47
+ * and a total evaluator.
48
+ */
49
+
50
+ const FLAGS: ReadonlyArray<DockerFlagSpec> = [
51
+ { name: "all", shorthand: "a", kind: DockerFlagKind.Bool },
52
+ { name: "quiet", shorthand: "q", kind: DockerFlagKind.Bool },
53
+ { name: "last", shorthand: "n", kind: DockerFlagKind.Value },
54
+ {
55
+ name: "filter",
56
+ shorthand: "f",
57
+ kind: DockerFlagKind.Value,
58
+ repeatable: true,
59
+ },
60
+ {
61
+ name: "timeout",
62
+ shorthand: "t",
63
+ kind: DockerFlagKind.Value,
64
+ aliases: ["time"],
65
+ },
66
+ {
67
+ name: "follow",
68
+ shorthand: "F",
69
+ kind: DockerFlagKind.Bool,
70
+ refusal: "is refused for the test",
71
+ },
72
+ ];
73
+
74
+ function parse(
75
+ words: Array<string>,
76
+ interspersed: boolean = true,
77
+ ): DockerParsedArgs {
78
+ return parseDockerFlags({
79
+ words,
80
+ flags: FLAGS,
81
+ command: "docker test",
82
+ interspersed,
83
+ });
84
+ }
85
+
86
+ function valuesOf(parsed: DockerParsedArgs): Record<string, Array<string>> {
87
+ const out: Record<string, Array<string>> = {};
88
+
89
+ parsed.values.forEach((values: Array<string>, name: string): void => {
90
+ out[name] = values;
91
+ });
92
+
93
+ return out;
94
+ }
95
+
96
+ describe("parseDockerFlags mirrors pflag", () => {
97
+ test.each([
98
+ [["--last=5"], { last: ["5"] }, []],
99
+ [["--last", "5"], { last: ["5"] }, []],
100
+ [["-n", "5"], { last: ["5"] }, []],
101
+ [["-n5"], { last: ["5"] }, []],
102
+ [["-n=5"], { last: ["5"] }, []],
103
+ [["-n="], { last: ["="] }, []],
104
+ [["-an", "5"], { all: ["true"], last: ["5"] }, []],
105
+ [["-aqn5"], { all: ["true"], quiet: ["true"], last: ["5"] }, []],
106
+ [["-na"], { last: ["a"] }, []],
107
+ [["-a=false"], { all: ["false"] }, []],
108
+ [["--all=false"], { all: ["false"] }, []],
109
+ [["--all", "false"], { all: ["true"] }, ["false"]],
110
+ [["-a", "x"], { all: ["true"] }, ["x"]],
111
+ [["x", "-a", "y"], { all: ["true"] }, ["x", "y"]],
112
+ [["-n", "-a"], { last: ["-a"] }, []],
113
+ [["--last", "--all"], { last: ["--all"] }, []],
114
+ [["--", "-a", "--all"], {}, ["-a", "--all"]],
115
+ [["-a", "--", "--"], { all: ["true"] }, ["--"]],
116
+ [["-"], {}, ["-"]],
117
+ [[""], {}, [""]],
118
+ [
119
+ ["-f", "a=1", "--filter=b=2", "-fc=3"],
120
+ { filter: ["a=1", "b=2", "c=3"] },
121
+ [],
122
+ ],
123
+ [["--time", "5"], { timeout: ["5"] }, []],
124
+ [["-t5"], { timeout: ["5"] }, []],
125
+ ])(
126
+ "%p parses to %p with positionals %p",
127
+ (
128
+ words: Array<string>,
129
+ values: Record<string, Array<string>>,
130
+ positionals: Array<string>,
131
+ ) => {
132
+ const parsed: DockerParsedArgs = parse(words);
133
+
134
+ expect(parsed.problem).toBeUndefined();
135
+ expect(valuesOf(parsed)).toEqual(values);
136
+ expect(parsed.positionals).toEqual(positionals);
137
+ },
138
+ );
139
+
140
+ test.each([
141
+ ["1", "true"],
142
+ ["t", "true"],
143
+ ["T", "true"],
144
+ ["TRUE", "true"],
145
+ ["true", "true"],
146
+ ["True", "true"],
147
+ ["0", "false"],
148
+ ["f", "false"],
149
+ ["F", "false"],
150
+ ["FALSE", "false"],
151
+ ["false", "false"],
152
+ ["False", "false"],
153
+ ])(
154
+ "a switch reads =%s as %s (Go's ParseBool)",
155
+ (written: string, value: string) => {
156
+ expect(dockerFlagValue(parse([`--all=${written}`]), "all")).toBe(value);
157
+ expect(dockerFlagValue(parse([`-a=${written}`]), "all")).toBe(value);
158
+ },
159
+ );
160
+
161
+ test.each([
162
+ [["--all=yes"], "is a switch"],
163
+ [["--all=tRUE"], "is a switch"],
164
+ [["-a=on"], "is a switch"],
165
+ [["--all="], "is a switch"],
166
+ [["-a="], "not one OneUptime AI may use"],
167
+ [["--last"], "needs a value"],
168
+ [["-n"], "needs a value"],
169
+ [["-an"], "needs a value"],
170
+ [["---all"], "not valid flag syntax"],
171
+ [["--=5"], "not valid flag syntax"],
172
+ [["--bogus"], "not one OneUptime AI may use with docker test"],
173
+ [["-z"], "not one OneUptime AI may use with docker test"],
174
+ [["-az"], '-z (in "-az")'],
175
+ [["--ALL"], "not one OneUptime AI"],
176
+ [["-A"], "not one OneUptime AI"],
177
+ [["--no_trunc"], "not one OneUptime AI"],
178
+ [["--follow"], "is refused for the test"],
179
+ [["-F"], "is refused for the test"],
180
+ [["-aF"], '-F (in "-aF") flag is refused'],
181
+ [["--follow=false"], "is refused for the test"],
182
+ [["-a", "-a"], "more than once"],
183
+ [["-aa"], "more than once"],
184
+ [["--all", "--all=false"], "more than once"],
185
+ [["-n", "1", "--last=2"], "more than once"],
186
+ [["-t", "1", "--time", "2"], "more than once"],
187
+ [["--host", "x"], "global flags"],
188
+ [["-H", "x"], "global flags"],
189
+ [["--tlscacert", "x"], "global flags"],
190
+ [["--context=x"], "global flags"],
191
+ [["-D"], "global flags"],
192
+ [["-а"], "not one OneUptime AI"],
193
+ [["—all"], ""],
194
+ ])("%p is refused (%s)", (words: Array<string>, phrase: string) => {
195
+ const parsed: DockerParsedArgs = parse(words);
196
+
197
+ if (phrase === "") {
198
+ // A look-alike dash is no flag at all: it is a positional.
199
+ expect(parsed.problem).toBeUndefined();
200
+ expect(parsed.positionals).toEqual(words);
201
+ return;
202
+ }
203
+
204
+ expect(parsed.problem).toContain(phrase);
205
+ });
206
+
207
+ test("a refused flag lists what the command allows, without refused flags", () => {
208
+ const problem: string = parse(["--bogus"]).problem || "";
209
+
210
+ expect(problem).toContain(
211
+ "-a/--all, -q/--quiet, -n/--last VALUE, -f/--filter VALUE, -t/--timeout VALUE",
212
+ );
213
+ expect(problem).not.toContain("--follow");
214
+ });
215
+
216
+ test("a non-interspersed command stops reading flags at its first positional", () => {
217
+ const parsed: DockerParsedArgs = parse(
218
+ ["-a", "web", "-q", "--last=5"],
219
+ false,
220
+ );
221
+
222
+ expect(parsed.problem).toBeUndefined();
223
+ expect(valuesOf(parsed)).toEqual({ all: ["true"] });
224
+ expect(parsed.positionals).toEqual(["web", "-q", "--last=5"]);
225
+ });
226
+
227
+ test("accessors", () => {
228
+ const parsed: DockerParsedArgs = parse([
229
+ "-a=false",
230
+ "-f",
231
+ "a=1",
232
+ "-f",
233
+ "b=2",
234
+ "-q",
235
+ ]);
236
+
237
+ expect(dockerFlagValues(parsed, "filter")).toEqual(["a=1", "b=2"]);
238
+ expect(dockerFlagValue(parsed, "filter")).toBe("b=2");
239
+ expect(dockerFlagValue(parsed, "last")).toBeUndefined();
240
+ expect(isDockerFlagGiven(parsed, "all")).toBe(true);
241
+ expect(isDockerSwitchOn(parsed, "all")).toBe(false);
242
+ expect(isDockerSwitchOn(parsed, "quiet")).toBe(true);
243
+ expect(isDockerFlagGiven(parsed, "last")).toBe(false);
244
+ });
245
+
246
+ test("describeAllowedDockerFlags says none when nothing is allowed", () => {
247
+ expect(describeAllowedDockerFlags([])).toBe("none");
248
+ expect(
249
+ describeAllowedDockerFlags([
250
+ { name: "x", kind: DockerFlagKind.Bool, refusal: "no" },
251
+ ]),
252
+ ).toBe("none");
253
+ });
254
+ });
255
+
256
+ describe("resolveDockerCommandPath", () => {
257
+ test.each([
258
+ [["docker", "ps", "-a"], "ps", undefined, ["-a"]],
259
+ [["docker", "container", "ls", "-a"], "container ls", "container", ["-a"]],
260
+ [["docker", "container", "list"], "container ls", "container", []],
261
+ [["docker", "container", "ps"], "container ls", "container", []],
262
+ [["docker", "image", "list"], "image ls", "image", []],
263
+ [["docker", "image", "rmi", "x"], "image rm", "image", ["x"]],
264
+ [
265
+ ["docker", "container", "remove", "x"],
266
+ "container rm",
267
+ "container",
268
+ ["x"],
269
+ ],
270
+ [["docker", "stack", "up"], "stack deploy", "stack", []],
271
+ [["docker", "stack", "down", "app"], "stack rm", "stack", ["app"]],
272
+ [["docker", "service", "list"], "service ls", "service", []],
273
+ [
274
+ ["docker", "container", "frobnicate"],
275
+ "container frobnicate",
276
+ "container",
277
+ [],
278
+ ],
279
+ [["docker", "secret", "ls"], "secret", undefined, ["ls"]],
280
+ [["docker", "constructor"], "constructor", undefined, []],
281
+ [
282
+ ["docker", "container", "__proto__"],
283
+ "container __proto__",
284
+ "container",
285
+ [],
286
+ ],
287
+ ])(
288
+ "%p resolves to %p",
289
+ (
290
+ words: Array<string>,
291
+ path: string,
292
+ group: string | undefined,
293
+ rest: Array<string>,
294
+ ) => {
295
+ const resolved: DockerCommandPath = resolveDockerCommandPath(words);
296
+
297
+ expect(resolved.problem).toBeUndefined();
298
+ expect(resolved.path).toBe(path);
299
+ expect(resolved.group).toBe(group);
300
+ expect(resolved.rest).toEqual(rest);
301
+ },
302
+ );
303
+
304
+ test.each([
305
+ [["docker"], 'after "docker"'],
306
+ [["docker", "-H", "x", "ps"], "global flags"],
307
+ [["docker", "--", "ps"], "global flags"],
308
+ [["docker", "container"], "needs a subcommand"],
309
+ [
310
+ ["docker", "container", "-a", "ls"],
311
+ "comes before the docker container subcommand",
312
+ ],
313
+ [
314
+ ["docker", "service", "--help"],
315
+ "comes before the docker service subcommand",
316
+ ],
317
+ ])("%p has a problem (%s)", (words: Array<string>, phrase: string) => {
318
+ expect(resolveDockerCommandPath(words).problem).toContain(phrase);
319
+ });
320
+ });
321
+
322
+ describe("values", () => {
323
+ test.each([
324
+ ["web", true],
325
+ ["web-1", true],
326
+ ["my_app.web.1", true],
327
+ ["3f2a9c1b7d4e", true],
328
+ ["a", true],
329
+ ["self", true],
330
+ ["-web", false],
331
+ ["_web", false],
332
+ [".web", false],
333
+ ["/web", false],
334
+ ["web app", false],
335
+ ["web;rm", false],
336
+ ["wеb", false],
337
+ ["web​", false],
338
+ ["", false],
339
+ ["{{.Name}}", false],
340
+ ["a".repeat(255), true],
341
+ ["a".repeat(256), false],
342
+ ])("isDockerObjectName(%p) is %p", (word: string, expected: boolean) => {
343
+ expect(isDockerObjectName(word)).toBe(expected);
344
+ });
345
+
346
+ test.each([
347
+ ["nginx", true],
348
+ ["nginx:1.27", true],
349
+ ["registry.example.com:5000/team/app:2.0", true],
350
+ ["app@sha256:0123abcdef", true],
351
+ ["-q", false],
352
+ ["", false],
353
+ ["nginx latest", false],
354
+ ["{{.}}", false],
355
+ ])("isDockerImageReference(%p) is %p", (word: string, expected: boolean) => {
356
+ expect(isDockerImageReference(word)).toBe(expected);
357
+ });
358
+
359
+ test.each([
360
+ ["30m", true],
361
+ ["0s", true],
362
+ ["1h30m", true],
363
+ ["1.5h", true],
364
+ ["300ms", true],
365
+ ["2026-09-29", true],
366
+ ["2026-09-29T10:00", true],
367
+ ["2026-09-29T10:00:00Z", true],
368
+ ["2026-09-29T10:00:00.123+02:00", true],
369
+ ["1758000000", true],
370
+ ["1758000000.25", true],
371
+ ["0", false],
372
+ ["", false],
373
+ ["-10m", false],
374
+ ["+10m", false],
375
+ ["10", false],
376
+ ["yesterday", false],
377
+ ["30 m", false],
378
+ ["1h".repeat(40), false],
379
+ ])("isDockerTimeValue(%p) is %p", (value: string, expected: boolean) => {
380
+ expect(isDockerTimeValue(value)).toBe(expected);
381
+ });
382
+
383
+ test.each([
384
+ ["0s", 0],
385
+ ["30m", 1800],
386
+ ["1h30m", 5400],
387
+ ["1.5h", 5400],
388
+ ["24h", 86400],
389
+ ["250ms", 0.25],
390
+ ["2026-09-29", null],
391
+ ["2026-09-29T10:00:00Z", null],
392
+ ["1758000000", null],
393
+ ["9999999999", null],
394
+ ["", null],
395
+ ["-10m", null],
396
+ ])(
397
+ "parseDockerRelativeTimeSeconds(%p) is %p",
398
+ (value: string, expected: number | null) => {
399
+ expect(parseDockerRelativeTimeSeconds(value)).toBe(expected);
400
+ },
401
+ );
402
+
403
+ test("isGoDuration accepts 0 (update delays) but not garbage", () => {
404
+ expect(isGoDuration("0")).toBe(true);
405
+ expect(isGoDuration("10s")).toBe(true);
406
+ expect(isGoDuration("soon")).toBe(false);
407
+ expect(isGoDuration("-1s")).toBe(false);
408
+ });
409
+
410
+ test.each([
411
+ ["0", 10, 0],
412
+ ["10", 10, 10],
413
+ ["0010", 10, 10],
414
+ ["11", 10, null],
415
+ ["-1", 10, null],
416
+ ["+1", 10, null],
417
+ ["1.5", 10, null],
418
+ ["", 10, null],
419
+ ["1e3", 10000, null],
420
+ ["9".repeat(10), 10, null],
421
+ ])(
422
+ "parseDockerCount(%p, %p) is %p",
423
+ (value: string, max: number, expected: number | null) => {
424
+ expect(parseDockerCount(value, max)).toBe(expected);
425
+ },
426
+ );
427
+
428
+ test.each([
429
+ ["512m", true],
430
+ ["1g", true],
431
+ ["1.5GiB", true],
432
+ ["536870912", true],
433
+ ["512MB", true],
434
+ ["256b", true],
435
+ ["lots", false],
436
+ ["-1", false],
437
+ ["1 g", false],
438
+ ["1gg", false],
439
+ ])("isDockerMemorySize(%p) is %p", (value: string, expected: boolean) => {
440
+ expect(isDockerMemorySize(value)).toBe(expected);
441
+ });
442
+
443
+ test.each([
444
+ ["0.5", true],
445
+ ["2", true],
446
+ ["1.25", true],
447
+ ["two", false],
448
+ ["-1", false],
449
+ ["1.2345", false],
450
+ ])("isDockerCpuCount(%p) is %p", (value: string, expected: boolean) => {
451
+ expect(isDockerCpuCount(value)).toBe(expected);
452
+ });
453
+
454
+ test("filters must be KEY=VALUE", () => {
455
+ const withFilters: (...filters: Array<string>) => DockerParsedArgs = (
456
+ ...filters: Array<string>
457
+ ): DockerParsedArgs => {
458
+ return parse(
459
+ filters.reduce(
460
+ (words: Array<string>, filter: string): Array<string> => {
461
+ return [...words, "--filter", filter];
462
+ },
463
+ [],
464
+ ),
465
+ );
466
+ };
467
+
468
+ expect(findBadDockerFilter(withFilters("status=exited"))).toBeNull();
469
+ expect(
470
+ findBadDockerFilter(withFilters("label=a=b", "name=^web$")),
471
+ ).toBeNull();
472
+ expect(findBadDockerFilter(withFilters("status"))).toContain("KEY=VALUE");
473
+ expect(findBadDockerFilter(withFilters("=x"))).toContain("KEY=VALUE");
474
+ expect(findBadDockerFilter(withFilters("-q=x"))).toContain("KEY=VALUE");
475
+ expect(
476
+ findBadDockerFilter(withFilters(`name=${"x".repeat(300)}`)),
477
+ ).toContain("KEY=VALUE");
478
+ });
479
+
480
+ test("formats are json or table, never a template", () => {
481
+ const withFormat: (format: string) => DockerParsedArgs = (
482
+ format: string,
483
+ ): DockerParsedArgs => {
484
+ return parseDockerFlags({
485
+ words: ["--format", format],
486
+ flags: [{ name: "format", kind: DockerFlagKind.Value }],
487
+ command: "docker test",
488
+ interspersed: true,
489
+ });
490
+ };
491
+
492
+ expect(findBadDockerFormat(parse([]), ["json"])).toBeNull();
493
+ expect(findBadDockerFormat(withFormat("json"), ["json"])).toBeNull();
494
+ expect(findBadDockerFormat(withFormat("table"), ["json"])).toContain(
495
+ '"json"',
496
+ );
497
+ expect(
498
+ findBadDockerFormat(withFormat("{{json .}}"), ["json", "table"]),
499
+ ).toContain("Go templates are not allowed");
500
+ expect(findBadDockerFormat(withFormat("JSON"), ["json"])).not.toBeNull();
501
+ });
502
+
503
+ test("findBadDockerName names the first bad word", () => {
504
+ expect(findBadDockerName(["web", "api"], "container")).toBeNull();
505
+ expect(findBadDockerName(["web", "-x", "y z"], "container")).toContain(
506
+ '"-x" is not a container name',
507
+ );
508
+ });
509
+
510
+ test("uniqueDockerTargets keeps the first of each, in order", () => {
511
+ expect(uniqueDockerTargets(["b", "a", "b", "c", "a"])).toEqual([
512
+ "b",
513
+ "a",
514
+ "c",
515
+ ]);
516
+ });
517
+ });
518
+
519
+ describe("evaluateDockerArgv", () => {
520
+ function spec(
521
+ judgement: DockerJudgement | (() => DockerJudgement),
522
+ ): DockerCommandSpec {
523
+ return {
524
+ verb: "probe",
525
+ flags: [],
526
+ judge(): DockerJudgement {
527
+ return typeof judgement === "function" ? judgement() : judgement;
528
+ },
529
+ };
530
+ }
531
+
532
+ function profile(
533
+ commands: Array<[string, DockerCommandSpec]>,
534
+ refusals: Array<[string, string]> = [],
535
+ ): DockerProfile {
536
+ return {
537
+ name: "test-profile",
538
+ resourceDescription: "a test engine",
539
+ commands: new Map<string, DockerCommandSpec>(commands),
540
+ refusals: new Map<string, string>(refusals),
541
+ allowedSummary: "Allowed: probe.",
542
+ };
543
+ }
544
+
545
+ test("a Read never carries targets or requiresHuman", () => {
546
+ const result: ResourceCommandPolicyResult = evaluateDockerArgv(
547
+ profile([
548
+ [
549
+ "probe",
550
+ spec({
551
+ tier: ResourceCommandTier.Read,
552
+ reason: "reads",
553
+ targets: ["web"],
554
+ requiresHuman: true,
555
+ }),
556
+ ],
557
+ ]),
558
+ ["docker", "probe"],
559
+ );
560
+
561
+ expect(result.tier).toBe(ResourceCommandTier.Read);
562
+ expect(result.targets).toEqual([]);
563
+ expect(result.requiresHuman).toBeUndefined();
564
+ expect(result.verb).toBe("probe");
565
+ });
566
+
567
+ test("a write keeps its targets (once each) and requiresHuman", () => {
568
+ const result: ResourceCommandPolicyResult = evaluateDockerArgv(
569
+ profile([
570
+ [
571
+ "probe",
572
+ spec({
573
+ tier: ResourceCommandTier.RiskyWrite,
574
+ reason: "writes",
575
+ targets: ["web", "web", "api"],
576
+ requiresHuman: true,
577
+ }),
578
+ ],
579
+ ]),
580
+ ["docker", "probe"],
581
+ );
582
+
583
+ expect(result.tier).toBe(ResourceCommandTier.RiskyWrite);
584
+ expect(result.targets).toEqual(["web", "api"]);
585
+ expect(result.requiresHuman).toBe(true);
586
+ });
587
+
588
+ test("an unknown tier from a judge is Denied", () => {
589
+ const result: ResourceCommandPolicyResult = evaluateDockerArgv(
590
+ profile([
591
+ [
592
+ "probe",
593
+ spec({
594
+ tier: "Mystery" as ResourceCommandTier,
595
+ reason: "?",
596
+ targets: ["web"],
597
+ }),
598
+ ],
599
+ ]),
600
+ ["docker", "probe"],
601
+ );
602
+
603
+ expect(result.targets).toEqual([]);
604
+ expect(result.tier).toBe(ResourceCommandTier.Denied);
605
+ expect(result.verb).toBe("probe");
606
+ });
607
+
608
+ test("a judge that throws is Denied by the safe wrapper", () => {
609
+ const broken: DockerProfile = profile([
610
+ [
611
+ "probe",
612
+ spec((): DockerJudgement => {
613
+ throw new Error("boom");
614
+ }),
615
+ ],
616
+ ]);
617
+
618
+ expect(() => {
619
+ evaluateDockerArgv(broken, ["docker", "probe"]);
620
+ }).toThrow();
621
+
622
+ const result: ResourceCommandPolicyResult = evaluateDockerArgvSafely(
623
+ broken,
624
+ ["docker", "probe"],
625
+ );
626
+
627
+ expect(result.tier).toBe(ResourceCommandTier.Denied);
628
+ expect(result.reason).toContain("could not evaluate");
629
+ });
630
+
631
+ test("refusals: the profile's path, then its group, then the shared list", () => {
632
+ const refusing: DockerProfile = profile(
633
+ [],
634
+ [
635
+ ["exec", "is refused by the profile"],
636
+ ["service", "is refused as a group"],
637
+ ],
638
+ );
639
+
640
+ expect(evaluateDockerArgv(refusing, ["docker", "exec", "x"]).reason).toBe(
641
+ "docker exec is never allowed for a test engine: it is refused by the profile. Allowed: probe.",
642
+ );
643
+ expect(
644
+ evaluateDockerArgv(refusing, ["docker", "service", "ls"]).reason,
645
+ ).toContain(
646
+ "docker service ls is never allowed for a test engine: it is refused as a group",
647
+ );
648
+ expect(
649
+ evaluateDockerArgv(refusing, ["docker", "service"]).reason,
650
+ ).toContain(
651
+ "docker service is never allowed for a test engine: it is refused as a group",
652
+ );
653
+ expect(
654
+ evaluateDockerArgv(refusing, ["docker", "run", "x"]).reason,
655
+ ).toContain("creates and starts a new container");
656
+ expect(evaluateDockerArgv(refusing, ["docker", "probe"]).reason).toContain(
657
+ "docker probe is not a docker command OneUptime AI may run",
658
+ );
659
+ });
660
+
661
+ test("bounds are enforced even without the dispatcher", () => {
662
+ const open: DockerProfile = profile([
663
+ ["probe", spec({ tier: ResourceCommandTier.Read, reason: "reads" })],
664
+ ]);
665
+
666
+ expect(
667
+ evaluateDockerArgv(open, [
668
+ "docker",
669
+ "probe",
670
+ ...Array.from({ length: 63 }, (): string => {
671
+ return "x";
672
+ }),
673
+ ]).reason,
674
+ ).toContain("at most 64 words");
675
+ expect(
676
+ evaluateDockerArgv(open, ["docker", "probe", "x".repeat(2000)]).reason,
677
+ ).toContain("2000-character limit");
678
+ });
679
+
680
+ test("mergeDockerCommands keeps the first table's spec for a path", () => {
681
+ const first: DockerCommandSpec = spec({
682
+ tier: ResourceCommandTier.Read,
683
+ reason: "first",
684
+ });
685
+ const second: DockerCommandSpec = spec({
686
+ tier: ResourceCommandTier.Read,
687
+ reason: "second",
688
+ });
689
+
690
+ const merged: ReadonlyMap<string, DockerCommandSpec> = mergeDockerCommands(
691
+ new Map<string, DockerCommandSpec>([["probe", first]]),
692
+ new Map<string, DockerCommandSpec>([
693
+ ["probe", second],
694
+ ["other", second],
695
+ ]),
696
+ );
697
+
698
+ expect(merged.get("probe")).toBe(first);
699
+ expect(merged.get("other")).toBe(second);
700
+ });
701
+ });
702
+
703
+ describe("the two profiles and the shared refusals agree", () => {
704
+ test("no refused path is also an allowed command of either profile", () => {
705
+ for (const profileUnderTest of [
706
+ DOCKER_ENGINE_PROFILE,
707
+ DOCKER_SWARM_PROFILE,
708
+ ]) {
709
+ for (const path of DOCKER_COMMAND_REFUSALS.keys()) {
710
+ expect(profileUnderTest.commands.has(path)).toBe(false);
711
+ }
712
+
713
+ for (const path of profileUnderTest.refusals.keys()) {
714
+ expect(profileUnderTest.commands.has(path)).toBe(false);
715
+ }
716
+ }
717
+ });
718
+
719
+ test("each profile's commands are keyed by their own verb", () => {
720
+ for (const profileUnderTest of [
721
+ DOCKER_ENGINE_PROFILE,
722
+ DOCKER_SWARM_PROFILE,
723
+ ]) {
724
+ profileUnderTest.commands.forEach(
725
+ (commandSpec: DockerCommandSpec, path: string): void => {
726
+ expect(commandSpec.verb).toBe(path);
727
+ },
728
+ );
729
+ }
730
+ });
731
+
732
+ test("the engine refuses every swarm group; the swarm refuses every engine write", () => {
733
+ for (const group of DOCKER_SWARM_GROUPS) {
734
+ expect(DOCKER_ENGINE_PROFILE.refusals.has(group)).toBe(true);
735
+ }
736
+
737
+ for (const path of DOCKER_ENGINE_WRITE_PATHS) {
738
+ expect(DOCKER_SWARM_PROFILE.refusals.has(path)).toBe(true);
739
+ expect(DOCKER_ENGINE_PROFILE.commands.has(path)).toBe(true);
740
+ }
741
+
742
+ for (const path of DOCKER_ENGINE_READ_COMMANDS.keys()) {
743
+ expect(DOCKER_ENGINE_PROFILE.commands.has(path)).toBe(true);
744
+ expect(DOCKER_SWARM_PROFILE.commands.has(path)).toBe(true);
745
+ }
746
+ });
747
+ });