@oneuptime/common 14.0.9 → 14.0.11
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/AIConversation.ts +127 -1
- package/Models/DatabaseModels/AutoRemediationSuggestion.ts +60 -0
- package/Models/DatabaseModels/CephCluster.ts +225 -0
- package/Models/DatabaseModels/CloudResource.ts +12 -0
- package/Models/DatabaseModels/DatabaseServer.ts +225 -0
- package/Models/DatabaseModels/DockerHost.ts +225 -0
- package/Models/DatabaseModels/DockerSwarmCluster.ts +225 -0
- package/Models/DatabaseModels/GlobalConfig.ts +1 -1
- package/Models/DatabaseModels/GlobalOidc.ts +0 -4
- package/Models/DatabaseModels/GlobalOidcProject.ts +0 -4
- package/Models/DatabaseModels/GlobalSso.ts +0 -4
- package/Models/DatabaseModels/GlobalSsoProject.ts +0 -4
- package/Models/DatabaseModels/Host.ts +225 -0
- package/Models/DatabaseModels/IncidentForm.ts +594 -0
- package/Models/DatabaseModels/IncidentFormSubmission.ts +283 -0
- package/Models/DatabaseModels/IncidentTemplate.ts +59 -0
- package/Models/DatabaseModels/Index.ts +16 -0
- package/Models/DatabaseModels/IoTFleet.ts +12 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +12 -0
- package/Models/DatabaseModels/MessageQueue.ts +1102 -0
- package/Models/DatabaseModels/MessageQueueLabelRule.ts +553 -0
- package/Models/DatabaseModels/MessageQueueOwnerRule.ts +633 -0
- package/Models/DatabaseModels/MessageQueueOwnerTeam.ts +491 -0
- package/Models/DatabaseModels/MessageQueueOwnerUser.ts +490 -0
- package/Models/DatabaseModels/PodmanHost.ts +225 -0
- package/Models/DatabaseModels/Project.ts +59 -0
- package/Models/DatabaseModels/ProjectOidc.ts +0 -4
- package/Models/DatabaseModels/ProjectSso.ts +0 -4
- package/Models/DatabaseModels/ProxmoxCluster.ts +225 -0
- package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
- package/Models/DatabaseModels/RumApplication.ts +12 -0
- package/Models/DatabaseModels/RunnerJob.ts +144 -0
- package/Models/DatabaseModels/ServerlessFunction.ts +12 -0
- package/Models/DatabaseModels/Service.ts +12 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +0 -4
- package/Models/DatabaseModels/StatusPageSso.ts +0 -4
- package/Models/DatabaseModels/TeamComplianceSetting.ts +47 -2
- package/Models/DatabaseModels/VMwareVCenter.ts +225 -0
- package/Server/API/AIChatAPI.ts +13 -114
- package/Server/API/AIInvestigationAPI.ts +3 -3
- package/Server/API/AIInvestigationConversationAPI.ts +266 -0
- package/Server/API/AutoRemediationAPI.ts +392 -1
- package/Server/API/IncidentFormAPI.ts +376 -0
- package/Server/API/ProjectOIDC.ts +16 -25
- package/Server/API/ProjectSSO.ts +16 -24
- package/Server/API/ResourceAiAccessAPI.ts +1669 -0
- package/Server/API/StatusPageAPI.ts +42 -77
- package/Server/Enterprise/EnterpriseEdition.ts +93 -28
- package/Server/Enterprise/EnterpriseFeature.ts +25 -3
- package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +1 -1
- package/Server/Enterprise/EnterpriseServerModule.ts +4 -1
- package/Server/EnvironmentConfig.ts +1 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.ts +129 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.ts +52 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.ts +75 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.ts +477 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Infrastructure/Semaphore.ts +22 -0
- package/Server/Middleware/IncidentFormRateLimit.ts +847 -0
- package/Server/Middleware/TelemetryIngest.ts +15 -5
- package/Server/Middleware/UserAuthorization.ts +16 -38
- package/Server/Services/AIService.ts +10 -13
- package/Server/Services/AnalyticsDatabaseService.ts +45 -1
- package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
- 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/IncidentCustomFieldService.ts +112 -2
- package/Server/Services/IncidentEpisodeMemberService.ts +24 -4
- package/Server/Services/IncidentEpisodeService.ts +10 -1
- package/Server/Services/IncidentFormService.ts +1566 -0
- package/Server/Services/IncidentFormSubmissionService.ts +97 -0
- package/Server/Services/IncidentGroupingEngineService.ts +45 -8
- package/Server/Services/IncidentService.ts +123 -5
- package/Server/Services/IncidentTemplateService.ts +22 -0
- package/Server/Services/Index.ts +14 -0
- package/Server/Services/MessageQueueLabelRuleEngineService.ts +321 -0
- package/Server/Services/MessageQueueLabelRuleService.ts +14 -0
- package/Server/Services/MessageQueueOwnerRuleEngineService.ts +412 -0
- package/Server/Services/MessageQueueOwnerRuleService.ts +14 -0
- package/Server/Services/MessageQueueOwnerTeamService.ts +62 -0
- package/Server/Services/MessageQueueOwnerUserService.ts +62 -0
- package/Server/Services/MessageQueueService.ts +1463 -0
- package/Server/Services/MetricRecordingRuleService.ts +47 -0
- package/Server/Services/OpenTelemetryIngestService.ts +37 -4
- package/Server/Services/PodmanHostService.ts +109 -1
- package/Server/Services/ProjectService.ts +0 -59
- package/Server/Services/ProxmoxClusterService.ts +110 -1
- 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 +611 -4
- package/Server/Services/StatusPagePrivateUserService.ts +1 -4
- package/Server/Services/StatusPageService.ts +1 -51
- package/Server/Services/TeamComplianceSettingService.ts +163 -42
- package/Server/Services/TelemetryUsageBillingService.ts +28 -0
- package/Server/Services/TraceRecordingRuleService.ts +33 -0
- package/Server/Services/UserNotificationRuleService.ts +8 -1
- package/Server/Services/VMwareVCenterService.ts +110 -1
- package/Server/Services/WorkspaceNotificationSummaryService.ts +12 -3
- package/Server/Types/Database/Permissions/CreatePermission.ts +17 -3
- package/Server/Types/Database/Permissions/EditionPermission.ts +140 -38
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +16 -0
- package/Server/Types/Database/Permissions/TablePermission.ts +3 -3
- package/Server/Types/Database/Permissions/UpdatePermission.ts +20 -6
- package/Server/Utils/AI/Chat/AgentContextCompactor.ts +200 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +307 -48
- package/Server/Utils/AI/Chat/ChatRunCancellation.ts +156 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +78 -18
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
- package/Server/Utils/AI/Chat/ToolOutputPager.ts +322 -0
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +88 -30
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +13 -1
- package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +0 -32
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +27 -25
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1442 -34
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +968 -34
- package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
- package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +622 -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 +882 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +125 -12
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +99 -15
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +99 -15
- package/Server/Utils/AI/SRE/InvestigationQueue.ts +16 -19
- package/Server/Utils/AI/SRE/InvestigationThread.ts +646 -0
- package/Server/Utils/AI/SRE/InvestigationThreadService.ts +715 -0
- package/Server/Utils/AI/Toolbox/Serializer.ts +10 -3
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +396 -13
- package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
- package/Server/Utils/EditionEnforcement.ts +19 -202
- package/Server/Utils/LLM/LLMService.ts +259 -63
- package/Server/Utils/RelaxedScimTeamLocksReport.ts +245 -0
- package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
- package/Server/Utils/SameOriginRequest.ts +203 -0
- package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
- package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
- package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +4 -1
- package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +1402 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +4 -1
- package/Server/Utils/VendorAssets.ts +3 -3
- 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 +301 -225
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +38 -16
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +376 -144
- 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/Accounts/IncidentFormPage.test.tsx +2036 -0
- package/Tests/App/Accounts/IncidentFormServerMessages.test.ts +119 -0
- package/Tests/App/Accounts/IncidentFormUtils.test.ts +1157 -0
- package/Tests/App/Accounts/LoginPasskey.test.tsx +6 -4
- package/Tests/App/Accounts/LoginSso.test.tsx +724 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationRequireSso.test.tsx +338 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoCardLocales.test.tsx +331 -0
- package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +47 -33
- package/Tests/App/AdminDashboard/GlobalSsoOidcPages.test.tsx +1021 -0
- package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +876 -78
- package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +20 -3
- package/Tests/App/Dashboard/CephProxmoxVMwareDocumentationCards.test.tsx +359 -0
- package/Tests/App/Dashboard/CephSetupGuide.test.ts +961 -0
- package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +381 -95
- package/Tests/App/Dashboard/CloudSetupGuide.test.ts +1463 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +267 -12
- package/Tests/App/Dashboard/ContainerSetupGuideCards.test.tsx +345 -0
- package/Tests/App/Dashboard/CoreListEmptyStates.test.tsx +501 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +0 -1
- package/Tests/App/Dashboard/DatabaseDocumentationCard.test.tsx +400 -0
- package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +23 -6
- package/Tests/App/Dashboard/DatabaseSetupGuide.test.ts +1869 -0
- package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +44 -0
- package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +50 -9
- package/Tests/App/Dashboard/DockerSetupGuide.test.ts +899 -0
- package/Tests/App/Dashboard/DockerSwarmSetupGuide.test.ts +964 -0
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +141 -7
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +52 -39
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +7 -1
- package/Tests/App/Dashboard/GettingStartedTaskRoutes.test.tsx +331 -0
- package/Tests/App/Dashboard/HomeOverviewStatsFirstRun.test.tsx +925 -0
- package/Tests/App/Dashboard/HostDocumentationCard.test.tsx +225 -0
- package/Tests/App/Dashboard/HostSetupGuide.test.ts +1183 -0
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +69 -45
- package/Tests/App/Dashboard/IncidentCreateTemplateCustomFieldSettings.test.tsx +745 -0
- package/Tests/App/Dashboard/IncidentCreateTemplateOwners.test.tsx +414 -0
- package/Tests/App/Dashboard/IncidentCustomFieldCreateSettingsForm.test.ts +1042 -0
- package/Tests/App/Dashboard/IncidentCustomFieldSettingsCard.test.tsx +1816 -0
- package/Tests/App/Dashboard/IncidentFormPlan.test.ts +89 -0
- package/Tests/App/Dashboard/IncidentFormShareLinkCard.test.tsx +846 -0
- package/Tests/App/Dashboard/IncidentFormsPages.test.tsx +1324 -0
- package/Tests/App/Dashboard/IncidentTemplateCustomFieldSettings.test.tsx +630 -0
- package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +13 -0
- package/Tests/App/Dashboard/IncomingEmailMonitorLinkVerifyHint.test.tsx +104 -0
- package/Tests/App/Dashboard/InvestigationConversation.test.tsx +1107 -0
- package/Tests/App/Dashboard/InvestigationConversationData.test.ts +546 -0
- package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +170 -5
- package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +207 -2
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +729 -34
- package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +9 -21
- package/Tests/App/Dashboard/InvestigationReportView.test.tsx +274 -37
- package/Tests/App/Dashboard/InvestigationStatusBadge.test.tsx +130 -0
- package/Tests/App/Dashboard/IoTDocumentationCard.test.tsx +218 -0
- package/Tests/App/Dashboard/IoTSetupGuide.test.ts +1124 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +20 -6
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +107 -83
- package/Tests/App/Dashboard/KubernetesSetupGuide.test.ts +787 -0
- package/Tests/App/Dashboard/MessageQueueBreadcrumbs.test.tsx +228 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealth.test.tsx +1538 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealthMetricChart.test.tsx +969 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealthReads.test.ts +889 -0
- package/Tests/App/Dashboard/MessageQueueBrokerMetricsReach.test.ts +236 -0
- package/Tests/App/Dashboard/MessageQueueDocumentationCard.test.tsx +479 -0
- package/Tests/App/Dashboard/MessageQueueListPages.test.tsx +1232 -0
- package/Tests/App/Dashboard/MessageQueueMetricDescriptions.test.ts +244 -0
- package/Tests/App/Dashboard/MessageQueueMonitorLink.test.ts +952 -0
- package/Tests/App/Dashboard/MessageQueueMonitorLinkMonitorCreate.test.tsx +859 -0
- package/Tests/App/Dashboard/MessageQueueOverview.test.tsx +1773 -0
- package/Tests/App/Dashboard/MessageQueueOverviewPresentation.test.ts +196 -0
- package/Tests/App/Dashboard/MessageQueuePresentation.test.ts +799 -0
- package/Tests/App/Dashboard/MessageQueueProducersConsumers.test.tsx +680 -0
- package/Tests/App/Dashboard/MessageQueueRoutes.test.tsx +383 -0
- package/Tests/App/Dashboard/MessageQueueRulePages.test.tsx +278 -0
- package/Tests/App/Dashboard/MessageQueueSetupGuide.test.ts +2778 -0
- package/Tests/App/Dashboard/MessageQueueSideMenus.test.tsx +273 -0
- package/Tests/App/Dashboard/MessageQueueSpanPopulations.test.ts +930 -0
- package/Tests/App/Dashboard/MessageQueueSpanStore.ts +351 -0
- package/Tests/App/Dashboard/MessageQueueTelemetryScope.test.ts +375 -0
- package/Tests/App/Dashboard/MessageQueueTelemetryScopeTabs.test.tsx +668 -0
- package/Tests/App/Dashboard/MessageQueueViewPages.test.tsx +685 -0
- package/Tests/App/Dashboard/MonitorAndHomeNotOperationalMenus.test.tsx +342 -0
- package/Tests/App/Dashboard/MonitorCreateFirstRunDefaults.test.tsx +623 -0
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +442 -0
- package/Tests/App/Dashboard/MonitorLogsPageViewSummary.test.tsx +814 -0
- package/Tests/App/Dashboard/MonitorSetupCardBodies.test.tsx +246 -0
- package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +8 -0
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +27 -12
- package/Tests/App/Dashboard/PlanGatedPage.test.tsx +292 -0
- package/Tests/App/Dashboard/PodmanSetupGuide.test.ts +948 -0
- package/Tests/App/Dashboard/ProductOrientation.test.tsx +5 -4
- package/Tests/App/Dashboard/ProductSettingsSectionCollapsed.test.tsx +266 -0
- package/Tests/App/Dashboard/ProxmoxSetupGuide.test.ts +1318 -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/ResourceAiAgentAttentionServerParity.test.ts +555 -0
- package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
- package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +2010 -0
- package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1455 -0
- package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
- package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +16 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideCard.test.tsx +444 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsInfra.test.tsx +798 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsPlatforms.test.tsx +717 -0
- package/Tests/App/Dashboard/ResourceConnectionGuides.test.ts +981 -0
- package/Tests/App/Dashboard/ResourceConnectionState.test.ts +132 -0
- package/Tests/App/Dashboard/RumDocumentationCard.test.tsx +293 -0
- package/Tests/App/Dashboard/RumSessionReplayRetentionSettings.test.tsx +467 -0
- package/Tests/App/Dashboard/RumSetupGuide.test.ts +758 -0
- package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +25 -0
- package/Tests/App/Dashboard/ServerlessDocumentationCard.test.tsx +254 -0
- package/Tests/App/Dashboard/ServerlessSetupGuide.test.ts +1074 -0
- package/Tests/App/Dashboard/SetupGuide.test.ts +246 -0
- package/Tests/App/Dashboard/SetupGuideCard.test.tsx +756 -0
- package/Tests/App/Dashboard/SloListSideMenu.test.tsx +120 -0
- package/Tests/App/Dashboard/SsoPages.test.tsx +833 -0
- package/Tests/App/Dashboard/TelemetryDocumentation.test.tsx +253 -0
- package/Tests/App/Dashboard/TelemetryRetentionShells.test.tsx +730 -0
- package/Tests/App/Dashboard/VMwareSetupGuide.test.ts +1033 -0
- package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +87 -7
- package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +61 -10
- package/Tests/Models/DatabaseModels/IncidentFormModel.test.ts +1250 -0
- package/Tests/Models/DatabaseModels/MessageQueueModels.test.ts +1983 -0
- package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
- package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +190 -14
- package/Tests/Models/IncidentTemplateCustomFieldSettingsColumn.test.ts +291 -0
- package/Tests/Server/API/AIInvestigationConversationAPI.test.ts +412 -0
- package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +38 -9
- package/Tests/Server/API/IncidentFormAPI.test.ts +942 -0
- package/Tests/Server/API/IncidentFormPublicRoutes.test.ts +1653 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -1
- package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
- package/Tests/Server/API/{SsoProviderListingsEdition.test.ts → SsoProviderListings.test.ts} +164 -110
- package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +76 -54
- package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +125 -42
- package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +36 -10
- package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +51 -9
- package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +13 -8
- package/Tests/Server/Enterprise/SsoInCommunityEdition.test.ts +540 -0
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
- package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentFormsMigration.test.ts +438 -0
- package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleNotificationChannelsMigration.test.ts +255 -0
- package/Tests/Server/Infrastructure/Postgres/MessageQueueTablesMigration.test.ts +637 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
- package/Tests/Server/Middleware/IncidentFormRateLimit.test.ts +1630 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +63 -5
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +103 -5
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +19 -1
- package/Tests/Server/Middleware/UserAuthorization.test.ts +16 -17
- package/Tests/Server/Middleware/UserAuthorizationSsoEnforcement.test.ts +544 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +37 -8
- package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
- 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/IncidentCreatedFeedTitle.test.ts +212 -0
- package/Tests/Server/Services/IncidentCustomFieldDeleteFormQuestions.test.ts +297 -0
- package/Tests/Server/Services/IncidentFormOwnersCreatedNotification.test.ts +497 -0
- package/Tests/Server/Services/IncidentFormPostgres.test.ts +958 -0
- package/Tests/Server/Services/IncidentFormPublicForm.test.ts +1260 -0
- package/Tests/Server/Services/IncidentFormPublicSubmission.test.ts +2520 -0
- package/Tests/Server/Services/IncidentFormRegistration.test.ts +159 -0
- package/Tests/Server/Services/IncidentFormService.test.ts +663 -0
- package/Tests/Server/Services/IncidentFormSubmissionService.test.ts +430 -0
- package/Tests/Server/Services/IncidentFormSubmissionTemplateBranch.test.ts +473 -0
- package/Tests/Server/Services/IncidentGroupingTemplateSubstitution.test.ts +81 -0
- package/Tests/Server/Services/IncidentTemplateCustomFieldSettings.test.ts +262 -0
- package/Tests/Server/Services/IncidentTemplateOwnersOnDeclare.test.ts +566 -0
- package/Tests/Server/Services/IncidentTitleMarkdownSinks.test.ts +640 -0
- package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +3 -3
- package/Tests/Server/Services/MessageQueueOwnerServices.test.ts +440 -0
- package/Tests/Server/Services/MessageQueueRegistries.test.ts +577 -0
- package/Tests/Server/Services/MessageQueueRuleEngines.test.ts +900 -0
- package/Tests/Server/Services/MessageQueueService.test.ts +2210 -0
- package/Tests/Server/Services/MessageQueueSqlPostgres.test.ts +1271 -0
- package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
- package/Tests/Server/Services/OpenTelemetryRetentionOverrideEdition.test.ts +474 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +21 -0
- package/Tests/Server/Services/OwnerRowUniqueness.test.ts +3 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +0 -1
- 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/RuleRun/LabelRuleEnginesGroupBRun.test.ts +56 -6
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -1
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +105 -0
- package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
- package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
- package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
- package/Tests/Server/Services/SsoRequirementReads.test.ts +454 -0
- package/Tests/Server/Services/SsoRequirementWrites.test.ts +529 -0
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +107 -89
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +1068 -176
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +1962 -200
- package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
- package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +654 -297
- package/Tests/Server/Types/Database/Permissions/RetentionOverrideColumns.test.ts +784 -0
- package/Tests/Server/Types/Database/Permissions/SsoScalePlanGate.test.ts +418 -0
- package/Tests/Server/Utils/AI/AIAlertGating.test.ts +0 -1
- package/Tests/Server/Utils/AI/AIInvestigationEngineRunLimits.test.ts +136 -0
- package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +15 -14
- package/Tests/Server/Utils/AI/AgentContextCompactor.test.ts +351 -0
- package/Tests/Server/Utils/AI/ChatAgentRunnerSharedThread.test.ts +842 -0
- package/Tests/Server/Utils/AI/ChatRunCancellation.test.ts +195 -0
- package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +10 -57
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +20 -24
- package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +7 -30
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +225 -29
- package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +694 -0
- package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
- package/Tests/Server/Utils/AI/InvestigationThread.test.ts +580 -0
- package/Tests/Server/Utils/AI/InvestigationThreadService.test.ts +801 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +525 -43
- package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +4 -2
- package/Tests/Server/Utils/AI/LLMServiceUnreachableProvider.test.ts +435 -0
- package/Tests/Server/Utils/AI/ObservabilityAssistantLimits.test.ts +462 -0
- package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
- package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +14 -25
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1251 -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 +1004 -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 +834 -0
- package/Tests/Server/Utils/AI/ToolOutputPager.test.ts +382 -0
- package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +23 -4
- package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +25 -6
- package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +14 -3
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
- package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
- package/Tests/Server/Utils/EditionEnforcement.test.ts +107 -147
- package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
- package/Tests/Server/Utils/{CommunityEditionSsoReport.test.ts → RelaxedScimTeamLocksReport.test.ts} +212 -208
- package/Tests/Server/Utils/SameOriginRequest.test.ts +372 -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/EntityRegistry.test.ts +20 -0
- package/Tests/Server/Utils/Telemetry/MessageQueueDiscovery.test.ts +2590 -0
- package/Tests/Server/Utils/Telemetry/MessageQueueSpanQueryTwin.ts +246 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +23 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +33 -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/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
- package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
- package/Tests/Types/AI/AIAgentRunLimits.test.ts +255 -0
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
- package/Tests/Types/Code/JsonSyntax.test.ts +1300 -0
- package/Tests/Types/CustomField/CustomFieldCreateSettings.test.ts +1113 -0
- package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +91 -0
- package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +30 -0
- package/Tests/Types/Incident/IncidentFormIpAllowlist.test.ts +227 -0
- package/Tests/Types/Incident/IncidentFormPublic.test.ts +1916 -0
- package/Tests/Types/MessageQueue/MessageQueueEntityKey.test.ts +916 -0
- package/Tests/Types/MessageQueue/MessageQueueIdentity.test.ts +567 -0
- package/Tests/Types/MessageQueue/MessageQueueManualIdentity.test.ts +686 -0
- package/Tests/Types/MessageQueue/MessageQueueMetricCatalog.test.ts +1726 -0
- package/Tests/Types/MessageQueue/MessageQueueMetricResolution.test.ts +1758 -0
- package/Tests/Types/MessageQueue/MessagingInstrumentationFixtures.test.ts +4686 -0
- package/Tests/Types/MessageQueue/MessagingSystem.test.ts +840 -0
- package/Tests/Types/MessageQueue/MessagingTelemetryFixtures.ts +3287 -0
- package/Tests/Types/MessageQueue/MessagingTelemetryResolver.test.ts +2966 -0
- package/Tests/Types/Monitor/MessageQueueAlertTemplates.test.ts +5401 -0
- package/Tests/Types/Monitor/MetricEngineFold.ts +154 -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 +519 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
- package/Tests/Types/Team/ComplianceRule.test.ts +588 -37
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +64 -11
- package/Tests/Types/XML.test.ts +51 -0
- package/Tests/UI/Components/CodeEditor/CodeEditor.test.tsx +2362 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorCommands.test.ts +810 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorHighlight.test.ts +338 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorLanguages.test.ts +222 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorStyles.test.ts +807 -0
- package/Tests/UI/Components/CodeEditor/NoMonaco.test.ts +245 -0
- package/Tests/UI/Components/CodeEditor/YamlEditor.test.tsx +729 -0
- package/Tests/UI/Components/CopyTextButton.test.tsx +76 -0
- package/Tests/UI/Components/EditionLabelLapseCopy.ts +51 -14
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +131 -23
- package/Tests/UI/Components/ErrorMessageAction.test.tsx +142 -0
- package/Tests/UI/Components/FacetSidebarInScope.test.tsx +459 -0
- package/Tests/UI/Components/FacetValuesInScope.test.ts +270 -0
- package/Tests/UI/Components/Forms/FormFieldCodeEditors.test.tsx +294 -0
- package/Tests/UI/Components/Forms/FormFieldMarkdown.test.tsx +126 -0
- package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +22 -75
- package/Tests/UI/Components/Forms/ModelFormOnBeforeCreateMiscData.test.tsx +254 -0
- package/Tests/UI/Components/Icon.test.tsx +32 -0
- package/Tests/UI/Components/Input.test.tsx +31 -0
- package/Tests/UI/Components/LockedFilterChipScope.test.tsx +501 -0
- package/Tests/UI/Components/MarkdownConverters.test.ts +253 -1
- package/Tests/UI/Components/MarkdownEditor.test.tsx +2785 -2
- package/Tests/UI/Components/MarkdownEditorHistory.test.ts +243 -0
- package/Tests/UI/Components/MarkdownListEditing.test.ts +1118 -0
- package/Tests/UI/Components/MarkdownPaste.test.ts +1180 -0
- package/Tests/UI/Components/MarkdownViewerCopy.test.tsx +466 -0
- package/Tests/UI/Components/MarkdownVisualEditing.test.ts +1089 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableEmptyStateAction.test.tsx +623 -0
- package/Tests/UI/Components/ResetObjectID.test.tsx +282 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
- package/Tests/UI/Components/Table/EmptyTableMessage.test.ts +439 -0
- package/Tests/UI/Components/Table/TableEmptyState.test.tsx +352 -0
- package/Tests/UI/Components/TableRowMobileTitles.test.tsx +78 -0
- package/Tests/UI/Components/TextArea.test.tsx +19 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +12 -29
- package/Tests/UI/Components/fixtures/MarkdownPasteFixtures.ts +460 -0
- package/Tests/UI/EsbuildConfig.test.ts +115 -39
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +4 -4
- package/Tests/UI/Monitor/MonitorLogSummaryRender.test.tsx +377 -0
- package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +81 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +17 -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/LabelRuleImportExport.test.ts +5 -0
- package/Tests/Utils/Markdown/DashboardMarkdownRenderer.ts +81 -0
- package/Tests/Utils/Markdown/UntrustedMarkdown.test.ts +1339 -0
- package/Tests/Utils/Monitor/MonitorLogSummaryUtil.test.ts +862 -0
- package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
- package/Types/AI/AIAgentRunLimits.ts +146 -0
- package/Types/AI/ResourceAiAccessApi.ts +140 -0
- package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +183 -2
- package/Types/Code/CodeType.ts +2 -0
- package/Types/Code/JsonSyntax.ts +923 -0
- package/Types/CustomField/CustomFieldCreateSettings.ts +549 -0
- package/Types/CustomField/CustomFieldMappingCatalog.ts +77 -0
- package/Types/CustomField/CustomFieldValueValidator.ts +10 -7
- package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +1 -1
- package/Types/Icon/IconProp.ts +2 -0
- package/Types/Incident/IncidentFormIpAllowlist.ts +206 -0
- package/Types/Incident/IncidentFormPublic.ts +1145 -0
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +10 -3
- package/Types/MessageQueue/MessageQueueIdentity.ts +256 -0
- package/Types/MessageQueue/MessageQueueManualIdentity.ts +325 -0
- package/Types/MessageQueue/MessageQueueMetricCatalog.ts +1357 -0
- package/Types/MessageQueue/MessagingSystem.ts +518 -0
- package/Types/MessageQueue/MessagingTelemetryResolver.ts +2311 -0
- package/Types/Monitor/MessageQueueAlertTemplates.ts +2128 -0
- 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/Permission.ts +310 -0
- package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
- package/Types/ResourceAiAgent/ResourceAiAccess.ts +580 -0
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
- package/Types/Rules/RuleRun.ts +4 -0
- package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
- package/Types/Runbook/RunbookStepType.ts +29 -0
- package/Types/Team/ComplianceNotificationChannel.ts +4 -3
- package/Types/Team/ComplianceRule.ts +71 -18
- package/Types/Team/ComplianceRuleType.ts +2 -2
- package/Types/Team/TeamComplianceStatus.ts +6 -2
- package/Types/Telemetry/EntityType.ts +16 -0
- package/Types/Telemetry/LockedFilterDetail.ts +22 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +14 -2
- package/Types/XML.ts +26 -0
- package/UI/Components/CodeEditor/CodeEditor.css +379 -0
- package/UI/Components/CodeEditor/CodeEditor.tsx +1128 -294
- package/UI/Components/CodeEditor/CodeEditorCommands.ts +774 -0
- package/UI/Components/CodeEditor/CodeEditorHighlight.ts +106 -0
- package/UI/Components/CodeEditor/CodeEditorLanguages.ts +164 -0
- package/UI/Components/CodeEditor/YamlEditor.tsx +28 -326
- package/UI/Components/CopyTextButton/CopyTextButton.tsx +5 -1
- package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +6 -25
- package/UI/Components/EditionLabel/EditionLabel.tsx +14 -13
- package/UI/Components/ErrorMessage/ErrorMessage.tsx +11 -1
- package/UI/Components/Forms/Fields/FormField.tsx +8 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/Icon/Icon.tsx +18 -0
- package/UI/Components/Input/Input.tsx +11 -4
- package/UI/Components/LogsViewer/LogsViewer.tsx +4 -0
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +21 -3
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +877 -79
- package/UI/Components/Markdown.tsx/MarkdownEditorHistory.ts +284 -0
- package/UI/Components/Markdown.tsx/MarkdownListEditing.ts +1362 -0
- package/UI/Components/Markdown.tsx/MarkdownPaste.ts +1326 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +106 -10
- package/UI/Components/Markdown.tsx/MarkdownVisualEditing.ts +1032 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +85 -7
- package/UI/Components/ResetObjectID/ResetObjectID.tsx +35 -9
- package/UI/Components/Table/EmptyTableMessage.ts +81 -0
- package/UI/Components/Table/Table.tsx +50 -21
- package/UI/Components/Table/TableRow.tsx +9 -1
- package/UI/Components/TelemetryViewer/FacetVisibility.ts +97 -2
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +13 -0
- package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +214 -7
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +21 -3
- package/UI/Components/TextArea/TextArea.tsx +9 -2
- package/UI/Components/Workflow/ModelFieldPicker.tsx +10 -12
- package/UI/Styles/Theme.css +8 -0
- package/UI/esbuild-config.js +2 -32
- package/Utils/AI/InvestigationReport.ts +121 -15
- 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/LabelRuleImportExport.ts +2 -0
- package/Utils/Markdown/UntrustedMarkdown.ts +1513 -0
- package/Utils/Monitor/IncomingEmailMonitorRequestUtil.ts +41 -0
- package/Utils/Monitor/MonitorLogSummaryUtil.ts +212 -0
- package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
- package/Utils/Telemetry/EntityKey.ts +48 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js +125 -1
- package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
- 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 +231 -0
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResource.js +12 -0
- package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseServer.js +231 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +231 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +231 -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/GlobalOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +231 -0
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentForm.js +605 -0
- package/build/dist/Models/DatabaseModels/IncidentForm.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js +299 -0
- package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js +60 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +16 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js +12 -0
- package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +12 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MessageQueue.js +1106 -0
- package/build/dist/Models/DatabaseModels/MessageQueue.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js +562 -0
- package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js +643 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js +506 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js +505 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js +231 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +61 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/ProjectOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectSso.js +0 -4
- package/build/dist/Models/DatabaseModels/ProjectSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +231 -0
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.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/RumApplication.js +12 -0
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +145 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServerlessFunction.js +12 -0
- package/build/dist/Models/DatabaseModels/ServerlessFunction.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Service.js +12 -0
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSso.js +0 -4
- package/build/dist/Models/DatabaseModels/StatusPageSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +49 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js +231 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +9 -103
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +3 -3
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationConversationAPI.js +162 -0
- package/build/dist/Server/API/AIInvestigationConversationAPI.js.map +1 -0
- package/build/dist/Server/API/AutoRemediationAPI.js +231 -1
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentFormAPI.js +245 -0
- package/build/dist/Server/API/IncidentFormAPI.js.map +1 -0
- package/build/dist/Server/API/ProjectOIDC.js +16 -24
- package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
- package/build/dist/Server/API/ProjectSSO.js +16 -24
- package/build/dist/Server/API/ProjectSSO.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/API/StatusPageAPI.js +42 -75
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseEdition.js +79 -25
- package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseFeature.js +24 -3
- package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +1 -1
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +1 -1
- 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/1796400000000-AddIncidentForms.js +63 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js +41 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js +183 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -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/IncidentFormRateLimit.js +559 -0
- package/build/dist/Server/Middleware/IncidentFormRateLimit.js.map +1 -0
- package/build/dist/Server/Middleware/TelemetryIngest.js +12 -5
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +11 -30
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +10 -13
- package/build/dist/Server/Services/AIService.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/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/IncidentCustomFieldService.js +83 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +10 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentFormService.js +1202 -0
- package/build/dist/Server/Services/IncidentFormService.js.map +1 -0
- package/build/dist/Server/Services/IncidentFormSubmissionService.js +91 -0
- package/build/dist/Server/Services/IncidentFormSubmissionService.js.map +1 -0
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +20 -8
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +106 -4
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +18 -0
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +14 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js +262 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleService.js +13 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js +334 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerTeamService.js +62 -0
- package/build/dist/Server/Services/MessageQueueOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerUserService.js +62 -0
- package/build/dist/Server/Services/MessageQueueOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueService.js +1140 -0
- package/build/dist/Server/Services/MessageQueueService.js.map +1 -0
- package/build/dist/Server/Services/MetricRecordingRuleService.js +46 -0
- package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +25 -4
- package/build/dist/Server/Services/OpenTelemetryIngestService.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 +0 -54
- 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/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 +344 -5
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -4
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +0 -46
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +120 -31
- 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/UserNotificationRuleService.js +8 -1
- package/build/dist/Server/Services/UserNotificationRuleService.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/Services/WorkspaceNotificationSummaryService.js +12 -3
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +6 -3
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +109 -37
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +16 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +3 -3
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +9 -6
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js +128 -0
- package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +192 -50
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js +133 -0
- package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +53 -13
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
- package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js +206 -0
- package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +53 -26
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +4 -2
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +1 -29
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +24 -24
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1036 -32
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +661 -41
- 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 +354 -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 +602 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +90 -14
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +73 -10
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +73 -10
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +15 -18
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js +412 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js +495 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +10 -3
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +290 -13
- 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/EditionEnforcement.js +20 -158
- package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +193 -54
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js +160 -0
- package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
- package/build/dist/Server/Utils/SameOriginRequest.js +151 -0
- package/build/dist/Server/Utils/SameOriginRequest.js.map +1 -0
- 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/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +4 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +1015 -0
- package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +4 -1
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +3 -3
- 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 +186 -210
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +22 -16
- 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 +273 -111
- 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/AIAgentRunLimits.js +91 -0
- package/build/dist/Types/AI/AIAgentRunLimits.js.map +1 -0
- 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 +116 -29
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/Code/CodeType.js +2 -0
- package/build/dist/Types/Code/CodeType.js.map +1 -1
- package/build/dist/Types/Code/JsonSyntax.js +604 -0
- package/build/dist/Types/Code/JsonSyntax.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldCreateSettings.js +310 -0
- package/build/dist/Types/CustomField/CustomFieldCreateSettings.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +38 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js +10 -7
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +1 -1
- package/build/dist/Types/Icon/IconProp.js +2 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/Incident/IncidentFormIpAllowlist.js +119 -0
- package/build/dist/Types/Incident/IncidentFormIpAllowlist.js.map +1 -0
- package/build/dist/Types/Incident/IncidentFormPublic.js +678 -0
- package/build/dist/Types/Incident/IncidentFormPublic.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +10 -3
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/MessageQueue/MessageQueueIdentity.js +184 -0
- package/build/dist/Types/MessageQueue/MessageQueueIdentity.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js +190 -0
- package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js +1057 -0
- package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessagingSystem.js +394 -0
- package/build/dist/Types/MessageQueue/MessagingSystem.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js +1768 -0
- package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js.map +1 -0
- package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js +1207 -0
- package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js.map +1 -0
- 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/Permission.js +274 -0
- package/build/dist/Types/Permission.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 +281 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +12 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rules/RuleRun.js +4 -0
- package/build/dist/Types/Rules/RuleRun.js.map +1 -1
- 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 +4 -3
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -1
- package/build/dist/Types/Team/ComplianceRule.js +48 -14
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -1
- package/build/dist/Types/Team/ComplianceRuleType.js +2 -2
- package/build/dist/Types/Telemetry/EntityType.js +16 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +13 -2
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/Types/XML.js +23 -0
- package/build/dist/Types/XML.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +641 -266
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js +464 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js +69 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js +108 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js +14 -186
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +5 -14
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +14 -13
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +1 -1
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +8 -3
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +8 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +11 -3
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +2 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +14 -4
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +710 -65
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js +238 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js +1028 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js +1088 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +70 -10
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js +887 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +57 -6
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js +7 -5
- package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js.map +1 -1
- package/build/dist/UI/Components/Table/EmptyTableMessage.js +51 -0
- package/build/dist/UI/Components/Table/EmptyTableMessage.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +30 -11
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +9 -2
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +63 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +4 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +91 -10
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +14 -4
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js +9 -3
- package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ModelFieldPicker.js +1 -2
- package/build/dist/UI/Components/Workflow/ModelFieldPicker.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/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/LabelRuleImportExport.js +2 -0
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/Markdown/UntrustedMarkdown.js +988 -0
- package/build/dist/Utils/Markdown/UntrustedMarkdown.js.map +1 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js +34 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js +148 -0
- package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js.map +1 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +36 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/package.json +1 -3
- package/Server/Utils/CommunityEditionSsoReport.ts +0 -361
- package/Tests/App/Accounts/LoginSsoEdition.test.tsx +0 -616
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +0 -217
- package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +0 -271
- package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +0 -215
- package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +0 -784
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +0 -518
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +0 -419
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +0 -769
- package/Tests/UI/Components/CodeEditor.test.tsx +0 -638
- package/Tests/UI/Components/MonacoLoader.test.ts +0 -67
- package/Tests/UI/Components/MonacoRuntime.test.ts +0 -121
- package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +0 -329
- package/Tests/UI/Components/YamlEditor.test.tsx +0 -847
- package/UI/Components/CodeEditor/MonacoLoader.ts +0 -36
- package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +0 -319
- package/UI/Components/Telemetry/TelemetryRetentionConfigSummary.tsx +0 -223
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js +0 -223
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +0 -1
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +0 -34
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +0 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +0 -171
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +0 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js +0 -119
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js.map +0 -1
|
@@ -0,0 +1,1653 @@
|
|
|
1
|
+
import CephCommandPolicy, {
|
|
2
|
+
CEPH_CLUSTER_TARGET,
|
|
3
|
+
CEPH_COMMANDS,
|
|
4
|
+
CEPH_CRASH_TARGET_PREFIX,
|
|
5
|
+
CEPH_OSD_FLAGS,
|
|
6
|
+
CEPH_OUTPUT_FORMATS,
|
|
7
|
+
} from "../../../../Utils/AiRemediation/Resource/CephCommandPolicy";
|
|
8
|
+
import ResourceCommandPolicy from "../../../../Utils/AiRemediation/Resource/ResourceCommandPolicy";
|
|
9
|
+
import {
|
|
10
|
+
ResourceAutoExecutionVerdict,
|
|
11
|
+
ResourceCommandPolicyResult,
|
|
12
|
+
ResourceTokenizeResult,
|
|
13
|
+
tokenizeResourceCommand,
|
|
14
|
+
} from "../../../../Utils/AiRemediation/Resource/ResourceCommandPolicyCore";
|
|
15
|
+
import {
|
|
16
|
+
ResourceOutputRedaction,
|
|
17
|
+
ResourceOutputRedactionHook,
|
|
18
|
+
getResourceOutputRedactionHooks,
|
|
19
|
+
redactResourceCommandOutput,
|
|
20
|
+
redactResourceCommandOutputWithCount,
|
|
21
|
+
} from "../../../../Utils/AiRemediation/Resource/ResourceOutputRedactor";
|
|
22
|
+
import AiResourceType, {
|
|
23
|
+
AI_RESOURCE_TYPE_INFO,
|
|
24
|
+
} from "../../../../Types/ResourceAiAgent/AiResourceType";
|
|
25
|
+
import {
|
|
26
|
+
RESOURCE_AI_ALLOW_WRITES_ENV,
|
|
27
|
+
RESOURCE_AI_WRITE_TARGETS_ENV,
|
|
28
|
+
ResourceCommandTier,
|
|
29
|
+
} from "../../../../Types/ResourceAiAgent/ResourceAiAccess";
|
|
30
|
+
import { AiRemediationCommandPolicyVerdict } from "../../../../Types/AutoRemediation/AiRemediationCommandPolicyVerdict";
|
|
31
|
+
import { describe, expect, test } from "@jest/globals";
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* Contract under test — the ceph command policy (CephCommandPolicy), the
|
|
35
|
+
* tool policy the dispatcher hands every command for a Ceph cluster.
|
|
36
|
+
*
|
|
37
|
+
* - Grammar: an allowlist of exact command words with validated arguments
|
|
38
|
+
* (OSD ids 3 / osd.3, pool names, PG ids, daemon names, crash ids); every
|
|
39
|
+
* Read command, every SafeWrite, RiskyWrite and requiresHuman change, and
|
|
40
|
+
* Denied for everything else, with a reason that says what may run.
|
|
41
|
+
* - Options, read the way ceph's argparse reads them: only --format /
|
|
42
|
+
* --format= / -f with json|json-pretty|plain (once, anywhere), -s alone,
|
|
43
|
+
* and orch ps's named arguments after "orch ps". Every other
|
|
44
|
+
* dash-prefixed word is Denied, so abbreviations, combined short options,
|
|
45
|
+
* configuration overrides, `--` and flags after positionals never hide.
|
|
46
|
+
* - Targets are canonical (osd.N, daemon names, pools, PG ids,
|
|
47
|
+
* crash/<id>, "cluster") and the displayCommand round-trips.
|
|
48
|
+
* - Total: nothing it is given makes it throw.
|
|
49
|
+
* - Dispatcher integration for AiResourceType.CephCluster: evaluateCommand,
|
|
50
|
+
* evaluateForAutoExecution, matchesAllowlist,
|
|
51
|
+
* describeAllowlistPatternProblem, isBroadAllowlistPattern,
|
|
52
|
+
* getWriteScopeRefusal and the command guides.
|
|
53
|
+
* - The ceph output redaction hooks: keyring keys, bare cephx secrets and
|
|
54
|
+
* audit-log config values.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
const CEPH: AiResourceType = AiResourceType.CephCluster;
|
|
58
|
+
|
|
59
|
+
const CRASH_ID: string =
|
|
60
|
+
"2024-05-21T10:15:42.123456Z_0c7d3c6e-1b2a-4c3d-9e8f-0123456789ab";
|
|
61
|
+
|
|
62
|
+
const NAUTILUS_CRASH_ID: string =
|
|
63
|
+
"2019-07-09_17:42:37.469390Z_0c7d3c6e-1b2a-4c3d-9e8f-0123456789ab";
|
|
64
|
+
|
|
65
|
+
const CEPHX_SECRET: string = "AQBv5pRkAAAAABAAIbnP0fYNy9LQYUcxJXAtdA==";
|
|
66
|
+
|
|
67
|
+
function evaluate(command: string): ResourceCommandPolicyResult {
|
|
68
|
+
return ResourceCommandPolicy.evaluateCommand({
|
|
69
|
+
resourceType: CEPH,
|
|
70
|
+
command,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function argvOf(command: string): Array<string> {
|
|
75
|
+
const tokenized: ResourceTokenizeResult = tokenizeResourceCommand(command);
|
|
76
|
+
|
|
77
|
+
if (!tokenized.argv) {
|
|
78
|
+
throw new Error(`test command does not tokenize: ${command}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return tokenized.argv;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function expectDenied(
|
|
85
|
+
result: ResourceCommandPolicyResult,
|
|
86
|
+
reasonPart: string,
|
|
87
|
+
): void {
|
|
88
|
+
expect(result.tier).toBe(ResourceCommandTier.Denied);
|
|
89
|
+
expect(result.targets).toEqual([]);
|
|
90
|
+
expect(result.requiresHuman).toBeUndefined();
|
|
91
|
+
expect(result.reason).toContain(reasonPart);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function expectRoundTrip(
|
|
95
|
+
command: string,
|
|
96
|
+
result: ResourceCommandPolicyResult,
|
|
97
|
+
): void {
|
|
98
|
+
const argv: Array<string> = argvOf(command);
|
|
99
|
+
|
|
100
|
+
expect(result.program).toBe("ceph");
|
|
101
|
+
expect(result.args).toEqual(argv.slice(1));
|
|
102
|
+
expect(tokenizeResourceCommand(result.displayCommand).argv).toEqual(argv);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ---- Module shape -------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
describe("the ceph tool policy", () => {
|
|
108
|
+
test("is named ceph, runs only the ceph program and is what the dispatcher uses", () => {
|
|
109
|
+
expect(CephCommandPolicy.name).toBe("ceph");
|
|
110
|
+
expect([...CephCommandPolicy.programs]).toEqual(["ceph"]);
|
|
111
|
+
expect([...CephCommandPolicy.programs]).toEqual([
|
|
112
|
+
...AI_RESOURCE_TYPE_INFO[CEPH].programs,
|
|
113
|
+
]);
|
|
114
|
+
expect(ResourceCommandPolicy.getToolPolicy(CEPH)).toBe(CephCommandPolicy);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("is no longer the fail-closed stub", () => {
|
|
118
|
+
expect(CephCommandPolicy.evaluateArgv(["ceph"]).reason).not.toContain(
|
|
119
|
+
"not implemented yet",
|
|
120
|
+
);
|
|
121
|
+
expect(CephCommandPolicy.readCommandGuide).not.toContain("Unavailable");
|
|
122
|
+
expect(CephCommandPolicy.writeCommandGuide).not.toContain("Unavailable");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("pins the exported vocabularies", () => {
|
|
126
|
+
expect(CEPH_CLUSTER_TARGET).toBe("cluster");
|
|
127
|
+
expect(CEPH_CRASH_TARGET_PREFIX).toBe("crash/");
|
|
128
|
+
expect([...CEPH_OUTPUT_FORMATS]).toEqual(["json", "json-pretty", "plain"]);
|
|
129
|
+
expect([...CEPH_OSD_FLAGS]).toEqual([
|
|
130
|
+
"noout",
|
|
131
|
+
"norebalance",
|
|
132
|
+
"nobackfill",
|
|
133
|
+
"norecover",
|
|
134
|
+
"noscrub",
|
|
135
|
+
"nodeep-scrub",
|
|
136
|
+
"pause",
|
|
137
|
+
]);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test("no command's words are a prefix of another's", () => {
|
|
141
|
+
for (const left of CEPH_COMMANDS) {
|
|
142
|
+
for (const right of CEPH_COMMANDS) {
|
|
143
|
+
if (left !== right) {
|
|
144
|
+
expect(right.startsWith(`${left} `)).toBe(false);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
expect(new Set<string>(CEPH_COMMANDS).size).toBe(CEPH_COMMANDS.length);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// ---- Reads --------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
const READ_COMMANDS: Array<[string, string]> = [
|
|
156
|
+
["ceph status", "status"],
|
|
157
|
+
["ceph -s", "status"],
|
|
158
|
+
["ceph health", "health"],
|
|
159
|
+
["ceph health detail", "health"],
|
|
160
|
+
["ceph df", "df"],
|
|
161
|
+
["ceph df detail", "df"],
|
|
162
|
+
["ceph versions", "versions"],
|
|
163
|
+
["ceph version", "version"],
|
|
164
|
+
["ceph progress", "progress"],
|
|
165
|
+
["ceph quorum_status", "quorum_status"],
|
|
166
|
+
["ceph log last", "log last"],
|
|
167
|
+
["ceph log last 100", "log last"],
|
|
168
|
+
["ceph log last 1000 warn", "log last"],
|
|
169
|
+
["ceph log last 50 error cluster", "log last"],
|
|
170
|
+
["ceph log last warn audit", "log last"],
|
|
171
|
+
["ceph log last cephadm", "log last"],
|
|
172
|
+
["ceph log last 20 debug '*'", "log last"],
|
|
173
|
+
["ceph log last 1 sec", "log last"],
|
|
174
|
+
["ceph log last info", "log last"],
|
|
175
|
+
["ceph osd tree", "osd tree"],
|
|
176
|
+
["ceph osd tree down", "osd tree"],
|
|
177
|
+
["ceph osd tree up in", "osd tree"],
|
|
178
|
+
["ceph osd tree out destroyed", "osd tree"],
|
|
179
|
+
["ceph osd df", "osd df"],
|
|
180
|
+
["ceph osd df tree", "osd df"],
|
|
181
|
+
["ceph osd perf", "osd perf"],
|
|
182
|
+
["ceph osd stat", "osd stat"],
|
|
183
|
+
["ceph osd dump", "osd dump"],
|
|
184
|
+
["ceph osd blocked-by", "osd blocked-by"],
|
|
185
|
+
["ceph osd find 3", "osd find"],
|
|
186
|
+
["ceph osd find osd.12", "osd find"],
|
|
187
|
+
["ceph osd metadata", "osd metadata"],
|
|
188
|
+
["ceph osd metadata 0", "osd metadata"],
|
|
189
|
+
["ceph osd metadata osd.7", "osd metadata"],
|
|
190
|
+
["ceph osd ok-to-stop 3", "osd ok-to-stop"],
|
|
191
|
+
["ceph osd ok-to-stop 3 4 osd.5", "osd ok-to-stop"],
|
|
192
|
+
["ceph osd safe-to-destroy osd.9", "osd safe-to-destroy"],
|
|
193
|
+
["ceph osd safe-to-destroy 1 2", "osd safe-to-destroy"],
|
|
194
|
+
["ceph osd pool ls", "osd pool ls"],
|
|
195
|
+
["ceph osd pool ls detail", "osd pool ls"],
|
|
196
|
+
["ceph osd pool stats", "osd pool stats"],
|
|
197
|
+
["ceph osd pool stats rbd", "osd pool stats"],
|
|
198
|
+
["ceph osd pool stats .mgr", "osd pool stats"],
|
|
199
|
+
["ceph osd pool get rbd size", "osd pool get"],
|
|
200
|
+
["ceph osd pool get rbd all", "osd pool get"],
|
|
201
|
+
["ceph osd pool get .rgw.root pg_num", "osd pool get"],
|
|
202
|
+
["ceph osd pool get cephfs_data nodeep-scrub", "osd pool get"],
|
|
203
|
+
["ceph pg stat", "pg stat"],
|
|
204
|
+
["ceph pg dump_stuck", "pg dump_stuck"],
|
|
205
|
+
["ceph pg dump_stuck inactive", "pg dump_stuck"],
|
|
206
|
+
["ceph pg dump_stuck unclean stale undersized degraded", "pg dump_stuck"],
|
|
207
|
+
["ceph pg dump_stuck stale 300", "pg dump_stuck"],
|
|
208
|
+
["ceph pg dump_stuck 60", "pg dump_stuck"],
|
|
209
|
+
["ceph pg 1.2f query", "pg query"],
|
|
210
|
+
["ceph pg 0.0 query", "pg query"],
|
|
211
|
+
["ceph pg 12.a3 list_unfound", "pg list_unfound"],
|
|
212
|
+
["ceph pg ls-by-osd 3", "pg ls-by-osd"],
|
|
213
|
+
["ceph pg ls-by-osd osd.3", "pg ls-by-osd"],
|
|
214
|
+
["ceph pg ls-by-pool rbd", "pg ls-by-pool"],
|
|
215
|
+
["ceph pg ls-by-primary osd.0", "pg ls-by-primary"],
|
|
216
|
+
["ceph mon stat", "mon stat"],
|
|
217
|
+
["ceph mon dump", "mon dump"],
|
|
218
|
+
["ceph mgr stat", "mgr stat"],
|
|
219
|
+
["ceph mgr services", "mgr services"],
|
|
220
|
+
["ceph mgr module ls", "mgr module ls"],
|
|
221
|
+
["ceph fs status", "fs status"],
|
|
222
|
+
["ceph fs status cephfs", "fs status"],
|
|
223
|
+
["ceph fs ls", "fs ls"],
|
|
224
|
+
["ceph mds stat", "mds stat"],
|
|
225
|
+
["ceph balancer status", "balancer status"],
|
|
226
|
+
["ceph crash ls", "crash ls"],
|
|
227
|
+
["ceph crash ls-new", "crash ls-new"],
|
|
228
|
+
["ceph crash stat", "crash stat"],
|
|
229
|
+
[`ceph crash info ${CRASH_ID}`, "crash info"],
|
|
230
|
+
[`ceph crash info ${NAUTILUS_CRASH_ID}`, "crash info"],
|
|
231
|
+
["ceph orch ps", "orch ps"],
|
|
232
|
+
["ceph orch ps --daemon_type osd", "orch ps"],
|
|
233
|
+
["ceph orch ps --daemon-type node-exporter", "orch ps"],
|
|
234
|
+
["ceph orch ps --service_name osd.all-available-devices", "orch ps"],
|
|
235
|
+
["ceph orch ps --service-name rgw.store --refresh", "orch ps"],
|
|
236
|
+
["ceph orch ps --refresh --daemon_type mon --service_name mon", "orch ps"],
|
|
237
|
+
["ceph orch ls", "orch ls"],
|
|
238
|
+
["ceph orch host ls", "orch host ls"],
|
|
239
|
+
["ceph orch device ls", "orch device ls"],
|
|
240
|
+
];
|
|
241
|
+
|
|
242
|
+
describe("Read commands", () => {
|
|
243
|
+
test.each(READ_COMMANDS)(
|
|
244
|
+
"%s is Read (%s)",
|
|
245
|
+
(command: string, verb: string) => {
|
|
246
|
+
const result: ResourceCommandPolicyResult = evaluate(command);
|
|
247
|
+
|
|
248
|
+
expect(result.tier).toBe(ResourceCommandTier.Read);
|
|
249
|
+
expect(result.verb).toBe(verb);
|
|
250
|
+
expect(result.targets).toEqual([]);
|
|
251
|
+
expect(result.requiresHuman).toBeUndefined();
|
|
252
|
+
expect(result.reason.length).toBeGreaterThan(0);
|
|
253
|
+
expectRoundTrip(command, result);
|
|
254
|
+
expect(
|
|
255
|
+
ResourceCommandPolicy.isReadOnly({ resourceType: CEPH, command }),
|
|
256
|
+
).toBe(true);
|
|
257
|
+
},
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
test("every Test connection command is a read", () => {
|
|
261
|
+
for (const command of AI_RESOURCE_TYPE_INFO[CEPH].testCommands) {
|
|
262
|
+
expect(evaluate(command).tier).toBe(ResourceCommandTier.Read);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
test.each([
|
|
267
|
+
["ceph status --format json", "status"],
|
|
268
|
+
["ceph status --format=json-pretty", "status"],
|
|
269
|
+
["ceph status -f plain", "status"],
|
|
270
|
+
["ceph --format json status", "status"],
|
|
271
|
+
["ceph -f json-pretty osd tree", "osd tree"],
|
|
272
|
+
["ceph osd -f json tree", "osd tree"],
|
|
273
|
+
["ceph osd tree down -f json", "osd tree"],
|
|
274
|
+
["ceph -s --format json", "status"],
|
|
275
|
+
["ceph --format=plain -s", "status"],
|
|
276
|
+
["ceph orch ps --daemon_type osd -f json", "orch ps"],
|
|
277
|
+
["ceph orch ps -f json --daemon_type osd", "orch ps"],
|
|
278
|
+
["ceph orch ps --daemon_type -f json osd", "orch ps"],
|
|
279
|
+
["ceph pg 1.2f query --format json", "pg query"],
|
|
280
|
+
["ceph log last 10 --format=json", "log last"],
|
|
281
|
+
["ceph health detail -f json-pretty", "health"],
|
|
282
|
+
])(
|
|
283
|
+
"%s: the output format is read wherever argparse reads it",
|
|
284
|
+
(command: string, verb: string) => {
|
|
285
|
+
const result: ResourceCommandPolicyResult = evaluate(command);
|
|
286
|
+
|
|
287
|
+
expect(result.tier).toBe(ResourceCommandTier.Read);
|
|
288
|
+
expect(result.verb).toBe(verb);
|
|
289
|
+
expectRoundTrip(command, result);
|
|
290
|
+
},
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
test("the log channel * is kept as one quoted word", () => {
|
|
294
|
+
const result: ResourceCommandPolicyResult = evaluate(
|
|
295
|
+
"ceph log last 20 warn '*'",
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
expect(result.args).toEqual(["log", "last", "20", "warn", "*"]);
|
|
299
|
+
expect(result.displayCommand).toBe("ceph log last 20 warn '*'");
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
test("a pool name may be 128 characters long, not 129", () => {
|
|
303
|
+
const longest: string = `p${"o".repeat(127)}`;
|
|
304
|
+
|
|
305
|
+
expect(evaluate(`ceph osd pool stats ${longest}`).tier).toBe(
|
|
306
|
+
ResourceCommandTier.Read,
|
|
307
|
+
);
|
|
308
|
+
expectDenied(
|
|
309
|
+
evaluate(`ceph osd pool stats ${longest}o`),
|
|
310
|
+
"is not a pool name",
|
|
311
|
+
);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
test("ok-to-stop may name 32 OSDs, not 33", () => {
|
|
315
|
+
const ids: Array<string> = Array.from(
|
|
316
|
+
{ length: 33 },
|
|
317
|
+
(_value: unknown, index: number): string => {
|
|
318
|
+
return String(index);
|
|
319
|
+
},
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
expect(
|
|
323
|
+
evaluate(`ceph osd ok-to-stop ${ids.slice(0, 32).join(" ")}`).tier,
|
|
324
|
+
).toBe(ResourceCommandTier.Read);
|
|
325
|
+
expectDenied(
|
|
326
|
+
evaluate(`ceph osd ok-to-stop ${ids.join(" ")}`),
|
|
327
|
+
"at most 32 OSDs",
|
|
328
|
+
);
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// ---- Writes -------------------------------------------------------------------
|
|
333
|
+
|
|
334
|
+
const SAFE_WRITES: Array<[string, string, Array<string>]> = [
|
|
335
|
+
["ceph osd in 3", "osd in", ["osd.3"]],
|
|
336
|
+
["ceph osd in osd.12", "osd in", ["osd.12"]],
|
|
337
|
+
["ceph osd in 0", "osd in", ["osd.0"]],
|
|
338
|
+
["ceph osd in 3 --format json", "osd in", ["osd.3"]],
|
|
339
|
+
...CEPH_OSD_FLAGS.map((flag: string): [string, string, Array<string>] => {
|
|
340
|
+
return [`ceph osd unset ${flag}`, "osd unset", ["cluster"]];
|
|
341
|
+
}),
|
|
342
|
+
[`ceph crash archive ${CRASH_ID}`, "crash archive", [`crash/${CRASH_ID}`]],
|
|
343
|
+
["ceph orch daemon restart osd.3", "orch daemon restart", ["osd.3"]],
|
|
344
|
+
["ceph orch daemon restart mon.host1", "orch daemon restart", ["mon.host1"]],
|
|
345
|
+
[
|
|
346
|
+
"ceph orch daemon restart rgw.store.host1.abcdef",
|
|
347
|
+
"orch daemon restart",
|
|
348
|
+
["rgw.store.host1.abcdef"],
|
|
349
|
+
],
|
|
350
|
+
[
|
|
351
|
+
"ceph orch daemon restart node-exporter.host1",
|
|
352
|
+
"orch daemon restart",
|
|
353
|
+
["node-exporter.host1"],
|
|
354
|
+
],
|
|
355
|
+
["ceph pg scrub 1.2f", "pg scrub", ["1.2f"]],
|
|
356
|
+
["ceph pg deep-scrub 3.0", "pg deep-scrub", ["3.0"]],
|
|
357
|
+
["ceph pg deep-scrub 10.ffffffff", "pg deep-scrub", ["10.ffffffff"]],
|
|
358
|
+
];
|
|
359
|
+
|
|
360
|
+
const RISKY_WRITES: Array<[string, string, Array<string>]> = [
|
|
361
|
+
["ceph osd out 3", "osd out", ["osd.3"]],
|
|
362
|
+
["ceph osd out osd.3", "osd out", ["osd.3"]],
|
|
363
|
+
["ceph osd down 7", "osd down", ["osd.7"]],
|
|
364
|
+
["ceph osd down osd.7", "osd down", ["osd.7"]],
|
|
365
|
+
...CEPH_OSD_FLAGS.filter((flag: string): boolean => {
|
|
366
|
+
return flag !== "pause";
|
|
367
|
+
}).map((flag: string): [string, string, Array<string>] => {
|
|
368
|
+
return [`ceph osd set ${flag}`, "osd set", ["cluster"]];
|
|
369
|
+
}),
|
|
370
|
+
["ceph osd reweight 3 0.85", "osd reweight", ["osd.3"]],
|
|
371
|
+
["ceph osd reweight osd.3 0", "osd reweight", ["osd.3"]],
|
|
372
|
+
["ceph osd reweight 3 1", "osd reweight", ["osd.3"]],
|
|
373
|
+
["ceph osd reweight 3 1.0", "osd reweight", ["osd.3"]],
|
|
374
|
+
["ceph osd reweight 3 0.0001", "osd reweight", ["osd.3"]],
|
|
375
|
+
["ceph pg repair 1.2f", "pg repair", ["1.2f"]],
|
|
376
|
+
["ceph mgr fail", "mgr fail", ["cluster"]],
|
|
377
|
+
["ceph mgr fail host1.abcdef", "mgr fail", ["mgr.host1.abcdef"]],
|
|
378
|
+
["ceph orch daemon stop osd.3", "orch daemon stop", ["osd.3"]],
|
|
379
|
+
[
|
|
380
|
+
"ceph orch daemon start mds.cephfs.host1.xyz",
|
|
381
|
+
"orch daemon start",
|
|
382
|
+
["mds.cephfs.host1.xyz"],
|
|
383
|
+
],
|
|
384
|
+
["ceph orch restart mgr", "orch restart", ["mgr"]],
|
|
385
|
+
[
|
|
386
|
+
"ceph orch restart osd.all-available-devices",
|
|
387
|
+
"orch restart",
|
|
388
|
+
["osd.all-available-devices"],
|
|
389
|
+
],
|
|
390
|
+
["ceph orch restart rgw.store", "orch restart", ["rgw.store"]],
|
|
391
|
+
["ceph crash archive-all", "crash archive-all", ["cluster"]],
|
|
392
|
+
["ceph balancer on", "balancer on", ["cluster"]],
|
|
393
|
+
["ceph balancer off", "balancer off", ["cluster"]],
|
|
394
|
+
];
|
|
395
|
+
|
|
396
|
+
const ALWAYS_HUMAN_WRITES: Array<[string, string, Array<string>]> = [
|
|
397
|
+
["ceph osd set pause", "osd set", ["cluster"]],
|
|
398
|
+
["ceph osd pool set rbd size 3", "osd pool set", ["rbd"]],
|
|
399
|
+
["ceph osd pool set rbd min_size 2", "osd pool set", ["rbd"]],
|
|
400
|
+
["ceph osd pool set .mgr size 1", "osd pool set", [".mgr"]],
|
|
401
|
+
["ceph osd pool set rbd size 10", "osd pool set", ["rbd"]],
|
|
402
|
+
];
|
|
403
|
+
|
|
404
|
+
describe("SafeWrite: a reversible change to one named object", () => {
|
|
405
|
+
test.each(SAFE_WRITES)(
|
|
406
|
+
"%s is SafeWrite (%s)",
|
|
407
|
+
(command: string, verb: string, targets: Array<string>) => {
|
|
408
|
+
const result: ResourceCommandPolicyResult = evaluate(command);
|
|
409
|
+
|
|
410
|
+
expect(result.tier).toBe(ResourceCommandTier.SafeWrite);
|
|
411
|
+
expect(result.verb).toBe(verb);
|
|
412
|
+
expect(result.targets).toEqual(targets);
|
|
413
|
+
expect(result.requiresHuman).toBeUndefined();
|
|
414
|
+
expectRoundTrip(command, result);
|
|
415
|
+
expect(
|
|
416
|
+
ResourceCommandPolicy.isReadOnly({ resourceType: CEPH, command }),
|
|
417
|
+
).toBe(false);
|
|
418
|
+
},
|
|
419
|
+
);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
describe("RiskyWrite: a human, the allowlist or Bypass approval decides", () => {
|
|
423
|
+
test.each(RISKY_WRITES)(
|
|
424
|
+
"%s is RiskyWrite (%s)",
|
|
425
|
+
(command: string, verb: string, targets: Array<string>) => {
|
|
426
|
+
const result: ResourceCommandPolicyResult = evaluate(command);
|
|
427
|
+
|
|
428
|
+
expect(result.tier).toBe(ResourceCommandTier.RiskyWrite);
|
|
429
|
+
expect(result.verb).toBe(verb);
|
|
430
|
+
expect(result.targets).toEqual(targets);
|
|
431
|
+
expect(result.requiresHuman).toBeUndefined();
|
|
432
|
+
expectRoundTrip(command, result);
|
|
433
|
+
},
|
|
434
|
+
);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
describe("requiresHuman: never unattended", () => {
|
|
438
|
+
test.each(ALWAYS_HUMAN_WRITES)(
|
|
439
|
+
"%s is RiskyWrite that always asks a human (%s)",
|
|
440
|
+
(command: string, verb: string, targets: Array<string>) => {
|
|
441
|
+
const result: ResourceCommandPolicyResult = evaluate(command);
|
|
442
|
+
|
|
443
|
+
expect(result.tier).toBe(ResourceCommandTier.RiskyWrite);
|
|
444
|
+
expect(result.verb).toBe(verb);
|
|
445
|
+
expect(result.targets).toEqual(targets);
|
|
446
|
+
expect(result.requiresHuman).toBe(true);
|
|
447
|
+
expectRoundTrip(command, result);
|
|
448
|
+
},
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
test("the reasons say what the change does and how to undo it", () => {
|
|
452
|
+
expect(evaluate("ceph osd out 3").reason).toContain("undo: ceph osd in 3");
|
|
453
|
+
expect(evaluate("ceph osd in osd.3").reason).toContain(
|
|
454
|
+
"undo: ceph osd out osd.3",
|
|
455
|
+
);
|
|
456
|
+
expect(evaluate("ceph osd set noout").reason).toContain(
|
|
457
|
+
"undo: ceph osd unset noout",
|
|
458
|
+
);
|
|
459
|
+
expect(evaluate("ceph osd unset noout").reason).toContain(
|
|
460
|
+
"undo: ceph osd set noout",
|
|
461
|
+
);
|
|
462
|
+
expect(evaluate("ceph balancer on").reason).toContain(
|
|
463
|
+
"undo: ceph balancer off",
|
|
464
|
+
);
|
|
465
|
+
expect(evaluate("ceph orch daemon stop osd.3").reason).toContain(
|
|
466
|
+
"undo: ceph orch daemon start osd.3",
|
|
467
|
+
);
|
|
468
|
+
expect(evaluate("ceph osd set pause").reason).toContain(
|
|
469
|
+
"every client read and write is stopped",
|
|
470
|
+
);
|
|
471
|
+
expect(evaluate("ceph osd pool set rbd size 2").reason).toContain(
|
|
472
|
+
"replica count",
|
|
473
|
+
);
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// ---- Denied families ------------------------------------------------------------
|
|
478
|
+
|
|
479
|
+
describe("Denied: commands that never run", () => {
|
|
480
|
+
test.each([
|
|
481
|
+
["ceph osd purge 3", "deletes an OSD"],
|
|
482
|
+
["ceph osd purge-new 3", "deletes an OSD"],
|
|
483
|
+
["ceph osd destroy 3", "destroys an OSD"],
|
|
484
|
+
["ceph osd rm 3", "removes an OSD"],
|
|
485
|
+
["ceph osd lost 3", "give up"],
|
|
486
|
+
["ceph osd new 0c7d3c6e-1b2a-4c3d-9e8f-0123456789ab", "adds an OSD"],
|
|
487
|
+
["ceph osd create", "adds an OSD"],
|
|
488
|
+
["ceph osd crush reweight osd.3 0.5", "CRUSH"],
|
|
489
|
+
["ceph osd crush rm osd.3", "CRUSH"],
|
|
490
|
+
["ceph osd crush move host1 root=default", "CRUSH"],
|
|
491
|
+
["ceph osd setcrushmap", "CRUSH"],
|
|
492
|
+
["ceph osd getcrushmap", "CRUSH"],
|
|
493
|
+
["ceph osd pool delete rbd rbd", "deletes a pool"],
|
|
494
|
+
["ceph osd pool rm rbd", "deletes a pool"],
|
|
495
|
+
["ceph osd pool rename rbd rbd2", "renames a pool"],
|
|
496
|
+
["ceph osd pool create newpool 32", "creates a pool"],
|
|
497
|
+
["ceph osd pool set rbd pg_num 64", "only size and min_size"],
|
|
498
|
+
["ceph osd pool set rbd nodelete false", "only size and min_size"],
|
|
499
|
+
["ceph osd pool set rbd crush_rule fast", "only size and min_size"],
|
|
500
|
+
["ceph osd pool set-quota rbd max_bytes 0", "quota"],
|
|
501
|
+
["ceph osd pool application enable rbd rbd", "applications"],
|
|
502
|
+
["ceph osd pool mksnap rbd s1", "snapshots"],
|
|
503
|
+
["ceph osd pool autoscale-status", "not among the pool reads"],
|
|
504
|
+
["ceph osd pool frobnicate", "only osd pool ls, stats and get"],
|
|
505
|
+
["ceph auth get client.admin", "cephx keys"],
|
|
506
|
+
["ceph auth ls", "cephx keys"],
|
|
507
|
+
["ceph auth print-key client.admin", "cephx keys"],
|
|
508
|
+
["ceph auth get-or-create client.x mon 'allow *'", "cephx keys"],
|
|
509
|
+
["ceph auth del client.x", "cephx keys"],
|
|
510
|
+
["ceph config-key get mgr/dashboard/key", "secrets"],
|
|
511
|
+
["ceph config-key dump", "secrets"],
|
|
512
|
+
["ceph config-key set k v", "secrets"],
|
|
513
|
+
["ceph config set osd osd_max_backfills 8", "cluster-wide"],
|
|
514
|
+
["ceph config rm osd osd_max_backfills", "cluster-wide"],
|
|
515
|
+
["ceph config assimilate-conf", "cluster-wide"],
|
|
516
|
+
["ceph config dump", "credentials"],
|
|
517
|
+
["ceph config get mon", "credentials"],
|
|
518
|
+
["ceph tell osd.3 bench", "inside a daemon"],
|
|
519
|
+
["ceph tell mon.a config set debug_mon 20", "inside a daemon"],
|
|
520
|
+
["ceph tell 'osd.*' version", "inside a daemon"],
|
|
521
|
+
["ceph daemon osd.3 config show", "admin socket"],
|
|
522
|
+
["ceph daemonperf osd.3", "admin socket"],
|
|
523
|
+
["ceph injectargs x", "runtime"],
|
|
524
|
+
["ceph fs rm cephfs", "file system"],
|
|
525
|
+
["ceph fs fail cephfs", "file system"],
|
|
526
|
+
["ceph fs reset cephfs", "file system"],
|
|
527
|
+
["ceph fs new cephfs meta data", "file system"],
|
|
528
|
+
["ceph fs set cephfs max_mds 2", "file system"],
|
|
529
|
+
["ceph mds fail 0", "MDS daemons"],
|
|
530
|
+
["ceph mon remove a", "monitor membership"],
|
|
531
|
+
["ceph mon add d 10.0.0.4", "monitor membership"],
|
|
532
|
+
["ceph mon rm a", "monitor membership"],
|
|
533
|
+
["ceph mon metadata a", "only ceph mon stat"],
|
|
534
|
+
["ceph mgr module enable telemetry", "manager module"],
|
|
535
|
+
["ceph mgr module disable dashboard", "manager module"],
|
|
536
|
+
["ceph mgr dump", "only ceph mgr stat"],
|
|
537
|
+
["ceph orch rm rgw.store", "cephadm deploys"],
|
|
538
|
+
["ceph orch apply mon 3", "cephadm deploys"],
|
|
539
|
+
["ceph orch host rm host1", "cephadm deploys"],
|
|
540
|
+
["ceph orch host add host4", "cephadm deploys"],
|
|
541
|
+
["ceph orch upgrade stop", "cephadm deploys"],
|
|
542
|
+
["ceph orch daemon rm osd.3", "daemon rm"],
|
|
543
|
+
["ceph orch daemon redeploy osd.3", "daemon rm"],
|
|
544
|
+
["ceph osd require-osd-release squid", "cannot be undone"],
|
|
545
|
+
["ceph osd set-full-ratio 0.99", "stops writes"],
|
|
546
|
+
["ceph osd set-nearfull-ratio 0.9", "warning threshold"],
|
|
547
|
+
["ceph osd set-backfillfull-ratio 0.95", "stops backfill"],
|
|
548
|
+
["ceph osd set-group noout host1", "groups of OSDs"],
|
|
549
|
+
["ceph pg force_create_pg 1.2f", "force PG creation"],
|
|
550
|
+
["ceph pg force-recovery 1.2f", "force PG creation"],
|
|
551
|
+
["ceph pg repeer 1.2f", "force PG creation"],
|
|
552
|
+
["ceph pg dump", "force PG creation"],
|
|
553
|
+
["ceph pg 1.2f mark_unfound_lost revert", "mark_unfound_lost"],
|
|
554
|
+
["ceph pg 1.2f mark_unfound_lost delete", "mark_unfound_lost"],
|
|
555
|
+
[`ceph crash rm ${CRASH_ID}`, "delete reports"],
|
|
556
|
+
["ceph crash prune 7", "delete reports"],
|
|
557
|
+
["ceph log 'hello world'", "writes a message"],
|
|
558
|
+
["ceph balancer mode upmap", "how it moves data"],
|
|
559
|
+
["ceph balancer optimize plan1", "how it moves data"],
|
|
560
|
+
["ceph balancer execute plan1", "how it moves data"],
|
|
561
|
+
["ceph health mute OSD_DOWN", "hides a problem"],
|
|
562
|
+
["ceph health mute OSD_DOWN 1h", "hides a problem"],
|
|
563
|
+
["ceph health unmute OSD_DOWN", "unmutes health checks"],
|
|
564
|
+
["ceph health foo", "the only word it takes"],
|
|
565
|
+
["ceph dashboard ac-user-show", "dashboard"],
|
|
566
|
+
["ceph restful create-key admin", "REST API keys"],
|
|
567
|
+
["ceph telemetry on", "outside itself"],
|
|
568
|
+
["ceph rgw realm list", "object gateway"],
|
|
569
|
+
["ceph nfs cluster ls", "NFS"],
|
|
570
|
+
["ceph cephadm get-ssh-config", "SSH keys"],
|
|
571
|
+
["ceph device ls", "device health"],
|
|
572
|
+
["ceph heap stats", "memory allocator"],
|
|
573
|
+
["ceph sync force", "syncs"],
|
|
574
|
+
["ceph quorum enter", "quorum"],
|
|
575
|
+
["ceph osd blocklist add 10.0.0.1", "cuts clients off"],
|
|
576
|
+
["ceph osd blacklist add 10.0.0.1", "cuts clients off"],
|
|
577
|
+
["ceph osd scrub 3", "every PG on an OSD"],
|
|
578
|
+
["ceph osd deep-scrub 3", "every PG on an OSD"],
|
|
579
|
+
["ceph osd repair 3", "every PG on an OSD"],
|
|
580
|
+
["ceph osd reweight-by-utilization", "many OSDs"],
|
|
581
|
+
["ceph osd reweight-by-pg", "many OSDs"],
|
|
582
|
+
["ceph osd primary-affinity osd.3 0", "serve reads"],
|
|
583
|
+
["ceph osd pg-upmap-items 1.2f 3 4", "placement"],
|
|
584
|
+
["ceph osd rm-pg-upmap-items 1.2f", "placement"],
|
|
585
|
+
["ceph osd erasure-code-profile set p k=2 m=1", "erasure-code"],
|
|
586
|
+
["ceph osd tier add a b", "cache tiering"],
|
|
587
|
+
["ceph osd map rbd obj", "OSD commands that may run"],
|
|
588
|
+
["ceph osd setmaxosd 10", "OSD map"],
|
|
589
|
+
["ceph report", "not a command OneUptime AI may run"],
|
|
590
|
+
["ceph foo", "not a command OneUptime AI may run"],
|
|
591
|
+
["ceph frobnicate everything now", "not a command OneUptime AI may run"],
|
|
592
|
+
])("%s", (command: string, reasonPart: string) => {
|
|
593
|
+
const result: ResourceCommandPolicyResult = evaluate(command);
|
|
594
|
+
|
|
595
|
+
expectDenied(result, reasonPart);
|
|
596
|
+
expect(result.verb).toBe("");
|
|
597
|
+
expect(result.program).toBe("ceph");
|
|
598
|
+
expect(result.displayCommand.startsWith("ceph ")).toBe(true);
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
test.each([
|
|
602
|
+
["ceph osd set noup", "is not a flag"],
|
|
603
|
+
["ceph osd set nodown", "is not a flag"],
|
|
604
|
+
["ceph osd set noin", "is not a flag"],
|
|
605
|
+
["ceph osd set full", "is not a flag"],
|
|
606
|
+
["ceph osd unset sortbitwise", "is not a flag"],
|
|
607
|
+
["ceph osd unset recovery_deletes", "is not a flag"],
|
|
608
|
+
])("%s: only the modeled OSD flags", (command: string, reason: string) => {
|
|
609
|
+
expectDenied(evaluate(command), reason);
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
test("an unknown command's reason names what may run", () => {
|
|
613
|
+
const reason: string = evaluate("ceph foo").reason;
|
|
614
|
+
|
|
615
|
+
expect(reason).toContain("Reads: status");
|
|
616
|
+
expect(reason).toContain("Changes: osd in|out|down ID");
|
|
617
|
+
expect(reason).toContain("osd pool set POOL size|min_size N");
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
test("ceph with no command (an interactive shell) is Denied", () => {
|
|
621
|
+
expectDenied(evaluate("ceph"), "interactive shell");
|
|
622
|
+
expectDenied(evaluate("ceph --format json"), "only an output format");
|
|
623
|
+
expectDenied(evaluate("ceph -f plain"), "only an output format");
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
// ---- Options: the argparse rules ---------------------------------------------
|
|
628
|
+
|
|
629
|
+
describe("options never smuggle anything past the grammar", () => {
|
|
630
|
+
test.each([
|
|
631
|
+
// A daemon's admin socket.
|
|
632
|
+
[
|
|
633
|
+
"ceph --admin-daemon /var/run/ceph/ceph-osd.0.asok status",
|
|
634
|
+
"admin socket",
|
|
635
|
+
],
|
|
636
|
+
["ceph status --admin-daemon=/var/run/ceph/x.asok", "admin socket"],
|
|
637
|
+
["ceph --admin_daemon /x.asok status", "admin socket"],
|
|
638
|
+
// Another cluster, identity or key.
|
|
639
|
+
["ceph -c /tmp/other.conf status", "own configuration"],
|
|
640
|
+
["ceph --conf=/tmp/other.conf status", "own configuration"],
|
|
641
|
+
["ceph -k /etc/ceph/ceph.client.admin.keyring status", "own configuration"],
|
|
642
|
+
["ceph --keyring /etc/ceph/admin.keyring health", "own configuration"],
|
|
643
|
+
["ceph health --keyring=/etc/ceph/admin.keyring", "own configuration"],
|
|
644
|
+
[`ceph --key=${CEPHX_SECRET} status`, "own configuration"],
|
|
645
|
+
["ceph --keyfile /tmp/k status", "own configuration"],
|
|
646
|
+
["ceph --id admin status", "own configuration"],
|
|
647
|
+
["ceph --user admin status", "own configuration"],
|
|
648
|
+
["ceph -n client.admin status", "own configuration"],
|
|
649
|
+
["ceph --name=client.admin status", "own configuration"],
|
|
650
|
+
["ceph --cluster other status", "own configuration"],
|
|
651
|
+
["ceph -m 10.0.0.1:6789 status", "own configuration"],
|
|
652
|
+
["ceph --mon-host 10.0.0.1 status", "own configuration"],
|
|
653
|
+
["ceph --mon_host=10.0.0.1 status", "own configuration"],
|
|
654
|
+
["ceph --setuser root status", "own configuration"],
|
|
655
|
+
["ceph --auth_client_required none status", "own configuration"],
|
|
656
|
+
// Files on the agent's machine.
|
|
657
|
+
["ceph -o /tmp/out status", "file on the agent"],
|
|
658
|
+
["ceph --out-file=/tmp/out status", "file on the agent"],
|
|
659
|
+
["ceph --in-file /etc/passwd status", "file on the agent"],
|
|
660
|
+
["ceph -i /etc/passwd status", "file on the agent"],
|
|
661
|
+
["ceph --log-file=/tmp/x status", "file on the agent"],
|
|
662
|
+
["ceph --log_file /tmp/x status", "file on the agent"],
|
|
663
|
+
["ceph --admin-socket=/tmp/x status", "file on the agent"],
|
|
664
|
+
// Abbreviations argparse would expand.
|
|
665
|
+
["ceph --keyr=/x status", "abbreviation"],
|
|
666
|
+
["ceph --out /tmp/out status", "abbreviation"],
|
|
667
|
+
["ceph --in /etc/passwd status", "abbreviation"],
|
|
668
|
+
["ceph --adm /x.asok status", "not an option"],
|
|
669
|
+
["ceph --form json status", "abbreviation of --format"],
|
|
670
|
+
["ceph --forma=json status", "abbreviation of --format"],
|
|
671
|
+
["ceph --fo json status", "abbreviation of --format"],
|
|
672
|
+
// Never-ending watches.
|
|
673
|
+
["ceph -w", "until it is killed"],
|
|
674
|
+
["ceph --watch", "until it is killed"],
|
|
675
|
+
["ceph --watch-warn", "until it is killed"],
|
|
676
|
+
["ceph --watch_error", "until it is killed"],
|
|
677
|
+
["ceph -W audit", "until it is killed"],
|
|
678
|
+
["ceph --watch-channel=audit", "until it is killed"],
|
|
679
|
+
// Confirmations of destructive changes.
|
|
680
|
+
["ceph osd out 3 --yes-i-really-mean-it", "destructive"],
|
|
681
|
+
["ceph osd pool set rbd size 1 --yes-i-really-mean-it", "destructive"],
|
|
682
|
+
["ceph osd purge 3 --yes-i-really-really-mean-it", "destructive"],
|
|
683
|
+
["ceph orch daemon restart osd.3 --force", "destructive"],
|
|
684
|
+
// Help, versions, verbosity, timeouts, debug.
|
|
685
|
+
["ceph -h", "help"],
|
|
686
|
+
["ceph --help", "help"],
|
|
687
|
+
["ceph status --help-all", "help"],
|
|
688
|
+
["ceph --status", "ceph status"],
|
|
689
|
+
["ceph -v", "ceph version"],
|
|
690
|
+
["ceph --version", "ceph version"],
|
|
691
|
+
["ceph --verbose status", "how much ceph prints"],
|
|
692
|
+
["ceph --concise status", "how much ceph prints"],
|
|
693
|
+
["ceph --connect-timeout 5 status", "timeouts"],
|
|
694
|
+
["ceph -p 1 status", "timeouts"],
|
|
695
|
+
["ceph --block pg scrub 1.2f", "timeouts"],
|
|
696
|
+
["ceph --debug-ms=20 status", "debug"],
|
|
697
|
+
["ceph --debug_ms 1 status", "debug"],
|
|
698
|
+
// Combined, inline and malformed spellings.
|
|
699
|
+
["ceph -sf json", "stand alone"],
|
|
700
|
+
["ceph -sw", "stand alone"],
|
|
701
|
+
["ceph -s=1", "stand alone"],
|
|
702
|
+
["ceph -fjson status", "its own word"],
|
|
703
|
+
["ceph -f=json status", "its own word"],
|
|
704
|
+
["ceph -fplain osd tree", "its own word"],
|
|
705
|
+
["ceph --FORMAT json status", "not an option"],
|
|
706
|
+
["ceph osd tree '--format json'", "not an option"],
|
|
707
|
+
["ceph osd out -1", "not an option"],
|
|
708
|
+
["ceph -x status", "not an option"],
|
|
709
|
+
["ceph ---format json status", "not an option"],
|
|
710
|
+
// The terminator.
|
|
711
|
+
["ceph --", "not needed"],
|
|
712
|
+
["ceph -- status", "not needed"],
|
|
713
|
+
["ceph status --", "not needed"],
|
|
714
|
+
["ceph osd tree -- down", "not needed"],
|
|
715
|
+
])("%s", (command: string, reasonPart: string) => {
|
|
716
|
+
expectDenied(evaluate(command), reasonPart);
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
test.each([
|
|
720
|
+
["ceph --format xml status", "not an output format"],
|
|
721
|
+
["ceph --format yaml status", "not an output format"],
|
|
722
|
+
["ceph --format xml-pretty status", "not an output format"],
|
|
723
|
+
["ceph --format JSON status", "not an output format"],
|
|
724
|
+
["ceph status --format", "needs a value"],
|
|
725
|
+
["ceph status -f", "needs a value"],
|
|
726
|
+
["ceph status --format=", "not an output format"],
|
|
727
|
+
["ceph -f --admin-daemon /x.asok status", "not an output format"],
|
|
728
|
+
["ceph -f -s", "not an output format"],
|
|
729
|
+
["ceph -f status", "not an output format"],
|
|
730
|
+
["ceph status --format json --format json", "twice"],
|
|
731
|
+
["ceph status -f json --format=plain", "twice"],
|
|
732
|
+
["ceph osd tree --format json-pretty -f json", "twice"],
|
|
733
|
+
["ceph -s -s", "twice"],
|
|
734
|
+
])("%s: the output format", (command: string, reasonPart: string) => {
|
|
735
|
+
expectDenied(evaluate(command), reasonPart);
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
test.each([
|
|
739
|
+
["ceph -s osd tree", "stand alone"],
|
|
740
|
+
["ceph status -s", "stand alone"],
|
|
741
|
+
["ceph -s osd out 3", "stand alone"],
|
|
742
|
+
["ceph osd tree -s", "stand alone"],
|
|
743
|
+
])("%s: -s is status and stands alone", (command: string, reason: string) => {
|
|
744
|
+
expectDenied(evaluate(command), reason);
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
test.each([
|
|
748
|
+
["ceph orch ps --daemon_type=osd", "two words"],
|
|
749
|
+
["ceph orch ps --service-name=mgr", "two words"],
|
|
750
|
+
["ceph orch ps --refresh=true", "takes no value"],
|
|
751
|
+
["ceph orch ps --daemon_type osd --daemon-type mon", "twice"],
|
|
752
|
+
["ceph orch ps --service_name a --service-name b", "twice"],
|
|
753
|
+
["ceph orch ps --refresh --refresh", "twice"],
|
|
754
|
+
["ceph orch ps --daemon_type --refresh", "not a daemon type"],
|
|
755
|
+
["ceph orch ps --service_name --refresh", "not a service name"],
|
|
756
|
+
["ceph orch ps --daemon_type", "needs a value"],
|
|
757
|
+
["ceph orch ps --service_name", "needs a value"],
|
|
758
|
+
["ceph orch ps --daemon_type OSD", "not a daemon type"],
|
|
759
|
+
["ceph orch ps --service_name -x", "not an option"],
|
|
760
|
+
["ceph orch ps --service_name -s", "stand alone"],
|
|
761
|
+
["ceph orch ps host1", "takes only"],
|
|
762
|
+
["ceph orch ps --hostname host1", "not an option"],
|
|
763
|
+
["ceph orch ps --daemon_id 3", "not an option"],
|
|
764
|
+
["ceph orch ps --sort_by name", "not an option"],
|
|
765
|
+
["ceph orch ps --format yaml", "not an output format"],
|
|
766
|
+
["ceph --refresh orch ps", "not an option"],
|
|
767
|
+
["ceph orch --refresh ps", "not an option"],
|
|
768
|
+
["ceph --daemon_type osd orch ps", "not an option"],
|
|
769
|
+
["ceph orch ls --refresh", "not an option"],
|
|
770
|
+
["ceph orch ls --export", "not an option"],
|
|
771
|
+
["ceph orch host ls --detail", "not an option"],
|
|
772
|
+
["ceph orch device ls --refresh", "not an option"],
|
|
773
|
+
["ceph osd tree --refresh", "not an option"],
|
|
774
|
+
])(
|
|
775
|
+
"%s: orch ps's named arguments, only after orch ps",
|
|
776
|
+
(command: string, reasonPart: string) => {
|
|
777
|
+
expectDenied(evaluate(command), reasonPart);
|
|
778
|
+
},
|
|
779
|
+
);
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
// ---- Arguments ----------------------------------------------------------------
|
|
783
|
+
|
|
784
|
+
describe("arguments are validated, so a target can never hide", () => {
|
|
785
|
+
test.each([
|
|
786
|
+
["ceph osd out", "needs an OSD id"],
|
|
787
|
+
["ceph osd out 1 2", "exactly one argument"],
|
|
788
|
+
["ceph osd out any", "not an OSD id"],
|
|
789
|
+
["ceph osd out all", "not an OSD id"],
|
|
790
|
+
["ceph osd out '*'", "not an OSD id"],
|
|
791
|
+
["ceph osd out 03", "without leading zeros"],
|
|
792
|
+
["ceph osd out osd.03", "without leading zeros"],
|
|
793
|
+
["ceph osd out osd.", "not an OSD id"],
|
|
794
|
+
["ceph osd out OSD.3", "not an OSD id"],
|
|
795
|
+
["ceph osd out osd3", "not an OSD id"],
|
|
796
|
+
["ceph osd out 1234567", "not an OSD id"],
|
|
797
|
+
["ceph osd out 3.0", "not an OSD id"],
|
|
798
|
+
["ceph osd out osd.3,osd.4", "not an OSD id"],
|
|
799
|
+
["ceph osd out mon.a", "not an OSD id"],
|
|
800
|
+
["ceph osd in 3 4", "exactly one argument"],
|
|
801
|
+
["ceph osd down osd.1 osd.2", "exactly one argument"],
|
|
802
|
+
["ceph osd find", "needs an OSD id"],
|
|
803
|
+
["ceph osd find 1 2", "exactly one argument"],
|
|
804
|
+
["ceph osd metadata x", "not an OSD id"],
|
|
805
|
+
["ceph osd ok-to-stop", "needs an OSD id"],
|
|
806
|
+
["ceph osd ok-to-stop any", "not an OSD id"],
|
|
807
|
+
["ceph osd safe-to-destroy 1 all", "not an OSD id"],
|
|
808
|
+
["ceph osd tree 5", "not one of"],
|
|
809
|
+
["ceph osd tree down down", "given twice"],
|
|
810
|
+
["ceph osd df plain", "only word"],
|
|
811
|
+
["ceph osd df tree class hdd", "only word"],
|
|
812
|
+
["ceph health detail extra", "only word"],
|
|
813
|
+
["ceph df DETAIL", "only word"],
|
|
814
|
+
["ceph status now", "takes no arguments"],
|
|
815
|
+
["ceph mon dump 3", "takes no arguments"],
|
|
816
|
+
["ceph crash ls extra", "takes no arguments"],
|
|
817
|
+
["ceph osd pool get rbd", "a pool name and one setting"],
|
|
818
|
+
["ceph osd pool get rbd size extra", "a pool name and one setting"],
|
|
819
|
+
["ceph osd pool get @rbd size", "not a pool name"],
|
|
820
|
+
["ceph osd pool get rbd SIZE", "not a pool setting"],
|
|
821
|
+
["ceph osd pool stats rbd extra", "exactly one argument"],
|
|
822
|
+
["ceph osd pool stats 'my pool'", "not a pool name"],
|
|
823
|
+
["ceph osd pool set rbd size 0", "replica count"],
|
|
824
|
+
["ceph osd pool set rbd size 11", "replica count"],
|
|
825
|
+
["ceph osd pool set rbd size 3.0", "replica count"],
|
|
826
|
+
["ceph osd pool set rbd min_size 03", "replica count"],
|
|
827
|
+
["ceph osd pool set rbd size", "a pool name, size or min_size"],
|
|
828
|
+
["ceph osd pool set @rbd size 3", "not a pool name"],
|
|
829
|
+
["ceph osd reweight 3", "a weight from 0 to 1"],
|
|
830
|
+
["ceph osd reweight 3 1.5", "not a weight"],
|
|
831
|
+
["ceph osd reweight 3 2", "not a weight"],
|
|
832
|
+
["ceph osd reweight 3 .5", "not a weight"],
|
|
833
|
+
["ceph osd reweight 3 0.12345", "not a weight"],
|
|
834
|
+
["ceph osd reweight 3 1e0", "not a weight"],
|
|
835
|
+
["ceph osd reweight 3 1.0001", "not a weight"],
|
|
836
|
+
["ceph osd reweight x 0.5", "not an OSD id"],
|
|
837
|
+
["ceph osd reweight 3 0.5 extra", "one OSD id and a weight"],
|
|
838
|
+
["ceph osd set", "needs one flag"],
|
|
839
|
+
["ceph osd set noout norebalance", "exactly one argument"],
|
|
840
|
+
["ceph osd unset NOOUT", "is not a flag"],
|
|
841
|
+
["ceph pg scrub", "needs a PG id"],
|
|
842
|
+
["ceph pg scrub 1.2F", "not a PG id"],
|
|
843
|
+
["ceph pg scrub 1.02f", "not a PG id"],
|
|
844
|
+
["ceph pg scrub 01.2f", "not a PG id"],
|
|
845
|
+
["ceph pg scrub 1", "not a PG id"],
|
|
846
|
+
["ceph pg scrub 1.2fs0", "not a PG id"],
|
|
847
|
+
["ceph pg scrub 1.2f 1.30", "exactly one argument"],
|
|
848
|
+
["ceph pg repair 1.123456789", "not a PG id"],
|
|
849
|
+
["ceph pg deep-scrub 1.g", "not a PG id"],
|
|
850
|
+
["ceph pg 1.2F query", "not a PG id"],
|
|
851
|
+
["ceph pg 1.2f", "takes only query or list_unfound"],
|
|
852
|
+
["ceph pg 1.2f query extra", "no more arguments"],
|
|
853
|
+
["ceph pg 1 query", "not a PG id"],
|
|
854
|
+
["ceph pg dump_stuck stuck", "not one of"],
|
|
855
|
+
["ceph pg dump_stuck stale stale", "given twice"],
|
|
856
|
+
["ceph pg dump_stuck 60 stale", "not one of"],
|
|
857
|
+
["ceph pg ls-by-osd", "needs an OSD id"],
|
|
858
|
+
["ceph pg ls-by-pool", "needs a pool name"],
|
|
859
|
+
["ceph log last 0", "line count"],
|
|
860
|
+
["ceph log last 1001", "line count"],
|
|
861
|
+
["ceph log last 00010", "line count"],
|
|
862
|
+
["ceph log last 99999999", "line count"],
|
|
863
|
+
["ceph log last warn 10", "in that order"],
|
|
864
|
+
["ceph log last 10 cluster warn", "in that order"],
|
|
865
|
+
["ceph log last 10 warn cluster extra", "in that order"],
|
|
866
|
+
["ceph log last 10 critical", "in that order"],
|
|
867
|
+
["ceph crash info", "needs a crash id"],
|
|
868
|
+
["ceph crash info abc", "not a crash id"],
|
|
869
|
+
[
|
|
870
|
+
"ceph crash info 2024-05-21T10:15:42.123456Z_0C7D3C6E-1B2A-4C3D-9E8F-0123456789AB",
|
|
871
|
+
"not a crash id",
|
|
872
|
+
],
|
|
873
|
+
[`ceph crash archive ${CRASH_ID} ${CRASH_ID}`, "exactly one argument"],
|
|
874
|
+
["ceph crash archive-all now", "takes no arguments"],
|
|
875
|
+
["ceph orch daemon restart", "needs one daemon name"],
|
|
876
|
+
["ceph orch daemon restart osd", "not a cephadm daemon name"],
|
|
877
|
+
["ceph orch daemon restart osd.03", "not a cephadm daemon name"],
|
|
878
|
+
["ceph orch daemon restart osd.osd.3", "not a cephadm daemon name"],
|
|
879
|
+
["ceph orch daemon restart osd.all", "not a cephadm daemon name"],
|
|
880
|
+
["ceph orch daemon restart Mon.host1", "not a cephadm daemon name"],
|
|
881
|
+
["ceph orch daemon restart .host1", "not a cephadm daemon name"],
|
|
882
|
+
["ceph orch daemon stop mon.", "not a cephadm daemon name"],
|
|
883
|
+
["ceph orch daemon restart mon.host1 mon.host2", "exactly one argument"],
|
|
884
|
+
["ceph orch restart", "needs one service name"],
|
|
885
|
+
["ceph orch restart Mgr", "not a cephadm service name"],
|
|
886
|
+
["ceph orch restart mgr mon", "exactly one argument"],
|
|
887
|
+
["ceph mgr fail a b", "at most one manager name"],
|
|
888
|
+
["ceph mgr fail .x", "at most one manager name"],
|
|
889
|
+
["ceph balancer on now", "takes no arguments"],
|
|
890
|
+
["ceph fs status 'bad name'", "not a file system name"],
|
|
891
|
+
["ceph fs status a b", "exactly one argument"],
|
|
892
|
+
])("%s", (command: string, reasonPart: string) => {
|
|
893
|
+
const result: ResourceCommandPolicyResult = evaluate(command);
|
|
894
|
+
|
|
895
|
+
expectDenied(result, reasonPart);
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
test("a refused argument names the usage", () => {
|
|
899
|
+
expect(evaluate("ceph osd reweight 3 2").reason).toContain(
|
|
900
|
+
"Usage: ceph osd reweight ID WEIGHT",
|
|
901
|
+
);
|
|
902
|
+
expect(evaluate("ceph orch daemon stop mon").reason).toContain(
|
|
903
|
+
"Usage: ceph orch daemon stop TYPE.ID",
|
|
904
|
+
);
|
|
905
|
+
});
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
// ---- Tokenization, quoting, look-alikes ---------------------------------------
|
|
909
|
+
|
|
910
|
+
describe("quotes, whitespace and look-alikes", () => {
|
|
911
|
+
test("quoted words are the same words", () => {
|
|
912
|
+
const result: ResourceCommandPolicyResult =
|
|
913
|
+
evaluate(`ceph 'osd' "out" '3'`);
|
|
914
|
+
|
|
915
|
+
expect(result.tier).toBe(ResourceCommandTier.RiskyWrite);
|
|
916
|
+
expect(result.targets).toEqual(["osd.3"]);
|
|
917
|
+
expect(result.displayCommand).toBe("ceph osd out 3");
|
|
918
|
+
});
|
|
919
|
+
|
|
920
|
+
test.each([
|
|
921
|
+
["ceph 'osd out' 3", "not a command"],
|
|
922
|
+
[`ceph "osd tree -f json"`, "not a command"],
|
|
923
|
+
["ceph '' status", "empty"],
|
|
924
|
+
["ceph status ''", "empty"],
|
|
925
|
+
["ceph ''", "empty"],
|
|
926
|
+
["ceph ' '", "empty"],
|
|
927
|
+
["ceph osd out '3 '", "not an OSD id"],
|
|
928
|
+
])("%s is Denied", (command: string, reasonPart: string) => {
|
|
929
|
+
expectDenied(evaluate(command), reasonPart);
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
test("tabs and surrounding spaces split words like spaces", () => {
|
|
933
|
+
expect(evaluate(" ceph\tosd tree ").tier).toBe(
|
|
934
|
+
ResourceCommandTier.Read,
|
|
935
|
+
);
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
test.each([
|
|
939
|
+
["ceph osd tree | head", "pipes and redirects are not supported"],
|
|
940
|
+
["ceph status; ceph auth ls", "pipes and redirects are not supported"],
|
|
941
|
+
["ceph status && ceph osd out 3", "pipes and redirects are not supported"],
|
|
942
|
+
["ceph status > /tmp/x", "pipes and redirects are not supported"],
|
|
943
|
+
["ceph $(echo status)", "pipes and redirects are not supported"],
|
|
944
|
+
["ceph `echo status`", "pipes and redirects are not supported"],
|
|
945
|
+
["ceph status\nceph auth ls", "single line"],
|
|
946
|
+
["sudo ceph status", "own permissions"],
|
|
947
|
+
["/usr/bin/ceph status", "without a path"],
|
|
948
|
+
["rados df", "is not a program the Ceph AI agent runs"],
|
|
949
|
+
["CEPH status", "is not a program the Ceph AI agent runs"],
|
|
950
|
+
["kubectl get pods", "is not a program the Ceph AI agent runs"],
|
|
951
|
+
])("%s never reaches the grammar", (command: string, reasonPart: string) => {
|
|
952
|
+
expectDenied(evaluate(command), reasonPart);
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
test.each([
|
|
956
|
+
["ceph оsd tree"], // Cyrillic o
|
|
957
|
+
["ceph osd tree ‐‐format json"], // Unicode hyphens
|
|
958
|
+
["ceph −f json status"], // minus sign
|
|
959
|
+
["ceph —format json status"], // em dash
|
|
960
|
+
["ceph osd out 3"], // fullwidth 3
|
|
961
|
+
["ceph osd out osd.3"],
|
|
962
|
+
["ceph status"], // zero-width space
|
|
963
|
+
["ceph status"], // fullwidth s
|
|
964
|
+
["ceph Status"],
|
|
965
|
+
["ceph STATUS"],
|
|
966
|
+
["ceph OSD tree"],
|
|
967
|
+
["ceph osd Out 3"],
|
|
968
|
+
["ceph osd out '3 '"], // no-break space inside the word
|
|
969
|
+
["ceph osd out 3"], // no-break space is not a word break
|
|
970
|
+
["ceph pg 1․2f query"], // one-dot leader
|
|
971
|
+
["ceph osd pool get rbd size"],
|
|
972
|
+
["ceph osd set noоut"],
|
|
973
|
+
["ceph orch daemon restart osd·3"],
|
|
974
|
+
])("%p is Denied", (command: string) => {
|
|
975
|
+
const result: ResourceCommandPolicyResult = evaluate(command);
|
|
976
|
+
|
|
977
|
+
expect(result.tier).toBe(ResourceCommandTier.Denied);
|
|
978
|
+
expect(result.targets).toEqual([]);
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
test("an over-long command or one with too many words is Denied", () => {
|
|
982
|
+
expect(evaluate(`ceph osd pool stats ${"a".repeat(2000)}`).tier).toBe(
|
|
983
|
+
ResourceCommandTier.Denied,
|
|
984
|
+
);
|
|
985
|
+
expect(evaluate(`ceph osd ok-to-stop ${"1 ".repeat(70).trim()}`).tier).toBe(
|
|
986
|
+
ResourceCommandTier.Denied,
|
|
987
|
+
);
|
|
988
|
+
});
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
// ---- Totality -----------------------------------------------------------------
|
|
992
|
+
|
|
993
|
+
describe("evaluateArgv is total and never changes its input", () => {
|
|
994
|
+
test.each([
|
|
995
|
+
[null],
|
|
996
|
+
[undefined],
|
|
997
|
+
[42],
|
|
998
|
+
["ceph status"],
|
|
999
|
+
[{}],
|
|
1000
|
+
[[]],
|
|
1001
|
+
[[1]],
|
|
1002
|
+
[["ceph", 1]],
|
|
1003
|
+
[[null]],
|
|
1004
|
+
[["ceph", null]],
|
|
1005
|
+
[["ceph", undefined]],
|
|
1006
|
+
[[["ceph"]]],
|
|
1007
|
+
[["ceph", {}]],
|
|
1008
|
+
[["ceph", ["status"]]],
|
|
1009
|
+
[["osd", "tree"]],
|
|
1010
|
+
[["", "status"]],
|
|
1011
|
+
[["ceph"]],
|
|
1012
|
+
])("%p is Denied without throwing", (argv: unknown) => {
|
|
1013
|
+
const result: ResourceCommandPolicyResult = CephCommandPolicy.evaluateArgv(
|
|
1014
|
+
argv as Array<string>,
|
|
1015
|
+
);
|
|
1016
|
+
|
|
1017
|
+
expect(result.tier).toBe(ResourceCommandTier.Denied);
|
|
1018
|
+
expect(result.targets).toEqual([]);
|
|
1019
|
+
expect(typeof result.reason).toBe("string");
|
|
1020
|
+
expect(result.reason.length).toBeGreaterThan(0);
|
|
1021
|
+
});
|
|
1022
|
+
|
|
1023
|
+
test("an argv whose words throw when read is Denied, not thrown", () => {
|
|
1024
|
+
const evil: Array<string> = ["ceph", "status"];
|
|
1025
|
+
|
|
1026
|
+
Object.defineProperty(evil, 1, {
|
|
1027
|
+
get(): string {
|
|
1028
|
+
throw new Error("boom");
|
|
1029
|
+
},
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
expect((): void => {
|
|
1033
|
+
CephCommandPolicy.evaluateArgv(evil);
|
|
1034
|
+
}).not.toThrow();
|
|
1035
|
+
expect(CephCommandPolicy.evaluateArgv(evil).tier).toBe(
|
|
1036
|
+
ResourceCommandTier.Denied,
|
|
1037
|
+
);
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
test("a frozen argv is read, not changed, and results are fresh arrays", () => {
|
|
1041
|
+
const argv: Array<string> = Object.freeze([
|
|
1042
|
+
"ceph",
|
|
1043
|
+
"osd",
|
|
1044
|
+
"out",
|
|
1045
|
+
"3",
|
|
1046
|
+
]) as unknown as Array<string>;
|
|
1047
|
+
const result: ResourceCommandPolicyResult =
|
|
1048
|
+
CephCommandPolicy.evaluateArgv(argv);
|
|
1049
|
+
|
|
1050
|
+
expect(result.tier).toBe(ResourceCommandTier.RiskyWrite);
|
|
1051
|
+
expect(argv).toEqual(["ceph", "osd", "out", "3"]);
|
|
1052
|
+
|
|
1053
|
+
result.args.push("--yes-i-really-mean-it");
|
|
1054
|
+
result.targets.push("osd.4");
|
|
1055
|
+
|
|
1056
|
+
const again: ResourceCommandPolicyResult =
|
|
1057
|
+
CephCommandPolicy.evaluateArgv(argv);
|
|
1058
|
+
|
|
1059
|
+
expect(again.args).toEqual(["osd", "out", "3"]);
|
|
1060
|
+
expect(again.targets).toEqual(["osd.3"]);
|
|
1061
|
+
});
|
|
1062
|
+
|
|
1063
|
+
test("huge argvs and words are Denied quickly", () => {
|
|
1064
|
+
const started: number = Date.now();
|
|
1065
|
+
const manyWords: Array<string> = [
|
|
1066
|
+
"ceph",
|
|
1067
|
+
"osd",
|
|
1068
|
+
"ok-to-stop",
|
|
1069
|
+
...Array.from({ length: 10000 }, (): string => {
|
|
1070
|
+
return "1";
|
|
1071
|
+
}),
|
|
1072
|
+
];
|
|
1073
|
+
|
|
1074
|
+
expect(CephCommandPolicy.evaluateArgv(manyWords).tier).toBe(
|
|
1075
|
+
ResourceCommandTier.Denied,
|
|
1076
|
+
);
|
|
1077
|
+
expect(
|
|
1078
|
+
CephCommandPolicy.evaluateArgv([
|
|
1079
|
+
"ceph",
|
|
1080
|
+
"crash",
|
|
1081
|
+
"info",
|
|
1082
|
+
`2024-05-21T10:15:42.${"1".repeat(100000)}Z_x`,
|
|
1083
|
+
]).tier,
|
|
1084
|
+
).toBe(ResourceCommandTier.Denied);
|
|
1085
|
+
expect(
|
|
1086
|
+
CephCommandPolicy.evaluateArgv(["ceph", "-".repeat(100000)]).tier,
|
|
1087
|
+
).toBe(ResourceCommandTier.Denied);
|
|
1088
|
+
expect(Date.now() - started).toBeLessThan(2000);
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
test("the dispatcher and the tool agree on an argv", () => {
|
|
1092
|
+
for (const [command] of [
|
|
1093
|
+
...READ_COMMANDS,
|
|
1094
|
+
...SAFE_WRITES,
|
|
1095
|
+
...RISKY_WRITES,
|
|
1096
|
+
]) {
|
|
1097
|
+
const argv: Array<string> = argvOf(command as string);
|
|
1098
|
+
|
|
1099
|
+
expect(
|
|
1100
|
+
ResourceCommandPolicy.evaluateArgv({ resourceType: CEPH, argv }),
|
|
1101
|
+
).toEqual(CephCommandPolicy.evaluateArgv(argv));
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1104
|
+
});
|
|
1105
|
+
|
|
1106
|
+
// ---- Dispatcher integration ---------------------------------------------------
|
|
1107
|
+
|
|
1108
|
+
function autoExecution(
|
|
1109
|
+
command: string,
|
|
1110
|
+
allowlistPatterns: Array<string> = [],
|
|
1111
|
+
bypassApproval: boolean = false,
|
|
1112
|
+
): ResourceAutoExecutionVerdict {
|
|
1113
|
+
return ResourceCommandPolicy.evaluateForAutoExecution({
|
|
1114
|
+
resourceType: CEPH,
|
|
1115
|
+
command,
|
|
1116
|
+
allowlistPatterns,
|
|
1117
|
+
bypassApproval,
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
describe("evaluateForAutoExecution (the ladder)", () => {
|
|
1122
|
+
test("a read is AutoApproved", () => {
|
|
1123
|
+
const verdict: ResourceAutoExecutionVerdict = autoExecution("ceph status");
|
|
1124
|
+
|
|
1125
|
+
expect(verdict.verdict).toBe(
|
|
1126
|
+
AiRemediationCommandPolicyVerdict.AutoApproved,
|
|
1127
|
+
);
|
|
1128
|
+
expect(verdict.tier).toBe(ResourceCommandTier.Read);
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
test.each(
|
|
1132
|
+
SAFE_WRITES.map((row: [string, string, Array<string>]) => {
|
|
1133
|
+
return [row[0]];
|
|
1134
|
+
}),
|
|
1135
|
+
)("%s runs unattended (SafeWrite)", (command: string) => {
|
|
1136
|
+
const verdict: ResourceAutoExecutionVerdict = autoExecution(command);
|
|
1137
|
+
|
|
1138
|
+
expect(verdict.verdict).toBe(
|
|
1139
|
+
AiRemediationCommandPolicyVerdict.AutoApproved,
|
|
1140
|
+
);
|
|
1141
|
+
expect(verdict.tier).toBe(ResourceCommandTier.SafeWrite);
|
|
1142
|
+
});
|
|
1143
|
+
|
|
1144
|
+
test.each(
|
|
1145
|
+
RISKY_WRITES.map((row: [string, string, Array<string>]) => {
|
|
1146
|
+
return [row[0]];
|
|
1147
|
+
}),
|
|
1148
|
+
)("%s asks, unless bypassed (RiskyWrite)", (command: string) => {
|
|
1149
|
+
expect(autoExecution(command).verdict).toBe(
|
|
1150
|
+
AiRemediationCommandPolicyVerdict.RequiresApproval,
|
|
1151
|
+
);
|
|
1152
|
+
expect(autoExecution(command, [], true).verdict).toBe(
|
|
1153
|
+
AiRemediationCommandPolicyVerdict.AutoApproved,
|
|
1154
|
+
);
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1157
|
+
test("the allowlist promotes the RiskyWrite it names, and only it", () => {
|
|
1158
|
+
expect(autoExecution("ceph osd out 3", ["ceph osd out *"]).verdict).toBe(
|
|
1159
|
+
AiRemediationCommandPolicyVerdict.AutoApproved,
|
|
1160
|
+
);
|
|
1161
|
+
expect(autoExecution("ceph osd out 3", ["ceph osd out *"]).reason).toBe(
|
|
1162
|
+
"Matched the resource's command allowlist.",
|
|
1163
|
+
);
|
|
1164
|
+
expect(autoExecution("ceph osd out 3", ["ceph osd out 3"]).verdict).toBe(
|
|
1165
|
+
AiRemediationCommandPolicyVerdict.AutoApproved,
|
|
1166
|
+
);
|
|
1167
|
+
expect(autoExecution("ceph osd out 3", ["ceph osd out 4"]).verdict).toBe(
|
|
1168
|
+
AiRemediationCommandPolicyVerdict.RequiresApproval,
|
|
1169
|
+
);
|
|
1170
|
+
expect(autoExecution("ceph osd down 3", ["ceph osd out *"]).verdict).toBe(
|
|
1171
|
+
AiRemediationCommandPolicyVerdict.RequiresApproval,
|
|
1172
|
+
);
|
|
1173
|
+
expect(
|
|
1174
|
+
autoExecution("ceph osd out 3 --format json", [
|
|
1175
|
+
"ceph osd out * --format json",
|
|
1176
|
+
]).verdict,
|
|
1177
|
+
).toBe(AiRemediationCommandPolicyVerdict.AutoApproved);
|
|
1178
|
+
expect(
|
|
1179
|
+
autoExecution("ceph osd out 3", ["ceph osd out * --format json"]).verdict,
|
|
1180
|
+
).toBe(AiRemediationCommandPolicyVerdict.RequiresApproval);
|
|
1181
|
+
expect(
|
|
1182
|
+
autoExecution("ceph balancer on", ["ceph balancer on"]).verdict,
|
|
1183
|
+
).toBe(AiRemediationCommandPolicyVerdict.AutoApproved);
|
|
1184
|
+
});
|
|
1185
|
+
|
|
1186
|
+
test.each([
|
|
1187
|
+
["ceph osd set pause", ["ceph osd set pause"]],
|
|
1188
|
+
["ceph osd pool set rbd size 2", ["ceph osd pool set * size *"]],
|
|
1189
|
+
["ceph osd pool set rbd min_size 1", ["ceph osd pool set rbd min_size 1"]],
|
|
1190
|
+
])(
|
|
1191
|
+
"%s always asks a human, even bypassed and allowlisted",
|
|
1192
|
+
(command: string, allowlist: Array<string>) => {
|
|
1193
|
+
const verdict: ResourceAutoExecutionVerdict = autoExecution(
|
|
1194
|
+
command,
|
|
1195
|
+
allowlist,
|
|
1196
|
+
true,
|
|
1197
|
+
);
|
|
1198
|
+
|
|
1199
|
+
expect(verdict.verdict).toBe(
|
|
1200
|
+
AiRemediationCommandPolicyVerdict.RequiresApproval,
|
|
1201
|
+
);
|
|
1202
|
+
expect(verdict.requiresHuman).toBe(true);
|
|
1203
|
+
expect(verdict.reason).toContain("Requires human approval");
|
|
1204
|
+
},
|
|
1205
|
+
);
|
|
1206
|
+
|
|
1207
|
+
test.each([
|
|
1208
|
+
["ceph auth ls", ["ceph auth ls *"]],
|
|
1209
|
+
["ceph osd purge 3", ["ceph osd purge *"]],
|
|
1210
|
+
["ceph osd out 3 --yes-i-really-mean-it", ["ceph osd out * *"]],
|
|
1211
|
+
["ceph --admin-daemon /x.asok status", []],
|
|
1212
|
+
["ceph tell osd.3 injectargs x", []],
|
|
1213
|
+
])(
|
|
1214
|
+
"%s is Denied, whatever is bypassed or allowlisted",
|
|
1215
|
+
(command: string, allowlist: Array<string>) => {
|
|
1216
|
+
const verdict: ResourceAutoExecutionVerdict = autoExecution(
|
|
1217
|
+
command,
|
|
1218
|
+
allowlist,
|
|
1219
|
+
true,
|
|
1220
|
+
);
|
|
1221
|
+
|
|
1222
|
+
expect(verdict.verdict).toBe(AiRemediationCommandPolicyVerdict.Denied);
|
|
1223
|
+
expect(verdict.tier).toBe(ResourceCommandTier.Denied);
|
|
1224
|
+
expect(verdict.reason).toContain("cannot run even with human approval");
|
|
1225
|
+
},
|
|
1226
|
+
);
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
describe("the allowlist", () => {
|
|
1230
|
+
function problem(pattern: unknown): string | null {
|
|
1231
|
+
return ResourceCommandPolicy.describeAllowlistPatternProblem({
|
|
1232
|
+
resourceType: CEPH,
|
|
1233
|
+
pattern,
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
function broad(pattern: unknown): boolean {
|
|
1238
|
+
return ResourceCommandPolicy.isBroadAllowlistPattern({
|
|
1239
|
+
resourceType: CEPH,
|
|
1240
|
+
pattern,
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
test.each([
|
|
1245
|
+
["ceph osd out *"],
|
|
1246
|
+
["ceph osd out 3"],
|
|
1247
|
+
["ceph osd in *"],
|
|
1248
|
+
["ceph osd down *"],
|
|
1249
|
+
["ceph osd set noout"],
|
|
1250
|
+
["ceph osd reweight 3 *"],
|
|
1251
|
+
["ceph osd reweight * 0.5"],
|
|
1252
|
+
["ceph balancer on"],
|
|
1253
|
+
["ceph crash archive-all"],
|
|
1254
|
+
["ceph mgr fail"],
|
|
1255
|
+
["ceph mgr fail *"],
|
|
1256
|
+
["ceph orch restart *"],
|
|
1257
|
+
["ceph orch daemon stop osd.3"],
|
|
1258
|
+
["ceph pg repair 1.2f"],
|
|
1259
|
+
["ceph osd pool set * size 3"],
|
|
1260
|
+
["ceph osd out * --format json"],
|
|
1261
|
+
// The grammar's own words stand in for these `*`s (daemon names, PG ids, flags, weights).
|
|
1262
|
+
["ceph orch daemon stop *"],
|
|
1263
|
+
["ceph pg repair *"],
|
|
1264
|
+
["ceph osd set *"],
|
|
1265
|
+
["ceph osd reweight * *"],
|
|
1266
|
+
])("%s is a valid entry", (pattern: string) => {
|
|
1267
|
+
expect(problem(pattern)).toBeNull();
|
|
1268
|
+
});
|
|
1269
|
+
|
|
1270
|
+
test.each([
|
|
1271
|
+
["ceph status", "fewer than two words"],
|
|
1272
|
+
["ceph -s", "fewer than two words"],
|
|
1273
|
+
["ceph health detail", "read-only command"],
|
|
1274
|
+
["ceph osd tree down", "read-only command"],
|
|
1275
|
+
["ceph osd pool get * size", "read-only command"],
|
|
1276
|
+
["ceph auth get *", "can never match"],
|
|
1277
|
+
["ceph osd purge * --yes-i-really-mean-it", "can never match"],
|
|
1278
|
+
["ceph osd out", "can never match"],
|
|
1279
|
+
["ceph * out 3", "where the command goes"],
|
|
1280
|
+
[
|
|
1281
|
+
"docker restart *",
|
|
1282
|
+
"does not start with a program the Ceph AI agent runs",
|
|
1283
|
+
],
|
|
1284
|
+
["ceph osd out * | tee", "cannot be read as one command"],
|
|
1285
|
+
["", "cannot be blank"],
|
|
1286
|
+
])("%s is refused (%s)", (pattern: string, problemPart: string) => {
|
|
1287
|
+
expect(problem(pattern)).toContain(problemPart);
|
|
1288
|
+
});
|
|
1289
|
+
|
|
1290
|
+
test.each([
|
|
1291
|
+
["ceph osd out *", true],
|
|
1292
|
+
["ceph osd in *", true],
|
|
1293
|
+
["ceph osd down *", true],
|
|
1294
|
+
["ceph osd reweight * 0.5", true],
|
|
1295
|
+
["ceph mgr fail *", true],
|
|
1296
|
+
["ceph orch restart *", true],
|
|
1297
|
+
["ceph osd pool set * size 3", true],
|
|
1298
|
+
["ceph osd out 3", false],
|
|
1299
|
+
["ceph osd reweight 3 *", false],
|
|
1300
|
+
["ceph osd pool set rbd size *", false],
|
|
1301
|
+
["ceph osd set noout", false],
|
|
1302
|
+
["ceph crash archive-all", false],
|
|
1303
|
+
["ceph health detail", false],
|
|
1304
|
+
["ceph orch daemon stop *", true],
|
|
1305
|
+
["ceph pg repair *", true],
|
|
1306
|
+
["ceph osd reweight * *", true],
|
|
1307
|
+
// The flag is a value of a cluster-wide change; the target stays "cluster".
|
|
1308
|
+
["ceph osd set *", false],
|
|
1309
|
+
])("%s broad: %s", (pattern: string, expected: boolean) => {
|
|
1310
|
+
expect(broad(pattern)).toBe(expected);
|
|
1311
|
+
});
|
|
1312
|
+
|
|
1313
|
+
test("matchesAllowlist matches word by word, skipping invalid entries", () => {
|
|
1314
|
+
const matches: (command: string, patterns: Array<string>) => boolean = (
|
|
1315
|
+
command: string,
|
|
1316
|
+
patterns: Array<string>,
|
|
1317
|
+
): boolean => {
|
|
1318
|
+
return ResourceCommandPolicy.matchesAllowlist({
|
|
1319
|
+
resourceType: CEPH,
|
|
1320
|
+
command,
|
|
1321
|
+
patterns,
|
|
1322
|
+
});
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
expect(matches("ceph osd out 3", ["ceph osd out *"])).toBe(true);
|
|
1326
|
+
expect(matches("ceph osd out 3", ["ceph osd out 3"])).toBe(true);
|
|
1327
|
+
expect(matches("ceph osd out osd.3", ["ceph osd out 3"])).toBe(false);
|
|
1328
|
+
expect(matches("ceph osd out 3", ["ceph osd * 3"])).toBe(false);
|
|
1329
|
+
expect(matches("ceph osd out 3", ["ceph osd out"])).toBe(false);
|
|
1330
|
+
expect(matches("ceph osd out 3", ["docker stop *"])).toBe(false);
|
|
1331
|
+
expect(matches("ceph health detail", ["ceph health detail"])).toBe(false);
|
|
1332
|
+
expect(matches("ceph osd out 3 4", ["ceph osd out *"])).toBe(false);
|
|
1333
|
+
});
|
|
1334
|
+
});
|
|
1335
|
+
|
|
1336
|
+
describe("getWriteScopeRefusal with ceph targets", () => {
|
|
1337
|
+
function refusal(
|
|
1338
|
+
command: string,
|
|
1339
|
+
options: {
|
|
1340
|
+
allowWrites?: boolean;
|
|
1341
|
+
writeTargets?: Array<string>;
|
|
1342
|
+
protectedTargets?: Array<string>;
|
|
1343
|
+
} = {},
|
|
1344
|
+
): string | null {
|
|
1345
|
+
return ResourceCommandPolicy.getWriteScopeRefusal({
|
|
1346
|
+
result: evaluate(command),
|
|
1347
|
+
allowWrites: options.allowWrites !== false,
|
|
1348
|
+
writeTargets: options.writeTargets || [],
|
|
1349
|
+
protectedTargets: options.protectedTargets || [],
|
|
1350
|
+
resourceType: CEPH,
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
test("reads are never refused, not even read-only", () => {
|
|
1355
|
+
expect(refusal("ceph status", { allowWrites: false })).toBeNull();
|
|
1356
|
+
expect(refusal("ceph osd tree", { writeTargets: ["osd.1"] })).toBeNull();
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
test("a Denied command is refused", () => {
|
|
1360
|
+
expect(refusal("ceph auth ls")).toContain("denied by the command policy");
|
|
1361
|
+
});
|
|
1362
|
+
|
|
1363
|
+
test("a read-only agent refuses every write and names the setting", () => {
|
|
1364
|
+
const text: string | null = refusal("ceph osd in 3", {
|
|
1365
|
+
allowWrites: false,
|
|
1366
|
+
});
|
|
1367
|
+
|
|
1368
|
+
expect(text).toContain(`${RESOURCE_AI_ALLOW_WRITES_ENV}=true`);
|
|
1369
|
+
expect(text).toContain("Ceph AI agent");
|
|
1370
|
+
});
|
|
1371
|
+
|
|
1372
|
+
test("with no write targets configured, any write may run", () => {
|
|
1373
|
+
for (const [command] of [
|
|
1374
|
+
...SAFE_WRITES,
|
|
1375
|
+
...RISKY_WRITES,
|
|
1376
|
+
...ALWAYS_HUMAN_WRITES,
|
|
1377
|
+
]) {
|
|
1378
|
+
expect(refusal(command as string)).toBeNull();
|
|
1379
|
+
}
|
|
1380
|
+
});
|
|
1381
|
+
|
|
1382
|
+
test.each([
|
|
1383
|
+
["ceph osd out 3", ["osd.*"], true],
|
|
1384
|
+
["ceph osd out osd.3", ["osd.3"], true],
|
|
1385
|
+
["ceph orch daemon restart osd.3", ["osd.*"], true],
|
|
1386
|
+
["ceph orch daemon restart mon.host1", ["osd.*"], false],
|
|
1387
|
+
["ceph osd set noout", ["osd.*"], false],
|
|
1388
|
+
["ceph osd set noout", ["cluster"], true],
|
|
1389
|
+
["ceph balancer on", ["cluster"], true],
|
|
1390
|
+
["ceph crash archive-all", ["cluster"], true],
|
|
1391
|
+
["ceph mgr fail", ["cluster"], true],
|
|
1392
|
+
["ceph mgr fail host1.abc", ["cluster"], false],
|
|
1393
|
+
["ceph mgr fail host1.abc", ["mgr.*"], true],
|
|
1394
|
+
[`ceph crash archive ${CRASH_ID}`, ["crash/*"], true],
|
|
1395
|
+
[`ceph crash archive ${CRASH_ID}`, ["osd.*"], false],
|
|
1396
|
+
["ceph pg scrub 1.2f", ["1.*"], true],
|
|
1397
|
+
["ceph pg scrub 2.0", ["1.*"], false],
|
|
1398
|
+
["ceph pg repair 1.2f", ["osd.*"], false],
|
|
1399
|
+
["ceph osd pool set rbd size 3", ["rbd"], true],
|
|
1400
|
+
["ceph osd pool set images size 3", ["rbd"], false],
|
|
1401
|
+
["ceph orch restart rgw.store", ["rgw.*"], true],
|
|
1402
|
+
])(
|
|
1403
|
+
"%s with write targets %p allowed: %s",
|
|
1404
|
+
(command: string, writeTargets: Array<string>, allowed: boolean) => {
|
|
1405
|
+
const text: string | null = refusal(command, { writeTargets });
|
|
1406
|
+
|
|
1407
|
+
if (allowed) {
|
|
1408
|
+
expect(text).toBeNull();
|
|
1409
|
+
} else {
|
|
1410
|
+
expect(text).toContain(RESOURCE_AI_WRITE_TARGETS_ENV);
|
|
1411
|
+
}
|
|
1412
|
+
},
|
|
1413
|
+
);
|
|
1414
|
+
|
|
1415
|
+
test("protected targets are never changed, in either OSD spelling", () => {
|
|
1416
|
+
expect(
|
|
1417
|
+
refusal("ceph osd out 3", { protectedTargets: ["osd.3"] }),
|
|
1418
|
+
).toContain("protects");
|
|
1419
|
+
expect(
|
|
1420
|
+
refusal("ceph osd out osd.3", { protectedTargets: ["osd.3"] }),
|
|
1421
|
+
).toContain("protects");
|
|
1422
|
+
expect(
|
|
1423
|
+
refusal("ceph orch daemon stop osd.3", { protectedTargets: ["osd.3"] }),
|
|
1424
|
+
).toContain("protects");
|
|
1425
|
+
expect(
|
|
1426
|
+
refusal("ceph mgr fail host1.abc", {
|
|
1427
|
+
protectedTargets: ["mgr.host1.abc"],
|
|
1428
|
+
}),
|
|
1429
|
+
).toContain("protects");
|
|
1430
|
+
expect(
|
|
1431
|
+
refusal("ceph osd out 4", { protectedTargets: ["osd.3"] }),
|
|
1432
|
+
).toBeNull();
|
|
1433
|
+
});
|
|
1434
|
+
});
|
|
1435
|
+
|
|
1436
|
+
// ---- Guides -------------------------------------------------------------------
|
|
1437
|
+
|
|
1438
|
+
describe("the command guides", () => {
|
|
1439
|
+
const read: string = CephCommandPolicy.readCommandGuide;
|
|
1440
|
+
const write: string = CephCommandPolicy.writeCommandGuide;
|
|
1441
|
+
|
|
1442
|
+
test("the dispatcher serves them for Ceph clusters", () => {
|
|
1443
|
+
expect(ResourceCommandPolicy.getReadCommandGuide(CEPH)).toBe(read);
|
|
1444
|
+
expect(ResourceCommandPolicy.getWriteCommandGuide(CEPH)).toBe(write);
|
|
1445
|
+
});
|
|
1446
|
+
|
|
1447
|
+
test("are compact markdown bullets", () => {
|
|
1448
|
+
for (const guide of [read, write]) {
|
|
1449
|
+
for (const line of guide.split("\n")) {
|
|
1450
|
+
expect(line.startsWith("- ")).toBe(true);
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
expect(guide.length).toBeLessThan(2000);
|
|
1454
|
+
}
|
|
1455
|
+
});
|
|
1456
|
+
|
|
1457
|
+
test("mention every command the grammar accepts", () => {
|
|
1458
|
+
const both: string = `${read}\n${write}`;
|
|
1459
|
+
|
|
1460
|
+
for (const command of CEPH_COMMANDS) {
|
|
1461
|
+
const words: Array<string> = command.split(" ");
|
|
1462
|
+
const last: string = words.pop() as string;
|
|
1463
|
+
const prefix: string =
|
|
1464
|
+
command === "pg query" || command === "pg list_unfound"
|
|
1465
|
+
? "ceph pg PGID "
|
|
1466
|
+
: `ceph ${words
|
|
1467
|
+
.map((word: string) => {
|
|
1468
|
+
return `${word} `;
|
|
1469
|
+
})
|
|
1470
|
+
.join("")}`;
|
|
1471
|
+
const escape: (text: string) => string = (text: string): string => {
|
|
1472
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1473
|
+
};
|
|
1474
|
+
const pattern: RegExp = new RegExp(
|
|
1475
|
+
`${escape(prefix)}(?:[\\w-]+\\|)*${escape(last)}(?:\\|[\\w-]+)*(?=[ \`])`,
|
|
1476
|
+
);
|
|
1477
|
+
|
|
1478
|
+
expect(both).toMatch(pattern);
|
|
1479
|
+
}
|
|
1480
|
+
});
|
|
1481
|
+
|
|
1482
|
+
test("put reads in the read guide and changes in the write guide", () => {
|
|
1483
|
+
expect(read).toContain("`ceph status`");
|
|
1484
|
+
expect(read).toContain("--format json");
|
|
1485
|
+
expect(read).not.toContain("ceph osd out");
|
|
1486
|
+
expect(write).toContain("SafeWrite");
|
|
1487
|
+
expect(write).toContain("RiskyWrite");
|
|
1488
|
+
expect(write).toContain("Always asks a human");
|
|
1489
|
+
expect(write).toContain("`ceph osd set pause`");
|
|
1490
|
+
expect(write).toContain("Never runs");
|
|
1491
|
+
});
|
|
1492
|
+
|
|
1493
|
+
test.each([
|
|
1494
|
+
["ceph osd in 3", ResourceCommandTier.SafeWrite, "ceph osd in ID"],
|
|
1495
|
+
["ceph osd out 3", ResourceCommandTier.RiskyWrite, "ceph osd out ID"],
|
|
1496
|
+
["ceph pg scrub 1.2f", ResourceCommandTier.SafeWrite, "ceph pg scrub PGID"],
|
|
1497
|
+
[
|
|
1498
|
+
"ceph orch daemon restart osd.3",
|
|
1499
|
+
ResourceCommandTier.SafeWrite,
|
|
1500
|
+
"ceph orch daemon restart TYPE.ID",
|
|
1501
|
+
],
|
|
1502
|
+
[
|
|
1503
|
+
"ceph orch restart mgr",
|
|
1504
|
+
ResourceCommandTier.RiskyWrite,
|
|
1505
|
+
"ceph orch restart SERVICE",
|
|
1506
|
+
],
|
|
1507
|
+
])(
|
|
1508
|
+
"the guide's tier for %s matches the grammar",
|
|
1509
|
+
(command: string, tier: ResourceCommandTier, guideForm: string) => {
|
|
1510
|
+
expect(evaluate(command).tier).toBe(tier);
|
|
1511
|
+
|
|
1512
|
+
const bullet: string | undefined = write
|
|
1513
|
+
.split("\n")
|
|
1514
|
+
.find((line: string): boolean => {
|
|
1515
|
+
return line.includes(guideForm);
|
|
1516
|
+
});
|
|
1517
|
+
|
|
1518
|
+
expect(bullet).toBeDefined();
|
|
1519
|
+
expect(bullet).toContain(
|
|
1520
|
+
tier === ResourceCommandTier.SafeWrite ? "SafeWrite" : "RiskyWrite",
|
|
1521
|
+
);
|
|
1522
|
+
},
|
|
1523
|
+
);
|
|
1524
|
+
});
|
|
1525
|
+
|
|
1526
|
+
// ---- Output redaction ---------------------------------------------------------
|
|
1527
|
+
|
|
1528
|
+
function redactCeph(text: string): ResourceOutputRedaction {
|
|
1529
|
+
return redactResourceCommandOutputWithCount({
|
|
1530
|
+
resourceType: CEPH,
|
|
1531
|
+
program: "ceph",
|
|
1532
|
+
text,
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
describe("ceph output redaction", () => {
|
|
1537
|
+
test("ceph has the keyring hook and the secret-value hook", () => {
|
|
1538
|
+
expect(getResourceOutputRedactionHooks("ceph").length).toBe(2);
|
|
1539
|
+
});
|
|
1540
|
+
|
|
1541
|
+
test.each([
|
|
1542
|
+
[`${CEPHX_SECRET}\n`, CEPHX_SECRET],
|
|
1543
|
+
[`exported keyring ${CEPHX_SECRET} for client.x`, CEPHX_SECRET],
|
|
1544
|
+
[`{\\"key\\": \\"${CEPHX_SECRET}\\"}`, CEPHX_SECRET],
|
|
1545
|
+
[`--key=${CEPHX_SECRET}`, CEPHX_SECRET],
|
|
1546
|
+
[`[client.admin]\n\tkey = ${CEPHX_SECRET}\n`, CEPHX_SECRET],
|
|
1547
|
+
[`client.admin\n\tkey: ${CEPHX_SECRET}\n`, CEPHX_SECRET],
|
|
1548
|
+
[`[{"entity":"client.admin","key":"${CEPHX_SECRET}"}]`, CEPHX_SECRET],
|
|
1549
|
+
[
|
|
1550
|
+
`audit [INF] from='client.? 10.0.0.1:0/1' entity='client.admin' cmd=[{"prefix": "config-key set", "key": "mgr/dashboard/pwd", "val": "hunter2"}]: dispatch`,
|
|
1551
|
+
"hunter2",
|
|
1552
|
+
],
|
|
1553
|
+
[
|
|
1554
|
+
`audit [INF] cmd=[{"prefix":"config set","who":"client.rgw","name":"rgw_keystone_admin_password","value":"s3cr3t-pw"}]: dispatch`,
|
|
1555
|
+
"s3cr3t-pw",
|
|
1556
|
+
],
|
|
1557
|
+
[
|
|
1558
|
+
`{"message":"cmd=[{\\"prefix\\": \\"config-key set\\", \\"key\\": \\"k\\", \\"val\\": \\"hunter2\\"}]: dispatch"}`,
|
|
1559
|
+
"hunter2",
|
|
1560
|
+
],
|
|
1561
|
+
[
|
|
1562
|
+
`{"message":"cmd=[{\\"prefix\\": \\"config-key set\\", \\"key\\": \\"k\\", \\"val\\": \\"{\\\\\\"password\\\\\\": \\\\\\"s3cr3t\\\\\\"}\\"}]: dispatch"}`,
|
|
1563
|
+
"s3cr3t",
|
|
1564
|
+
],
|
|
1565
|
+
[`{"val": "multi \\"quoted\\" secret"}`, "secret"],
|
|
1566
|
+
])("%p loses %p", (text: string, secret: string) => {
|
|
1567
|
+
const redacted: ResourceOutputRedaction = redactCeph(text);
|
|
1568
|
+
|
|
1569
|
+
expect(redacted.text).not.toContain(secret);
|
|
1570
|
+
expect(redacted.text).toContain("[redacted]");
|
|
1571
|
+
expect(redacted.redactionCount).toBeGreaterThan(0);
|
|
1572
|
+
});
|
|
1573
|
+
|
|
1574
|
+
test("what the audit entry did stays readable", () => {
|
|
1575
|
+
const redacted: string = redactResourceCommandOutput({
|
|
1576
|
+
resourceType: CEPH,
|
|
1577
|
+
program: "ceph",
|
|
1578
|
+
text: `audit [INF] cmd=[{"prefix": "config-key set", "key": "k", "val": "hunter2"}]: dispatch`,
|
|
1579
|
+
});
|
|
1580
|
+
|
|
1581
|
+
expect(redacted).toContain('"prefix": "config-key set"');
|
|
1582
|
+
expect(redacted).toContain(": dispatch");
|
|
1583
|
+
});
|
|
1584
|
+
|
|
1585
|
+
test("redaction is idempotent", () => {
|
|
1586
|
+
const once: string = redactCeph(
|
|
1587
|
+
`{"val": "hunter2"} ${CEPHX_SECRET} key = ${CEPHX_SECRET}`,
|
|
1588
|
+
).text;
|
|
1589
|
+
const twice: ResourceOutputRedaction = redactCeph(once);
|
|
1590
|
+
|
|
1591
|
+
expect(twice.text).toBe(once);
|
|
1592
|
+
});
|
|
1593
|
+
|
|
1594
|
+
test.each([
|
|
1595
|
+
[
|
|
1596
|
+
"ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF\n-1 0.29306 root default\n-3 0.09769 host node1\n 0 hdd 0.09769 osd.0 up 1.00000 1.00000",
|
|
1597
|
+
],
|
|
1598
|
+
[
|
|
1599
|
+
"HEALTH_WARN 1 osds down; Degraded data redundancy: 12/345 objects degraded (3.478%), 5 pgs degraded\n[WRN] OSD_DOWN: 1 osds down\n osd.3 (root=default,host=node2) is down",
|
|
1600
|
+
],
|
|
1601
|
+
[
|
|
1602
|
+
"--- RAW STORAGE ---\nCLASS SIZE AVAIL USED RAW USED %RAW USED\nhdd 300 GiB 290 GiB 10 GiB 10 GiB 3.33",
|
|
1603
|
+
],
|
|
1604
|
+
[
|
|
1605
|
+
"ok\npg_stat\tstate\tup\tup_primary\tacting\tacting_primary\n1.2f\tstale+active+clean\t[0,1,2]\t0\t[0,1,2]\t0",
|
|
1606
|
+
],
|
|
1607
|
+
['{"val": ""}'],
|
|
1608
|
+
])("ordinary ceph output keeps its values: %p", (text: string) => {
|
|
1609
|
+
for (const hook of getResourceOutputRedactionHooks("ceph")) {
|
|
1610
|
+
const hooked: ResourceOutputRedaction = (
|
|
1611
|
+
hook as ResourceOutputRedactionHook
|
|
1612
|
+
)({ resourceType: CEPH, program: "ceph", text });
|
|
1613
|
+
|
|
1614
|
+
expect(hooked.text).toBe(text);
|
|
1615
|
+
expect(hooked.redactionCount).toBe(0);
|
|
1616
|
+
}
|
|
1617
|
+
});
|
|
1618
|
+
|
|
1619
|
+
test("the ceph hooks are total and linear on hostile text", () => {
|
|
1620
|
+
const started: number = Date.now();
|
|
1621
|
+
const hostile: Array<string> = [
|
|
1622
|
+
"",
|
|
1623
|
+
`AQ${"A".repeat(200000)}`,
|
|
1624
|
+
'"val": "'.repeat(20000),
|
|
1625
|
+
'\\"val\\": \\"'.repeat(20000),
|
|
1626
|
+
`{"val": "${"\\\\".repeat(50000)}`,
|
|
1627
|
+
`\\"value\\": \\"${"\\\\\\\\".repeat(50000)}`,
|
|
1628
|
+
];
|
|
1629
|
+
|
|
1630
|
+
for (const text of hostile) {
|
|
1631
|
+
for (const hook of getResourceOutputRedactionHooks("ceph")) {
|
|
1632
|
+
expect((): void => {
|
|
1633
|
+
hook({ resourceType: CEPH, program: "ceph", text });
|
|
1634
|
+
}).not.toThrow();
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
expect(Date.now() - started).toBeLessThan(3000);
|
|
1639
|
+
});
|
|
1640
|
+
|
|
1641
|
+
test("the ceph hooks run for ceph only", () => {
|
|
1642
|
+
const text: string = '{"val": "plain-value"}';
|
|
1643
|
+
|
|
1644
|
+
expect(
|
|
1645
|
+
redactResourceCommandOutput({
|
|
1646
|
+
resourceType: AiResourceType.Host,
|
|
1647
|
+
program: "unknown-program",
|
|
1648
|
+
text,
|
|
1649
|
+
}),
|
|
1650
|
+
).toContain("plain-value");
|
|
1651
|
+
expect(redactCeph(text).text).not.toContain("plain-value");
|
|
1652
|
+
});
|
|
1653
|
+
});
|