@oneuptime/common 14.0.9 → 14.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/AutoRemediationSuggestion.ts +60 -0
- package/Models/DatabaseModels/CephCluster.ts +213 -0
- package/Models/DatabaseModels/DatabaseServer.ts +213 -0
- package/Models/DatabaseModels/DockerHost.ts +213 -0
- package/Models/DatabaseModels/DockerSwarmCluster.ts +213 -0
- package/Models/DatabaseModels/GlobalConfig.ts +1 -1
- package/Models/DatabaseModels/Host.ts +213 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/PodmanHost.ts +213 -0
- package/Models/DatabaseModels/ProxmoxCluster.ts +213 -0
- package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
- package/Models/DatabaseModels/RunnerJob.ts +144 -0
- package/Models/DatabaseModels/VMwareVCenter.ts +213 -0
- package/Server/API/AutoRemediationAPI.ts +392 -1
- package/Server/API/ResourceAiAccessAPI.ts +1669 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Infrastructure/Semaphore.ts +22 -0
- package/Server/Middleware/TelemetryIngest.ts +15 -5
- 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/MetricRecordingRuleService.ts +47 -0
- package/Server/Services/PodmanHostService.ts +109 -1
- 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/TelemetryUsageBillingService.ts +28 -0
- package/Server/Services/TraceRecordingRuleService.ts +33 -0
- package/Server/Services/VMwareVCenterService.ts +110 -1
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1434 -32
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +935 -21
- package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
- package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +577 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
- package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
- package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +873 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +72 -2
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +72 -5
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +72 -5
- 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/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
- package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +35 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +298 -224
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +35 -15
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +366 -143
- 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/Dashboard/ClusterAccessNotice.test.tsx +93 -0
- package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +18 -6
- package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardDescription.test.tsx +209 -0
- package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
- package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
- package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
- package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +1721 -0
- package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1002 -0
- package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
- package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
- package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
- package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +33 -1
- package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
- package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
- package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
- package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
- package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
- package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -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/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/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
- package/Tests/Server/Services/RecordingRuleReservedMetricName.test.ts +171 -0
- package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
- package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
- package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
- package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
- package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
- package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
- package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
- package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
- package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +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/TelemetryUsageBillingSloExclusion.test.ts +218 -0
- package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
- package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +453 -0
- package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
- package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
- package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1249 -0
- package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
- package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
- package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +722 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +830 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
- package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
- package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
- package/Tests/Server/Utils/Telemetry/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/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
- package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
- package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
- package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +517 -0
- package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
- package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
- 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/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
- package/Types/AI/ResourceAiAccessApi.ts +140 -0
- package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +183 -2
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
- package/Types/Monitor/RumAlertTemplates.ts +351 -4
- package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
- package/Types/ResourceAiAgent/ResourceAiAccess.ts +574 -0
- package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
- package/Types/Runbook/RunbookStepType.ts +29 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +14 -2
- 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/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
- package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js +219 -0
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseServer.js +219 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +219 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +219 -0
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +219 -0
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PodmanHost.js +219 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +219 -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/RunnerJob.js +145 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js +219 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +231 -1
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/ResourceAiAccessAPI.js +1119 -0
- package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js +168 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +12 -5
- package/build/dist/Server/Middleware/TelemetryIngest.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/MetricRecordingRuleService.js +46 -0
- package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostService.js +104 -0
- package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
- package/build/dist/Server/Services/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/TelemetryUsageBillingService.js +26 -0
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
- package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
- package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1029 -30
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +633 -28
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +330 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +600 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +50 -4
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +55 -4
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +55 -4
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/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/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/Workspace/MicrosoftTeams/Actions/Alert.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +183 -209
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +19 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +263 -110
- 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/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/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
- package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +275 -0
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
- package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
- package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +13 -2
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.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/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
- package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { JSONObject } from "../../../../Types/JSON";
|
|
2
|
+
import ErrorClass from "../../../../Types/Telemetry/ErrorClass";
|
|
3
|
+
import { ERROR_CLASS_ATTRIBUTE_KEY } from "../../../../Types/Telemetry/UnitOfWork";
|
|
4
|
+
import GlobalCache from "../../../Infrastructure/GlobalCache";
|
|
5
|
+
import InMemoryTTLCache from "../../../Infrastructure/InMemoryTTLCache";
|
|
6
|
+
import Redis from "../../../Infrastructure/Redis";
|
|
7
|
+
import logger, { LogAttributes } from "../../Logger";
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* Teams delivers an activity again when the bot was slow to answer it
|
|
11
|
+
* (documented: more than 15 seconds) and, in practice, when the bot answered
|
|
12
|
+
* it with an error. The redelivery carries the same activity id. Without a
|
|
13
|
+
* guard the user sees every reply twice, and a submitted form creates two
|
|
14
|
+
* incidents (issue #4111 showed each error bubble twice). Claiming the id
|
|
15
|
+
* before acting on an activity turns every delivery after the first into a
|
|
16
|
+
* no-op.
|
|
17
|
+
*
|
|
18
|
+
* The claim is shared through Redis, because a redelivery can reach another
|
|
19
|
+
* App instance, and kept in this process's memory as well. When Redis is
|
|
20
|
+
* disconnected the memory decides at once; when it is slow, after at most
|
|
21
|
+
* REDIS_CLAIM_TIMEOUT_IN_MS. Memory alone still covers a single instance.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const CLAIM_NAMESPACE: string = "microsoft-teams-inbound-activity";
|
|
25
|
+
|
|
26
|
+
// Redeliveries arrive within seconds; ten minutes leaves a wide margin.
|
|
27
|
+
const CLAIM_TTL_IN_SECONDS: number = 10 * 60;
|
|
28
|
+
|
|
29
|
+
// How long a Redis claim may take before this process's memory decides.
|
|
30
|
+
const REDIS_CLAIM_TIMEOUT_IN_MS: number = 2000;
|
|
31
|
+
|
|
32
|
+
// A Redis fallback is logged at most this often; each message would repeat it.
|
|
33
|
+
const FALLBACK_LOG_INTERVAL_IN_MS: number = 60 * 1000;
|
|
34
|
+
|
|
35
|
+
export default class MicrosoftTeamsActivityDeduplicator {
|
|
36
|
+
private static localClaims: InMemoryTTLCache<boolean> =
|
|
37
|
+
new InMemoryTTLCache<boolean>(10_000);
|
|
38
|
+
|
|
39
|
+
private static lastFallbackLoggedAt: number = 0;
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
* The key an activity is claimed under: its conversation and its id. Null
|
|
43
|
+
* when the activity has no id, which Teams always sends.
|
|
44
|
+
*/
|
|
45
|
+
public static getClaimKey(activity: JSONObject): string | null {
|
|
46
|
+
const activityId: string = (activity["id"] as string | undefined) || "";
|
|
47
|
+
|
|
48
|
+
if (!activityId) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const conversationId: string =
|
|
53
|
+
((activity["conversation"] as JSONObject | undefined)?.["id"] as
|
|
54
|
+
| string
|
|
55
|
+
| undefined) || "";
|
|
56
|
+
|
|
57
|
+
return `${conversationId}|${activityId}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
* True for the first delivery of an activity, false for a repeat. An
|
|
62
|
+
* activity without an id is always processed.
|
|
63
|
+
*/
|
|
64
|
+
public static async claim(activity: JSONObject): Promise<boolean> {
|
|
65
|
+
const key: string | null = this.getClaimKey(activity);
|
|
66
|
+
|
|
67
|
+
if (!key) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/*
|
|
72
|
+
* This process's memory is consulted whatever Redis says: a claim made
|
|
73
|
+
* here while Redis was down never reached Redis, so once Redis is back it
|
|
74
|
+
* would let a redelivery of that activity through.
|
|
75
|
+
*/
|
|
76
|
+
const isClaimedHere: boolean = this.localClaims.has(key);
|
|
77
|
+
|
|
78
|
+
// A repeat leaves the claim alone, so it lapses with the Redis key.
|
|
79
|
+
if (!isClaimedHere) {
|
|
80
|
+
this.localClaims.set(key, true, CLAIM_TTL_IN_SECONDS * 1000);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Asked even then, so that other App instances learn of the claim.
|
|
84
|
+
const claimedInRedis: boolean | null = await this.claimInRedis(key);
|
|
85
|
+
|
|
86
|
+
if (isClaimedHere) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return claimedInRedis ?? true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// The Redis answer, or null when Redis could not answer in time.
|
|
94
|
+
private static async claimInRedis(key: string): Promise<boolean | null> {
|
|
95
|
+
let timeout: ReturnType<typeof setTimeout> | undefined = undefined;
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
return await Promise.race([
|
|
99
|
+
GlobalCache.setStringIfNotExists(CLAIM_NAMESPACE, key, "1", {
|
|
100
|
+
expiresInSeconds: CLAIM_TTL_IN_SECONDS,
|
|
101
|
+
}),
|
|
102
|
+
new Promise<null>((resolve: (value: null) => void) => {
|
|
103
|
+
timeout = setTimeout(() => {
|
|
104
|
+
this.logFallback(
|
|
105
|
+
`Redis did not answer within ${REDIS_CLAIM_TIMEOUT_IN_MS} ms`,
|
|
106
|
+
);
|
|
107
|
+
resolve(null);
|
|
108
|
+
}, REDIS_CLAIM_TIMEOUT_IN_MS);
|
|
109
|
+
}),
|
|
110
|
+
]);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
this.logFallback("Redis refused the claim", error);
|
|
113
|
+
return null;
|
|
114
|
+
} finally {
|
|
115
|
+
if (timeout) {
|
|
116
|
+
clearTimeout(timeout);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/*
|
|
122
|
+
* Falling back to memory means a redelivery that reaches another App
|
|
123
|
+
* instance is handled twice, which an operator should hear about. Logged at
|
|
124
|
+
* error level (warn is dropped at the default LOG_LEVEL) and at most once a
|
|
125
|
+
* minute. A process that never had a Redis client (a script, a test) has no
|
|
126
|
+
* other instance to share with, so it only logs at debug.
|
|
127
|
+
*
|
|
128
|
+
* It never throws: it runs from the claim's catch and from its timeout, and
|
|
129
|
+
* a throw there would lose the claim, or the reply, over a log line.
|
|
130
|
+
*/
|
|
131
|
+
private static logFallback(reason: string, error?: unknown): void {
|
|
132
|
+
try {
|
|
133
|
+
const now: number = Date.now();
|
|
134
|
+
|
|
135
|
+
if (
|
|
136
|
+
!Redis.getClient() ||
|
|
137
|
+
now - this.lastFallbackLoggedAt < FALLBACK_LOG_INTERVAL_IN_MS
|
|
138
|
+
) {
|
|
139
|
+
logger.debug(
|
|
140
|
+
`Microsoft Teams activity dedupe is using this process's memory: ${reason}`,
|
|
141
|
+
);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
this.lastFallbackLoggedAt = now;
|
|
146
|
+
|
|
147
|
+
const attributes: LogAttributes = {
|
|
148
|
+
[ERROR_CLASS_ATTRIBUTE_KEY]: ErrorClass.Infrastructure,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
logger.error(
|
|
152
|
+
`Microsoft Teams activity dedupe fell back to this process's memory (${reason}); a Teams redelivery that reaches another App instance may be handled twice.`,
|
|
153
|
+
attributes,
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
if (error) {
|
|
157
|
+
logger.error(error, attributes);
|
|
158
|
+
}
|
|
159
|
+
} catch {
|
|
160
|
+
// Nothing to do: the claim goes on from memory either way.
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { JSONObject } from "../../../../Types/JSON";
|
|
2
|
+
import ObjectID from "../../../../Types/ObjectID";
|
|
3
|
+
import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
|
|
4
|
+
import Monitor from "../../../../Models/DatabaseModels/Monitor";
|
|
5
|
+
import MonitorStatus from "../../../../Models/DatabaseModels/MonitorStatus";
|
|
6
|
+
import Label from "../../../../Models/DatabaseModels/Label";
|
|
7
|
+
import IncidentSeverity from "../../../../Models/DatabaseModels/IncidentSeverity";
|
|
8
|
+
import OnCallDutyPolicy from "../../../../Models/DatabaseModels/OnCallDutyPolicy";
|
|
9
|
+
import MonitorService from "../../../Services/MonitorService";
|
|
10
|
+
import MonitorStatusService from "../../../Services/MonitorStatusService";
|
|
11
|
+
import LabelService from "../../../Services/LabelService";
|
|
12
|
+
import IncidentSeverityService from "../../../Services/IncidentSeverityService";
|
|
13
|
+
import OnCallDutyPolicyService from "../../../Services/OnCallDutyPolicyService";
|
|
14
|
+
import { truncateToLength } from "../../Database/TruncateColumnValue";
|
|
15
|
+
import MicrosoftTeamsMessageSize from "./MicrosoftTeamsMessageSize";
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* The choice lists of the "create incident" and "create maintenance" cards.
|
|
19
|
+
*
|
|
20
|
+
* Those cards used to list every monitor, label and on-call policy of the
|
|
21
|
+
* project (up to 10,000 of each), which Microsoft Teams refuses as too large
|
|
22
|
+
* once a project has a few hundred of them (issue #4111). Each list is now
|
|
23
|
+
* read up to a cap (monitors, labels and on-call policies in name order,
|
|
24
|
+
* severities and monitor statuses in their own order), and fitCardToBudget()
|
|
25
|
+
* shortens the long lists until the card fits a size budget. Whatever is
|
|
26
|
+
* left off is named on the card, so the user knows to add it in OneUptime.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// A type, not an interface, so a list of them is a JSONValue on a card.
|
|
30
|
+
export type MicrosoftTeamsCardChoice = {
|
|
31
|
+
title: string;
|
|
32
|
+
value: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// The choices of one list, and how many records the project has in all.
|
|
36
|
+
export interface MicrosoftTeamsCardChoiceList {
|
|
37
|
+
choices: Array<MicrosoftTeamsCardChoice>;
|
|
38
|
+
totalCount: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface MicrosoftTeamsFittedCard<TKey extends string> {
|
|
42
|
+
card: JSONObject;
|
|
43
|
+
// How many choices of each list the card shows.
|
|
44
|
+
shownCounts: Record<TKey, number>;
|
|
45
|
+
// False when the card is over budget even with every trimmable list empty.
|
|
46
|
+
fitsBudget: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
* Most choices read for one list. The size budget, not these caps, decides
|
|
51
|
+
* how many a card shows; the caps only keep the reads small. More than a
|
|
52
|
+
* couple of hundred entries is not a usable dropdown anyway.
|
|
53
|
+
*/
|
|
54
|
+
export const MICROSOFT_TEAMS_MAX_MONITOR_CHOICES: number = 250;
|
|
55
|
+
export const MICROSOFT_TEAMS_MAX_LABEL_CHOICES: number = 100;
|
|
56
|
+
export const MICROSOFT_TEAMS_MAX_ON_CALL_POLICY_CHOICES: number = 100;
|
|
57
|
+
export const MICROSOFT_TEAMS_MAX_SEVERITY_CHOICES: number = 50;
|
|
58
|
+
export const MICROSOFT_TEAMS_MAX_MONITOR_STATUS_CHOICES: number = 50;
|
|
59
|
+
|
|
60
|
+
// Longer names are cut: a Teams dropdown shows about this much of a row.
|
|
61
|
+
export const MICROSOFT_TEAMS_MAX_CHOICE_TITLE_LENGTH: number = 80;
|
|
62
|
+
|
|
63
|
+
type NamedRecord = {
|
|
64
|
+
_id?: string | undefined;
|
|
65
|
+
name?: string | undefined;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default class MicrosoftTeamsCardChoices {
|
|
69
|
+
// Rows to choices, skipping rows without a name or id.
|
|
70
|
+
public static toChoices(
|
|
71
|
+
rows: Array<NamedRecord>,
|
|
72
|
+
): Array<MicrosoftTeamsCardChoice> {
|
|
73
|
+
const choices: Array<MicrosoftTeamsCardChoice> = [];
|
|
74
|
+
|
|
75
|
+
for (const row of rows) {
|
|
76
|
+
const title: string = (row.name || "").trim();
|
|
77
|
+
const value: string = row._id?.toString() || "";
|
|
78
|
+
|
|
79
|
+
if (!title || !value) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
choices.push({
|
|
84
|
+
title:
|
|
85
|
+
title.length > MICROSOFT_TEAMS_MAX_CHOICE_TITLE_LENGTH
|
|
86
|
+
? truncateToLength(
|
|
87
|
+
title,
|
|
88
|
+
MICROSOFT_TEAMS_MAX_CHOICE_TITLE_LENGTH - 1,
|
|
89
|
+
) + "…"
|
|
90
|
+
: title,
|
|
91
|
+
value: value,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return choices;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/*
|
|
99
|
+
* Builds the card from every choice it was given, then, while it is over
|
|
100
|
+
* the budget, shortens the longest trimmable list by a quarter (at least by
|
|
101
|
+
* one). The longest list goes first because it is what makes the card big,
|
|
102
|
+
* and shortening it by a share keeps the number of rebuilds small even for
|
|
103
|
+
* hundreds of choices. Lists that are not trimmable are always shown whole.
|
|
104
|
+
*/
|
|
105
|
+
public static fitCardToBudget<TKey extends string>(data: {
|
|
106
|
+
lists: Record<TKey, MicrosoftTeamsCardChoiceList>;
|
|
107
|
+
trimmableKeys: ReadonlyArray<TKey>;
|
|
108
|
+
budgetInBytes: number;
|
|
109
|
+
buildCard: (
|
|
110
|
+
shownLists: Record<TKey, MicrosoftTeamsCardChoiceList>,
|
|
111
|
+
) => JSONObject;
|
|
112
|
+
}): MicrosoftTeamsFittedCard<TKey> {
|
|
113
|
+
const keys: Array<TKey> = Object.keys(data.lists) as Array<TKey>;
|
|
114
|
+
const shownCounts: Record<TKey, number> = {} as Record<TKey, number>;
|
|
115
|
+
|
|
116
|
+
for (const key of keys) {
|
|
117
|
+
shownCounts[key] = data.lists[key].choices.length;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// No budget: leave every trimmable list off in one go.
|
|
121
|
+
if (data.budgetInBytes <= 0) {
|
|
122
|
+
for (const key of data.trimmableKeys) {
|
|
123
|
+
shownCounts[key] = 0;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const build: () => JSONObject = (): JSONObject => {
|
|
128
|
+
const shownLists: Record<TKey, MicrosoftTeamsCardChoiceList> =
|
|
129
|
+
{} as Record<TKey, MicrosoftTeamsCardChoiceList>;
|
|
130
|
+
|
|
131
|
+
for (const key of keys) {
|
|
132
|
+
shownLists[key] = {
|
|
133
|
+
choices: data.lists[key].choices.slice(0, shownCounts[key]),
|
|
134
|
+
totalCount: data.lists[key].totalCount,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return data.buildCard(shownLists);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
let card: JSONObject = build();
|
|
142
|
+
|
|
143
|
+
while (
|
|
144
|
+
MicrosoftTeamsMessageSize.getSizeInBytes(card) > data.budgetInBytes
|
|
145
|
+
) {
|
|
146
|
+
let longestKey: TKey | null = null;
|
|
147
|
+
|
|
148
|
+
for (const key of data.trimmableKeys) {
|
|
149
|
+
if (
|
|
150
|
+
shownCounts[key] > 0 &&
|
|
151
|
+
(longestKey === null || shownCounts[key] > shownCounts[longestKey])
|
|
152
|
+
) {
|
|
153
|
+
longestKey = key;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (longestKey === null) {
|
|
158
|
+
return { card: card, shownCounts: shownCounts, fitsBudget: false };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const count: number = shownCounts[longestKey];
|
|
162
|
+
shownCounts[longestKey] = Math.min(count - 1, Math.floor(count * 0.75));
|
|
163
|
+
card = build();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return { card: card, shownCounts: shownCounts, fitsBudget: true };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// A small line of text on a card, such as what a list leaves out.
|
|
170
|
+
public static buildNoteElement(text: string): JSONObject {
|
|
171
|
+
return {
|
|
172
|
+
type: "TextBlock",
|
|
173
|
+
text: text,
|
|
174
|
+
wrap: true,
|
|
175
|
+
isSubtle: true,
|
|
176
|
+
size: "Small",
|
|
177
|
+
spacing: "Small",
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// The note element for a list the card could not show in full, or null.
|
|
182
|
+
public static buildNotShownNoteElement(data: {
|
|
183
|
+
list: MicrosoftTeamsCardChoiceList;
|
|
184
|
+
pluralNoun: string;
|
|
185
|
+
addLaterHint: string;
|
|
186
|
+
}): JSONObject | null {
|
|
187
|
+
const note: string | null = this.getNotShownNote(data);
|
|
188
|
+
|
|
189
|
+
return note ? this.buildNoteElement(note) : null;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// The button a card offers when it had to leave something off.
|
|
193
|
+
public static buildCreateInOneUptimeAction(url: string): JSONObject {
|
|
194
|
+
return {
|
|
195
|
+
type: "Action.OpenUrl",
|
|
196
|
+
title: "Create in OneUptime",
|
|
197
|
+
url: url,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/*
|
|
202
|
+
* The line shown under a list the card could not show in full, or null
|
|
203
|
+
* when it shows every record.
|
|
204
|
+
*/
|
|
205
|
+
public static getNotShownNote(data: {
|
|
206
|
+
list: MicrosoftTeamsCardChoiceList;
|
|
207
|
+
pluralNoun: string; // e.g. "monitors"
|
|
208
|
+
addLaterHint: string; // e.g. "You can add them to the incident in OneUptime after it is created."
|
|
209
|
+
}): string | null {
|
|
210
|
+
const shownCount: number = data.list.choices.length;
|
|
211
|
+
const totalCount: number = Math.max(data.list.totalCount, shownCount);
|
|
212
|
+
|
|
213
|
+
if (shownCount >= totalCount) {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (shownCount === 0) {
|
|
218
|
+
return `This project has ${totalCount} ${data.pluralNoun}, too many to list in Microsoft Teams. ${data.addLaterHint}`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return `Showing the first ${shownCount} of ${totalCount} ${data.pluralNoun}, by name. ${data.addLaterHint}`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
public static async getMonitorChoices(
|
|
225
|
+
projectId: ObjectID,
|
|
226
|
+
): Promise<MicrosoftTeamsCardChoiceList> {
|
|
227
|
+
const monitors: Array<Monitor> = await MonitorService.findBy({
|
|
228
|
+
query: {
|
|
229
|
+
projectId: projectId,
|
|
230
|
+
},
|
|
231
|
+
select: {
|
|
232
|
+
_id: true,
|
|
233
|
+
name: true,
|
|
234
|
+
},
|
|
235
|
+
sort: {
|
|
236
|
+
name: SortOrder.Ascending,
|
|
237
|
+
},
|
|
238
|
+
limit: MICROSOFT_TEAMS_MAX_MONITOR_CHOICES,
|
|
239
|
+
skip: 0,
|
|
240
|
+
props: {
|
|
241
|
+
isRoot: true,
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
choices: this.toChoices(monitors),
|
|
247
|
+
totalCount:
|
|
248
|
+
monitors.length < MICROSOFT_TEAMS_MAX_MONITOR_CHOICES
|
|
249
|
+
? monitors.length
|
|
250
|
+
: (
|
|
251
|
+
await MonitorService.countBy({
|
|
252
|
+
query: {
|
|
253
|
+
projectId: projectId,
|
|
254
|
+
},
|
|
255
|
+
props: {
|
|
256
|
+
isRoot: true,
|
|
257
|
+
},
|
|
258
|
+
})
|
|
259
|
+
).toNumber(),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
public static async getMonitorStatusChoices(
|
|
264
|
+
projectId: ObjectID,
|
|
265
|
+
): Promise<MicrosoftTeamsCardChoiceList> {
|
|
266
|
+
const monitorStatuses: Array<MonitorStatus> =
|
|
267
|
+
await MonitorStatusService.findBy({
|
|
268
|
+
query: {
|
|
269
|
+
projectId: projectId,
|
|
270
|
+
},
|
|
271
|
+
select: {
|
|
272
|
+
_id: true,
|
|
273
|
+
name: true,
|
|
274
|
+
},
|
|
275
|
+
sort: {
|
|
276
|
+
priority: SortOrder.Ascending,
|
|
277
|
+
},
|
|
278
|
+
limit: MICROSOFT_TEAMS_MAX_MONITOR_STATUS_CHOICES,
|
|
279
|
+
skip: 0,
|
|
280
|
+
props: {
|
|
281
|
+
isRoot: true,
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const choices: Array<MicrosoftTeamsCardChoice> =
|
|
286
|
+
this.toChoices(monitorStatuses);
|
|
287
|
+
|
|
288
|
+
return { choices: choices, totalCount: choices.length };
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
public static async getLabelChoices(
|
|
292
|
+
projectId: ObjectID,
|
|
293
|
+
): Promise<MicrosoftTeamsCardChoiceList> {
|
|
294
|
+
const labels: Array<Label> = await LabelService.findBy({
|
|
295
|
+
query: {
|
|
296
|
+
projectId: projectId,
|
|
297
|
+
},
|
|
298
|
+
select: {
|
|
299
|
+
_id: true,
|
|
300
|
+
name: true,
|
|
301
|
+
},
|
|
302
|
+
sort: {
|
|
303
|
+
name: SortOrder.Ascending,
|
|
304
|
+
},
|
|
305
|
+
limit: MICROSOFT_TEAMS_MAX_LABEL_CHOICES,
|
|
306
|
+
skip: 0,
|
|
307
|
+
props: {
|
|
308
|
+
isRoot: true,
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
choices: this.toChoices(labels),
|
|
314
|
+
totalCount:
|
|
315
|
+
labels.length < MICROSOFT_TEAMS_MAX_LABEL_CHOICES
|
|
316
|
+
? labels.length
|
|
317
|
+
: (
|
|
318
|
+
await LabelService.countBy({
|
|
319
|
+
query: {
|
|
320
|
+
projectId: projectId,
|
|
321
|
+
},
|
|
322
|
+
props: {
|
|
323
|
+
isRoot: true,
|
|
324
|
+
},
|
|
325
|
+
})
|
|
326
|
+
).toNumber(),
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
public static async getIncidentSeverityChoices(
|
|
331
|
+
projectId: ObjectID,
|
|
332
|
+
): Promise<MicrosoftTeamsCardChoiceList> {
|
|
333
|
+
const severities: Array<IncidentSeverity> =
|
|
334
|
+
await IncidentSeverityService.findBy({
|
|
335
|
+
query: {
|
|
336
|
+
projectId: projectId,
|
|
337
|
+
},
|
|
338
|
+
select: {
|
|
339
|
+
_id: true,
|
|
340
|
+
name: true,
|
|
341
|
+
},
|
|
342
|
+
sort: {
|
|
343
|
+
order: SortOrder.Ascending,
|
|
344
|
+
},
|
|
345
|
+
limit: MICROSOFT_TEAMS_MAX_SEVERITY_CHOICES,
|
|
346
|
+
skip: 0,
|
|
347
|
+
props: {
|
|
348
|
+
isRoot: true,
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
const choices: Array<MicrosoftTeamsCardChoice> = this.toChoices(severities);
|
|
353
|
+
|
|
354
|
+
return { choices: choices, totalCount: choices.length };
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
public static async getOnCallDutyPolicyChoices(
|
|
358
|
+
projectId: ObjectID,
|
|
359
|
+
): Promise<MicrosoftTeamsCardChoiceList> {
|
|
360
|
+
const policies: Array<OnCallDutyPolicy> =
|
|
361
|
+
await OnCallDutyPolicyService.findBy({
|
|
362
|
+
query: {
|
|
363
|
+
projectId: projectId,
|
|
364
|
+
},
|
|
365
|
+
select: {
|
|
366
|
+
_id: true,
|
|
367
|
+
name: true,
|
|
368
|
+
},
|
|
369
|
+
sort: {
|
|
370
|
+
name: SortOrder.Ascending,
|
|
371
|
+
},
|
|
372
|
+
limit: MICROSOFT_TEAMS_MAX_ON_CALL_POLICY_CHOICES,
|
|
373
|
+
skip: 0,
|
|
374
|
+
props: {
|
|
375
|
+
isRoot: true,
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
return {
|
|
380
|
+
choices: this.toChoices(policies),
|
|
381
|
+
totalCount:
|
|
382
|
+
policies.length < MICROSOFT_TEAMS_MAX_ON_CALL_POLICY_CHOICES
|
|
383
|
+
? policies.length
|
|
384
|
+
: (
|
|
385
|
+
await OnCallDutyPolicyService.countBy({
|
|
386
|
+
query: {
|
|
387
|
+
projectId: projectId,
|
|
388
|
+
},
|
|
389
|
+
props: {
|
|
390
|
+
isRoot: true,
|
|
391
|
+
},
|
|
392
|
+
})
|
|
393
|
+
).toNumber(),
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
}
|