@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.
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
- package/Models/DatabaseModels/Project.ts +55 -5
- package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
- package/Models/DatabaseModels/RunnerJob.ts +75 -0
- package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
- package/Server/API/AIChatAPI.ts +6 -3
- package/Server/API/AIInvestigationAPI.ts +17 -10
- package/Server/API/AutoRemediationAPI.ts +207 -25
- package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
- package/Server/API/MicrosoftTeamsAPI.ts +93 -14
- package/Server/API/ProxmoxResourceAPI.ts +244 -14
- package/Server/Infrastructure/GlobalCache.ts +32 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/TelemetryIngest.ts +41 -18
- package/Server/Services/AIService.ts +70 -1
- package/Server/Services/AlertService.ts +352 -11
- package/Server/Services/AlertSeverityService.ts +65 -15
- package/Server/Services/AutoRemediationRuleService.ts +1 -1
- package/Server/Services/IncidentService.ts +280 -104
- package/Server/Services/IncidentSeverityService.ts +66 -15
- package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
- package/Server/Services/KubernetesAiAgentService.ts +1634 -0
- package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
- package/Server/Services/KubernetesClusterService.ts +129 -21
- package/Server/Services/ProjectService.ts +32 -0
- package/Server/Services/ProxmoxResourceService.ts +322 -5
- package/Server/Services/RunnerJobService.ts +241 -104
- package/Server/Services/RunnerService.ts +1 -1
- package/Server/Services/ScheduledMaintenanceService.ts +737 -1
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
- package/Server/Services/TeamComplianceSettingService.ts +1125 -9
- package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
- package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
- package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
- package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
- package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
- package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
- package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
- package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
- package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
- package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
- package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
- package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
- package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
- package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
- package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
- package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
- package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
- package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
- package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
- package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
- package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
- package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
- package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
- package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
- package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
- package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
- package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
- package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
- package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
- package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
- package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
- package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
- package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
- package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
- package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
- package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
- package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
- package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
- package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
- package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
- package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
- package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
- package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
- package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
- package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
- package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
- package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
- package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
- package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
- package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
- package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
- package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
- package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
- package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
- package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
- package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
- package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
- package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
- package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
- package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
- package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
- package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
- package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
- package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
- package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
- package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
- package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
- package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
- package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
- package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
- package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
- package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
- package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
- package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
- package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
- package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
- package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
- package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
- package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
- package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
- package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
- package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
- package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
- package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
- package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
- package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
- package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
- package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
- package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
- package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
- package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
- package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
- package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
- package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
- package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
- package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
- package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
- package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
- package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
- package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
- package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
- package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
- package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
- package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
- package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
- package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
- package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
- package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
- package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
- package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
- package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
- package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
- package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
- package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
- package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
- package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
- package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
- package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
- package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
- package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
- package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
- package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
- package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
- package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
- package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
- package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
- package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
- package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
- package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
- package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
- package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
- package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
- package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
- package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
- package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
- package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
- package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
- package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
- package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
- package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
- package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
- package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
- package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
- package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
- package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
- package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
- package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
- package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
- package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
- package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
- package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
- package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
- package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
- package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
- package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
- package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
- package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
- package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
- package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
- package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
- package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
- package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
- package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
- package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
- package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
- package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
- package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
- package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
- package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
- package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
- package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
- package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
- package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
- package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
- package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
- package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
- package/Tests/UI/Components/Input.test.tsx +80 -1
- package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
- package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
- package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
- package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
- package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
- package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
- package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
- package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
- package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
- package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
- package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
- package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
- package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
- package/Tests/UI/Components/Toggle.test.tsx +66 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
- package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
- package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
- package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
- package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
- package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
- package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
- package/Types/AI/AIRunType.ts +9 -4
- package/Types/AI/InvestigationNotStartedReason.ts +6 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
- package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
- package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
- package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
- package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
- package/Types/Team/ComplianceNotificationChannel.ts +22 -0
- package/Types/Team/ComplianceRule.ts +434 -0
- package/Types/Team/ComplianceRuleType.ts +21 -0
- package/Types/Team/TeamComplianceStatus.ts +81 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
- package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
- package/UI/Components/ActionButton/RowActions.tsx +238 -0
- package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
- package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
- package/UI/Components/Charts/Line/LineChart.tsx +32 -2
- package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
- package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
- package/UI/Components/Charts/Utils/XAxis.ts +75 -0
- package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
- package/UI/Components/Forms/Fields/FormField.tsx +10 -0
- package/UI/Components/Input/Input.tsx +90 -57
- package/UI/Components/List/ListRow.tsx +8 -74
- package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
- package/UI/Components/OrderedStatesList/Item.tsx +7 -72
- package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
- package/UI/Components/Table/TableBody.tsx +8 -2
- package/UI/Components/Table/TableRow.tsx +20 -140
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
- package/UI/Components/TelemetryViewer/types.ts +2 -0
- package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
- package/UI/Components/Toggle/Toggle.tsx +26 -0
- package/UI/Components/Tooltip/Tooltip.tsx +8 -1
- package/UI/Styles/Theme.css +14 -2
- package/Utils/AiRemediation/CommandPolicy.ts +1 -1
- package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
- package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +56 -5
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +6 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
- package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +59 -1
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +248 -13
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +51 -15
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +199 -72
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
- package/build/dist/Server/Services/RunnerJobService.js +178 -92
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/RunnerService.js +1 -1
- package/build/dist/Server/Services/RunnerService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIRunType.js +9 -4
- package/build/dist/Types/AI/AIRunType.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRule.js +304 -0
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
- package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
- package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
- package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
- package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +69 -54
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/List/ListRow.js +4 -39
- package/build/dist/UI/Components/List/ListRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
- package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +6 -2
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +12 -75
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
- 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
|
-
|
|
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
|
|
17
|
-
* the environment the chart hands the
|
|
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
|
|
23
|
-
* declares (the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* RBAC;
|
|
28
|
-
* - every variable the chart sets itself is one
|
|
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-
|
|
31
|
-
* renders the
|
|
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
|
-
* -
|
|
35
|
-
*
|
|
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
|
|
38
|
-
*
|
|
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
|
|
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
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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 \$
|
|
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-
|
|
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
|
|
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
|
|
105
|
-
function
|
|
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
|
|
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
|
-
|
|
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("
|
|
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(
|
|
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
|
|
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 $
|
|
143
|
-
* would otherwise leave an Automatic cluster
|
|
144
|
-
* the API server refuses Forbidden.
|
|
145
|
-
* the
|
|
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: {{
|
|
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: ${
|
|
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
|
|
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("
|
|
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("
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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("
|
|
181
|
-
expect(
|
|
182
|
-
|
|
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
|
|
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
|
-
|
|
396
|
+
getSchemaProperty(readSchema(), "aiAgent.extraEnv").description || "";
|
|
194
397
|
|
|
195
398
|
for (const name of reservedEnvNames) {
|
|
196
|
-
expect({ name, inValuesYaml:
|
|
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("
|
|
208
|
-
const
|
|
209
|
-
|
|
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
|
-
|
|
213
|
-
|
|
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
|
|
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
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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("
|
|
239
|
-
|
|
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
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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("
|
|
252
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
577
|
+
declared: true,
|
|
261
578
|
});
|
|
262
579
|
}
|
|
263
580
|
});
|
|
264
581
|
|
|
265
|
-
it("
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
612
|
+
expect(
|
|
613
|
+
getSchemaProperty(schema, "aiAccess.remediation.namespaces").items,
|
|
614
|
+
).toEqual(namespaces.items);
|
|
285
615
|
});
|
|
286
616
|
|
|
287
|
-
it("
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
});
|