@oneuptime/common 14.0.8 → 14.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (639) hide show
  1. package/Models/DatabaseModels/Index.ts +2 -0
  2. package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
  3. package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
  4. package/Models/DatabaseModels/Project.ts +55 -5
  5. package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
  6. package/Models/DatabaseModels/RunnerJob.ts +75 -0
  7. package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
  8. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
  9. package/Server/API/AIChatAPI.ts +6 -3
  10. package/Server/API/AIInvestigationAPI.ts +17 -10
  11. package/Server/API/AutoRemediationAPI.ts +207 -25
  12. package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
  13. package/Server/API/MicrosoftTeamsAPI.ts +93 -14
  14. package/Server/API/ProxmoxResourceAPI.ts +244 -14
  15. package/Server/Infrastructure/GlobalCache.ts +32 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/TelemetryIngest.ts +41 -18
  21. package/Server/Services/AIService.ts +70 -1
  22. package/Server/Services/AlertService.ts +352 -11
  23. package/Server/Services/AlertSeverityService.ts +65 -15
  24. package/Server/Services/AutoRemediationRuleService.ts +1 -1
  25. package/Server/Services/IncidentService.ts +280 -104
  26. package/Server/Services/IncidentSeverityService.ts +66 -15
  27. package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
  28. package/Server/Services/KubernetesAiAgentService.ts +1634 -0
  29. package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
  30. package/Server/Services/KubernetesClusterService.ts +129 -21
  31. package/Server/Services/ProjectService.ts +32 -0
  32. package/Server/Services/ProxmoxResourceService.ts +322 -5
  33. package/Server/Services/RunnerJobService.ts +241 -104
  34. package/Server/Services/RunnerService.ts +1 -1
  35. package/Server/Services/ScheduledMaintenanceService.ts +737 -1
  36. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
  37. package/Server/Services/TeamComplianceSettingService.ts +1125 -9
  38. package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
  39. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
  40. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
  41. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
  42. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
  43. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
  44. package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
  45. package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
  46. package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
  47. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
  48. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
  49. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
  50. package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
  51. package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
  52. package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
  53. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
  54. package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
  55. package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
  56. package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
  57. package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
  58. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
  59. package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
  60. package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
  61. package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
  62. package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
  63. package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
  64. package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
  65. package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
  66. package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
  67. package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
  68. package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
  69. package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
  70. package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
  71. package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
  72. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
  73. package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
  74. package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
  75. package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
  76. package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
  77. package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
  78. package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
  79. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
  80. package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
  81. package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
  82. package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
  83. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
  84. package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
  85. package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
  86. package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
  87. package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
  88. package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
  89. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
  90. package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
  91. package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
  92. package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
  93. package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
  94. package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
  95. package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
  96. package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
  97. package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
  98. package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
  99. package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
  100. package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
  101. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
  102. package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
  103. package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
  104. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
  105. package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
  106. package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
  107. package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
  108. package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
  109. package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
  110. package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
  111. package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
  112. package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
  113. package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
  114. package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
  115. package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
  116. package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
  117. package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
  118. package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
  119. package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
  120. package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
  121. package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
  122. package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
  123. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
  124. package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
  125. package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
  126. package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
  127. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
  128. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
  129. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
  130. package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
  131. package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
  132. package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
  133. package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
  134. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
  135. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
  136. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
  137. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
  138. package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
  139. package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
  140. package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
  141. package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
  142. package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
  143. package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
  144. package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
  145. package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
  146. package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
  147. package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
  148. package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
  149. package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
  150. package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
  151. package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
  152. package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
  153. package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
  154. package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
  155. package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
  156. package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
  157. package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
  158. package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
  159. package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
  160. package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
  161. package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
  162. package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
  163. package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
  164. package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
  165. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
  166. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
  167. package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
  168. package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
  169. package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
  170. package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
  171. package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
  172. package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
  173. package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
  174. package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
  175. package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
  176. package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
  177. package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
  178. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
  179. package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
  180. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
  181. package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
  182. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
  183. package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
  184. package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
  185. package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
  186. package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
  187. package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
  188. package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
  189. package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
  190. package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
  191. package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
  192. package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
  193. package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
  194. package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
  195. package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
  196. package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
  197. package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
  198. package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
  199. package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
  200. package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
  201. package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
  202. package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
  203. package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
  204. package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
  205. package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
  206. package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
  207. package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
  208. package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
  209. package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
  210. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
  211. package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
  212. package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
  213. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
  214. package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
  215. package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
  216. package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
  217. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
  218. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
  219. package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
  220. package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
  221. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
  222. package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
  223. package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
  224. package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
  225. package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
  226. package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
  227. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
  228. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
  229. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
  230. package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
  231. package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
  232. package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
  233. package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
  234. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
  235. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
  236. package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
  237. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
  238. package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
  239. package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
  240. package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
  241. package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
  242. package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
  243. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
  244. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
  245. package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
  246. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
  247. package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
  248. package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
  249. package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
  250. package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
  251. package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
  252. package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
  253. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
  254. package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
  255. package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
  256. package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
  257. package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
  258. package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
  259. package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
  260. package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
  261. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
  262. package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
  263. package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
  264. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
  265. package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
  266. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
  267. package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
  268. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
  269. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
  270. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
  271. package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
  272. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
  273. package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
  274. package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
  275. package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
  276. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
  277. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
  278. package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
  279. package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
  280. package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
  281. package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
  282. package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
  283. package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
  284. package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
  285. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
  286. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
  287. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
  288. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
  289. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
  290. package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
  291. package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
  292. package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
  293. package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
  294. package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
  295. package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
  296. package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
  297. package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
  298. package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
  299. package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
  300. package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
  301. package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
  302. package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
  303. package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
  304. package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
  305. package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
  306. package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
  307. package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
  308. package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
  309. package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
  310. package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
  311. package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
  312. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
  313. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
  314. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
  315. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
  316. package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
  317. package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
  318. package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
  319. package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
  320. package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
  321. package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
  322. package/Tests/UI/Components/Input.test.tsx +80 -1
  323. package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
  324. package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
  325. package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
  326. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
  327. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
  328. package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
  329. package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
  330. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
  331. package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
  332. package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
  333. package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
  334. package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
  335. package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
  336. package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
  337. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
  338. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
  339. package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
  340. package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
  341. package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
  342. package/Tests/UI/Components/Toggle.test.tsx +66 -0
  343. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
  344. package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
  345. package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
  346. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
  347. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
  348. package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
  349. package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
  350. package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
  351. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
  352. package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
  353. package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
  354. package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
  355. package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
  356. package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
  357. package/Types/AI/AIRunType.ts +9 -4
  358. package/Types/AI/InvestigationNotStartedReason.ts +6 -0
  359. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
  360. package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
  361. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
  362. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
  363. package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
  364. package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
  365. package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
  366. package/Types/Team/ComplianceNotificationChannel.ts +22 -0
  367. package/Types/Team/ComplianceRule.ts +434 -0
  368. package/Types/Team/ComplianceRuleType.ts +21 -0
  369. package/Types/Team/TeamComplianceStatus.ts +81 -0
  370. package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
  371. package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
  372. package/UI/Components/ActionButton/RowActions.tsx +238 -0
  373. package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
  374. package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
  375. package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
  376. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
  377. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
  378. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
  379. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
  380. package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
  381. package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
  382. package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
  383. package/UI/Components/Charts/Line/LineChart.tsx +32 -2
  384. package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
  385. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
  386. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
  387. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
  388. package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
  389. package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
  390. package/UI/Components/Charts/Utils/XAxis.ts +75 -0
  391. package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
  392. package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
  393. package/UI/Components/Forms/Fields/FormField.tsx +10 -0
  394. package/UI/Components/Input/Input.tsx +90 -57
  395. package/UI/Components/List/ListRow.tsx +8 -74
  396. package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
  397. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
  398. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
  399. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
  400. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
  401. package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
  402. package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
  403. package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
  404. package/UI/Components/OrderedStatesList/Item.tsx +7 -72
  405. package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
  406. package/UI/Components/Table/TableBody.tsx +8 -2
  407. package/UI/Components/Table/TableRow.tsx +20 -140
  408. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
  409. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
  410. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
  411. package/UI/Components/TelemetryViewer/types.ts +2 -0
  412. package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
  413. package/UI/Components/Toggle/Toggle.tsx +26 -0
  414. package/UI/Components/Tooltip/Tooltip.tsx +8 -1
  415. package/UI/Styles/Theme.css +14 -2
  416. package/Utils/AiRemediation/CommandPolicy.ts +1 -1
  417. package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
  418. package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
  419. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  420. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  421. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
  422. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
  423. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
  424. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  425. package/build/dist/Models/DatabaseModels/Project.js +56 -5
  426. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  427. package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
  428. package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
  429. package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
  430. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  431. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
  432. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
  433. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  434. package/build/dist/Server/API/AIChatAPI.js +6 -1
  435. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  436. package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
  437. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  438. package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
  439. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  440. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
  441. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
  442. package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
  443. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  444. package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
  445. package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
  446. package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
  447. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  448. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
  449. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
  450. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
  451. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
  452. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
  453. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
  454. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  455. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  456. package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
  457. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  458. package/build/dist/Server/Services/AIService.js +59 -1
  459. package/build/dist/Server/Services/AIService.js.map +1 -1
  460. package/build/dist/Server/Services/AlertService.js +248 -13
  461. package/build/dist/Server/Services/AlertService.js.map +1 -1
  462. package/build/dist/Server/Services/AlertSeverityService.js +51 -15
  463. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
  464. package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
  465. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  466. package/build/dist/Server/Services/IncidentService.js +199 -72
  467. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  468. package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
  469. package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
  470. package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
  471. package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
  472. package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
  473. package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
  474. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
  475. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
  476. package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
  477. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  478. package/build/dist/Server/Services/ProjectService.js +22 -0
  479. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  480. package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
  481. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  482. package/build/dist/Server/Services/RunnerJobService.js +178 -92
  483. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  484. package/build/dist/Server/Services/RunnerService.js +1 -1
  485. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  486. package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
  487. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  488. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
  489. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  490. package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
  491. package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
  492. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
  493. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
  494. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
  495. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
  496. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
  497. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
  498. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
  499. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  500. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
  501. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  502. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
  503. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  504. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
  505. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
  506. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
  507. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
  508. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
  509. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
  510. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  511. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
  512. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  513. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
  514. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
  515. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
  516. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
  517. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
  518. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
  519. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
  520. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  521. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
  522. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  523. package/build/dist/Types/AI/AIRunType.js +9 -4
  524. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  525. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
  526. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  527. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
  528. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
  529. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
  530. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  531. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
  532. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
  533. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
  534. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
  535. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
  536. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  537. package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
  538. package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
  539. package/build/dist/Types/Team/ComplianceRule.js +304 -0
  540. package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
  541. package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
  542. package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
  543. package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
  544. package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
  545. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
  546. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  547. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
  548. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
  549. package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
  550. package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
  551. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
  552. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
  553. package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
  554. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  555. package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
  556. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
  558. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
  560. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
  562. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  563. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
  564. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  565. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
  566. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
  567. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
  568. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
  569. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
  570. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
  571. package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
  572. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  573. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
  574. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
  575. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
  576. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
  577. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
  578. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
  579. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
  580. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
  581. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
  582. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
  583. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
  584. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  585. package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
  586. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  587. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
  588. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
  589. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
  590. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  591. package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
  592. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  593. package/build/dist/UI/Components/Input/Input.js +69 -54
  594. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  595. package/build/dist/UI/Components/List/ListRow.js +4 -39
  596. package/build/dist/UI/Components/List/ListRow.js.map +1 -1
  597. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
  598. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  599. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
  600. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  601. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
  602. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  603. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
  604. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  605. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
  606. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  607. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
  608. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  609. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
  610. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  611. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
  612. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  613. package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
  614. package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
  615. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
  616. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
  617. package/build/dist/UI/Components/Table/TableBody.js +6 -2
  618. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  619. package/build/dist/UI/Components/Table/TableRow.js +12 -75
  620. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  621. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
  622. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  623. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
  624. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  625. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
  626. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  627. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
  628. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
  629. package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
  630. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  631. package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
  632. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  633. package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
  634. package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
  635. package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
  636. package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
  637. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
  638. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
  639. package/package.json +1 -1
@@ -1,11 +1,12 @@
1
1
  import {
2
+ AI_AGENT_POD_NAMESPACE_ENV,
2
3
  KUBECTL_ALLOW_NODE_OPERATIONS_ENV,
3
4
  KUBECTL_ALLOW_WRITES_ENV,
4
5
  KUBECTL_WRITE_NAMESPACES_ENV,
5
- KUBERNETES_AGENT_RUNNER_NAME_PREFIX,
6
+ KUBERNETES_AI_AGENT_COMPONENT,
7
+ KUBERNETES_AI_AGENT_IMAGE_REPOSITORY,
6
8
  PROTECTED_KUBERNETES_NAMESPACES,
7
9
  RUNNER_POD_NAMESPACE_ENV,
8
- isKubernetesAgentRunnerName,
9
10
  } from "../../../Types/Kubernetes/KubernetesClusterAiAccess";
10
11
  import { describe, expect, it } from "@jest/globals";
11
12
  import fs from "fs";
@@ -13,31 +14,42 @@ import yaml from "js-yaml";
13
14
  import path from "path";
14
15
 
15
16
  /*
16
- * Contract under test — the kubernetes-agent chart and the Runner agree on
17
- * the environment the chart hands the in-cluster Runner, and the chart's
17
+ * Contract under test — the kubernetes-agent chart and the Kubernetes AI
18
+ * agent agree on the environment the chart hands the agent, and the chart's
18
19
  * operator-facing copy keeps up with its own template:
19
20
  *
20
21
  * - the chart sets ONEUPTIME_KUBECTL_ALLOW_WRITES,
21
22
  * ONEUPTIME_KUBECTL_WRITE_NAMESPACES, ONEUPTIME_KUBECTL_ALLOW_NODE_OPERATIONS
22
- * and ONEUPTIME_RUNNER_POD_NAMESPACE under exactly the names Common
23
- * declares (the Runner reads them through the same constants), the pod
24
- * namespace from the downward API, and the node-operations switch from
25
- * the same two values that decide whether the node role is rendered — so
26
- * aiAccess.remediation.nodeOperations=false reaches the Runner, not only
27
- * RBAC;
28
- * - every variable the chart sets itself is one aiAccess.extraEnv may not
23
+ * and ONEUPTIME_AI_AGENT_POD_NAMESPACE under exactly the names Common
24
+ * declares (the agent reads them under the same names), the pod namespace
25
+ * from the downward API, and the node-operations switch from the same
26
+ * setting that decides whether the node role is rendered — so
27
+ * aiAgent.remediation.nodeOperations=false reaches the agent, not only
28
+ * RBAC. None of the Runner's variables: the agent is not a Runner;
29
+ * - every variable the chart sets itself is one aiAgent.extraEnv may not
29
30
  * set: the kubelet keeps the LAST definition of a duplicate name, so an
30
- * unreserved one could be silently replaced (tests/ai-runner_test.yaml
31
- * renders the refusal; this pins that the list keeps up with the env);
31
+ * unreserved one could be silently replaced (tests/ai-agent_test.yaml
32
+ * renders the refusals; this pins that the list keeps up with the env);
32
33
  * - values.yaml and values.schema.json name every reserved variable, so an
33
34
  * operator learns it before the render fails;
34
- * - the Runner row the chart registers is one the server recognises as the
35
- * agent's own (isKubernetesAgentRunnerName);
35
+ * - values.yaml leaves aiAgent.remediation.* and aiAgent.extraEnv unset.
36
+ * The chart carries a release's stored aiAccess values over only while
37
+ * the matching aiAgent key is unset, and --reset-then-reuse-values would
38
+ * make any default there count as set: a stored write grant could then
39
+ * never carry over, and an explicit revoke could never be told apart;
40
+ * - aiAccess stays in the schema, whole and marked deprecated, because
41
+ * `helm upgrade --reuse-values` validates a 14.0.2-14.0.8 release's
42
+ * stored aiAccess block against it;
43
+ * - the pod is labelled with the component, and runs the image, that the
44
+ * rest of OneUptime names (KUBERNETES_AI_AGENT_COMPONENT,
45
+ * KUBERNETES_AI_AGENT_IMAGE_REPOSITORY);
36
46
  * - the values tables in the chart README and the Kubernetes agent docs
37
- * page list every aiAccess value values.yaml defines, and values.yaml
38
- * names every protected namespace.
47
+ * page list every aiAgent value the schema defines, values.yaml names
48
+ * every protected namespace, and the README names the kubectl version
49
+ * the agent's image pins.
39
50
  *
40
- * The RBAC itself is asserted by rendering, in tests/ai-runner_test.yaml.
51
+ * The RBAC itself, and every aiAccess carry-over rule, is asserted by
52
+ * rendering, in tests/ai-agent_test.yaml and tests/ai-agent-notes_test.yaml.
41
53
  */
42
54
 
43
55
  const REPO_ROOT: string = path.resolve(__dirname, "../../../../..");
@@ -47,14 +59,17 @@ const CHART_DIR: string = path.join(
47
59
  "Public",
48
60
  "kubernetes-agent",
49
61
  );
50
- const TEMPLATE_PATH: string = path.join(
51
- CHART_DIR,
52
- "templates",
53
- "ai-runner.yaml",
62
+ const TEMPLATES_DIR: string = path.join(CHART_DIR, "templates");
63
+ const TEMPLATE_PATH: string = path.join(TEMPLATES_DIR, "ai-agent.yaml");
64
+ const SETTINGS_TEMPLATE_PATH: string = path.join(
65
+ TEMPLATES_DIR,
66
+ "_ai-agent.tpl",
54
67
  );
68
+ const NOTES_PATH: string = path.join(TEMPLATES_DIR, "NOTES.txt");
55
69
  const VALUES_PATH: string = path.join(CHART_DIR, "values.yaml");
56
70
  const SCHEMA_PATH: string = path.join(CHART_DIR, "values.schema.json");
57
71
  const README_PATH: string = path.join(CHART_DIR, "README.md");
72
+ const TROUBLESHOOT_PATH: string = path.join(CHART_DIR, "troubleshoot.sh");
58
73
  const TELEMETRY_DOC_PATH: string = path.join(
59
74
  REPO_ROOT,
60
75
  "packages",
@@ -66,21 +81,90 @@ const TELEMETRY_DOC_PATH: string = path.join(
66
81
  "telemetry",
67
82
  "kubernetes-agent.md",
68
83
  );
84
+ const RUNNER_DOCKERFILE_PATH: string = path.join(
85
+ REPO_ROOT,
86
+ "packages",
87
+ "Runner",
88
+ "Dockerfile.tpl",
89
+ );
90
+ const AGENT_DOCKERFILE_PATH: string = path.join(
91
+ REPO_ROOT,
92
+ "agents",
93
+ "KubernetesAIAgent",
94
+ "Dockerfile.tpl",
95
+ );
96
+
97
+ // Where the values.yaml block for the agent starts, and where it ends.
98
+ const VALUES_BLOCK_HEADING: string = "# Kubernetes AI agent";
99
+ const DEPRECATION_NOTE_HEADING: string = "# aiAccess (charts";
100
+ // The header row of the chart README's aiAgent.* table.
101
+ const README_TABLE_HEADER: string = "| `aiAgent.*` | Default | What it does |";
69
102
 
70
- // The node-operations role renders only inside both switches.
103
+ /*
104
+ * The node-operations role renders only inside the write role's block, and
105
+ * the helper gives allowNodeOperations only with writes on, so the env
106
+ * switch and the role cannot disagree.
107
+ */
71
108
  const NODE_ROLE_GATE_PATTERN: RegExp =
72
- /\{\{- if \$allowWrites \}\}[\s\S]*\{\{- if \$nodeOperations \}\}[\s\S]*-ai-runner-node-operations/;
109
+ /\{\{- if \$allowWrites \}\}[\s\S]*\{\{- if \$allowNodeOperations \}\}[\s\S]*-ai-agent-node-operations/;
110
+
111
+ // What a Runner reads, or is told, that the agent never is.
112
+ const RUNNER_ONLY_ENV_PATTERN: RegExp =
113
+ /^ONEUPTIME_(RUNNER_[A-Z_]+|INGESTION_KEY)$/;
114
+
115
+ // The chart's template files: manifests, helpers and NOTES.txt.
116
+ const TEMPLATE_FILE_PATTERN: RegExp = /\.(ya?ml|tpl|txt)$/;
117
+
118
+ // A read of the deprecated aiAccess block's Runner image or resources.
119
+ const AI_ACCESS_IMAGE_OR_RESOURCES_PATTERN: RegExp =
120
+ /\$aiAccess\.(image|resources)|\.Values\.aiAccess\.(image|resources)/;
121
+
122
+ interface JsonSchema {
123
+ type?: string;
124
+ description?: string;
125
+ properties?: Record<string, JsonSchema>;
126
+ items?: JsonSchema;
127
+ required?: Array<string>;
128
+ additionalProperties?: boolean | JsonSchema;
129
+ enum?: Array<string>;
130
+ pattern?: string;
131
+ minLength?: number;
132
+ maxLength?: number;
133
+ }
73
134
 
74
135
  function read(filePath: string): string {
75
136
  return fs.readFileSync(filePath, "utf8");
76
137
  }
77
138
 
139
+ function readSchema(): JsonSchema {
140
+ return JSON.parse(read(SCHEMA_PATH)) as JsonSchema;
141
+ }
142
+
143
+ function getSchemaProperty(
144
+ schema: JsonSchema,
145
+ propertyPath: string,
146
+ ): JsonSchema {
147
+ let current: JsonSchema = schema;
148
+
149
+ for (const key of propertyPath.split(".")) {
150
+ const next: JsonSchema | undefined = current.properties?.[key];
151
+
152
+ if (!next) {
153
+ throw new Error(`values.schema.json has no ${propertyPath}`);
154
+ }
155
+
156
+ current = next;
157
+ }
158
+
159
+ return current;
160
+ }
161
+
78
162
  // The names the Deployment's container env sets, in order.
79
163
  function getChartEnvNames(template: string): Array<string> {
80
164
  const envBlock: string | undefined = template.split(/^ {10}env:$/m)[1];
81
165
 
82
166
  if (!envBlock) {
83
- throw new Error("templates/ai-runner.yaml has no container env block");
167
+ throw new Error("templates/ai-agent.yaml has no container env block");
84
168
  }
85
169
 
86
170
  const envSection: string = envBlock.split(/^ {10}ports:$/m)[0] || "";
@@ -92,7 +176,7 @@ function getChartEnvNames(template: string): Array<string> {
92
176
  });
93
177
  }
94
178
 
95
- // The names the template refuses in aiAccess.extraEnv.
179
+ // The names the template refuses in extraEnv.
96
180
  function getReservedEnvNames(template: string): Array<string> {
97
181
  return Array.from(
98
182
  template.matchAll(/set \$reservedEnv "([A-Za-z0-9_]+)"/g),
@@ -101,12 +185,25 @@ function getReservedEnvNames(template: string): Array<string> {
101
185
  });
102
186
  }
103
187
 
104
- // "remediation.namespaces", "image.tag", ... for every leaf under aiAccess.
105
- function getLeafKeys(value: unknown, prefix: string): Array<string> {
188
+ // "remediation.namespaces", "image.tag", ... for every leaf of a values map.
189
+ function getValueLeafKeys(value: unknown, prefix: string): Array<string> {
106
190
  if (value && typeof value === "object" && !Array.isArray(value)) {
107
191
  return Object.entries(value as Record<string, unknown>).flatMap(
108
192
  ([key, child]: [string, unknown]) => {
109
- return getLeafKeys(child, prefix ? `${prefix}.${key}` : key);
193
+ return getValueLeafKeys(child, prefix ? `${prefix}.${key}` : key);
194
+ },
195
+ );
196
+ }
197
+
198
+ return [prefix];
199
+ }
200
+
201
+ // The same, for every leaf property a schema object declares.
202
+ function getSchemaLeafKeys(schema: JsonSchema, prefix: string): Array<string> {
203
+ if (schema.properties) {
204
+ return Object.entries(schema.properties).flatMap(
205
+ ([key, child]: [string, JsonSchema]) => {
206
+ return getSchemaLeafKeys(child, prefix ? `${prefix}.${key}` : key);
110
207
  },
111
208
  );
112
209
  }
@@ -114,7 +211,65 @@ function getLeafKeys(value: unknown, prefix: string): Array<string> {
114
211
  return [prefix];
115
212
  }
116
213
 
117
- describe("the kubernetes-agent chart's Runner environment", () => {
214
+ // Every object schema under (and including) this one, with its path.
215
+ function getObjectSchemas(
216
+ schema: JsonSchema,
217
+ prefix: string,
218
+ ): Array<{ path: string; schema: JsonSchema }> {
219
+ const own: Array<{ path: string; schema: JsonSchema }> =
220
+ schema.type === "object" ? [{ path: prefix, schema }] : [];
221
+ const children: Array<{ path: string; schema: JsonSchema }> = Object.entries(
222
+ schema.properties || {},
223
+ ).flatMap(([key, child]: [string, JsonSchema]) => {
224
+ return getObjectSchemas(child, `${prefix}.${key}`);
225
+ });
226
+ const items: Array<{ path: string; schema: JsonSchema }> = schema.items
227
+ ? getObjectSchemas(schema.items, `${prefix}[]`)
228
+ : [];
229
+
230
+ return [...own, ...children, ...items];
231
+ }
232
+
233
+ // resources.requests.cpu and friends share one "resources" row.
234
+ function getTableRowKey(key: string): string {
235
+ return key.startsWith("resources.") ? "resources" : key;
236
+ }
237
+
238
+ // The values.yaml text from the agent's comment block to the aiAccess deprecation note.
239
+ function getValuesAiAgentBlock(): string {
240
+ const values: string = read(VALUES_PATH);
241
+ const start: number = values.indexOf(VALUES_BLOCK_HEADING);
242
+
243
+ if (start === -1) {
244
+ throw new Error(`values.yaml has no "${VALUES_BLOCK_HEADING}" block`);
245
+ }
246
+
247
+ const end: number = values.indexOf(DEPRECATION_NOTE_HEADING, start);
248
+
249
+ return values.slice(start, end === -1 ? undefined : end);
250
+ }
251
+
252
+ // The chart README's aiAgent.* table, header to the first blank line.
253
+ function getReadmeAiAgentTable(): string {
254
+ const readme: string = read(README_PATH);
255
+ const start: number = readme.indexOf(README_TABLE_HEADER);
256
+
257
+ if (start === -1) {
258
+ throw new Error("README.md has no aiAgent.* values table");
259
+ }
260
+
261
+ const end: number = readme.indexOf("\n\n", start);
262
+
263
+ return readme.slice(start, end === -1 ? undefined : end);
264
+ }
265
+
266
+ function getPinnedKubectlVersion(dockerfilePath: string): string | undefined {
267
+ return read(dockerfilePath).match(
268
+ /^ARG KUBECTL_VERSION=(v\d+\.\d+\.\d+)$/m,
269
+ )?.[1];
270
+ }
271
+
272
+ describe("the kubernetes-agent chart's Kubernetes AI agent environment", () => {
118
273
  const template: string = read(TEMPLATE_PATH);
119
274
  const envNames: Array<string> = getChartEnvNames(template);
120
275
  const reservedEnvNames: Array<string> = getReservedEnvNames(template);
@@ -129,40 +284,75 @@ describe("the kubernetes-agent chart's Runner environment", () => {
129
284
  expect(reservedEnvNames.length).toBeGreaterThanOrEqual(envNames.length);
130
285
  });
131
286
 
132
- it("sets the write switch, the write namespaces, the node-operations switch and the pod namespace under the names the Runner reads", () => {
287
+ it("replaces the in-cluster Runner's template instead of rendering both", () => {
288
+ expect(fs.existsSync(path.join(TEMPLATES_DIR, "ai-runner.yaml"))).toBe(
289
+ false,
290
+ );
291
+ expect(fs.existsSync(TEMPLATE_PATH)).toBe(true);
292
+ });
293
+
294
+ it("sets the write switch, the write namespaces, the node-operations switch and the pod namespace under the names the agent reads", () => {
133
295
  expect(envNames).toContain(KUBECTL_ALLOW_WRITES_ENV);
134
296
  expect(envNames).toContain(KUBECTL_WRITE_NAMESPACES_ENV);
135
297
  expect(envNames).toContain(KUBECTL_ALLOW_NODE_OPERATIONS_ENV);
136
- expect(envNames).toContain(RUNNER_POD_NAMESPACE_ENV);
298
+ expect(envNames).toContain(AI_AGENT_POD_NAMESPACE_ENV);
299
+ });
300
+
301
+ it("sets none of the Runner's variables, because the agent is not a Runner", () => {
302
+ expect(envNames).not.toContain(RUNNER_POD_NAMESPACE_ENV);
303
+ expect(
304
+ envNames.filter((name: string) => {
305
+ return RUNNER_ONLY_ENV_PATTERN.test(name);
306
+ }),
307
+ ).toEqual([]);
308
+ });
309
+
310
+ it("hands the agent the collector's API key from the chart's Secret, never a literal", () => {
311
+ expect(template).toContain(
312
+ `- name: ONEUPTIME_API_KEY\n valueFrom:\n secretKeyRef:\n name: {{ $fullname }}\n key: api-key`,
313
+ );
314
+ expect(template).not.toContain(".Values.oneuptime.apiKey");
137
315
  });
138
316
 
139
- it("tells the Runner node operations are on exactly when the node role is rendered", () => {
317
+ it("tells the agent node operations are on exactly when the node role is rendered", () => {
140
318
  /*
141
319
  * The node-operations ClusterRole renders inside `if $allowWrites` and
142
- * `if $nodeOperations`, so the switch must be both: nodeOperations=false
143
- * would otherwise leave an Automatic cluster auto-running a cordon that
144
- * the API server refuses Forbidden. tests/ai-runner_test.yaml renders
145
- * the four combinations.
320
+ * `if $allowNodeOperations`, and the env switch is the same setting, so
321
+ * nodeOperations=false would otherwise leave an Automatic cluster
322
+ * auto-running a cordon that the API server refuses Forbidden.
323
+ * tests/ai-agent_test.yaml renders the combinations.
146
324
  */
147
325
  expect(template).toContain(
148
- `- name: ${KUBECTL_ALLOW_NODE_OPERATIONS_ENV}\n value: {{ and $allowWrites $nodeOperations | quote }}`,
326
+ `- name: ${KUBECTL_ALLOW_NODE_OPERATIONS_ENV}\n value: {{ $allowNodeOperations | quote }}`,
149
327
  );
150
328
  expect(template).toMatch(NODE_ROLE_GATE_PATTERN);
329
+ expect(read(SETTINGS_TEMPLATE_PATH)).toContain(
330
+ '"allowNodeOperations" (and $allowWrites $nodeOperations)',
331
+ );
151
332
  });
152
333
 
153
334
  it("takes the pod namespace from the downward API, not from a value an operator could get wrong", () => {
154
335
  expect(template).toContain(
155
- `- name: ${RUNNER_POD_NAMESPACE_ENV}\n valueFrom:\n fieldRef:\n fieldPath: metadata.namespace`,
336
+ `- name: ${AI_AGENT_POD_NAMESPACE_ENV}\n valueFrom:\n fieldRef:\n fieldPath: metadata.namespace`,
156
337
  );
157
338
  });
158
339
 
159
- it("tells the Runner exactly the namespaces it bound write access in", () => {
340
+ it("tells the agent exactly the namespaces it bound write access in", () => {
160
341
  expect(template).toContain(
161
342
  `- name: ${KUBECTL_WRITE_NAMESPACES_ENV}\n value: {{ join "," $writeNamespaces | quote }}`,
162
343
  );
163
344
  });
164
345
 
165
- it("reserves every variable it sets, so aiAccess.extraEnv can never silently replace one", () => {
346
+ it("serves the health probes on the port it tells the agent to listen on", () => {
347
+ const port: string | undefined = template.match(
348
+ /- name: PORT\n\s+value: "(\d+)"/,
349
+ )?.[1];
350
+
351
+ expect(port).toBe("3876");
352
+ expect(template).toContain(`containerPort: ${port}`);
353
+ });
354
+
355
+ it("reserves every variable it sets, so extraEnv can never silently replace one", () => {
166
356
  const unreserved: Array<string> = envNames.filter((name: string) => {
167
357
  return !reservedEnvNames.includes(name);
168
358
  });
@@ -170,30 +360,43 @@ describe("the kubernetes-agent chart's Runner environment", () => {
170
360
  expect(unreserved).toEqual([]);
171
361
  });
172
362
 
173
- it("reserves the node-operations switch with a message naming the values to change", () => {
174
- expect(reservedEnvNames).toContain(KUBECTL_ALLOW_NODE_OPERATIONS_ENV);
175
- expect(template).toContain(
176
- `set $reservedEnv "${KUBECTL_ALLOW_NODE_OPERATIONS_ENV}" "the chart sets it from aiAccess.remediation.nodeOperations`,
177
- );
363
+ it("leaves the proxy settings to the operator", () => {
364
+ /*
365
+ * Proxy users carry HTTPS_PROXY / NO_PROXY over from aiAccess.extraEnv;
366
+ * reserving them would fail those upgrades.
367
+ */
368
+ for (const name of [
369
+ "HTTPS_PROXY",
370
+ "HTTP_PROXY",
371
+ "NO_PROXY",
372
+ "NODE_USE_ENV_PROXY",
373
+ ]) {
374
+ expect({ name, reserved: reservedEnvNames.includes(name) }).toEqual({
375
+ name,
376
+ reserved: false,
377
+ });
378
+ }
178
379
  });
179
380
 
180
- it("also reserves the dashboard-issued Runner identity, which would take the Runner out of kubernetes-agent mode", () => {
181
- expect(reservedEnvNames).toContain("ONEUPTIME_RUNNER_ID");
182
- expect(reservedEnvNames).toContain("ONEUPTIME_RUNNER_KEY");
381
+ it("reserves the switches with a message naming the aiAgent value to change", () => {
382
+ expect(template).toContain(
383
+ `set $reservedEnv "${KUBECTL_ALLOW_WRITES_ENV}" "the chart sets it from aiAgent.remediation.enabled`,
384
+ );
385
+ expect(template).toContain(
386
+ `set $reservedEnv "${KUBECTL_WRITE_NAMESPACES_ENV}" "the chart sets it from aiAgent.remediation.namespaces`,
387
+ );
388
+ expect(template).toContain(
389
+ `set $reservedEnv "${KUBECTL_ALLOW_NODE_OPERATIONS_ENV}" "the chart sets it from aiAgent.remediation.nodeOperations`,
390
+ );
183
391
  });
184
392
 
185
- it("names every reserved variable in values.yaml and in the schema description", () => {
186
- const values: string = read(VALUES_PATH);
187
- const schema: {
188
- properties: {
189
- aiAccess: { properties: { extraEnv: { description: string } } };
190
- };
191
- } = JSON.parse(read(SCHEMA_PATH));
393
+ it("names every reserved variable in values.yaml and in the schema's aiAgent.extraEnv description", () => {
394
+ const valuesBlock: string = getValuesAiAgentBlock();
192
395
  const schemaDescription: string =
193
- schema.properties.aiAccess.properties.extraEnv.description;
396
+ getSchemaProperty(readSchema(), "aiAgent.extraEnv").description || "";
194
397
 
195
398
  for (const name of reservedEnvNames) {
196
- expect({ name, inValuesYaml: values.includes(name) }).toEqual({
399
+ expect({ name, inValuesYaml: valuesBlock.includes(name) }).toEqual({
197
400
  name,
198
401
  inValuesYaml: true,
199
402
  });
@@ -204,24 +407,104 @@ describe("the kubernetes-agent chart's Runner environment", () => {
204
407
  }
205
408
  });
206
409
 
207
- it("registers the Runner under a name the server recognises as the agent's own", () => {
208
- const runnerName: RegExpMatchArray | null = template.match(
209
- /- name: ONEUPTIME_RUNNER_NAME\n\s+value: "([^"{]+)\{\{/,
410
+ it("labels every object with the component the rest of OneUptime names", () => {
411
+ const labels: Array<string> = Array.from(
412
+ template.matchAll(/^\s+component: ([a-z-]+)$/gm),
413
+ ).map((match: RegExpMatchArray) => {
414
+ return match[1]!;
415
+ });
416
+
417
+ /*
418
+ * ServiceAccount, three ClusterRoles, their bindings, the RoleBinding
419
+ * range, the Deployment, its selector and its pod template.
420
+ */
421
+ expect(labels.length).toBeGreaterThanOrEqual(10);
422
+ expect(Array.from(new Set(labels))).toEqual([
423
+ KUBERNETES_AI_AGENT_COMPONENT,
424
+ ]);
425
+ });
426
+
427
+ it("falls back to the image the rest of OneUptime names, the same one values.yaml sets", () => {
428
+ const values: { aiAgent: { image: { repository: string } } } = yaml.load(
429
+ read(VALUES_PATH),
430
+ ) as { aiAgent: { image: { repository: string } } };
431
+
432
+ expect(template).toContain(
433
+ `$image.repository | default "${KUBERNETES_AI_AGENT_IMAGE_REPOSITORY}"`,
434
+ );
435
+ expect(values.aiAgent.image.repository).toBe(
436
+ KUBERNETES_AI_AGENT_IMAGE_REPOSITORY,
210
437
  );
438
+ });
439
+
440
+ it("reads the deprecated aiAccess values in one place only, and never its image or resources", () => {
441
+ /*
442
+ * On 14.0.2-14.0.8 releases aiAccess.image is always the Runner image
443
+ * and aiAccess.resources the Runner's defaults, so reading either would
444
+ * deploy the wrong pod. Only the settings helper may read aiAccess, so
445
+ * the template and NOTES can never disagree about a carried-over value.
446
+ */
447
+ const templateFiles: Array<string> = fs
448
+ .readdirSync(TEMPLATES_DIR)
449
+ .filter((name: string) => {
450
+ return TEMPLATE_FILE_PATTERN.test(name);
451
+ });
452
+
453
+ for (const name of templateFiles) {
454
+ const text: string = read(path.join(TEMPLATES_DIR, name));
211
455
 
212
- expect(runnerName?.[1]).toBe(`${KUBERNETES_AGENT_RUNNER_NAME_PREFIX}/`);
213
- expect(isKubernetesAgentRunnerName(`${runnerName?.[1]}prod-us`)).toBe(true);
456
+ expect({
457
+ name,
458
+ readsAiAccess: text.includes(".Values.aiAccess"),
459
+ }).toEqual({ name, readsAiAccess: name === "_ai-agent.tpl" });
460
+ expect({
461
+ name,
462
+ readsRunnerImageOrResources:
463
+ AI_ACCESS_IMAGE_OR_RESOURCES_PATTERN.test(text),
464
+ }).toEqual({ name, readsRunnerImageOrResources: false });
465
+ }
466
+ });
467
+
468
+ it("points NOTES.txt at the agent's pod, not the Runner's", () => {
469
+ const notes: string = read(NOTES_PATH);
470
+
471
+ expect(notes).toContain(`-l component=${KUBERNETES_AI_AGENT_COMPONENT}`);
472
+ expect(notes).toContain(
473
+ 'include "kubernetes-agent.aiAgent.settings" . | fromJson',
474
+ );
475
+ expect(notes).not.toContain("ai-runner");
476
+ expect(notes).not.toContain("--set aiAccess");
477
+ });
478
+
479
+ it("tells troubleshoot.sh to read the agent's own container on a crash loop", () => {
480
+ const script: string = read(TROUBLESHOOT_PATH);
481
+
482
+ expect(script).toContain(
483
+ `[ "$component" = "${KUBERNETES_AI_AGENT_COMPONENT}" ] && container="ai-agent"`,
484
+ );
485
+ expect(script).toContain(
486
+ "Inspect: kubectl logs -n $NS $pod -c $container --previous",
487
+ );
488
+ // Its image is the one a mirror most often lacks; say how to fix or skip it.
489
+ expect(script).toContain("aiAgent.image.repository");
490
+ expect(script).toContain("--set aiAgent.enabled=false");
214
491
  });
215
492
  });
216
493
 
217
- describe("the kubernetes-agent chart's aiAccess copy", () => {
494
+ describe("the kubernetes-agent chart's aiAgent values and schema", () => {
218
495
  const values: Record<string, unknown> = yaml.load(
219
496
  read(VALUES_PATH),
220
497
  ) as Record<string, unknown>;
221
- const aiAccessKeys: Array<string> = getLeafKeys(values["aiAccess"], "");
222
-
223
- it("reads the aiAccess values it compares against", () => {
224
- expect(aiAccessKeys).toEqual(
498
+ const aiAgent: Record<string, unknown> = values["aiAgent"] as Record<
499
+ string,
500
+ unknown
501
+ >;
502
+ const schema: JsonSchema = readSchema();
503
+ const aiAgentSchema: JsonSchema = getSchemaProperty(schema, "aiAgent");
504
+ const schemaLeafKeys: Array<string> = getSchemaLeafKeys(aiAgentSchema, "");
505
+
506
+ it("reads the aiAgent values and schema it compares against", () => {
507
+ expect(schemaLeafKeys).toEqual(
225
508
  expect.arrayContaining([
226
509
  "enabled",
227
510
  "remediation.enabled",
@@ -230,77 +513,262 @@ describe("the kubernetes-agent chart's aiAccess copy", () => {
230
513
  "image.repository",
231
514
  "image.tag",
232
515
  "image.pullPolicy",
516
+ "imagePullSecrets",
517
+ "resources.requests.cpu",
233
518
  "extraEnv",
234
519
  ]),
235
520
  );
236
521
  });
237
522
 
238
- it("lists every aiAccess value in the chart README's table", () => {
239
- const readme: string = read(README_PATH);
523
+ it("sets only the keys that are safe to store, leaving remediation and extraEnv to the aiAccess carry-over", () => {
524
+ expect(Object.keys(aiAgent).sort()).toEqual([
525
+ "enabled",
526
+ "image",
527
+ "imagePullSecrets",
528
+ "resources",
529
+ ]);
530
+ });
240
531
 
241
- for (const key of aiAccessKeys) {
242
- // resources.requests.cpu and friends share one "resources" row.
243
- const rowKey: string = key.startsWith("resources.") ? "resources" : key;
244
- expect({ key, listed: readme.includes(`\`${rowKey}\``) }).toEqual({
245
- key,
246
- listed: true,
532
+ it("is on by default, tracks the moving release tag, and asks for little", () => {
533
+ expect(aiAgent).toEqual({
534
+ enabled: true,
535
+ image: {
536
+ repository: KUBERNETES_AI_AGENT_IMAGE_REPOSITORY,
537
+ // Empty tag = the moving `release`; empty pullPolicy = Always for it.
538
+ tag: "",
539
+ pullPolicy: "",
540
+ },
541
+ imagePullSecrets: [],
542
+ resources: {
543
+ requests: { cpu: "50m", memory: "64Mi" },
544
+ limits: { cpu: "500m", memory: "256Mi" },
545
+ },
546
+ });
547
+ });
548
+
549
+ it("documents the unset keys, with their effective defaults, as commented keys", () => {
550
+ const block: string = getValuesAiAgentBlock();
551
+
552
+ for (const line of [
553
+ " # remediation:",
554
+ " # enabled: false",
555
+ " # namespaces: []",
556
+ " # nodeOperations: true",
557
+ " # extraEnv: []",
558
+ ]) {
559
+ expect({ line, documented: block.includes(`\n${line}\n`) }).toEqual({
560
+ line,
561
+ documented: true,
247
562
  });
248
563
  }
249
564
  });
250
565
 
251
- it("lists every aiAccess value in the Kubernetes agent docs page's table", () => {
252
- const doc: string = read(TELEMETRY_DOC_PATH);
566
+ it("no longer sets aiAccess, and says what replaced it", () => {
567
+ expect(values).not.toHaveProperty("aiAccess");
568
+ expect(read(VALUES_PATH)).toContain(
569
+ `${DEPRECATION_NOTE_HEADING} 14.0.2 to 14.0.8) is deprecated: use aiAgent.`,
570
+ );
571
+ });
253
572
 
254
- for (const key of aiAccessKeys) {
255
- const rowKey: string = key.startsWith("resources.")
256
- ? "aiAccess.resources"
257
- : `aiAccess.${key}`;
258
- expect({ key, listed: doc.includes(`\`${rowKey}\``) }).toEqual({
573
+ it("declares every value values.yaml sets", () => {
574
+ for (const key of getValueLeafKeys(aiAgent, "")) {
575
+ expect({ key, declared: schemaLeafKeys.includes(key) }).toEqual({
259
576
  key,
260
- listed: true,
577
+ declared: true,
261
578
  });
262
579
  }
263
580
  });
264
581
 
265
- it("defaults to read-only, cluster-wide binding when remediation is on, and node operations on", () => {
266
- const aiAccess: {
267
- enabled: boolean;
268
- remediation: {
269
- enabled: boolean;
270
- namespaces: Array<string>;
271
- nodeOperations: boolean;
272
- };
273
- image: { tag: string; pullPolicy: string };
274
- } = values["aiAccess"] as never;
275
-
276
- expect(aiAccess.enabled).toBe(false);
277
- expect(aiAccess.remediation).toEqual({
278
- enabled: false,
279
- namespaces: [],
280
- nodeOperations: true,
582
+ it("refuses unknown keys at every level of aiAgent", () => {
583
+ for (const object of getObjectSchemas(aiAgentSchema, "aiAgent")) {
584
+ /*
585
+ * extraEnv[].valueFrom is a Kubernetes EnvVarSource, passed through
586
+ * as-is.
587
+ */
588
+ if (!object.schema.properties) {
589
+ continue;
590
+ }
591
+
592
+ expect({
593
+ path: object.path,
594
+ additionalProperties: object.schema.additionalProperties,
595
+ }).toEqual({ path: object.path, additionalProperties: false });
596
+ }
597
+ });
598
+
599
+ it("takes only Kubernetes namespace names, the same rule the deprecated aiAccess list had", () => {
600
+ const namespaces: JsonSchema = getSchemaProperty(
601
+ schema,
602
+ "aiAgent.remediation.namespaces",
603
+ );
604
+
605
+ expect(namespaces.type).toBe("array");
606
+ expect(namespaces.items).toEqual({
607
+ type: "string",
608
+ minLength: 1,
609
+ maxLength: 63,
610
+ pattern: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
281
611
  });
282
- // Empty tag = the moving `release`; empty pullPolicy = Always for it.
283
- expect(aiAccess.image.tag).toBe("");
284
- expect(aiAccess.image.pullPolicy).toBe("");
612
+ expect(
613
+ getSchemaProperty(schema, "aiAccess.remediation.namespaces").items,
614
+ ).toEqual(namespaces.items);
285
615
  });
286
616
 
287
- it("names every protected namespace where it explains the cluster-wide default", () => {
288
- // Only the aiAccess block: coreDns already mentions kube-system.
289
- const valuesText: string = read(VALUES_PATH);
290
- const blockStart: number = valuesText.indexOf("# OneUptime AI access");
617
+ it("types the switches as booleans, so --set 'true' cannot pass as a truthy string", () => {
618
+ for (const key of [
619
+ "aiAgent.enabled",
620
+ "aiAgent.remediation.enabled",
621
+ "aiAgent.remediation.nodeOperations",
622
+ ]) {
623
+ expect({ key, type: getSchemaProperty(schema, key).type }).toEqual({
624
+ key,
625
+ type: "boolean",
626
+ });
627
+ }
628
+ });
291
629
 
292
- expect(blockStart).toBeGreaterThan(-1);
630
+ it("takes image pull secrets as Kubernetes LocalObjectReferences", () => {
631
+ expect(getSchemaProperty(schema, "aiAgent.imagePullSecrets")).toMatchObject(
632
+ {
633
+ type: "array",
634
+ items: {
635
+ type: "object",
636
+ required: ["name"],
637
+ properties: { name: { type: "string", minLength: 1 } },
638
+ additionalProperties: false,
639
+ },
640
+ },
641
+ );
642
+ });
643
+
644
+ it("takes only the pull policies Kubernetes knows, or empty for the default", () => {
645
+ expect(getSchemaProperty(schema, "aiAgent.image.pullPolicy").enum).toEqual([
646
+ "",
647
+ "Always",
648
+ "IfNotPresent",
649
+ "Never",
650
+ ]);
651
+ });
293
652
 
294
- const aiAccessComments: string = valuesText.slice(blockStart);
653
+ it("keeps the whole deprecated aiAccess block, so a 14.0.x release's stored values still validate", () => {
654
+ const aiAccess: JsonSchema = getSchemaProperty(schema, "aiAccess");
655
+
656
+ expect(aiAccess.description).toMatch(/^Deprecated: use aiAgent\./);
657
+ expect(aiAccess.additionalProperties).toBe(false);
658
+ expect(getSchemaLeafKeys(aiAccess, "").sort()).toEqual(
659
+ [
660
+ "enabled",
661
+ "extraEnv",
662
+ "image.pullPolicy",
663
+ "image.repository",
664
+ "image.tag",
665
+ "remediation.enabled",
666
+ "remediation.namespaces",
667
+ "remediation.nodeOperations",
668
+ "resources.limits.cpu",
669
+ "resources.limits.memory",
670
+ "resources.requests.cpu",
671
+ "resources.requests.memory",
672
+ ].sort(),
673
+ );
674
+ // Every value a 14.0.x release stored is one this schema accepts.
675
+ expect(getSchemaProperty(schema, "aiAccess.image.pullPolicy").enum).toEqual(
676
+ ["", "Always", "IfNotPresent", "Never"],
677
+ );
678
+ expect(getSchemaProperty(schema, "aiAccess.extraEnv").items).toEqual(
679
+ getSchemaProperty(schema, "aiAgent.extraEnv").items,
680
+ );
681
+ });
682
+
683
+ it("names every protected namespace where it explains the cluster-wide binding", () => {
684
+ // Only the agent's block: coreDns already mentions kube-system.
685
+ const block: string = getValuesAiAgentBlock();
295
686
 
296
687
  for (const namespace of PROTECTED_KUBERNETES_NAMESPACES) {
297
- expect({
298
- namespace,
299
- named: aiAccessComments.includes(namespace),
300
- }).toEqual({
688
+ expect({ namespace, named: block.includes(namespace) }).toEqual({
301
689
  namespace,
302
690
  named: true,
303
691
  });
304
692
  }
305
693
  });
306
694
  });
695
+
696
+ describe("the kubernetes-agent chart's aiAgent tables", () => {
697
+ const schemaLeafKeys: Array<string> = getSchemaLeafKeys(
698
+ getSchemaProperty(readSchema(), "aiAgent"),
699
+ "",
700
+ );
701
+
702
+ it("lists every aiAgent value in the chart README's table", () => {
703
+ const table: string = getReadmeAiAgentTable();
704
+ const firstCells: Array<string> = table
705
+ .split("\n")
706
+ .slice(2)
707
+ .map((row: string) => {
708
+ return row.split(" | ")[0] || "";
709
+ });
710
+
711
+ for (const key of schemaLeafKeys) {
712
+ const rowKey: string = getTableRowKey(key);
713
+
714
+ expect({
715
+ key,
716
+ listed: firstCells.some((cell: string) => {
717
+ return cell.includes(`\`${rowKey}\``);
718
+ }),
719
+ }).toEqual({ key, listed: true });
720
+ }
721
+ });
722
+
723
+ it("gives every README row a default and an explanation", () => {
724
+ const rows: Array<string> = getReadmeAiAgentTable().split("\n").slice(2);
725
+
726
+ expect(rows.length).toBeGreaterThan(0);
727
+
728
+ for (const row of rows) {
729
+ const cells: Array<string> = row
730
+ .split(" | ")
731
+ .map((cell: string) => {
732
+ return cell.replace(/^\|\s*|\s*\|$/g, "").trim();
733
+ })
734
+ .filter(Boolean);
735
+
736
+ expect({ row, cells: cells.length }).toEqual({ row, cells: 3 });
737
+ }
738
+ });
739
+
740
+ it("lists every aiAgent value in the Kubernetes agent docs page's table", () => {
741
+ const doc: string = read(TELEMETRY_DOC_PATH);
742
+
743
+ for (const key of schemaLeafKeys) {
744
+ const rowKey: string = `aiAgent.${getTableRowKey(key)}`;
745
+
746
+ expect({ key, listed: doc.includes(`\`${rowKey}\``) }).toEqual({
747
+ key,
748
+ listed: true,
749
+ });
750
+ }
751
+ });
752
+ });
753
+
754
+ describe("the kubectl version the chart README names", () => {
755
+ const named: Array<string> = Array.from(
756
+ read(README_PATH).matchAll(/pinned kubectl \((v\d+\.\d+\.\d+)\)/g),
757
+ ).map((match: RegExpMatchArray) => {
758
+ return match[1]!;
759
+ });
760
+
761
+ it("names one", () => {
762
+ expect(named.length).toBeGreaterThan(0);
763
+ expect(new Set(named).size).toBe(1);
764
+ });
765
+
766
+ it("is the one the Runner image pins", () => {
767
+ expect(named[0]).toBe(getPinnedKubectlVersion(RUNNER_DOCKERFILE_PATH));
768
+ });
769
+
770
+ it("is the one the Kubernetes AI agent image pins", () => {
771
+ // The README describes the agent's kubectl; both images pin one version.
772
+ expect(named[0]).toBe(getPinnedKubectlVersion(AGENT_DOCKERFILE_PATH));
773
+ });
774
+ });