@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
package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts
ADDED
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
import { AddKubernetesAiAgentAndAiDefaults1796100000000 } from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults";
|
|
2
|
+
import SchemaMigrations from "../../../../Server/Infrastructure/Postgres/SchemaMigrations/Index";
|
|
3
|
+
import KubernetesAiAgent from "../../../../Models/DatabaseModels/KubernetesAiAgent";
|
|
4
|
+
import KubernetesCluster from "../../../../Models/DatabaseModels/KubernetesCluster";
|
|
5
|
+
import Project from "../../../../Models/DatabaseModels/Project";
|
|
6
|
+
import RunnerJob from "../../../../Models/DatabaseModels/RunnerJob";
|
|
7
|
+
import { ColumnAccessControl } from "../../../../Types/BaseDatabase/AccessControl";
|
|
8
|
+
import { describe, expect, test } from "@jest/globals";
|
|
9
|
+
import fs from "fs";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import {
|
|
12
|
+
DefaultNamingStrategy,
|
|
13
|
+
QueryRunner,
|
|
14
|
+
getMetadataArgsStorage,
|
|
15
|
+
} from "typeorm";
|
|
16
|
+
import type { ColumnMetadataArgs } from "typeorm/metadata-args/ColumnMetadataArgs";
|
|
17
|
+
import type { RelationMetadataArgs } from "typeorm/metadata-args/RelationMetadataArgs";
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
* The Kubernetes AI agent's schema, and the migration that turns AI on by
|
|
21
|
+
* default without turning anything on that an operator switched off.
|
|
22
|
+
*
|
|
23
|
+
* Pinned here, each a silent regression if it moves on its own:
|
|
24
|
+
*
|
|
25
|
+
* 1. REGISTRATION. The migration is registered once, last, with a
|
|
26
|
+
* timestamp above everything before it, and its class name matches its
|
|
27
|
+
* file.
|
|
28
|
+
* 2. THE SCHEMA IS THE ENTITIES'. The new table, RunnerJob's new target
|
|
29
|
+
* column and Project's new postmortem flag are created exactly as the
|
|
30
|
+
* models declare them, with TypeORM's own index and foreign key names
|
|
31
|
+
* (a mismatch is a green deploy and a red Schema Drift job).
|
|
32
|
+
* 3. THE DEFAULT AND THE ENTITY AGREE. KubernetesCluster
|
|
33
|
+
* .isAiInvestigationEnabled defaults to true in the model and in this
|
|
34
|
+
* migration's SET DEFAULT; the drift job does not reliably catch a
|
|
35
|
+
* DEFAULT that disagrees.
|
|
36
|
+
* 4. EVERY BACKFILL IS SCOPED, word for word. Widening one would switch AI
|
|
37
|
+
* on for a cluster whose operator switched it off, or start unattended
|
|
38
|
+
* kubectl writes in a project that never opted in.
|
|
39
|
+
* 5. down() REVERSES THE SCHEMA AND THE DEFAULT, NOT THE DATA. Rows the
|
|
40
|
+
* backfills moved are indistinguishable from later operator choices.
|
|
41
|
+
*
|
|
42
|
+
* Fake QueryRunner only.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
const OWN_CLASS_NAME: string = "AddKubernetesAiAgentAndAiDefaults1796100000000";
|
|
46
|
+
|
|
47
|
+
// The last migration registered before this one.
|
|
48
|
+
const REGISTERED_BEFORE_IT: string =
|
|
49
|
+
"AddSubscriberNotificationClaimedAt1795900000000";
|
|
50
|
+
|
|
51
|
+
const MIGRATION_PATH: string = path.join(
|
|
52
|
+
__dirname,
|
|
53
|
+
"../../../../Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts",
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const namingStrategy: DefaultNamingStrategy = new DefaultNamingStrategy();
|
|
57
|
+
|
|
58
|
+
const registeredNames: Array<string> = (
|
|
59
|
+
SchemaMigrations as unknown as Array<{ name: string }>
|
|
60
|
+
).map((migration: { name: string }): string => {
|
|
61
|
+
return migration.name;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
function timestampOfClassName(className: string): number | null {
|
|
65
|
+
const match: RegExpMatchArray | null = className.match(/(\d{13})$/);
|
|
66
|
+
return match ? Number(match[1]) : null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function recordQueries(direction: "up" | "down"): Promise<Array<string>> {
|
|
70
|
+
const statements: Array<string> = [];
|
|
71
|
+
|
|
72
|
+
const queryRunner: QueryRunner = {
|
|
73
|
+
query: async (statement: string): Promise<void> => {
|
|
74
|
+
statements.push(statement);
|
|
75
|
+
},
|
|
76
|
+
} as unknown as QueryRunner;
|
|
77
|
+
|
|
78
|
+
await new AddKubernetesAiAgentAndAiDefaults1796100000000()[direction](
|
|
79
|
+
queryRunner,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return statements;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function isUpdate(statement: string): boolean {
|
|
86
|
+
return statement.startsWith("UPDATE ");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function declaredColumn(
|
|
90
|
+
model: { new (): unknown; name: string },
|
|
91
|
+
property: string,
|
|
92
|
+
): ColumnMetadataArgs {
|
|
93
|
+
const declared: ColumnMetadataArgs | undefined =
|
|
94
|
+
getMetadataArgsStorage().columns.find(
|
|
95
|
+
(column: ColumnMetadataArgs): boolean => {
|
|
96
|
+
return column.target === model && column.propertyName === property;
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (!declared) {
|
|
101
|
+
throw new Error(`${model.name} declares no column ${property}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return declared;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function declaredRelation(
|
|
108
|
+
model: { new (): unknown; name: string },
|
|
109
|
+
property: string,
|
|
110
|
+
): RelationMetadataArgs {
|
|
111
|
+
const declared: RelationMetadataArgs | undefined =
|
|
112
|
+
getMetadataArgsStorage().relations.find(
|
|
113
|
+
(relation: RelationMetadataArgs): boolean => {
|
|
114
|
+
return relation.target === model && relation.propertyName === property;
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
if (!declared) {
|
|
119
|
+
throw new Error(`${model.name} declares no relation ${property}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return declared;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// The hand-added data statements, exactly, in the order they must run.
|
|
126
|
+
const POSTMORTEM_BACKFILL: string = `UPDATE "Project" SET "enableAutomaticPostmortemDraft" = true WHERE "enableAutomaticIncidentInvestigation" = true`;
|
|
127
|
+
|
|
128
|
+
const NEVER_CONFIGURED_CLUSTERS_INVESTIGATE: string = `UPDATE "KubernetesCluster" SET "isAiInvestigationEnabled" = true WHERE "aiAccessConfiguredAt" IS NULL`;
|
|
129
|
+
|
|
130
|
+
const REVOCATIONS_CARRY_OVER: string = `UPDATE "KubernetesCluster" SET "isAiInvestigationEnabled" = false, "aiRemediationMode" = 'Disabled', "aiAccessConfiguredAt" = COALESCE("aiAccessConfiguredAt", NOW()) WHERE "aiAccessRunnerId" IS NULL AND ("aiAccessRunnerBoundAt" IS NOT NULL OR "aiAccessLastVerifiedAt" IS NOT NULL OR "aiAccessLastError" IS NOT NULL)`;
|
|
131
|
+
|
|
132
|
+
const NO_UNATTENDED_SURPRISE: string = `UPDATE "KubernetesCluster" c SET "aiRemediationMode" = 'RequireApproval' FROM "Project" p WHERE c."projectId" = p."_id" AND p."enableAiCommandExecution" IS NOT TRUE AND c."aiRemediationMode" IN ('Automatic','BypassApproval')`;
|
|
133
|
+
|
|
134
|
+
describe("AddKubernetesAiAgentAndAiDefaults migration - identity and registration", () => {
|
|
135
|
+
test("its class name and name carry its stamp, matching its file", () => {
|
|
136
|
+
const source: string = fs.readFileSync(MIGRATION_PATH, "utf8");
|
|
137
|
+
|
|
138
|
+
expect(source).toContain(`export class ${OWN_CLASS_NAME}`);
|
|
139
|
+
expect(source).toContain(`public name: string = "${OWN_CLASS_NAME}";`);
|
|
140
|
+
expect(new AddKubernetesAiAgentAndAiDefaults1796100000000().name).toBe(
|
|
141
|
+
OWN_CLASS_NAME,
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test("is registered exactly once", () => {
|
|
146
|
+
expect(SchemaMigrations).toContain(
|
|
147
|
+
AddKubernetesAiAgentAndAiDefaults1796100000000,
|
|
148
|
+
);
|
|
149
|
+
expect(
|
|
150
|
+
registeredNames.filter((name: string): boolean => {
|
|
151
|
+
return name === OWN_CLASS_NAME;
|
|
152
|
+
}),
|
|
153
|
+
).toHaveLength(1);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("sorts after every migration registered before it", () => {
|
|
157
|
+
const ownIndex: number = registeredNames.indexOf(OWN_CLASS_NAME);
|
|
158
|
+
const ownTimestamp: number = timestampOfClassName(OWN_CLASS_NAME)!;
|
|
159
|
+
|
|
160
|
+
expect(ownIndex).toBeGreaterThan(
|
|
161
|
+
registeredNames.indexOf(REGISTERED_BEFORE_IT),
|
|
162
|
+
);
|
|
163
|
+
expect(
|
|
164
|
+
registeredNames.slice(0, ownIndex).filter((className: string) => {
|
|
165
|
+
const timestamp: number | null = timestampOfClassName(className);
|
|
166
|
+
return timestamp !== null && timestamp >= ownTimestamp;
|
|
167
|
+
}),
|
|
168
|
+
).toEqual([]);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
describe("AddKubernetesAiAgentAndAiDefaults migration - the KubernetesAiAgent table", () => {
|
|
173
|
+
const ownColumns: Array<ColumnMetadataArgs> =
|
|
174
|
+
getMetadataArgsStorage().columns.filter(
|
|
175
|
+
(column: ColumnMetadataArgs): boolean => {
|
|
176
|
+
return column.target === KubernetesAiAgent;
|
|
177
|
+
},
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
test("the model declares the columns the design names", () => {
|
|
181
|
+
expect(
|
|
182
|
+
ownColumns
|
|
183
|
+
.map((column: ColumnMetadataArgs): string => {
|
|
184
|
+
return column.propertyName;
|
|
185
|
+
})
|
|
186
|
+
.sort(),
|
|
187
|
+
).toEqual(
|
|
188
|
+
[
|
|
189
|
+
"projectId",
|
|
190
|
+
"kubernetesClusterId",
|
|
191
|
+
"keyHash",
|
|
192
|
+
"agentVersion",
|
|
193
|
+
"posture",
|
|
194
|
+
"lastAliveAt",
|
|
195
|
+
"connectionStatus",
|
|
196
|
+
"lastRegisteredAt",
|
|
197
|
+
"registeredWithIngestionKeyId",
|
|
198
|
+
"lastRefusedRegistrationAt",
|
|
199
|
+
"lastRefusedRegistrationReason",
|
|
200
|
+
].sort(),
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test.each([
|
|
205
|
+
["projectId", `"projectId" uuid NOT NULL`],
|
|
206
|
+
["kubernetesClusterId", `"kubernetesClusterId" uuid NOT NULL`],
|
|
207
|
+
["keyHash", `"keyHash" character varying(100),`],
|
|
208
|
+
["agentVersion", `"agentVersion" character varying(100),`],
|
|
209
|
+
["posture", `"posture" jsonb,`],
|
|
210
|
+
["lastAliveAt", `"lastAliveAt" TIMESTAMP WITH TIME ZONE,`],
|
|
211
|
+
[
|
|
212
|
+
"connectionStatus",
|
|
213
|
+
`"connectionStatus" character varying(100) NOT NULL DEFAULT 'disconnected'`,
|
|
214
|
+
],
|
|
215
|
+
["lastRegisteredAt", `"lastRegisteredAt" TIMESTAMP WITH TIME ZONE,`],
|
|
216
|
+
["registeredWithIngestionKeyId", `"registeredWithIngestionKeyId" uuid,`],
|
|
217
|
+
[
|
|
218
|
+
"lastRefusedRegistrationAt",
|
|
219
|
+
`"lastRefusedRegistrationAt" TIMESTAMP WITH TIME ZONE,`,
|
|
220
|
+
],
|
|
221
|
+
[
|
|
222
|
+
"lastRefusedRegistrationReason",
|
|
223
|
+
`"lastRefusedRegistrationReason" character varying(100),`,
|
|
224
|
+
],
|
|
225
|
+
])(
|
|
226
|
+
"creates %s as the model declares it",
|
|
227
|
+
async (property: string, ddl: string) => {
|
|
228
|
+
const declared: ColumnMetadataArgs = declaredColumn(
|
|
229
|
+
KubernetesAiAgent,
|
|
230
|
+
property,
|
|
231
|
+
);
|
|
232
|
+
const createTable: string | undefined = (await recordQueries("up")).find(
|
|
233
|
+
(statement: string): boolean => {
|
|
234
|
+
return statement.startsWith(`CREATE TABLE "KubernetesAiAgent"`);
|
|
235
|
+
},
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
expect(createTable).toBeDefined();
|
|
239
|
+
expect(createTable).toContain(ddl);
|
|
240
|
+
|
|
241
|
+
if (declared.options.nullable === false) {
|
|
242
|
+
expect(ddl).toContain("NOT NULL");
|
|
243
|
+
} else {
|
|
244
|
+
expect(ddl).not.toContain("NOT NULL");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (declared.options.default !== undefined) {
|
|
248
|
+
expect(ddl).toContain(`DEFAULT '${String(declared.options.default)}'`);
|
|
249
|
+
} else {
|
|
250
|
+
expect(ddl).not.toContain("DEFAULT");
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
test("enforces one agent per cluster with the unique index the model names", async () => {
|
|
256
|
+
expect(await recordQueries("up")).toContain(
|
|
257
|
+
`CREATE UNIQUE INDEX "IDX_KubernetesAiAgent_kubernetesClusterId" ON "KubernetesAiAgent" ("kubernetesClusterId") WHERE "deletedAt" IS NULL`,
|
|
258
|
+
);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test("indexes projectId under TypeORM's name", async () => {
|
|
262
|
+
expect(await recordQueries("up")).toContain(
|
|
263
|
+
`CREATE INDEX "${namingStrategy.indexName("KubernetesAiAgent", [
|
|
264
|
+
"projectId",
|
|
265
|
+
])}" ON "KubernetesAiAgent" ("projectId") `,
|
|
266
|
+
);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test.each([
|
|
270
|
+
["project", "projectId", "Project", Project],
|
|
271
|
+
[
|
|
272
|
+
"kubernetesCluster",
|
|
273
|
+
"kubernetesClusterId",
|
|
274
|
+
"KubernetesCluster",
|
|
275
|
+
KubernetesCluster,
|
|
276
|
+
],
|
|
277
|
+
])(
|
|
278
|
+
"KubernetesAiAgent.%s goes when its %s row goes (ON DELETE CASCADE)",
|
|
279
|
+
async (
|
|
280
|
+
relation: string,
|
|
281
|
+
column: string,
|
|
282
|
+
referencedTable: string,
|
|
283
|
+
referencedModel: unknown,
|
|
284
|
+
) => {
|
|
285
|
+
const declared: RelationMetadataArgs = declaredRelation(
|
|
286
|
+
KubernetesAiAgent,
|
|
287
|
+
relation,
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
expect(declared.relationType).toBe("many-to-one");
|
|
291
|
+
expect(declared.options.onDelete).toBe("CASCADE");
|
|
292
|
+
expect((declared.type as () => unknown)()).toBe(referencedModel);
|
|
293
|
+
|
|
294
|
+
expect(await recordQueries("up")).toContain(
|
|
295
|
+
`ALTER TABLE "KubernetesAiAgent" ADD CONSTRAINT "${namingStrategy.foreignKeyName(
|
|
296
|
+
"KubernetesAiAgent",
|
|
297
|
+
[column],
|
|
298
|
+
)}" FOREIGN KEY ("${column}") REFERENCES "${referencedTable}"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
299
|
+
);
|
|
300
|
+
},
|
|
301
|
+
);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
describe("AddKubernetesAiAgentAndAiDefaults migration - RunnerJob.targetKubernetesAiAgentId", () => {
|
|
305
|
+
test("adds the nullable uuid column the model declares", async () => {
|
|
306
|
+
const declared: ColumnMetadataArgs = declaredColumn(
|
|
307
|
+
RunnerJob,
|
|
308
|
+
"targetKubernetesAiAgentId",
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
expect(declared.options.nullable).toBe(true);
|
|
312
|
+
expect(await recordQueries("up")).toContain(
|
|
313
|
+
`ALTER TABLE "RunnerJob" ADD "targetKubernetesAiAgentId" uuid`,
|
|
314
|
+
);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
test("indexes it under TypeORM's name, for the agent's claim query", async () => {
|
|
318
|
+
expect(await recordQueries("up")).toContain(
|
|
319
|
+
`CREATE INDEX "${namingStrategy.indexName("RunnerJob", [
|
|
320
|
+
"targetKubernetesAiAgentId",
|
|
321
|
+
])}" ON "RunnerJob" ("targetKubernetesAiAgentId") `,
|
|
322
|
+
);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test("references KubernetesAiAgent and is nulled, never cascaded, when the agent row goes", async () => {
|
|
326
|
+
const declared: RelationMetadataArgs = declaredRelation(
|
|
327
|
+
RunnerJob,
|
|
328
|
+
"targetKubernetesAiAgent",
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
expect(declared.relationType).toBe("many-to-one");
|
|
332
|
+
expect(declared.options.onDelete).toBe("SET NULL");
|
|
333
|
+
expect((declared.type as () => unknown)()).toBe(KubernetesAiAgent);
|
|
334
|
+
|
|
335
|
+
expect(await recordQueries("up")).toContain(
|
|
336
|
+
`ALTER TABLE "RunnerJob" ADD CONSTRAINT "${namingStrategy.foreignKeyName(
|
|
337
|
+
"RunnerJob",
|
|
338
|
+
["targetKubernetesAiAgentId"],
|
|
339
|
+
)}" FOREIGN KEY ("targetKubernetesAiAgentId") REFERENCES "KubernetesAiAgent"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
340
|
+
);
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
describe("AddKubernetesAiAgentAndAiDefaults migration - defaults", () => {
|
|
345
|
+
test("isAiInvestigationEnabled defaults to true, in the entity and in the database", async () => {
|
|
346
|
+
const declared: ColumnMetadataArgs = declaredColumn(
|
|
347
|
+
KubernetesCluster,
|
|
348
|
+
"isAiInvestigationEnabled",
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
expect(declared.options.default).toBe(true);
|
|
352
|
+
expect(
|
|
353
|
+
new KubernetesCluster().getTableColumnMetadata("isAiInvestigationEnabled")
|
|
354
|
+
.defaultValue,
|
|
355
|
+
).toBe(true);
|
|
356
|
+
expect(await recordQueries("up")).toContain(
|
|
357
|
+
`ALTER TABLE "KubernetesCluster" ALTER COLUMN "isAiInvestigationEnabled" SET DEFAULT ${String(
|
|
358
|
+
declared.options.default,
|
|
359
|
+
)}`,
|
|
360
|
+
);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
test("adds Project.enableAutomaticPostmortemDraft as the model declares it: NOT NULL, default off", async () => {
|
|
364
|
+
const declared: ColumnMetadataArgs = declaredColumn(
|
|
365
|
+
Project,
|
|
366
|
+
"enableAutomaticPostmortemDraft",
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
expect(declared.options.nullable).toBe(false);
|
|
370
|
+
expect(declared.options.default).toBe(false);
|
|
371
|
+
expect(
|
|
372
|
+
new Project().getTableColumnMetadata("enableAutomaticPostmortemDraft")
|
|
373
|
+
.defaultValue,
|
|
374
|
+
).toBe(false);
|
|
375
|
+
expect(await recordQueries("up")).toContain(
|
|
376
|
+
`ALTER TABLE "Project" ADD "enableAutomaticPostmortemDraft" boolean NOT NULL DEFAULT false`,
|
|
377
|
+
);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
test("the postmortem flag carries the same access rules as the investigation flag it was split from", () => {
|
|
381
|
+
const project: Project = new Project();
|
|
382
|
+
const postmortem: ColumnAccessControl | null =
|
|
383
|
+
project.getColumnAccessControlFor("enableAutomaticPostmortemDraft");
|
|
384
|
+
const investigation: ColumnAccessControl | null =
|
|
385
|
+
project.getColumnAccessControlFor("enableAutomaticIncidentInvestigation");
|
|
386
|
+
|
|
387
|
+
expect(postmortem).not.toBeNull();
|
|
388
|
+
expect(postmortem).toEqual(investigation);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
/*
|
|
392
|
+
* The project opt-ins are switched on for NEW projects by ProjectService,
|
|
393
|
+
* never by a column default: a default would be emitted as the generated
|
|
394
|
+
* Terraform provider's static default and flip existing Terraform-managed
|
|
395
|
+
* projects on their next apply, and a backfill would start spending
|
|
396
|
+
* existing projects' AI budget.
|
|
397
|
+
*/
|
|
398
|
+
test.each([
|
|
399
|
+
"enableAutomaticIncidentInvestigation",
|
|
400
|
+
"enableAutomaticAlertInvestigation",
|
|
401
|
+
])(
|
|
402
|
+
"leaves Project.%s's default off and every existing project as it was",
|
|
403
|
+
async (property: string) => {
|
|
404
|
+
const declared: ColumnMetadataArgs = declaredColumn(Project, property);
|
|
405
|
+
|
|
406
|
+
expect(declared.options.default).toBe(false);
|
|
407
|
+
expect(new Project().getTableColumnMetadata(property).defaultValue).toBe(
|
|
408
|
+
false,
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
for (const statement of await recordQueries("up")) {
|
|
412
|
+
expect(statement).not.toMatch(
|
|
413
|
+
new RegExp(`SET "${property}"|"${property}" SET DEFAULT`),
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
);
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
describe("AddKubernetesAiAgentAndAiDefaults migration - the backfills", () => {
|
|
421
|
+
test("runs exactly four hand-added UPDATEs, in order, after every schema change", async () => {
|
|
422
|
+
const up: Array<string> = await recordQueries("up");
|
|
423
|
+
const updates: Array<string> = up.filter(isUpdate);
|
|
424
|
+
|
|
425
|
+
expect(updates).toEqual([
|
|
426
|
+
POSTMORTEM_BACKFILL,
|
|
427
|
+
NEVER_CONFIGURED_CLUSTERS_INVESTIGATE,
|
|
428
|
+
REVOCATIONS_CARRY_OVER,
|
|
429
|
+
NO_UNATTENDED_SURPRISE,
|
|
430
|
+
]);
|
|
431
|
+
|
|
432
|
+
const firstUpdate: number = up.findIndex(isUpdate);
|
|
433
|
+
|
|
434
|
+
expect(up.slice(firstUpdate).every(isUpdate)).toBe(true);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
/*
|
|
438
|
+
* Postmortem drafting used to ride on the investigation flag. The new
|
|
439
|
+
* column was just added as NOT NULL DEFAULT false, so setting it to true
|
|
440
|
+
* where investigation is on is the complete copy — and it rewrites only
|
|
441
|
+
* the projects that had the behaviour.
|
|
442
|
+
*/
|
|
443
|
+
test("postmortem drafts stay on exactly where investigations were on", async () => {
|
|
444
|
+
const where: string = POSTMORTEM_BACKFILL.slice(
|
|
445
|
+
POSTMORTEM_BACKFILL.indexOf(" WHERE "),
|
|
446
|
+
);
|
|
447
|
+
|
|
448
|
+
expect(POSTMORTEM_BACKFILL).toContain(
|
|
449
|
+
`SET "enableAutomaticPostmortemDraft" = true`,
|
|
450
|
+
);
|
|
451
|
+
expect(where).toBe(` WHERE "enableAutomaticIncidentInvestigation" = true`);
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
test("investigation is turned on only for clusters nobody ever configured", () => {
|
|
455
|
+
expect(NEVER_CONFIGURED_CLUSTERS_INVESTIGATE).toContain(
|
|
456
|
+
`SET "isAiInvestigationEnabled" = true`,
|
|
457
|
+
);
|
|
458
|
+
expect(
|
|
459
|
+
NEVER_CONFIGURED_CLUSTERS_INVESTIGATE.slice(
|
|
460
|
+
NEVER_CONFIGURED_CLUSTERS_INVESTIGATE.indexOf(" WHERE "),
|
|
461
|
+
),
|
|
462
|
+
).toBe(` WHERE "aiAccessConfiguredAt" IS NULL`);
|
|
463
|
+
expect(NEVER_CONFIGURED_CLUSTERS_INVESTIGATE).not.toContain(
|
|
464
|
+
"aiRemediationMode",
|
|
465
|
+
);
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
/*
|
|
469
|
+
* Before the AI agent, unbinding or deleting the cluster's Runner WAS the
|
|
470
|
+
* off switch. Such a cluster has no Runner now but had one bound, or AI
|
|
471
|
+
* already ran (or tried to run) kubectl on it. It must stay off — and it
|
|
472
|
+
* runs AFTER the never-configured backfill, so the revocation wins even
|
|
473
|
+
* for a cluster that also has no configured marker.
|
|
474
|
+
*/
|
|
475
|
+
test("a cluster whose Runner was unbound or deleted is switched fully off, after the default backfill", async () => {
|
|
476
|
+
expect(REVOCATIONS_CARRY_OVER).toContain(
|
|
477
|
+
`SET "isAiInvestigationEnabled" = false, "aiRemediationMode" = 'Disabled'`,
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
/*
|
|
481
|
+
* Marked configured (keeping an earlier timestamp), so the AI agent's
|
|
482
|
+
* first-connection defaults — which only apply while
|
|
483
|
+
* aiAccessConfiguredAt IS NULL — never turn a revoked cluster back on.
|
|
484
|
+
*/
|
|
485
|
+
expect(REVOCATIONS_CARRY_OVER).toContain(
|
|
486
|
+
`"aiAccessConfiguredAt" = COALESCE("aiAccessConfiguredAt", NOW())`,
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
const where: string = REVOCATIONS_CARRY_OVER.slice(
|
|
490
|
+
REVOCATIONS_CARRY_OVER.indexOf(" WHERE "),
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
expect(where).toBe(
|
|
494
|
+
` WHERE "aiAccessRunnerId" IS NULL AND ("aiAccessRunnerBoundAt" IS NOT NULL OR "aiAccessLastVerifiedAt" IS NOT NULL OR "aiAccessLastError" IS NOT NULL)`,
|
|
495
|
+
);
|
|
496
|
+
|
|
497
|
+
const up: Array<string> = await recordQueries("up");
|
|
498
|
+
|
|
499
|
+
expect(up.indexOf(REVOCATIONS_CARRY_OVER)).toBeGreaterThan(
|
|
500
|
+
up.indexOf(NEVER_CONFIGURED_CLUSTERS_INVESTIGATE),
|
|
501
|
+
);
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
/*
|
|
505
|
+
* Cluster rounds through the in-cluster agent no longer need the
|
|
506
|
+
* project's "Enable AI command execution" opt-in. Without this, a cluster
|
|
507
|
+
* left in an unattended mode in a project that never opted in would start
|
|
508
|
+
* changing the cluster on its own the moment the server upgraded.
|
|
509
|
+
*/
|
|
510
|
+
test("unattended modes drop to RequireApproval only in projects that never opted in to AI command execution", () => {
|
|
511
|
+
expect(NO_UNATTENDED_SURPRISE).toContain(
|
|
512
|
+
`SET "aiRemediationMode" = 'RequireApproval'`,
|
|
513
|
+
);
|
|
514
|
+
|
|
515
|
+
const where: string = NO_UNATTENDED_SURPRISE.slice(
|
|
516
|
+
NO_UNATTENDED_SURPRISE.indexOf(" WHERE "),
|
|
517
|
+
);
|
|
518
|
+
|
|
519
|
+
expect(where).toBe(
|
|
520
|
+
` WHERE c."projectId" = p."_id" AND p."enableAiCommandExecution" IS NOT TRUE AND c."aiRemediationMode" IN ('Automatic','BypassApproval')`,
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
// IS NOT TRUE, not = false: a NULL opt-in is not an opt-in.
|
|
524
|
+
expect(where).not.toContain(`"enableAiCommandExecution" = false`);
|
|
525
|
+
// Disabled and RequireApproval clusters are never touched.
|
|
526
|
+
expect(where).not.toContain("'Disabled'");
|
|
527
|
+
expect(where).not.toContain("'RequireApproval'");
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
test("no backfill touches the new table or RunnerJob", () => {
|
|
531
|
+
for (const statement of [
|
|
532
|
+
POSTMORTEM_BACKFILL,
|
|
533
|
+
NEVER_CONFIGURED_CLUSTERS_INVESTIGATE,
|
|
534
|
+
REVOCATIONS_CARRY_OVER,
|
|
535
|
+
NO_UNATTENDED_SURPRISE,
|
|
536
|
+
]) {
|
|
537
|
+
expect(statement).not.toContain(`"KubernetesAiAgent"`);
|
|
538
|
+
expect(statement).not.toContain(`"RunnerJob"`);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
describe("AddKubernetesAiAgentAndAiDefaults migration - down()", () => {
|
|
544
|
+
/*
|
|
545
|
+
* The inverse of every schema statement of up(), in reverse order, and
|
|
546
|
+
* nothing for the backfills.
|
|
547
|
+
*/
|
|
548
|
+
test("undoes exactly the schema and default changes of up(), in reverse order", async () => {
|
|
549
|
+
const up: Array<string> = await recordQueries("up");
|
|
550
|
+
|
|
551
|
+
const inverse: Array<string> = up
|
|
552
|
+
.filter((statement: string): boolean => {
|
|
553
|
+
return !isUpdate(statement);
|
|
554
|
+
})
|
|
555
|
+
.map((statement: string): string => {
|
|
556
|
+
const constraint: RegExpMatchArray | null = statement.match(
|
|
557
|
+
/^ALTER TABLE "([^"]+)" ADD CONSTRAINT "([^"]+)"/,
|
|
558
|
+
);
|
|
559
|
+
if (constraint) {
|
|
560
|
+
return `ALTER TABLE "${constraint[1]}" DROP CONSTRAINT "${constraint[2]}"`;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const index: RegExpMatchArray | null = statement.match(
|
|
564
|
+
/^CREATE (?:UNIQUE )?INDEX "([^"]+)"/,
|
|
565
|
+
);
|
|
566
|
+
if (index) {
|
|
567
|
+
return `DROP INDEX "public"."${index[1]}"`;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
const column: RegExpMatchArray | null = statement.match(
|
|
571
|
+
/^ALTER TABLE "([^"]+)" ADD "([^"]+)"/,
|
|
572
|
+
);
|
|
573
|
+
if (column) {
|
|
574
|
+
return `ALTER TABLE "${column[1]}" DROP COLUMN "${column[2]}"`;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
const setDefault: RegExpMatchArray | null = statement.match(
|
|
578
|
+
/^ALTER TABLE "KubernetesCluster" ALTER COLUMN "isAiInvestigationEnabled" SET DEFAULT true$/,
|
|
579
|
+
);
|
|
580
|
+
if (setDefault) {
|
|
581
|
+
return `ALTER TABLE "KubernetesCluster" ALTER COLUMN "isAiInvestigationEnabled" SET DEFAULT false`;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
const table: RegExpMatchArray | null = statement.match(
|
|
585
|
+
/^CREATE TABLE "([^"]+)"/,
|
|
586
|
+
);
|
|
587
|
+
if (table) {
|
|
588
|
+
return `DROP TABLE "${table[1]}"`;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
throw new Error(
|
|
592
|
+
`up() ran a statement with no known inverse: ${statement}`,
|
|
593
|
+
);
|
|
594
|
+
})
|
|
595
|
+
.reverse();
|
|
596
|
+
|
|
597
|
+
expect(await recordQueries("down")).toEqual(inverse);
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
test("restores the previous investigation default", async () => {
|
|
601
|
+
expect(await recordQueries("down")).toContain(
|
|
602
|
+
`ALTER TABLE "KubernetesCluster" ALTER COLUMN "isAiInvestigationEnabled" SET DEFAULT false`,
|
|
603
|
+
);
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
test("leaves every backfilled row alone", async () => {
|
|
607
|
+
expect((await recordQueries("down")).some(isUpdate)).toBe(false);
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
test("drops the table last, after everything that references it", async () => {
|
|
611
|
+
const down: Array<string> = await recordQueries("down");
|
|
612
|
+
|
|
613
|
+
expect(down[down.length - 1]).toBe(`DROP TABLE "KubernetesAiAgent"`);
|
|
614
|
+
expect(
|
|
615
|
+
down.indexOf(
|
|
616
|
+
`ALTER TABLE "RunnerJob" DROP CONSTRAINT "${namingStrategy.foreignKeyName(
|
|
617
|
+
"RunnerJob",
|
|
618
|
+
["targetKubernetesAiAgentId"],
|
|
619
|
+
)}"`,
|
|
620
|
+
),
|
|
621
|
+
).toBe(0);
|
|
622
|
+
});
|
|
623
|
+
});
|