@oneuptime/common 14.0.8 → 14.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/AutoRemediationSuggestion.ts +60 -0
- package/Models/DatabaseModels/CephCluster.ts +213 -0
- package/Models/DatabaseModels/DatabaseServer.ts +213 -0
- package/Models/DatabaseModels/DockerHost.ts +213 -0
- package/Models/DatabaseModels/DockerSwarmCluster.ts +213 -0
- package/Models/DatabaseModels/GlobalConfig.ts +1 -1
- package/Models/DatabaseModels/Host.ts +213 -0
- package/Models/DatabaseModels/Index.ts +4 -0
- package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
- package/Models/DatabaseModels/PodmanHost.ts +213 -0
- package/Models/DatabaseModels/Project.ts +55 -5
- package/Models/DatabaseModels/ProxmoxCluster.ts +213 -0
- package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
- package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
- package/Models/DatabaseModels/RunnerJob.ts +219 -0
- package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
- package/Models/DatabaseModels/VMwareVCenter.ts +213 -0
- 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 +598 -25
- package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
- package/Server/API/MicrosoftTeamsAPI.ts +93 -14
- package/Server/API/ProxmoxResourceAPI.ts +244 -14
- package/Server/API/ResourceAiAccessAPI.ts +1669 -0
- 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/1796300000000-AddResourceAiAgents.ts +423 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Infrastructure/Semaphore.ts +22 -0
- package/Server/Middleware/TelemetryIngest.ts +51 -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/AnalyticsDatabaseService.ts +45 -1
- package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
- package/Server/Services/AutoRemediationRuleService.ts +1 -1
- package/Server/Services/CephClusterService.ts +109 -1
- package/Server/Services/DatabaseServerService.ts +116 -1
- package/Server/Services/DockerHostService.ts +109 -1
- package/Server/Services/DockerSwarmClusterService.ts +113 -1
- package/Server/Services/HostService.ts +126 -4
- 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/MetricRecordingRuleService.ts +47 -0
- package/Server/Services/PodmanHostService.ts +109 -1
- package/Server/Services/ProjectService.ts +32 -0
- package/Server/Services/ProxmoxClusterService.ts +110 -1
- package/Server/Services/ProxmoxResourceService.ts +322 -5
- package/Server/Services/ResourceAiAccessService.ts +1439 -0
- package/Server/Services/ResourceAiAgentJobService.ts +202 -0
- package/Server/Services/ResourceAiAgentService.ts +2432 -0
- package/Server/Services/RunnerJobService.ts +852 -108
- 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/Services/TelemetryUsageBillingService.ts +28 -0
- package/Server/Services/TraceRecordingRuleService.ts +33 -0
- package/Server/Services/VMwareVCenterService.ts +110 -1
- 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 +1475 -51
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +1000 -43
- package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
- package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +577 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
- package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +873 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +120 -7
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +72 -5
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +72 -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 +402 -14
- package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
- package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
- package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
- 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/Actions/Alert.ts +35 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +298 -224
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +35 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +1073 -213
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.ts +163 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +396 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.ts +418 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.ts +152 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.ts +251 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.ts +214 -0
- 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 +184 -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/DatabaseDocumentationMarkdown.test.ts +18 -6
- 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/InvestigationInfrastructureTools.test.tsx +506 -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/RemediationSuggestionCardDescription.test.tsx +209 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
- package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
- package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
- package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +1721 -0
- package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1002 -0
- package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
- package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
- package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
- package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
- package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
- 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/DatabaseServerModels.test.ts +33 -1
- package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
- package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
- package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -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/AutoRemediationApproveResourceRound.test.ts +835 -0
- 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/API/ResourceAiAccessAPI.test.ts +2730 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
- package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -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/AddResourceAiAgentsMigration.test.ts +659 -0
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +119 -4
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +196 -2
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +123 -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/AutoRemediationResourceRuleEngine.test.ts +1279 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
- package/Tests/Server/Services/DatabaseServerService.test.ts +55 -0
- package/Tests/Server/Services/GroupTelemetryUsageExcludeNames.test.ts +299 -0
- package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +44 -0
- 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/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
- 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/RecordingRuleReservedMetricName.test.ts +171 -0
- package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
- package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
- package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
- package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
- package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
- package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
- package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
- package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
- package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +153 -15
- package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
- package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
- package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
- package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
- 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/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
- package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
- 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/InvestigationInfrastructureAccessWiring.test.ts +453 -0
- package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -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/RemediationCommandTools.test.ts +94 -1
- 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/RemediationCommandToolsResource.test.ts +1530 -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/RemediationExecutionRunnerResourceMode.test.ts +1249 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
- package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
- package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +722 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +830 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -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/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
- package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
- 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 +75 -3
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsAccountNotLinked.test.ts +1093 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.test.ts +1049 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +1676 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCards.test.ts +2884 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.test.ts +2490 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmit.test.ts +2293 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmitServerTimezone.test.ts +386 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.test.ts +1477 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.test.ts +1967 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsStripHtmlTags.test.ts +92 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsSubmittedFormRemoval.test.ts +1819 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.test.ts +1033 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezoneServerZone.test.ts +610 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsBotMessageHandling.test.ts +2610 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
- package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
- package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
- package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
- package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +517 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
- 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/RecordingHealthDashboard.test.tsx +769 -1
- 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/AiRemediation/Resource/CephCommandPolicy.test.ts +1653 -0
- package/Tests/Utils/AiRemediation/Resource/CephOutputRedaction.test.ts +204 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseCommandPolicy.test.ts +1077 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.test.ts +558 -0
- package/Tests/Utils/AiRemediation/Resource/DatabaseQueryRedactor.test.ts +834 -0
- package/Tests/Utils/AiRemediation/Resource/DockerCliGrammar.test.ts +747 -0
- package/Tests/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.test.ts +1259 -0
- package/Tests/Utils/AiRemediation/Resource/DockerOutputRedaction.test.ts +386 -0
- package/Tests/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.test.ts +782 -0
- package/Tests/Utils/AiRemediation/Resource/GovcCommandPolicy.test.ts +2259 -0
- package/Tests/Utils/AiRemediation/Resource/HostCommandPolicy.test.ts +2019 -0
- package/Tests/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.test.ts +2497 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicy.test.ts +1305 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.test.ts +585 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactor.test.ts +334 -0
- package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactorCopyParity.test.ts +98 -0
- package/Tests/Utils/AiRemediation/Resource/ResourcePolicyImportClosure.test.ts +391 -0
- package/Tests/Utils/AiRemediation/ResourceAiAgentPolicyCopyParity.test.ts +497 -0
- package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
- package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
- package/Types/AI/AIRunType.ts +9 -4
- package/Types/AI/InvestigationNotStartedReason.ts +6 -0
- package/Types/AI/ResourceAiAccessApi.ts +140 -0
- package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +197 -18
- 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/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
- package/Types/Monitor/RumAlertTemplates.ts +351 -4
- package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
- package/Types/ResourceAiAgent/ResourceAiAccess.ts +574 -0
- package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
- package/Types/Runbook/RunbookStepType.ts +29 -0
- 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 +40 -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/AI/InvestigationReport.ts +121 -15
- package/Utils/AiRemediation/CommandPolicy.ts +1 -1
- package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
- package/Utils/AiRemediation/Resource/CephCommandPolicy.ts +1936 -0
- package/Utils/AiRemediation/Resource/DatabaseCommandPolicy.ts +166 -0
- package/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.ts +1532 -0
- package/Utils/AiRemediation/Resource/DatabaseQueryRedactor.ts +1394 -0
- package/Utils/AiRemediation/Resource/DockerCliGrammar.ts +1839 -0
- package/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.ts +490 -0
- package/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.ts +687 -0
- package/Utils/AiRemediation/Resource/GovcCommandPolicy.ts +2096 -0
- package/Utils/AiRemediation/Resource/HostCommandPolicy.ts +2982 -0
- package/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.ts +1679 -0
- package/Utils/AiRemediation/Resource/ResourceCommandPolicy.ts +851 -0
- package/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.ts +593 -0
- package/Utils/AiRemediation/Resource/ResourceOutputRedactor.ts +2812 -0
- package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
- package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js +219 -0
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseServer.js +219 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +219 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +219 -0
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +219 -0
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +4 -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/PodmanHost.js +219 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.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/ProxmoxCluster.js +219 -0
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.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/ResourceAiAgent.js +439 -0
- package/build/dist/Models/DatabaseModels/ResourceAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js +219 -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/VMwareVCenter.js +219 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.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 +374 -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/API/ResourceAiAccessAPI.js +1119 -0
- package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
- 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/1796300000000-AddResourceAiAgents.js +168 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +41 -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/AnalyticsDatabaseService.js +26 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +601 -3
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.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/CephClusterService.js +104 -0
- package/build/dist/Server/Services/CephClusterService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseServerService.js +99 -0
- package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +104 -0
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterService.js +104 -0
- package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +114 -2
- package/build/dist/Server/Services/HostService.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/MetricRecordingRuleService.js +46 -0
- package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostService.js +104 -0
- package/build/dist/Server/Services/PodmanHostService.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/ProxmoxClusterService.js +104 -0
- package/build/dist/Server/Services/ProxmoxClusterService.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/ResourceAiAccessService.js +1028 -0
- package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -0
- package/build/dist/Server/Services/ResourceAiAgentJobService.js +173 -0
- package/build/dist/Server/Services/ResourceAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/ResourceAiAgentService.js +1687 -0
- package/build/dist/Server/Services/ResourceAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/RunnerJobService.js +522 -97
- 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/Services/TelemetryUsageBillingService.js +26 -0
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
- package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
- package/build/dist/Server/Services/VMwareVCenterService.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 +1056 -43
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +683 -42
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +330 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +600 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +89 -9
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +55 -4
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +55 -4
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.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 +294 -15
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +29 -1
- package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +9 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +627 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js +60 -5
- package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.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/Actions/Alert.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +183 -209
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +768 -152
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js +129 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +266 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js +258 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js +104 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js +183 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js +123 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js.map +1 -0
- package/build/dist/Types/AI/AIRunType.js +9 -4
- package/build/dist/Types/AI/AIRunType.js.map +1 -1
- package/build/dist/Types/AI/ResourceAiAccessApi.js +30 -0
- package/build/dist/Types/AI/ResourceAiAccessApi.js.map +1 -0
- package/build/dist/Types/AI/ResourceAiAccessPermissions.js +98 -0
- package/build/dist/Types/AI/ResourceAiAccessPermissions.js.map +1 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +126 -45
- 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/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +275 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
- package/build/dist/Types/Runbook/RunbookStepType.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 +36 -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/AI/InvestigationReport.js +71 -11
- package/build/dist/Utils/AI/InvestigationReport.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/AiRemediation/Resource/CephCommandPolicy.js +1462 -0
- package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js +122 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js +1139 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js +1060 -0
- package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js +1301 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js +370 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js +498 -0
- package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js +1565 -0
- package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js +2206 -0
- package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js +1129 -0
- package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js +565 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js +408 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js.map +1 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js +1910 -0
- package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js.map +1 -0
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1462 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The ceph command policy: tiers the ceph CLI (health, OSDs, pools,
|
|
3
|
+
* placement groups, daemons) for Ceph clusters.
|
|
4
|
+
*
|
|
5
|
+
* The agent spawns the ceph binary (Squid 19) with the argv this policy
|
|
6
|
+
* read and with its OWN --conf, --keyring and --id, so what this policy has
|
|
7
|
+
* to bound is what one ceph command can do. It is an allowlist of exact
|
|
8
|
+
* command words with validated arguments; anything it does not model is
|
|
9
|
+
* Denied, with a reason that names what may run instead.
|
|
10
|
+
*
|
|
11
|
+
* ---- How ceph reads its argv --------------------------------------------------
|
|
12
|
+
*
|
|
13
|
+
* ceph parses its own options with Python's argparse (parse_known_args)
|
|
14
|
+
* BEFORE it looks at the command, and hands every word it did not consume
|
|
15
|
+
* to the monitors, which match it against their command table. That parser
|
|
16
|
+
* decides what a dash-prefixed word means, and it is generous:
|
|
17
|
+
* - options may appear anywhere: before, between and after the command
|
|
18
|
+
* words (`ceph osd -f json tree` is `ceph osd tree -f json`);
|
|
19
|
+
* - long options may be ABBREVIATED (allow_abbrev): `--out` is --out-file
|
|
20
|
+
* and `--keyr`-style prefixes of any option it knows are that option;
|
|
21
|
+
* - short options may be combined (`-sw`) or carry their value inline
|
|
22
|
+
* (`-fjson`, `-f=json`), and `--opt=value` carries one too;
|
|
23
|
+
* - whatever argparse does not consume, librados reads as a configuration
|
|
24
|
+
* override: `--keyring=...`, `--mon-host=...`, `--log-file=...`,
|
|
25
|
+
* `--admin-socket=...` switch the cluster, the identity or write files;
|
|
26
|
+
* - `--admin-daemon`, `-i`/`--in-file`, `-o`/`--out-file`, `-w`/`--watch`
|
|
27
|
+
* read a local admin socket, read or write local files, or never end.
|
|
28
|
+
* So this policy NEVER interprets a dash-prefixed word it does not know. It
|
|
29
|
+
* accepts exactly:
|
|
30
|
+
* - `--format V`, `--format=V` or `-f V`, with V one of json, json-pretty
|
|
31
|
+
* or plain, at most once, anywhere (argparse reads it anywhere);
|
|
32
|
+
* - `-s` alone, which is `ceph status`;
|
|
33
|
+
* - after `orch ps` only, the named arguments that command takes:
|
|
34
|
+
* `--daemon_type T` (or `--daemon-type T`), `--service_name S` (or
|
|
35
|
+
* `--service-name S`) and `--refresh`, each at most once.
|
|
36
|
+
* Every other word that starts with "-" is Denied — which also defeats
|
|
37
|
+
* abbreviations, combined short options, `--` and negative numbers. A flag
|
|
38
|
+
* that takes a value accepts only a value it validates, so it can never
|
|
39
|
+
* swallow a word that would otherwise have been refused. An empty word, a
|
|
40
|
+
* word with a Unicode look-alike and a word of the wrong case match nothing
|
|
41
|
+
* and are Denied.
|
|
42
|
+
*
|
|
43
|
+
* ---- Tiers ----------------------------------------------------------------------
|
|
44
|
+
*
|
|
45
|
+
* Read (what an investigation may run): status (or -s), health [detail],
|
|
46
|
+
* df [detail], versions, version, progress, quorum_status; osd tree
|
|
47
|
+
* [up|down|in|out|destroyed]..., osd df [tree], osd perf, osd stat, osd
|
|
48
|
+
* dump, osd blocked-by, osd find ID, osd metadata [ID], osd ok-to-stop
|
|
49
|
+
* ID..., osd safe-to-destroy ID...; osd pool ls [detail], osd pool stats
|
|
50
|
+
* [POOL], osd pool get POOL VAR|all; pg stat, pg dump_stuck [STATE]...
|
|
51
|
+
* [SECONDS], pg PGID query, pg PGID list_unfound, pg ls-by-osd ID, pg
|
|
52
|
+
* ls-by-pool POOL, pg ls-by-primary ID; mon stat, mon dump; mgr stat, mgr
|
|
53
|
+
* module ls, mgr services; crash ls, crash ls-new, crash stat, crash info
|
|
54
|
+
* CRASH_ID; orch ps (see above), orch ls, orch host ls, orch device ls; log
|
|
55
|
+
* last [N<=1000] [debug|info|sec|warn|error] [*|cluster|audit|cephadm];
|
|
56
|
+
* balancer status; fs status [FS], fs ls, mds stat.
|
|
57
|
+
*
|
|
58
|
+
* SafeWrite (runs unattended in Automatic mode) is a reversible change to
|
|
59
|
+
* exactly ONE named object, or the clearing of a flag that returns the
|
|
60
|
+
* cluster to normal: osd in ID; osd unset FLAG; crash archive CRASH_ID;
|
|
61
|
+
* orch daemon restart TYPE.ID; pg scrub PGID; pg deep-scrub PGID.
|
|
62
|
+
*
|
|
63
|
+
* RiskyWrite (a human, the allowlist or Bypass approval decides): osd out
|
|
64
|
+
* ID; osd down ID; osd set FLAG; osd reweight ID 0..1; pg repair PGID; mgr
|
|
65
|
+
* fail [NAME]; orch daemon stop|start TYPE.ID; orch restart SERVICE; crash
|
|
66
|
+
* archive-all; balancer on|off.
|
|
67
|
+
*
|
|
68
|
+
* RiskyWrite that always asks a human (requiresHuman — not Bypass approval,
|
|
69
|
+
* not the allowlist): osd pool set POOL size|min_size N, which re-replicates
|
|
70
|
+
* or discards copies of every object in the pool, or blocks its I/O; and
|
|
71
|
+
* osd set pause, which stops every client read and write in the cluster.
|
|
72
|
+
*
|
|
73
|
+
* FLAG is one of noout, norebalance, nobackfill, norecover, noscrub,
|
|
74
|
+
* nodeep-scrub, pause. Every OSD command names ONE OSD; ceph's lists, `any`,
|
|
75
|
+
* `all` and `*` are Denied.
|
|
76
|
+
*
|
|
77
|
+
* Denied: everything else — among it osd purge/destroy/rm/lost/new/create,
|
|
78
|
+
* osd crush, osd pool create/delete/rm/rename and every other pool setting,
|
|
79
|
+
* auth (cephx keys), config-key (secrets), config, tell, daemon and
|
|
80
|
+
* --admin-daemon (commands inside a daemon), injectargs, fs changes, mon
|
|
81
|
+
* membership, mgr module enable/disable, orch apply/rm/host/upgrade and
|
|
82
|
+
* daemon rm, osd require-osd-release, osd set-*-ratio, pg force_create_pg,
|
|
83
|
+
* pg PGID mark_unfound_lost, crash rm/prune and `ceph log TEXT`.
|
|
84
|
+
*
|
|
85
|
+
* ---- Targets ------------------------------------------------------------------
|
|
86
|
+
*
|
|
87
|
+
* The canonical names a write's targets hold, which the agent's
|
|
88
|
+
* ONEUPTIME_AI_WRITE_TARGETS globs and protected targets are compared with:
|
|
89
|
+
* osd.N for an OSD (whether the command wrote 3 or osd.3; leading zeros are
|
|
90
|
+
* refused so an OSD has one spelling), the daemon name for a cephadm daemon
|
|
91
|
+
* (osd.3, mon.host1, rgw.store.host1.abcdef), the service name for orch
|
|
92
|
+
* restart, mgr.NAME for mgr fail NAME, the pool name, the PG id (1.2f),
|
|
93
|
+
* crash/CRASH_ID for one crash report, and "cluster" for a cluster-wide
|
|
94
|
+
* change (osd set/unset, balancer on/off, crash archive-all, and mgr fail
|
|
95
|
+
* without a name).
|
|
96
|
+
*
|
|
97
|
+
* Part of the import-closed resource policy directory that the resource AI
|
|
98
|
+
* agent carries a byte-identical copy of: relative imports of that set only,
|
|
99
|
+
* and nothing from Node.
|
|
100
|
+
*/
|
|
101
|
+
import { ResourceCommandTier } from "../../../Types/ResourceAiAgent/ResourceAiAccess";
|
|
102
|
+
import { deniedResult, renderResourceDisplayCommand, } from "./ResourceCommandPolicyCore";
|
|
103
|
+
const CEPH_PROGRAM = "ceph";
|
|
104
|
+
// The target a cluster-wide change names (osd set/unset, balancer, ...).
|
|
105
|
+
export const CEPH_CLUSTER_TARGET = "cluster";
|
|
106
|
+
// The prefix of a crash report's target: "crash/<crash id>".
|
|
107
|
+
export const CEPH_CRASH_TARGET_PREFIX = "crash/";
|
|
108
|
+
// The output formats --format (or -f) may name.
|
|
109
|
+
export const CEPH_OUTPUT_FORMATS = [
|
|
110
|
+
"json",
|
|
111
|
+
"json-pretty",
|
|
112
|
+
"plain",
|
|
113
|
+
];
|
|
114
|
+
// The cluster-wide OSD flags osd set and osd unset may name.
|
|
115
|
+
export const CEPH_OSD_FLAGS = [
|
|
116
|
+
"noout",
|
|
117
|
+
"norebalance",
|
|
118
|
+
"nobackfill",
|
|
119
|
+
"norecover",
|
|
120
|
+
"noscrub",
|
|
121
|
+
"nodeep-scrub",
|
|
122
|
+
"pause",
|
|
123
|
+
];
|
|
124
|
+
// The one flag whose setting stops client I/O cluster-wide.
|
|
125
|
+
const CLIENT_IO_PAUSE_FLAG = "pause";
|
|
126
|
+
// What each flag does while it is set, for the reasons on approval cards.
|
|
127
|
+
const OSD_FLAG_EFFECTS = {
|
|
128
|
+
noout: "down OSDs are never marked out, so their data is not re-replicated",
|
|
129
|
+
norebalance: "data is not rebalanced across OSDs",
|
|
130
|
+
nobackfill: "PGs are not backfilled",
|
|
131
|
+
norecover: "PGs are not recovered",
|
|
132
|
+
noscrub: "PGs are not scrubbed",
|
|
133
|
+
"nodeep-scrub": "PGs are not deep-scrubbed",
|
|
134
|
+
pause: "every client read and write is stopped",
|
|
135
|
+
};
|
|
136
|
+
const OSD_TREE_STATES = [
|
|
137
|
+
"up",
|
|
138
|
+
"down",
|
|
139
|
+
"in",
|
|
140
|
+
"out",
|
|
141
|
+
"destroyed",
|
|
142
|
+
];
|
|
143
|
+
const STUCK_PG_STATES = [
|
|
144
|
+
"inactive",
|
|
145
|
+
"unclean",
|
|
146
|
+
"stale",
|
|
147
|
+
"undersized",
|
|
148
|
+
"degraded",
|
|
149
|
+
];
|
|
150
|
+
const LOG_LEVELS = [
|
|
151
|
+
"debug",
|
|
152
|
+
"info",
|
|
153
|
+
"sec",
|
|
154
|
+
"warn",
|
|
155
|
+
"error",
|
|
156
|
+
];
|
|
157
|
+
const LOG_CHANNELS = [
|
|
158
|
+
"*",
|
|
159
|
+
"cluster",
|
|
160
|
+
"audit",
|
|
161
|
+
"cephadm",
|
|
162
|
+
];
|
|
163
|
+
// The pool settings osd pool set may change (always with a human).
|
|
164
|
+
const POOL_REPLICA_SETTINGS = ["size", "min_size"];
|
|
165
|
+
// The most OSDs one ok-to-stop / safe-to-destroy check may name.
|
|
166
|
+
const MAX_OSD_IDS_PER_CHECK = 32;
|
|
167
|
+
// The most cluster-log lines log last may print.
|
|
168
|
+
const MAX_LOG_LAST_LINES = 1000;
|
|
169
|
+
/*
|
|
170
|
+
* ---- Argument shapes ----------------------------------------------------------
|
|
171
|
+
*
|
|
172
|
+
* Each is anchored, ASCII-only and linear. None accepts a word that starts
|
|
173
|
+
* with "-" (argparse would read it as an option) or "@".
|
|
174
|
+
*/
|
|
175
|
+
// An OSD id as ceph reads one, "3" or "osd.3", without leading zeros.
|
|
176
|
+
const OSD_ID_REGEX = /^(?:osd\.)?(0|[1-9][0-9]{0,5})$/;
|
|
177
|
+
// An OSD's number alone: the ID of an "osd.ID" daemon.
|
|
178
|
+
const OSD_NUMBER_REGEX = /^(?:0|[1-9][0-9]{0,5})$/;
|
|
179
|
+
// A pool name: ".mgr" and ".rgw.root" are real pools.
|
|
180
|
+
const POOL_NAME_REGEX = /^[A-Za-z0-9_.][A-Za-z0-9_.-]{0,127}$/;
|
|
181
|
+
// A pool setting osd pool get may read ("size", "pg_num", "nodeep-scrub").
|
|
182
|
+
const POOL_VARIABLE_REGEX = /^[a-z][a-z0-9_-]{0,63}$/;
|
|
183
|
+
// A PG id, POOL.SEED in lowercase hex, as ceph prints it (no leading zeros).
|
|
184
|
+
const PGID_REGEX = /^(?:0|[1-9][0-9]{0,9})\.(?:0|[1-9a-f][0-9a-f]{0,7})$/;
|
|
185
|
+
// A cephadm daemon name: TYPE.ID ("osd.3", "mon.host1", "rgw.a.host1.xyz").
|
|
186
|
+
const DAEMON_NAME_REGEX = /^([a-z][a-z0-9-]{0,31})\.([A-Za-z0-9][A-Za-z0-9_.-]{0,127})$/;
|
|
187
|
+
// A cephadm daemon type ("osd", "node-exporter").
|
|
188
|
+
const DAEMON_TYPE_REGEX = /^[a-z][a-z0-9-]{0,31}$/;
|
|
189
|
+
// A cephadm service name: TYPE or TYPE.ID ("mon", "osd.all-available-devices").
|
|
190
|
+
const SERVICE_NAME_REGEX = /^[a-z][a-z0-9-]{0,31}(?:\.[A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$/;
|
|
191
|
+
// A manager daemon's name as mgr fail takes it ("host1.abcdef").
|
|
192
|
+
const MGR_NAME_REGEX = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/;
|
|
193
|
+
// A file system's name.
|
|
194
|
+
const FS_NAME_REGEX = /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$/;
|
|
195
|
+
/*
|
|
196
|
+
* A crash report id: its UTC timestamp and a UUID
|
|
197
|
+
* ("2024-05-21T10:15:42.123456Z_0c7d3c6e-..."); Nautilus wrote "_" where
|
|
198
|
+
* later releases write "T".
|
|
199
|
+
*/
|
|
200
|
+
const CRASH_ID_REGEX = /^[0-9]{4}-[0-9]{2}-[0-9]{2}[T_][0-9]{2}:[0-9]{2}:[0-9]{2}(?:\.[0-9]{1,9})?Z_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
201
|
+
// A whole number of seconds (pg dump_stuck's threshold).
|
|
202
|
+
const SECONDS_REGEX = /^(?:0|[1-9][0-9]{0,8})$/;
|
|
203
|
+
// A digit string of any length, to tell "out of range" from "not a number".
|
|
204
|
+
const DIGITS_REGEX = /^[0-9]+$/;
|
|
205
|
+
// An OSD weight: 0 to 1 with at most four decimals ("0", "0.85", "1.0").
|
|
206
|
+
const WEIGHT_REGEX = /^[01](?:\.[0-9]{1,4})?$/;
|
|
207
|
+
// A pool's replica count (ceph caps size at 10).
|
|
208
|
+
const REPLICA_COUNT_REGEX = /^(?:[1-9]|10)$/;
|
|
209
|
+
// A word that starts with a digit is a PG id to `ceph pg ...`.
|
|
210
|
+
const STARTS_WITH_DIGIT_REGEX = /^[0-9]/;
|
|
211
|
+
/*
|
|
212
|
+
* ---- Options ------------------------------------------------------------------
|
|
213
|
+
*/
|
|
214
|
+
const LONG_FORMAT_OPTION = "--format";
|
|
215
|
+
const SHORT_FORMAT_OPTION = "-f";
|
|
216
|
+
const STATUS_OPTION = "-s";
|
|
217
|
+
// "-fjson" / "-foo": argparse reads -f with an inline value.
|
|
218
|
+
const INLINE_SHORT_FORMAT_REGEX = /^-f[^-]/;
|
|
219
|
+
// "-sw", "-sf", "-s=1": -s combined with something else.
|
|
220
|
+
const COMBINED_STATUS_REGEX = /^-s./;
|
|
221
|
+
// The named arguments orch ps takes, each spelling mapped to its argument.
|
|
222
|
+
const ORCH_PS_OPTIONS = {
|
|
223
|
+
"--daemon_type": "daemon_type",
|
|
224
|
+
"--daemon-type": "daemon_type",
|
|
225
|
+
"--service_name": "service_name",
|
|
226
|
+
"--service-name": "service_name",
|
|
227
|
+
"--refresh": "refresh",
|
|
228
|
+
};
|
|
229
|
+
const OPTION_LIST_FOR_HUMANS = "the only options accepted are --format json|json-pretty|plain (or -f json), -s on its own (ceph status), and --daemon_type TYPE, --service_name NAME and --refresh after orch ps";
|
|
230
|
+
/*
|
|
231
|
+
* Options (and configuration overrides) refused with their own reason, so
|
|
232
|
+
* the model learns why rather than only that. Any other dash-prefixed word
|
|
233
|
+
* is refused with the generic reason. Compared after dropping an inline
|
|
234
|
+
* "=value" and reading "_" as "-", the way ceph reads configuration names.
|
|
235
|
+
*/
|
|
236
|
+
const DENIED_OPTION_GROUPS = [
|
|
237
|
+
{
|
|
238
|
+
reason: "the agent connects with its own configuration, keyring and identity, so a command may not choose another cluster, monitor, user or key",
|
|
239
|
+
options: [
|
|
240
|
+
"-c",
|
|
241
|
+
"--conf",
|
|
242
|
+
"-k",
|
|
243
|
+
"--keyring",
|
|
244
|
+
"--keyfile",
|
|
245
|
+
"--key",
|
|
246
|
+
"--id",
|
|
247
|
+
"--user",
|
|
248
|
+
"-n",
|
|
249
|
+
"--name",
|
|
250
|
+
"--cluster",
|
|
251
|
+
"-m",
|
|
252
|
+
"--mon-host",
|
|
253
|
+
"--mon-addr",
|
|
254
|
+
"--setuser",
|
|
255
|
+
"--setgroup",
|
|
256
|
+
"--auth-client-required",
|
|
257
|
+
"--auth-cluster-required",
|
|
258
|
+
"--auth-service-required",
|
|
259
|
+
"--auth-supported",
|
|
260
|
+
],
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
reason: "it makes ceph read or write a file on the agent's machine (-i/--in-file, -o/--out-file, log files)",
|
|
264
|
+
options: [
|
|
265
|
+
"-i",
|
|
266
|
+
"--in-file",
|
|
267
|
+
"-o",
|
|
268
|
+
"--out-file",
|
|
269
|
+
"--log-file",
|
|
270
|
+
"--log-to-file",
|
|
271
|
+
"--log-to-stderr",
|
|
272
|
+
"--err-to-stderr",
|
|
273
|
+
"--admin-socket",
|
|
274
|
+
],
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
reason: "it sends the command to a daemon's admin socket, which accepts any command that daemon has",
|
|
278
|
+
options: ["--admin-daemon"],
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
reason: "it watches the cluster until it is killed; read recent events with ceph log last or the state with ceph status instead",
|
|
282
|
+
options: [
|
|
283
|
+
"-w",
|
|
284
|
+
"--watch",
|
|
285
|
+
"--watch-debug",
|
|
286
|
+
"--watch-info",
|
|
287
|
+
"--watch-sec",
|
|
288
|
+
"--watch-warn",
|
|
289
|
+
"--watch-error",
|
|
290
|
+
"-W",
|
|
291
|
+
"--watch-channel",
|
|
292
|
+
],
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
reason: "it confirms a destructive change, and destructive changes never run",
|
|
296
|
+
options: [
|
|
297
|
+
"--yes-i-really-mean-it",
|
|
298
|
+
"--yes-i-really-really-mean-it",
|
|
299
|
+
"--yes-i-really-really-mean-it-not-faking",
|
|
300
|
+
"--i-know-what-i-am-doing",
|
|
301
|
+
"--force",
|
|
302
|
+
],
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
reason: "it prints ceph's help; the read and write command guides list what may run",
|
|
306
|
+
options: ["-h", "--help", "--help-all", "--completion"],
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
reason: "the agent sets its own timeouts and never polls",
|
|
310
|
+
options: ["--connect-timeout", "--period", "-p", "--block"],
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
reason: "write ceph status (or -s) instead",
|
|
314
|
+
options: ["--status"],
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
reason: "write ceph version (or ceph versions) instead",
|
|
318
|
+
options: ["-v", "--version"],
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
reason: "it changes how much ceph prints; write the command without it",
|
|
322
|
+
options: ["--verbose", "--concise"],
|
|
323
|
+
},
|
|
324
|
+
];
|
|
325
|
+
const DENIED_OPTION_REASONS = new Map();
|
|
326
|
+
for (const group of DENIED_OPTION_GROUPS) {
|
|
327
|
+
for (const option of group.options) {
|
|
328
|
+
DENIED_OPTION_REASONS.set(option, group.reason);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// Why a dash-prefixed word is refused, in words for the model.
|
|
332
|
+
function describeOptionRefusal(word) {
|
|
333
|
+
const shown = `"${word}"`;
|
|
334
|
+
if (word === "--") {
|
|
335
|
+
return `${shown} is not needed: no ceph command OneUptime AI may run takes a word that starts with "-", and ${OPTION_LIST_FOR_HUMANS}`;
|
|
336
|
+
}
|
|
337
|
+
const equals = word.indexOf("=");
|
|
338
|
+
const name = equals >= 0 ? word.slice(0, equals) : word;
|
|
339
|
+
if (name === SHORT_FORMAT_OPTION || INLINE_SHORT_FORMAT_REGEX.test(word)) {
|
|
340
|
+
return `${shown} is not accepted: write the output format as its own word, --format json (or -f json), with json, json-pretty or plain`;
|
|
341
|
+
}
|
|
342
|
+
if (COMBINED_STATUS_REGEX.test(word)) {
|
|
343
|
+
return `${shown} is not accepted: -s must stand alone (it is ceph status), and ${OPTION_LIST_FOR_HUMANS}`;
|
|
344
|
+
}
|
|
345
|
+
const normalized = name.startsWith("--")
|
|
346
|
+
? `--${name.slice(2).replace(/_/g, "-")}`
|
|
347
|
+
: name;
|
|
348
|
+
let groupReason = DENIED_OPTION_REASONS.get(normalized);
|
|
349
|
+
if (!groupReason && normalized.startsWith("--watch")) {
|
|
350
|
+
groupReason = DENIED_OPTION_REASONS.get("--watch");
|
|
351
|
+
}
|
|
352
|
+
if (!groupReason && normalized.startsWith("--debug")) {
|
|
353
|
+
groupReason =
|
|
354
|
+
"it changes ceph's debug logging, which ceph reads as a configuration override";
|
|
355
|
+
}
|
|
356
|
+
if (groupReason) {
|
|
357
|
+
return `${shown} is not accepted: ${groupReason}`;
|
|
358
|
+
}
|
|
359
|
+
if (normalized.length >= 3 &&
|
|
360
|
+
normalized !== LONG_FORMAT_OPTION &&
|
|
361
|
+
LONG_FORMAT_OPTION.startsWith(normalized)) {
|
|
362
|
+
return `${shown} is not accepted: ceph would read it as an abbreviation of --format, so write --format in full`;
|
|
363
|
+
}
|
|
364
|
+
return `${shown} is not an option OneUptime AI may pass to ceph: ceph reads an option it does not know as an abbreviation of one it does (--out is --out-file) or as a configuration override (--keyring, --mon-host, --log-file), so ${OPTION_LIST_FOR_HUMANS}`;
|
|
365
|
+
}
|
|
366
|
+
function formatRefusal(value) {
|
|
367
|
+
if (value === undefined) {
|
|
368
|
+
return "--format (or -f) needs a value: json, json-pretty or plain";
|
|
369
|
+
}
|
|
370
|
+
return `"${value}" is not an output format OneUptime AI may ask for: --format (or -f) takes json, json-pretty or plain`;
|
|
371
|
+
}
|
|
372
|
+
/*
|
|
373
|
+
* Take the output format and -s out of the words, wherever they are (see
|
|
374
|
+
* the header). Returns why the words cannot be read, or the command line.
|
|
375
|
+
*/
|
|
376
|
+
function readCommandLine(args) {
|
|
377
|
+
const words = [];
|
|
378
|
+
let format = null;
|
|
379
|
+
let status = false;
|
|
380
|
+
for (let index = 0; index < args.length; index++) {
|
|
381
|
+
const word = args[index];
|
|
382
|
+
let value;
|
|
383
|
+
if (word === LONG_FORMAT_OPTION || word === SHORT_FORMAT_OPTION) {
|
|
384
|
+
value = args[index + 1];
|
|
385
|
+
index++;
|
|
386
|
+
}
|
|
387
|
+
else if (word.startsWith(`${LONG_FORMAT_OPTION}=`)) {
|
|
388
|
+
value = word.slice(LONG_FORMAT_OPTION.length + 1);
|
|
389
|
+
}
|
|
390
|
+
else if (word === STATUS_OPTION) {
|
|
391
|
+
if (status) {
|
|
392
|
+
return "-s is given twice; write it once";
|
|
393
|
+
}
|
|
394
|
+
status = true;
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
words.push(word);
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
if (format !== null) {
|
|
402
|
+
return "the output format is given twice (ceph would keep only the last); give --format once";
|
|
403
|
+
}
|
|
404
|
+
if (value === undefined || !CEPH_OUTPUT_FORMATS.includes(value)) {
|
|
405
|
+
return formatRefusal(value);
|
|
406
|
+
}
|
|
407
|
+
format = value;
|
|
408
|
+
}
|
|
409
|
+
return { words, format, status };
|
|
410
|
+
}
|
|
411
|
+
function read(reason) {
|
|
412
|
+
return { tier: ResourceCommandTier.Read, reason, targets: [] };
|
|
413
|
+
}
|
|
414
|
+
function safeWrite(reason, targets) {
|
|
415
|
+
return { tier: ResourceCommandTier.SafeWrite, reason, targets };
|
|
416
|
+
}
|
|
417
|
+
function riskyWrite(reason, targets, requiresHuman = false) {
|
|
418
|
+
const verdict = {
|
|
419
|
+
tier: ResourceCommandTier.RiskyWrite,
|
|
420
|
+
reason,
|
|
421
|
+
targets,
|
|
422
|
+
};
|
|
423
|
+
if (requiresHuman) {
|
|
424
|
+
verdict.requiresHuman = true;
|
|
425
|
+
}
|
|
426
|
+
return verdict;
|
|
427
|
+
}
|
|
428
|
+
// The canonical target of an OSD id word, or null when it is not one.
|
|
429
|
+
function osdTarget(word) {
|
|
430
|
+
if (typeof word !== "string") {
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
const match = OSD_ID_REGEX.exec(word);
|
|
434
|
+
return match ? `osd.${match[1]}` : null;
|
|
435
|
+
}
|
|
436
|
+
function describeBadOsdId(word) {
|
|
437
|
+
if (word === undefined) {
|
|
438
|
+
return "it needs an OSD id, such as 3 or osd.3";
|
|
439
|
+
}
|
|
440
|
+
return `"${word}" is not an OSD id: write one OSD as its number or osd.NUMBER (3 or osd.3), without leading zeros`;
|
|
441
|
+
}
|
|
442
|
+
function describeBadPgid(word) {
|
|
443
|
+
if (word === undefined) {
|
|
444
|
+
return "it needs a PG id, such as 1.2f";
|
|
445
|
+
}
|
|
446
|
+
return `"${word}" is not a PG id: write it as POOL.SEED the way ceph prints it, such as 1.2f (lowercase hex, no leading zeros)`;
|
|
447
|
+
}
|
|
448
|
+
function describeBadPool(word) {
|
|
449
|
+
if (word === undefined) {
|
|
450
|
+
return "it needs a pool name";
|
|
451
|
+
}
|
|
452
|
+
return `"${word}" is not a pool name OneUptime AI may use: letters, digits, "_", "." and "-" (not first), at most 128 characters`;
|
|
453
|
+
}
|
|
454
|
+
function describeBadCrashId(word) {
|
|
455
|
+
if (word === undefined) {
|
|
456
|
+
return "it needs a crash id from ceph crash ls";
|
|
457
|
+
}
|
|
458
|
+
return `"${word}" is not a crash id: copy one from ceph crash ls (TIMESTAMP_UUID, such as 2024-05-21T10:15:42.123456Z_0c7d3c6e-1b2a-4c3d-9e8f-0123456789ab)`;
|
|
459
|
+
}
|
|
460
|
+
// The canonical daemon name, or null (an OSD daemon's id is its number).
|
|
461
|
+
function daemonTarget(word) {
|
|
462
|
+
if (typeof word !== "string") {
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
const match = DAEMON_NAME_REGEX.exec(word);
|
|
466
|
+
if (!match) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
if (match[1] === "osd" && !OSD_NUMBER_REGEX.test(match[2] || "")) {
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
return word;
|
|
473
|
+
}
|
|
474
|
+
function describeBadDaemon(word) {
|
|
475
|
+
if (word === undefined) {
|
|
476
|
+
return "it needs one daemon name from ceph orch ps, such as osd.3 or mon.host1";
|
|
477
|
+
}
|
|
478
|
+
return `"${word}" is not a cephadm daemon name: write one daemon as TYPE.ID exactly as ceph orch ps lists it (osd.3, mon.host1, rgw.store.host1.abcdef)`;
|
|
479
|
+
}
|
|
480
|
+
// Exactly one word, checked by `accept`; the rest refused.
|
|
481
|
+
function exactlyOne(rest, describeBad, accept) {
|
|
482
|
+
if (rest.length === 0) {
|
|
483
|
+
return describeBad(undefined);
|
|
484
|
+
}
|
|
485
|
+
if (rest.length > 1) {
|
|
486
|
+
return `it takes exactly one argument, and ${rest.length} were given: run one command per object`;
|
|
487
|
+
}
|
|
488
|
+
const verdict = accept(rest[0]);
|
|
489
|
+
return verdict || describeBad(rest[0]);
|
|
490
|
+
}
|
|
491
|
+
function noArguments(reason) {
|
|
492
|
+
return (rest) => {
|
|
493
|
+
return rest.length === 0 ? read(reason) : "it takes no arguments";
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
// No arguments, or one optional keyword ("detail", "tree").
|
|
497
|
+
function optionalKeyword(keyword, reason, keywordReason) {
|
|
498
|
+
return (rest) => {
|
|
499
|
+
if (rest.length === 0) {
|
|
500
|
+
return read(reason);
|
|
501
|
+
}
|
|
502
|
+
if (rest.length === 1 && rest[0] === keyword) {
|
|
503
|
+
return read(keywordReason);
|
|
504
|
+
}
|
|
505
|
+
return `the only word it takes is "${keyword}"`;
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
// Zero or more distinct words from `choices`.
|
|
509
|
+
function distinctChoices(rest, choices) {
|
|
510
|
+
const seen = new Set();
|
|
511
|
+
for (const word of rest) {
|
|
512
|
+
if (!choices.includes(word)) {
|
|
513
|
+
return `"${word}" is not one of ${choices.join(", ")}`;
|
|
514
|
+
}
|
|
515
|
+
if (seen.has(word)) {
|
|
516
|
+
return `"${word}" is given twice`;
|
|
517
|
+
}
|
|
518
|
+
seen.add(word);
|
|
519
|
+
}
|
|
520
|
+
return null;
|
|
521
|
+
}
|
|
522
|
+
// One to MAX_OSD_IDS_PER_CHECK OSD ids (ok-to-stop, safe-to-destroy).
|
|
523
|
+
function osdIdList(reason) {
|
|
524
|
+
return (rest) => {
|
|
525
|
+
if (rest.length === 0) {
|
|
526
|
+
return describeBadOsdId(undefined);
|
|
527
|
+
}
|
|
528
|
+
if (rest.length > MAX_OSD_IDS_PER_CHECK) {
|
|
529
|
+
return `it may name at most ${MAX_OSD_IDS_PER_CHECK} OSDs`;
|
|
530
|
+
}
|
|
531
|
+
for (const word of rest) {
|
|
532
|
+
if (!osdTarget(word)) {
|
|
533
|
+
return describeBadOsdId(word);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return read(reason);
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
function readOsdFlag(rest, verdictFor) {
|
|
540
|
+
return exactlyOne(rest, (word) => {
|
|
541
|
+
return word === undefined
|
|
542
|
+
? `it needs one flag: ${CEPH_OSD_FLAGS.join(", ")}`
|
|
543
|
+
: `"${word}" is not a flag OneUptime AI may change: only ${CEPH_OSD_FLAGS.join(", ")} (flags such as noup, nodown, noin, full and sortbitwise are never changed)`;
|
|
544
|
+
}, (word) => {
|
|
545
|
+
return CEPH_OSD_FLAGS.includes(word) ? verdictFor(word) : null;
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
function readOrchPsArguments(rest) {
|
|
549
|
+
const seen = new Set();
|
|
550
|
+
let index = 0;
|
|
551
|
+
while (index < rest.length) {
|
|
552
|
+
const word = rest[index];
|
|
553
|
+
const argument = Object.prototype.hasOwnProperty.call(ORCH_PS_OPTIONS, word)
|
|
554
|
+
? ORCH_PS_OPTIONS[word]
|
|
555
|
+
: undefined;
|
|
556
|
+
if (!argument) {
|
|
557
|
+
return `"${word}" is not accepted: orch ps takes only --daemon_type TYPE, --service_name NAME and --refresh (to list one host's daemons, filter the full list)`;
|
|
558
|
+
}
|
|
559
|
+
if (seen.has(argument)) {
|
|
560
|
+
return `--${argument} is given twice; give it once`;
|
|
561
|
+
}
|
|
562
|
+
seen.add(argument);
|
|
563
|
+
if (argument === "refresh") {
|
|
564
|
+
index++;
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
const value = rest[index + 1];
|
|
568
|
+
const valid = typeof value === "string" &&
|
|
569
|
+
(argument === "daemon_type"
|
|
570
|
+
? DAEMON_TYPE_REGEX.test(value)
|
|
571
|
+
: SERVICE_NAME_REGEX.test(value));
|
|
572
|
+
if (!valid) {
|
|
573
|
+
return value === undefined
|
|
574
|
+
? `${word} needs a value`
|
|
575
|
+
: `"${value}" is not a ${argument === "daemon_type"
|
|
576
|
+
? "daemon type (osd, mon, mgr, mds, rgw, crash, ...)"
|
|
577
|
+
: "service name (mon, osd.all-available-devices, rgw.store, ...)"}`;
|
|
578
|
+
}
|
|
579
|
+
index += 2;
|
|
580
|
+
}
|
|
581
|
+
return read("lists the daemons cephadm manages, with their hosts, status and versions");
|
|
582
|
+
}
|
|
583
|
+
function readLogLastArguments(rest) {
|
|
584
|
+
let index = 0;
|
|
585
|
+
const first = rest[0];
|
|
586
|
+
if (first !== undefined && DIGITS_REGEX.test(first)) {
|
|
587
|
+
const count = Number(first);
|
|
588
|
+
if (first.length > 4 ||
|
|
589
|
+
first.startsWith("0") ||
|
|
590
|
+
count < 1 ||
|
|
591
|
+
count > MAX_LOG_LAST_LINES) {
|
|
592
|
+
return `"${first}" is not a line count OneUptime AI may ask for: 1 to ${MAX_LOG_LAST_LINES}`;
|
|
593
|
+
}
|
|
594
|
+
index++;
|
|
595
|
+
}
|
|
596
|
+
if (index < rest.length && LOG_LEVELS.includes(rest[index])) {
|
|
597
|
+
index++;
|
|
598
|
+
}
|
|
599
|
+
if (index < rest.length && LOG_CHANNELS.includes(rest[index])) {
|
|
600
|
+
index++;
|
|
601
|
+
}
|
|
602
|
+
if (index < rest.length) {
|
|
603
|
+
return `"${rest[index]}" is not accepted here: the arguments are an optional line count (1 to ${MAX_LOG_LAST_LINES}), then a level (${LOG_LEVELS.join(", ")}), then a channel (${LOG_CHANNELS.join(", ")}), in that order`;
|
|
604
|
+
}
|
|
605
|
+
return read("reads the most recent entries of the cluster log");
|
|
606
|
+
}
|
|
607
|
+
function readDumpStuckArguments(rest) {
|
|
608
|
+
const states = rest.slice();
|
|
609
|
+
const last = states[states.length - 1];
|
|
610
|
+
if (last !== undefined && SECONDS_REGEX.test(last)) {
|
|
611
|
+
states.pop();
|
|
612
|
+
}
|
|
613
|
+
const problem = distinctChoices(states, STUCK_PG_STATES);
|
|
614
|
+
if (problem) {
|
|
615
|
+
return `${problem}; it takes stuck states (${STUCK_PG_STATES.join(", ")}) and then an optional threshold in seconds`;
|
|
616
|
+
}
|
|
617
|
+
return read("lists the placement groups stuck in a state");
|
|
618
|
+
}
|
|
619
|
+
function readPoolGetArguments(rest) {
|
|
620
|
+
if (rest.length !== 2) {
|
|
621
|
+
return "it takes a pool name and one setting (or all)";
|
|
622
|
+
}
|
|
623
|
+
const [pool, variable] = rest;
|
|
624
|
+
if (!POOL_NAME_REGEX.test(pool)) {
|
|
625
|
+
return describeBadPool(pool);
|
|
626
|
+
}
|
|
627
|
+
if (variable !== "all" && !POOL_VARIABLE_REGEX.test(variable)) {
|
|
628
|
+
return `"${variable}" is not a pool setting: name one (size, min_size, pg_num, crush_rule, ...) or all`;
|
|
629
|
+
}
|
|
630
|
+
return read(`reads pool ${pool}'s settings`);
|
|
631
|
+
}
|
|
632
|
+
function readPoolSetArguments(rest) {
|
|
633
|
+
if (rest.length !== 3) {
|
|
634
|
+
return "it takes a pool name, size or min_size, and a count";
|
|
635
|
+
}
|
|
636
|
+
const [pool, variable, value] = rest;
|
|
637
|
+
if (!POOL_NAME_REGEX.test(pool)) {
|
|
638
|
+
return describeBadPool(pool);
|
|
639
|
+
}
|
|
640
|
+
if (!POOL_REPLICA_SETTINGS.includes(variable)) {
|
|
641
|
+
return `"${variable}" is not a pool setting OneUptime AI may change: only size and min_size (pg_num, crush_rule, nodelete, quotas and every other pool setting are never changed)`;
|
|
642
|
+
}
|
|
643
|
+
if (!REPLICA_COUNT_REGEX.test(value)) {
|
|
644
|
+
return `"${value}" is not a replica count: 1 to 10`;
|
|
645
|
+
}
|
|
646
|
+
return variable === "size"
|
|
647
|
+
? riskyWrite(`sets pool ${pool}'s replica count (size) to ${value}, which re-replicates or discards a copy of every object in the pool`, [pool], true)
|
|
648
|
+
: riskyWrite(`sets the number of replicas pool ${pool} needs to serve I/O (min_size) to ${value}, which can block the pool's I/O or accept writes with too few copies`, [pool], true);
|
|
649
|
+
}
|
|
650
|
+
function readReweightArguments(rest) {
|
|
651
|
+
if (rest.length !== 2) {
|
|
652
|
+
return "it takes one OSD id and a weight from 0 to 1";
|
|
653
|
+
}
|
|
654
|
+
const [id, weight] = rest;
|
|
655
|
+
const target = osdTarget(id);
|
|
656
|
+
if (!target) {
|
|
657
|
+
return describeBadOsdId(id);
|
|
658
|
+
}
|
|
659
|
+
if (!WEIGHT_REGEX.test(weight) || Number(weight) > 1) {
|
|
660
|
+
return `"${weight}" is not a weight: 0 to 1, such as 0.85`;
|
|
661
|
+
}
|
|
662
|
+
return riskyWrite(`overrides ${target}'s weight to ${weight}, which moves data off (or back onto) it (undo: ceph osd reweight ${id} 1)`, [target]);
|
|
663
|
+
}
|
|
664
|
+
function readMgrFailArguments(rest) {
|
|
665
|
+
if (rest.length === 0) {
|
|
666
|
+
return riskyWrite("fails the active manager over to a standby, restarting every manager module", [CEPH_CLUSTER_TARGET]);
|
|
667
|
+
}
|
|
668
|
+
if (rest.length > 1 || !MGR_NAME_REGEX.test(rest[0])) {
|
|
669
|
+
return "it takes at most one manager name, as ceph mgr stat shows it";
|
|
670
|
+
}
|
|
671
|
+
return riskyWrite(`fails manager ${rest[0]} over to a standby, restarting every manager module`, [`mgr.${rest[0]}`]);
|
|
672
|
+
}
|
|
673
|
+
/*
|
|
674
|
+
* Every command OneUptime AI may run, by its exact words. No rule's words
|
|
675
|
+
* are a prefix of another's, so the longest match is the only match.
|
|
676
|
+
*/
|
|
677
|
+
const COMMAND_RULES = [
|
|
678
|
+
// ---- Cluster ----
|
|
679
|
+
{
|
|
680
|
+
words: ["status"],
|
|
681
|
+
usage: "",
|
|
682
|
+
readArguments: noArguments("reads the cluster's status: health, monitors, OSDs, PGs and usage"),
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
words: ["health"],
|
|
686
|
+
usage: "[detail]",
|
|
687
|
+
readArguments: optionalKeyword("detail", "reads the cluster's health", "reads every health check and what it affects"),
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
words: ["df"],
|
|
691
|
+
usage: "[detail]",
|
|
692
|
+
readArguments: optionalKeyword("detail", "reads the cluster's and each pool's usage", "reads the cluster's and each pool's detailed usage"),
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
words: ["versions"],
|
|
696
|
+
usage: "",
|
|
697
|
+
readArguments: noArguments("reads the versions every daemon runs"),
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
words: ["version"],
|
|
701
|
+
usage: "",
|
|
702
|
+
readArguments: noArguments("reads the monitors' version"),
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
words: ["progress"],
|
|
706
|
+
usage: "",
|
|
707
|
+
readArguments: noArguments("reads the progress of recovery and other long-running events"),
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
words: ["quorum_status"],
|
|
711
|
+
usage: "",
|
|
712
|
+
readArguments: noArguments("reads the monitor quorum"),
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
words: ["log", "last"],
|
|
716
|
+
usage: "[N] [debug|info|sec|warn|error] [*|cluster|audit|cephadm]",
|
|
717
|
+
readArguments: readLogLastArguments,
|
|
718
|
+
},
|
|
719
|
+
// ---- OSDs ----
|
|
720
|
+
{
|
|
721
|
+
words: ["osd", "tree"],
|
|
722
|
+
usage: "[up|down|in|out|destroyed]...",
|
|
723
|
+
readArguments: (rest) => {
|
|
724
|
+
const problem = distinctChoices(rest, OSD_TREE_STATES);
|
|
725
|
+
return problem
|
|
726
|
+
? problem
|
|
727
|
+
: read("reads the OSD tree and each OSD's state");
|
|
728
|
+
},
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
words: ["osd", "df"],
|
|
732
|
+
usage: "[tree]",
|
|
733
|
+
readArguments: optionalKeyword("tree", "reads each OSD's usage", "reads each OSD's usage along the CRUSH tree"),
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
words: ["osd", "perf"],
|
|
737
|
+
usage: "",
|
|
738
|
+
readArguments: noArguments("reads each OSD's commit and apply latency"),
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
words: ["osd", "stat"],
|
|
742
|
+
usage: "",
|
|
743
|
+
readArguments: noArguments("reads how many OSDs are up and in"),
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
words: ["osd", "dump"],
|
|
747
|
+
usage: "",
|
|
748
|
+
readArguments: noArguments("reads the OSD map"),
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
words: ["osd", "blocked-by"],
|
|
752
|
+
usage: "",
|
|
753
|
+
readArguments: noArguments("reads which OSDs are blocking peering"),
|
|
754
|
+
},
|
|
755
|
+
{
|
|
756
|
+
words: ["osd", "find"],
|
|
757
|
+
usage: "ID",
|
|
758
|
+
readArguments: (rest) => {
|
|
759
|
+
return exactlyOne(rest, describeBadOsdId, (word) => {
|
|
760
|
+
return osdTarget(word) ? read("reads where an OSD runs") : null;
|
|
761
|
+
});
|
|
762
|
+
},
|
|
763
|
+
},
|
|
764
|
+
{
|
|
765
|
+
words: ["osd", "metadata"],
|
|
766
|
+
usage: "[ID]",
|
|
767
|
+
readArguments: (rest) => {
|
|
768
|
+
if (rest.length === 0) {
|
|
769
|
+
return read("reads every OSD's metadata");
|
|
770
|
+
}
|
|
771
|
+
return exactlyOne(rest, describeBadOsdId, (word) => {
|
|
772
|
+
return osdTarget(word) ? read("reads an OSD's metadata") : null;
|
|
773
|
+
});
|
|
774
|
+
},
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
words: ["osd", "ok-to-stop"],
|
|
778
|
+
usage: "ID...",
|
|
779
|
+
readArguments: osdIdList("checks whether stopping these OSDs would leave PGs unavailable (changes nothing)"),
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
words: ["osd", "safe-to-destroy"],
|
|
783
|
+
usage: "ID...",
|
|
784
|
+
readArguments: osdIdList("checks whether these OSDs still hold data the cluster needs (changes nothing)"),
|
|
785
|
+
},
|
|
786
|
+
// ---- Pools ----
|
|
787
|
+
{
|
|
788
|
+
words: ["osd", "pool", "ls"],
|
|
789
|
+
usage: "[detail]",
|
|
790
|
+
readArguments: optionalKeyword("detail", "lists the pools", "lists the pools and their settings"),
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
words: ["osd", "pool", "stats"],
|
|
794
|
+
usage: "[POOL]",
|
|
795
|
+
readArguments: (rest) => {
|
|
796
|
+
if (rest.length === 0) {
|
|
797
|
+
return read("reads every pool's I/O and recovery rates");
|
|
798
|
+
}
|
|
799
|
+
return exactlyOne(rest, describeBadPool, (word) => {
|
|
800
|
+
return POOL_NAME_REGEX.test(word)
|
|
801
|
+
? read("reads a pool's I/O and recovery rates")
|
|
802
|
+
: null;
|
|
803
|
+
});
|
|
804
|
+
},
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
words: ["osd", "pool", "get"],
|
|
808
|
+
usage: "POOL VAR|all",
|
|
809
|
+
readArguments: readPoolGetArguments,
|
|
810
|
+
},
|
|
811
|
+
// ---- Placement groups ----
|
|
812
|
+
{
|
|
813
|
+
words: ["pg", "stat"],
|
|
814
|
+
usage: "",
|
|
815
|
+
readArguments: noArguments("reads a summary of PG states"),
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
words: ["pg", "dump_stuck"],
|
|
819
|
+
usage: "[inactive|unclean|stale|undersized|degraded]... [SECONDS]",
|
|
820
|
+
readArguments: readDumpStuckArguments,
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
words: ["pg", "ls-by-osd"],
|
|
824
|
+
usage: "ID",
|
|
825
|
+
readArguments: (rest) => {
|
|
826
|
+
return exactlyOne(rest, describeBadOsdId, (word) => {
|
|
827
|
+
return osdTarget(word) ? read("lists the PGs on an OSD") : null;
|
|
828
|
+
});
|
|
829
|
+
},
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
words: ["pg", "ls-by-primary"],
|
|
833
|
+
usage: "ID",
|
|
834
|
+
readArguments: (rest) => {
|
|
835
|
+
return exactlyOne(rest, describeBadOsdId, (word) => {
|
|
836
|
+
return osdTarget(word)
|
|
837
|
+
? read("lists the PGs an OSD is primary for")
|
|
838
|
+
: null;
|
|
839
|
+
});
|
|
840
|
+
},
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
words: ["pg", "ls-by-pool"],
|
|
844
|
+
usage: "POOL",
|
|
845
|
+
readArguments: (rest) => {
|
|
846
|
+
return exactlyOne(rest, describeBadPool, (word) => {
|
|
847
|
+
return POOL_NAME_REGEX.test(word) ? read("lists a pool's PGs") : null;
|
|
848
|
+
});
|
|
849
|
+
},
|
|
850
|
+
},
|
|
851
|
+
// ---- Monitors, managers, file systems ----
|
|
852
|
+
{
|
|
853
|
+
words: ["mon", "stat"],
|
|
854
|
+
usage: "",
|
|
855
|
+
readArguments: noArguments("reads the monitors and the quorum"),
|
|
856
|
+
},
|
|
857
|
+
{
|
|
858
|
+
words: ["mon", "dump"],
|
|
859
|
+
usage: "",
|
|
860
|
+
readArguments: noArguments("reads the monitor map"),
|
|
861
|
+
},
|
|
862
|
+
{
|
|
863
|
+
words: ["mgr", "stat"],
|
|
864
|
+
usage: "",
|
|
865
|
+
readArguments: noArguments("reads which manager is active"),
|
|
866
|
+
},
|
|
867
|
+
{
|
|
868
|
+
words: ["mgr", "services"],
|
|
869
|
+
usage: "",
|
|
870
|
+
readArguments: noArguments("reads the endpoints the manager modules serve"),
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
words: ["mgr", "module", "ls"],
|
|
874
|
+
usage: "",
|
|
875
|
+
readArguments: noArguments("lists the manager modules"),
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
words: ["fs", "status"],
|
|
879
|
+
usage: "[FS]",
|
|
880
|
+
readArguments: (rest) => {
|
|
881
|
+
if (rest.length === 0) {
|
|
882
|
+
return read("reads the file systems' MDS ranks and pools");
|
|
883
|
+
}
|
|
884
|
+
return exactlyOne(rest, (word) => {
|
|
885
|
+
return word === undefined
|
|
886
|
+
? "it needs a file system name"
|
|
887
|
+
: `"${word}" is not a file system name`;
|
|
888
|
+
}, (word) => {
|
|
889
|
+
return FS_NAME_REGEX.test(word)
|
|
890
|
+
? read("reads a file system's MDS ranks and pools")
|
|
891
|
+
: null;
|
|
892
|
+
});
|
|
893
|
+
},
|
|
894
|
+
},
|
|
895
|
+
{
|
|
896
|
+
words: ["fs", "ls"],
|
|
897
|
+
usage: "",
|
|
898
|
+
readArguments: noArguments("lists the file systems"),
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
words: ["mds", "stat"],
|
|
902
|
+
usage: "",
|
|
903
|
+
readArguments: noArguments("reads the MDS daemons' states"),
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
words: ["balancer", "status"],
|
|
907
|
+
usage: "",
|
|
908
|
+
readArguments: noArguments("reads the balancer's mode and state"),
|
|
909
|
+
},
|
|
910
|
+
// ---- Crash reports ----
|
|
911
|
+
{
|
|
912
|
+
words: ["crash", "ls"],
|
|
913
|
+
usage: "",
|
|
914
|
+
readArguments: noArguments("lists the crash reports"),
|
|
915
|
+
},
|
|
916
|
+
{
|
|
917
|
+
words: ["crash", "ls-new"],
|
|
918
|
+
usage: "",
|
|
919
|
+
readArguments: noArguments("lists the crash reports not yet archived"),
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
words: ["crash", "stat"],
|
|
923
|
+
usage: "",
|
|
924
|
+
readArguments: noArguments("counts the crash reports by age"),
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
words: ["crash", "info"],
|
|
928
|
+
usage: "CRASH_ID",
|
|
929
|
+
readArguments: (rest) => {
|
|
930
|
+
return exactlyOne(rest, describeBadCrashId, (word) => {
|
|
931
|
+
return CRASH_ID_REGEX.test(word)
|
|
932
|
+
? read("reads one crash report and its backtrace")
|
|
933
|
+
: null;
|
|
934
|
+
});
|
|
935
|
+
},
|
|
936
|
+
},
|
|
937
|
+
// ---- cephadm ----
|
|
938
|
+
{
|
|
939
|
+
words: ["orch", "ps"],
|
|
940
|
+
usage: "[--daemon_type TYPE] [--service_name NAME] [--refresh]",
|
|
941
|
+
readArguments: readOrchPsArguments,
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
words: ["orch", "ls"],
|
|
945
|
+
usage: "",
|
|
946
|
+
readArguments: noArguments("lists the services cephadm manages"),
|
|
947
|
+
},
|
|
948
|
+
{
|
|
949
|
+
words: ["orch", "host", "ls"],
|
|
950
|
+
usage: "",
|
|
951
|
+
readArguments: noArguments("lists the hosts cephadm manages"),
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
words: ["orch", "device", "ls"],
|
|
955
|
+
usage: "",
|
|
956
|
+
readArguments: noArguments("lists the storage devices cephadm sees"),
|
|
957
|
+
},
|
|
958
|
+
// ---- Changes: one OSD ----
|
|
959
|
+
{
|
|
960
|
+
words: ["osd", "in"],
|
|
961
|
+
usage: "ID",
|
|
962
|
+
readArguments: (rest) => {
|
|
963
|
+
return exactlyOne(rest, describeBadOsdId, (word) => {
|
|
964
|
+
const target = osdTarget(word);
|
|
965
|
+
return target
|
|
966
|
+
? safeWrite(`marks ${target} in, so CRUSH maps data back to it (undo: ceph osd out ${word})`, [target])
|
|
967
|
+
: null;
|
|
968
|
+
});
|
|
969
|
+
},
|
|
970
|
+
},
|
|
971
|
+
{
|
|
972
|
+
words: ["osd", "out"],
|
|
973
|
+
usage: "ID",
|
|
974
|
+
readArguments: (rest) => {
|
|
975
|
+
return exactlyOne(rest, describeBadOsdId, (word) => {
|
|
976
|
+
const target = osdTarget(word);
|
|
977
|
+
return target
|
|
978
|
+
? riskyWrite(`marks ${target} out, so CRUSH moves its data to other OSDs (undo: ceph osd in ${word})`, [target])
|
|
979
|
+
: null;
|
|
980
|
+
});
|
|
981
|
+
},
|
|
982
|
+
},
|
|
983
|
+
{
|
|
984
|
+
words: ["osd", "down"],
|
|
985
|
+
usage: "ID",
|
|
986
|
+
readArguments: (rest) => {
|
|
987
|
+
return exactlyOne(rest, describeBadOsdId, (word) => {
|
|
988
|
+
const target = osdTarget(word);
|
|
989
|
+
return target
|
|
990
|
+
? riskyWrite(`marks ${target} down, so its PGs re-peer without it until the OSD, if it is running, marks itself up again`, [target])
|
|
991
|
+
: null;
|
|
992
|
+
});
|
|
993
|
+
},
|
|
994
|
+
},
|
|
995
|
+
{
|
|
996
|
+
words: ["osd", "reweight"],
|
|
997
|
+
usage: "ID WEIGHT",
|
|
998
|
+
readArguments: readReweightArguments,
|
|
999
|
+
},
|
|
1000
|
+
// ---- Changes: cluster-wide flags ----
|
|
1001
|
+
{
|
|
1002
|
+
words: ["osd", "unset"],
|
|
1003
|
+
usage: CEPH_OSD_FLAGS.join("|"),
|
|
1004
|
+
readArguments: (rest) => {
|
|
1005
|
+
return readOsdFlag(rest, (flag) => {
|
|
1006
|
+
return safeWrite(`clears the cluster-wide ${flag} flag (while set, ${OSD_FLAG_EFFECTS[flag]}), returning the cluster to normal (undo: ceph osd set ${flag})`, [CEPH_CLUSTER_TARGET]);
|
|
1007
|
+
});
|
|
1008
|
+
},
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
words: ["osd", "set"],
|
|
1012
|
+
usage: CEPH_OSD_FLAGS.join("|"),
|
|
1013
|
+
readArguments: (rest) => {
|
|
1014
|
+
return readOsdFlag(rest, (flag) => {
|
|
1015
|
+
return riskyWrite(`sets the cluster-wide ${flag} flag: until it is unset, ${OSD_FLAG_EFFECTS[flag]} (undo: ceph osd unset ${flag})`, [CEPH_CLUSTER_TARGET], flag === CLIENT_IO_PAUSE_FLAG);
|
|
1016
|
+
});
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
words: ["balancer", "on"],
|
|
1021
|
+
usage: "",
|
|
1022
|
+
readArguments: (rest) => {
|
|
1023
|
+
return rest.length === 0
|
|
1024
|
+
? riskyWrite("turns the automatic balancer on, which starts moving PGs between OSDs (undo: ceph balancer off)", [CEPH_CLUSTER_TARGET])
|
|
1025
|
+
: "it takes no arguments";
|
|
1026
|
+
},
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
words: ["balancer", "off"],
|
|
1030
|
+
usage: "",
|
|
1031
|
+
readArguments: (rest) => {
|
|
1032
|
+
return rest.length === 0
|
|
1033
|
+
? riskyWrite("turns the automatic balancer off, so PGs stop being rebalanced (undo: ceph balancer on)", [CEPH_CLUSTER_TARGET])
|
|
1034
|
+
: "it takes no arguments";
|
|
1035
|
+
},
|
|
1036
|
+
},
|
|
1037
|
+
// ---- Changes: placement groups ----
|
|
1038
|
+
{
|
|
1039
|
+
words: ["pg", "scrub"],
|
|
1040
|
+
usage: "PGID",
|
|
1041
|
+
readArguments: (rest) => {
|
|
1042
|
+
return exactlyOne(rest, describeBadPgid, (word) => {
|
|
1043
|
+
return PGID_REGEX.test(word)
|
|
1044
|
+
? safeWrite(`schedules a scrub of PG ${word}, which compares its replicas' metadata and changes no data`, [word])
|
|
1045
|
+
: null;
|
|
1046
|
+
});
|
|
1047
|
+
},
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
words: ["pg", "deep-scrub"],
|
|
1051
|
+
usage: "PGID",
|
|
1052
|
+
readArguments: (rest) => {
|
|
1053
|
+
return exactlyOne(rest, describeBadPgid, (word) => {
|
|
1054
|
+
return PGID_REGEX.test(word)
|
|
1055
|
+
? safeWrite(`schedules a deep scrub of PG ${word}, which reads and checksums every replica and changes no data`, [word])
|
|
1056
|
+
: null;
|
|
1057
|
+
});
|
|
1058
|
+
},
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
words: ["pg", "repair"],
|
|
1062
|
+
usage: "PGID",
|
|
1063
|
+
readArguments: (rest) => {
|
|
1064
|
+
return exactlyOne(rest, describeBadPgid, (word) => {
|
|
1065
|
+
return PGID_REGEX.test(word)
|
|
1066
|
+
? riskyWrite(`repairs PG ${word}, overwriting the replicas ceph judges inconsistent with the copy it judges authoritative`, [word])
|
|
1067
|
+
: null;
|
|
1068
|
+
});
|
|
1069
|
+
},
|
|
1070
|
+
},
|
|
1071
|
+
// ---- Changes: pools ----
|
|
1072
|
+
{
|
|
1073
|
+
words: ["osd", "pool", "set"],
|
|
1074
|
+
usage: "POOL size|min_size N",
|
|
1075
|
+
readArguments: readPoolSetArguments,
|
|
1076
|
+
},
|
|
1077
|
+
// ---- Changes: managers and cephadm daemons ----
|
|
1078
|
+
{
|
|
1079
|
+
words: ["mgr", "fail"],
|
|
1080
|
+
usage: "[NAME]",
|
|
1081
|
+
readArguments: readMgrFailArguments,
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
words: ["orch", "daemon", "restart"],
|
|
1085
|
+
usage: "TYPE.ID",
|
|
1086
|
+
readArguments: (rest) => {
|
|
1087
|
+
return exactlyOne(rest, describeBadDaemon, (word) => {
|
|
1088
|
+
const target = daemonTarget(word);
|
|
1089
|
+
return target
|
|
1090
|
+
? safeWrite(`restarts one cephadm daemon, ${target}, which comes back with the same configuration`, [target])
|
|
1091
|
+
: null;
|
|
1092
|
+
});
|
|
1093
|
+
},
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
words: ["orch", "daemon", "stop"],
|
|
1097
|
+
usage: "TYPE.ID",
|
|
1098
|
+
readArguments: (rest) => {
|
|
1099
|
+
return exactlyOne(rest, describeBadDaemon, (word) => {
|
|
1100
|
+
const target = daemonTarget(word);
|
|
1101
|
+
return target
|
|
1102
|
+
? riskyWrite(`stops one cephadm daemon, ${target}, until it is started again (undo: ceph orch daemon start ${target})`, [target])
|
|
1103
|
+
: null;
|
|
1104
|
+
});
|
|
1105
|
+
},
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
words: ["orch", "daemon", "start"],
|
|
1109
|
+
usage: "TYPE.ID",
|
|
1110
|
+
readArguments: (rest) => {
|
|
1111
|
+
return exactlyOne(rest, describeBadDaemon, (word) => {
|
|
1112
|
+
const target = daemonTarget(word);
|
|
1113
|
+
return target
|
|
1114
|
+
? riskyWrite(`starts one cephadm daemon, ${target}`, [target])
|
|
1115
|
+
: null;
|
|
1116
|
+
});
|
|
1117
|
+
},
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
words: ["orch", "restart"],
|
|
1121
|
+
usage: "SERVICE",
|
|
1122
|
+
readArguments: (rest) => {
|
|
1123
|
+
return exactlyOne(rest, (word) => {
|
|
1124
|
+
return word === undefined
|
|
1125
|
+
? "it needs one service name from ceph orch ls, such as mgr or rgw.store"
|
|
1126
|
+
: `"${word}" is not a cephadm service name: write one service exactly as ceph orch ls lists it (mon, mgr, osd.all-available-devices, rgw.store)`;
|
|
1127
|
+
}, (word) => {
|
|
1128
|
+
return SERVICE_NAME_REGEX.test(word)
|
|
1129
|
+
? riskyWrite(`restarts every daemon of the cephadm service ${word}`, [word])
|
|
1130
|
+
: null;
|
|
1131
|
+
});
|
|
1132
|
+
},
|
|
1133
|
+
},
|
|
1134
|
+
// ---- Changes: crash reports ----
|
|
1135
|
+
{
|
|
1136
|
+
words: ["crash", "archive"],
|
|
1137
|
+
usage: "CRASH_ID",
|
|
1138
|
+
readArguments: (rest) => {
|
|
1139
|
+
return exactlyOne(rest, describeBadCrashId, (word) => {
|
|
1140
|
+
return CRASH_ID_REGEX.test(word)
|
|
1141
|
+
? safeWrite("archives one crash report so it no longer raises RECENT_CRASH; the report is kept (ceph crash ls still lists it)", [`${CEPH_CRASH_TARGET_PREFIX}${word}`])
|
|
1142
|
+
: null;
|
|
1143
|
+
});
|
|
1144
|
+
},
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
words: ["crash", "archive-all"],
|
|
1148
|
+
usage: "",
|
|
1149
|
+
readArguments: (rest) => {
|
|
1150
|
+
return rest.length === 0
|
|
1151
|
+
? riskyWrite("archives every crash report at once, clearing RECENT_CRASH without looking at each one (the reports are kept)", [CEPH_CLUSTER_TARGET])
|
|
1152
|
+
: "it takes no arguments (archive one report with ceph crash archive CRASH_ID)";
|
|
1153
|
+
},
|
|
1154
|
+
},
|
|
1155
|
+
];
|
|
1156
|
+
/*
|
|
1157
|
+
* The exact command words of every command OneUptime AI may run on a Ceph
|
|
1158
|
+
* cluster ("osd pool get", "pg query" for `ceph pg PGID query`), for tests
|
|
1159
|
+
* and documentation.
|
|
1160
|
+
*/
|
|
1161
|
+
export const CEPH_COMMANDS = [
|
|
1162
|
+
...COMMAND_RULES.map((rule) => {
|
|
1163
|
+
return rule.words.join(" ");
|
|
1164
|
+
}),
|
|
1165
|
+
"pg query",
|
|
1166
|
+
"pg list_unfound",
|
|
1167
|
+
];
|
|
1168
|
+
/*
|
|
1169
|
+
* `ceph pg PGID CMD` is a command ceph sends to the PG's primary OSD, not
|
|
1170
|
+
* to the monitors. Only the two that change nothing are allowed:
|
|
1171
|
+
* mark_unfound_lost (which gives up on objects for good) and every other
|
|
1172
|
+
* PG command are Denied.
|
|
1173
|
+
*/
|
|
1174
|
+
const PG_TARGETED_COMMANDS = {
|
|
1175
|
+
query: "reads one PG's peering and recovery state",
|
|
1176
|
+
list_unfound: "lists the objects one PG cannot find",
|
|
1177
|
+
};
|
|
1178
|
+
/*
|
|
1179
|
+
* Families refused with their own reason, by their leading words. Only
|
|
1180
|
+
* asked when no rule matched, so `fs status` still reads while `fs rm` is
|
|
1181
|
+
* explained here. The longest matching key wins.
|
|
1182
|
+
*/
|
|
1183
|
+
const DENIED_FAMILY_REASONS = {
|
|
1184
|
+
auth: "ceph auth prints and changes cephx keys, the cluster's credentials",
|
|
1185
|
+
"config-key": "ceph config-key holds secrets (dashboard, RGW and cephadm credentials) and settings daemons act on",
|
|
1186
|
+
config: "ceph config changes daemon settings cluster-wide, and its dump, get, show and log print settings that can hold credentials",
|
|
1187
|
+
tell: "ceph tell runs commands inside a daemon (injectargs, config set, heap and debug commands)",
|
|
1188
|
+
daemon: "ceph daemon talks to a daemon's admin socket on the agent's machine, which accepts any command that daemon has",
|
|
1189
|
+
daemonperf: "ceph daemonperf talks to a daemon's admin socket on the agent's machine",
|
|
1190
|
+
injectargs: "injectargs changes daemon settings at runtime",
|
|
1191
|
+
"osd purge": "it deletes an OSD and its data from the cluster for good",
|
|
1192
|
+
"osd purge-new": "it deletes an OSD from the cluster for good",
|
|
1193
|
+
"osd destroy": "it destroys an OSD's data and keys for good",
|
|
1194
|
+
"osd rm": "it removes an OSD from the cluster",
|
|
1195
|
+
"osd lost": "it tells the cluster to give up on an OSD's data for good",
|
|
1196
|
+
"osd new": "it adds an OSD to the cluster",
|
|
1197
|
+
"osd create": "it adds an OSD to the cluster",
|
|
1198
|
+
"osd crush": "it changes the CRUSH map, which moves data across the cluster",
|
|
1199
|
+
"osd setcrushmap": "it replaces the CRUSH map, which moves data across the cluster",
|
|
1200
|
+
"osd getcrushmap": "it writes the binary CRUSH map (read the tree with ceph osd tree instead)",
|
|
1201
|
+
"osd setmaxosd": "it changes the OSD map's size",
|
|
1202
|
+
"osd require-osd-release": "it raises the minimum OSD release, which cannot be undone",
|
|
1203
|
+
"osd set-full-ratio": "it changes the ratio at which the cluster stops writes",
|
|
1204
|
+
"osd set-nearfull-ratio": "it changes the cluster's capacity warning threshold",
|
|
1205
|
+
"osd set-backfillfull-ratio": "it changes the ratio at which the cluster stops backfill",
|
|
1206
|
+
"osd set-group": "it sets flags on groups of OSDs (use one OSD at a time)",
|
|
1207
|
+
"osd unset-group": "it clears flags on groups of OSDs (use one OSD at a time)",
|
|
1208
|
+
"osd blocklist": "it cuts clients off from the cluster",
|
|
1209
|
+
"osd blacklist": "it cuts clients off from the cluster",
|
|
1210
|
+
"osd erasure-code-profile": "it changes erasure-code profiles",
|
|
1211
|
+
"osd tier": "it changes cache tiering, which moves data between pools",
|
|
1212
|
+
"osd primary-affinity": "it changes which OSDs serve reads",
|
|
1213
|
+
"osd primary-temp": "it overrides PG placement",
|
|
1214
|
+
"osd pg-temp": "it overrides PG placement",
|
|
1215
|
+
"osd pg-upmap": "it overrides PG placement",
|
|
1216
|
+
"osd pg-upmap-items": "it overrides PG placement",
|
|
1217
|
+
"osd pg-upmap-primary": "it overrides PG placement",
|
|
1218
|
+
"osd rm-pg-upmap": "it changes PG placement overrides",
|
|
1219
|
+
"osd rm-pg-upmap-items": "it changes PG placement overrides",
|
|
1220
|
+
"osd rm-pg-upmap-primary": "it changes PG placement overrides",
|
|
1221
|
+
"osd reweight-by-utilization": "it reweights many OSDs at once (reweight one with ceph osd reweight ID WEIGHT)",
|
|
1222
|
+
"osd reweight-by-pg": "it reweights many OSDs at once (reweight one with ceph osd reweight ID WEIGHT)",
|
|
1223
|
+
"osd test-reweight-by-utilization": "it is not a command OneUptime AI needs (read usage with ceph osd df)",
|
|
1224
|
+
"osd test-reweight-by-pg": "it is not a command OneUptime AI needs (read usage with ceph osd df)",
|
|
1225
|
+
"osd scrub": "it scrubs every PG on an OSD at once (scrub one PG with ceph pg scrub PGID)",
|
|
1226
|
+
"osd deep-scrub": "it deep-scrubs every PG on an OSD at once (deep-scrub one PG with ceph pg deep-scrub PGID)",
|
|
1227
|
+
"osd repair": "it repairs every PG on an OSD at once (repair one PG with ceph pg repair PGID)",
|
|
1228
|
+
"osd pool create": "it creates a pool",
|
|
1229
|
+
"osd pool delete": "it deletes a pool and every object in it",
|
|
1230
|
+
"osd pool rm": "it deletes a pool and every object in it",
|
|
1231
|
+
"osd pool rename": "it renames a pool, which breaks every client that uses it",
|
|
1232
|
+
"osd pool mksnap": "it creates pool snapshots",
|
|
1233
|
+
"osd pool rmsnap": "it deletes pool snapshots",
|
|
1234
|
+
"osd pool set-quota": "it changes a pool's quota, which can stop its writes",
|
|
1235
|
+
"osd pool application": "it changes which applications a pool is tagged for",
|
|
1236
|
+
"osd pool autoscale-status": "it is not among the pool reads OneUptime AI may run (read pool settings with ceph osd pool ls detail)",
|
|
1237
|
+
"osd pool": "only osd pool ls, stats and get read pools, and osd pool set POOL size|min_size N changes one (with a human)",
|
|
1238
|
+
fs: "only ceph fs status and ceph fs ls may run; the other fs commands create, remove, fail or reconfigure a file system",
|
|
1239
|
+
mds: "only ceph mds stat may run; the other mds commands change MDS daemons' state",
|
|
1240
|
+
mon: "only ceph mon stat and ceph mon dump may run; the other mon commands change monitor membership or settings",
|
|
1241
|
+
"mgr module": "only ceph mgr module ls may run; enabling or disabling a manager module changes what the cluster runs",
|
|
1242
|
+
mgr: "only ceph mgr stat, mgr services, mgr module ls and mgr fail [NAME] may run",
|
|
1243
|
+
orch: "only orch ps, ls, host ls, device ls, daemon restart|stop|start TYPE.ID and restart SERVICE may run; apply, rm, host, daemon rm, upgrade and the rest change what cephadm deploys",
|
|
1244
|
+
"orch daemon": "only ceph orch daemon restart|stop|start TYPE.ID may change a daemon (daemon rm and redeploy never run)",
|
|
1245
|
+
pg: "only pg stat, dump_stuck, ls-by-osd, ls-by-pool, ls-by-primary, PGID query, PGID list_unfound, scrub, deep-scrub and repair may run; the rest force PG creation, recovery or peering",
|
|
1246
|
+
crash: "only crash ls, ls-new, stat, info, archive and archive-all may run; crash rm and prune delete reports for good",
|
|
1247
|
+
log: "only ceph log last may run; ceph log TEXT writes a message into the cluster log",
|
|
1248
|
+
balancer: "only ceph balancer status, on and off may run; the other balancer commands change how it moves data",
|
|
1249
|
+
"health mute": "it mutes a health check, which hides a problem",
|
|
1250
|
+
"health unmute": "it unmutes health checks (only ceph health [detail] may run)",
|
|
1251
|
+
dashboard: "it manages the dashboard's users and credentials",
|
|
1252
|
+
restful: "it manages REST API keys",
|
|
1253
|
+
rgw: "it manages object gateway realms, zones and users",
|
|
1254
|
+
nfs: "it manages NFS exports and clusters",
|
|
1255
|
+
smb: "it manages SMB shares and clusters",
|
|
1256
|
+
telemetry: "it changes what the cluster reports outside itself",
|
|
1257
|
+
device: "it manages device health monitoring and lights",
|
|
1258
|
+
cephadm: "it manages cephadm's SSH keys and hosts",
|
|
1259
|
+
quorum: "it changes the monitor quorum",
|
|
1260
|
+
sync: "it forces monitor store syncs",
|
|
1261
|
+
heap: "it changes a daemon's memory allocator",
|
|
1262
|
+
osd: "the OSD commands that may run are osd tree, df, perf, stat, dump, blocked-by, find, metadata, ok-to-stop, safe-to-destroy (reads) and osd in, out, down, set, unset, reweight (changes)",
|
|
1263
|
+
};
|
|
1264
|
+
const SUPPORTED_COMMANDS_SUMMARY = "Reads: status (or -s), health [detail], df [detail], versions, progress, quorum_status, log last, osd tree|df|perf|stat|dump|blocked-by|find|metadata|ok-to-stop|safe-to-destroy, osd pool ls|stats|get, pg stat|dump_stuck|ls-by-osd|ls-by-pool|ls-by-primary, pg PGID query|list_unfound, mon stat|dump, mgr stat|services|module ls, fs status|ls, mds stat, balancer status, crash ls|ls-new|stat|info, orch ps|ls|host ls|device ls. Changes: osd in|out|down ID, osd set|unset FLAG, osd reweight ID W, pg scrub|deep-scrub|repair PGID, crash archive ID, crash archive-all, orch daemon restart|stop|start TYPE.ID, orch restart SERVICE, mgr fail [NAME], balancer on|off, osd pool set POOL size|min_size N";
|
|
1265
|
+
/*
|
|
1266
|
+
* The family reason for these words, from their longest leading words down
|
|
1267
|
+
* to (but not including) `shortest` words; null when none names them.
|
|
1268
|
+
*/
|
|
1269
|
+
function findFamilyRefusal(words, shortest) {
|
|
1270
|
+
const shown = `ceph ${renderResourceDisplayCommand(words)}`;
|
|
1271
|
+
for (let length = Math.min(3, words.length); length > shortest; length--) {
|
|
1272
|
+
const key = words.slice(0, length).join(" ");
|
|
1273
|
+
if (Object.prototype.hasOwnProperty.call(DENIED_FAMILY_REASONS, key)) {
|
|
1274
|
+
return `"${shown}" is not allowed: ${DENIED_FAMILY_REASONS[key]}`;
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
return null;
|
|
1278
|
+
}
|
|
1279
|
+
// Why no rule matched these words: a family reason, or the general one.
|
|
1280
|
+
function describeUnknownCommand(words) {
|
|
1281
|
+
return (findFamilyRefusal(words, 0) ||
|
|
1282
|
+
`"ceph ${renderResourceDisplayCommand(words)}" is not a command OneUptime AI may run on a Ceph cluster. ${SUPPORTED_COMMANDS_SUMMARY}`);
|
|
1283
|
+
}
|
|
1284
|
+
// `ceph pg PGID CMD`: the two PG commands that change nothing.
|
|
1285
|
+
function evaluatePgTargeted(words) {
|
|
1286
|
+
const pgid = words[1];
|
|
1287
|
+
if (!PGID_REGEX.test(pgid)) {
|
|
1288
|
+
return describeBadPgid(pgid);
|
|
1289
|
+
}
|
|
1290
|
+
const command = words[2];
|
|
1291
|
+
if (command === undefined ||
|
|
1292
|
+
!Object.prototype.hasOwnProperty.call(PG_TARGETED_COMMANDS, command)) {
|
|
1293
|
+
return `ceph pg ${pgid} takes only query or list_unfound (mark_unfound_lost and every other PG command never run)`;
|
|
1294
|
+
}
|
|
1295
|
+
if (words.length > 3) {
|
|
1296
|
+
return `ceph pg ${pgid} ${command} takes no more arguments`;
|
|
1297
|
+
}
|
|
1298
|
+
return read(PG_TARGETED_COMMANDS[command]);
|
|
1299
|
+
}
|
|
1300
|
+
// The rule whose words start these words (longest first), or null.
|
|
1301
|
+
function findRule(words) {
|
|
1302
|
+
let best = null;
|
|
1303
|
+
for (const rule of COMMAND_RULES) {
|
|
1304
|
+
if (rule.words.length > words.length) {
|
|
1305
|
+
continue;
|
|
1306
|
+
}
|
|
1307
|
+
const matches = rule.words.every((word, index) => {
|
|
1308
|
+
return words[index] === word;
|
|
1309
|
+
});
|
|
1310
|
+
if (matches && (!best || rule.words.length > best.words.length)) {
|
|
1311
|
+
best = rule;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
return best;
|
|
1315
|
+
}
|
|
1316
|
+
function commandResult(argv, verb, verdict) {
|
|
1317
|
+
const result = {
|
|
1318
|
+
tier: verdict.tier,
|
|
1319
|
+
reason: verdict.reason,
|
|
1320
|
+
program: CEPH_PROGRAM,
|
|
1321
|
+
args: argv.slice(1),
|
|
1322
|
+
verb,
|
|
1323
|
+
displayCommand: renderResourceDisplayCommand(argv),
|
|
1324
|
+
targets: verdict.targets.slice(),
|
|
1325
|
+
};
|
|
1326
|
+
if (verdict.requiresHuman === true) {
|
|
1327
|
+
result.requiresHuman = true;
|
|
1328
|
+
}
|
|
1329
|
+
return result;
|
|
1330
|
+
}
|
|
1331
|
+
function evaluateCephArgv(rawArgv) {
|
|
1332
|
+
if (!Array.isArray(rawArgv) ||
|
|
1333
|
+
rawArgv.length === 0 ||
|
|
1334
|
+
rawArgv.some((word) => {
|
|
1335
|
+
return typeof word !== "string";
|
|
1336
|
+
})) {
|
|
1337
|
+
return deniedResult(rawArgv, "the command is not a list of words");
|
|
1338
|
+
}
|
|
1339
|
+
const argv = rawArgv.slice();
|
|
1340
|
+
if (argv[0] !== CEPH_PROGRAM) {
|
|
1341
|
+
return deniedResult(argv, `the ceph command policy only reads commands that start with "${CEPH_PROGRAM}"`);
|
|
1342
|
+
}
|
|
1343
|
+
const args = argv.slice(1);
|
|
1344
|
+
if (args.length === 0) {
|
|
1345
|
+
return deniedResult(argv, "the command names no ceph command (ceph on its own opens an interactive shell); run one command, such as ceph status");
|
|
1346
|
+
}
|
|
1347
|
+
if (args.some((word) => {
|
|
1348
|
+
return word.trim() === "";
|
|
1349
|
+
})) {
|
|
1350
|
+
return deniedResult(argv, "a word of the command is empty");
|
|
1351
|
+
}
|
|
1352
|
+
const line = readCommandLine(args);
|
|
1353
|
+
if (typeof line === "string") {
|
|
1354
|
+
return deniedResult(argv, line);
|
|
1355
|
+
}
|
|
1356
|
+
if (line.status) {
|
|
1357
|
+
if (line.words.length > 0) {
|
|
1358
|
+
return deniedResult(argv, "-s is ceph status and must stand alone: run the other command separately");
|
|
1359
|
+
}
|
|
1360
|
+
return commandResult(argv, "status", read("reads the cluster's status: health, monitors, OSDs, PGs and usage"));
|
|
1361
|
+
}
|
|
1362
|
+
const words = line.words;
|
|
1363
|
+
if (words.length === 0) {
|
|
1364
|
+
return deniedResult(argv, "the command names no ceph command, only an output format; add one, such as ceph status --format json");
|
|
1365
|
+
}
|
|
1366
|
+
const isOrchPs = words[0] === "orch" && words[1] === "ps";
|
|
1367
|
+
for (let index = 0; index < words.length; index++) {
|
|
1368
|
+
const word = words[index];
|
|
1369
|
+
if (!word.startsWith("-")) {
|
|
1370
|
+
continue;
|
|
1371
|
+
}
|
|
1372
|
+
if (isOrchPs &&
|
|
1373
|
+
index >= 2 &&
|
|
1374
|
+
Object.prototype.hasOwnProperty.call(ORCH_PS_OPTIONS, word)) {
|
|
1375
|
+
continue;
|
|
1376
|
+
}
|
|
1377
|
+
const name = word.split("=")[0];
|
|
1378
|
+
if (isOrchPs &&
|
|
1379
|
+
name !== word &&
|
|
1380
|
+
Object.prototype.hasOwnProperty.call(ORCH_PS_OPTIONS, name)) {
|
|
1381
|
+
return deniedResult(argv, ORCH_PS_OPTIONS[name] === "refresh"
|
|
1382
|
+
? `"${word}" is not accepted: --refresh takes no value, so write it on its own`
|
|
1383
|
+
: `"${word}" is not accepted: write orch ps's named arguments as two words (${name} VALUE)`);
|
|
1384
|
+
}
|
|
1385
|
+
return deniedResult(argv, describeOptionRefusal(word));
|
|
1386
|
+
}
|
|
1387
|
+
if (words[0] === "pg" &&
|
|
1388
|
+
words.length >= 2 &&
|
|
1389
|
+
STARTS_WITH_DIGIT_REGEX.test(words[1])) {
|
|
1390
|
+
const verdict = evaluatePgTargeted(words);
|
|
1391
|
+
return typeof verdict === "string"
|
|
1392
|
+
? deniedResult(argv, verdict)
|
|
1393
|
+
: commandResult(argv, `pg ${words[2]}`, verdict);
|
|
1394
|
+
}
|
|
1395
|
+
const rule = findRule(words);
|
|
1396
|
+
if (!rule) {
|
|
1397
|
+
return deniedResult(argv, describeUnknownCommand(words));
|
|
1398
|
+
}
|
|
1399
|
+
const verb = rule.words.join(" ");
|
|
1400
|
+
const verdict = rule.readArguments(words.slice(rule.words.length));
|
|
1401
|
+
if (typeof verdict === "string") {
|
|
1402
|
+
// `health mute X` is its own (refused) command, not bad health arguments.
|
|
1403
|
+
return deniedResult(argv, findFamilyRefusal(words, rule.words.length) ||
|
|
1404
|
+
`ceph ${verb} is refused: ${verdict}. Usage: ceph ${verb}${rule.usage ? ` ${rule.usage}` : ""}`);
|
|
1405
|
+
}
|
|
1406
|
+
return commandResult(argv, verb, verdict);
|
|
1407
|
+
}
|
|
1408
|
+
const READ_COMMAND_GUIDE = [
|
|
1409
|
+
"- Cluster: `ceph status` (or `ceph -s`), `ceph health [detail]`, `ceph df [detail]`, `ceph versions`, `ceph version`, `ceph progress`, `ceph quorum_status`, `ceph log last [N<=1000] [debug|info|sec|warn|error] [*|cluster|audit|cephadm]`",
|
|
1410
|
+
"- OSDs (ID = 3 or osd.3): `ceph osd tree [up|down|in|out|destroyed]`, `ceph osd df [tree]`, `ceph osd perf`, `ceph osd stat`, `ceph osd dump`, `ceph osd blocked-by`, `ceph osd find ID`, `ceph osd metadata [ID]`, `ceph osd ok-to-stop ID...`, `ceph osd safe-to-destroy ID...`",
|
|
1411
|
+
"- Pools: `ceph osd pool ls [detail]`, `ceph osd pool stats [POOL]`, `ceph osd pool get POOL VAR|all`",
|
|
1412
|
+
"- PGs (PGID = 1.2f): `ceph pg stat`, `ceph pg dump_stuck [inactive|unclean|stale|undersized|degraded]... [SECONDS]`, `ceph pg PGID query`, `ceph pg PGID list_unfound`, `ceph pg ls-by-osd ID`, `ceph pg ls-by-pool POOL`, `ceph pg ls-by-primary ID`",
|
|
1413
|
+
"- Daemons: `ceph mon stat`, `ceph mon dump`, `ceph mgr stat`, `ceph mgr services`, `ceph mgr module ls`, `ceph fs status [FS]`, `ceph fs ls`, `ceph mds stat`, `ceph balancer status`",
|
|
1414
|
+
"- Crashes: `ceph crash ls`, `ceph crash ls-new`, `ceph crash stat`, `ceph crash info CRASH_ID`",
|
|
1415
|
+
"- cephadm: `ceph orch ps [--daemon_type TYPE] [--service_name NAME] [--refresh]`, `ceph orch ls`, `ceph orch host ls`, `ceph orch device ls`",
|
|
1416
|
+
"- Add `--format json` (or `-f json`, `json-pretty`, `plain`) for structured output; no other option is accepted (never -c, --keyring, --id, --admin-daemon, -i, -o or -w), and `auth`, `config-key`, `config`, `tell` and `daemon` never run",
|
|
1417
|
+
].join("\n");
|
|
1418
|
+
const WRITE_COMMAND_GUIDE = [
|
|
1419
|
+
"- SafeWrite (runs unattended in Automatic mode): `ceph osd in ID`, `ceph osd unset noout|norebalance|nobackfill|norecover|noscrub|nodeep-scrub|pause`, `ceph crash archive CRASH_ID`, `ceph orch daemon restart TYPE.ID`, `ceph pg scrub PGID`, `ceph pg deep-scrub PGID`",
|
|
1420
|
+
"- RiskyWrite (needs approval unless allowlisted or approvals are bypassed): `ceph osd out ID`, `ceph osd down ID`, `ceph osd set noout|norebalance|nobackfill|norecover|noscrub|nodeep-scrub`, `ceph osd reweight ID 0..1`, `ceph pg repair PGID`, `ceph mgr fail [NAME]`, `ceph orch daemon stop|start TYPE.ID`, `ceph orch restart SERVICE`, `ceph crash archive-all`, `ceph balancer on|off`",
|
|
1421
|
+
"- Always asks a human: `ceph osd set pause` (stops all client I/O) and `ceph osd pool set POOL size|min_size N`",
|
|
1422
|
+
"- One OSD, PG, daemon, service or crash report per command (ID = 3 or osd.3, PGID = 1.2f, TYPE.ID as `ceph orch ps` lists it); rollbacks: osd out/in, osd set/unset, balancer on/off, orch daemon stop/start",
|
|
1423
|
+
"- Never runs: osd purge|destroy|rm|lost|new|crush, pool create|delete|rename or any other pool setting, `auth`, `config-key`, `config`, `tell`, `daemon`, `injectargs`, fs changes, mon changes, `mgr module enable|disable`, `orch apply|rm|host|upgrade`, `crash rm|prune`",
|
|
1424
|
+
].join("\n");
|
|
1425
|
+
const CephCommandPolicy = {
|
|
1426
|
+
name: "ceph",
|
|
1427
|
+
programs: [CEPH_PROGRAM],
|
|
1428
|
+
readCommandGuide: READ_COMMAND_GUIDE,
|
|
1429
|
+
writeCommandGuide: WRITE_COMMAND_GUIDE,
|
|
1430
|
+
/*
|
|
1431
|
+
* What a `*` in an allowlist entry may stand for in ceph's grammar — two
|
|
1432
|
+
* of each kind (daemon names, PG ids, OSD flags, weights), so an entry
|
|
1433
|
+
* such as `ceph orch daemon stop *` is valid and seen to be broad.
|
|
1434
|
+
*/
|
|
1435
|
+
allowlistStandIns: [
|
|
1436
|
+
"osd.1",
|
|
1437
|
+
"osd.2",
|
|
1438
|
+
"mgr.a",
|
|
1439
|
+
"mgr.b",
|
|
1440
|
+
"1.1f",
|
|
1441
|
+
"1.2a",
|
|
1442
|
+
"noout",
|
|
1443
|
+
"norebalance",
|
|
1444
|
+
"0.5",
|
|
1445
|
+
"0.8",
|
|
1446
|
+
],
|
|
1447
|
+
evaluateArgv(argv) {
|
|
1448
|
+
try {
|
|
1449
|
+
return evaluateCephArgv(argv);
|
|
1450
|
+
}
|
|
1451
|
+
catch (_a) {
|
|
1452
|
+
/*
|
|
1453
|
+
* Total: whatever the argv held, a failure to read it is a refusal —
|
|
1454
|
+
* one that never reads the argv again (a word that threw once may
|
|
1455
|
+
* throw twice).
|
|
1456
|
+
*/
|
|
1457
|
+
return deniedResult([], "the ceph command policy could not read this command");
|
|
1458
|
+
}
|
|
1459
|
+
},
|
|
1460
|
+
};
|
|
1461
|
+
export default CephCommandPolicy;
|
|
1462
|
+
//# sourceMappingURL=CephCommandPolicy.js.map
|