@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,418 @@
|
|
|
1
|
+
import { TurnContext } from "botbuilder";
|
|
2
|
+
import { JSONObject } from "../../../../Types/JSON";
|
|
3
|
+
import ObjectID from "../../../../Types/ObjectID";
|
|
4
|
+
import NotAuthorizedException from "../../../../Types/Exception/NotAuthorizedException";
|
|
5
|
+
import DatabaseCommonInteractionProps from "../../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
6
|
+
import { DatabaseBaseModelType } from "../../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
7
|
+
import ScheduledMaintenance from "../../../../Models/DatabaseModels/ScheduledMaintenance";
|
|
8
|
+
import logger from "../../Logger";
|
|
9
|
+
import CaptureSpan from "../../Telemetry/CaptureSpan";
|
|
10
|
+
import WorkspaceActionAuthorization from "../WorkspaceActionAuthorization";
|
|
11
|
+
import MicrosoftTeamsAuthAction, {
|
|
12
|
+
MicrosoftTeamsAccountNotLinkedException,
|
|
13
|
+
} from "./Actions/Auth";
|
|
14
|
+
import MicrosoftTeamsIncidentActions, {
|
|
15
|
+
MicrosoftTeamsNewIncidentFormChoices,
|
|
16
|
+
} from "./Actions/Incident";
|
|
17
|
+
import MicrosoftTeamsScheduledMaintenanceActions, {
|
|
18
|
+
MicrosoftTeamsNewScheduledMaintenanceFormChoices,
|
|
19
|
+
} from "./Actions/ScheduledMaintenance";
|
|
20
|
+
import MicrosoftTeamsMessageSize from "./MicrosoftTeamsMessageSize";
|
|
21
|
+
import MicrosoftTeamsReplies from "./MicrosoftTeamsReplies";
|
|
22
|
+
import MicrosoftTeamsTimezone from "./MicrosoftTeamsTimezone";
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
* "create incident" and "create maintenance" typed to the Microsoft Teams bot.
|
|
26
|
+
*
|
|
27
|
+
* Each answers with exactly one message: the form, or a reason it cannot be
|
|
28
|
+
* shown that says what to do next (issue #4111 answered both with a generic
|
|
29
|
+
* "Sorry, I encountered an error...", twice).
|
|
30
|
+
*
|
|
31
|
+
* 1. In a personal chat the sender is the only one who can submit the form,
|
|
32
|
+
* so a sender without a connected account, who is not a member of the
|
|
33
|
+
* project, or who may not create the thing, is told so before filling it
|
|
34
|
+
* in, not after. In a channel or group chat anyone there may submit it, and
|
|
35
|
+
* the submit checks whoever does, so the form is posted for everyone.
|
|
36
|
+
* 2. The form's lists (monitors, labels, on-call policies...) are read in name
|
|
37
|
+
* order up to a cap, and the card is fitted to a size budget that Teams
|
|
38
|
+
* accepts; a card Teams still refuses as too large is sent again smaller,
|
|
39
|
+
* and finally without the lists at all.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
export interface CreateFormText {
|
|
43
|
+
// "an incident", "a scheduled maintenance event": what the form creates.
|
|
44
|
+
what: string;
|
|
45
|
+
// Below the project in the dashboard, where the same thing can be created.
|
|
46
|
+
dashboardRoute: string;
|
|
47
|
+
// Completes "To ...": why the sender needs a connected account.
|
|
48
|
+
purpose: string;
|
|
49
|
+
// The lists that are left off a card refused as too large.
|
|
50
|
+
lists: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const INCIDENT_FORM: CreateFormText = {
|
|
54
|
+
what: "an incident",
|
|
55
|
+
dashboardRoute: "/incidents/create",
|
|
56
|
+
purpose: "create incidents from Microsoft Teams",
|
|
57
|
+
lists: "monitors, labels and on-call policies",
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const SCHEDULED_MAINTENANCE_FORM: CreateFormText = {
|
|
61
|
+
what: "a scheduled maintenance event",
|
|
62
|
+
dashboardRoute: "/scheduled-maintenance-events/create",
|
|
63
|
+
purpose: "schedule maintenance from Microsoft Teams",
|
|
64
|
+
lists: "monitors and labels",
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default class MicrosoftTeamsCreateCommands {
|
|
68
|
+
@CaptureSpan()
|
|
69
|
+
public static async handleCreateIncidentCommand(data: {
|
|
70
|
+
turnContext: TurnContext;
|
|
71
|
+
activity: JSONObject;
|
|
72
|
+
projectId: ObjectID;
|
|
73
|
+
initialTitle?: string | undefined;
|
|
74
|
+
}): Promise<void> {
|
|
75
|
+
const { turnContext, activity, projectId } = data;
|
|
76
|
+
|
|
77
|
+
if (
|
|
78
|
+
this.isPersonalConversation(activity) &&
|
|
79
|
+
!(await this.authorizeSender({
|
|
80
|
+
turnContext: turnContext,
|
|
81
|
+
activity: activity,
|
|
82
|
+
projectId: projectId,
|
|
83
|
+
form: INCIDENT_FORM,
|
|
84
|
+
}))
|
|
85
|
+
) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let choices: MicrosoftTeamsNewIncidentFormChoices;
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
choices =
|
|
93
|
+
await MicrosoftTeamsIncidentActions.getNewIncidentFormChoices(
|
|
94
|
+
projectId,
|
|
95
|
+
);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
await this.replyFormCouldNotLoad({
|
|
98
|
+
turnContext: turnContext,
|
|
99
|
+
projectId: projectId,
|
|
100
|
+
form: INCIDENT_FORM,
|
|
101
|
+
error: error,
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (choices.severities.choices.length === 0) {
|
|
107
|
+
const severitySettingsUrl: string | null =
|
|
108
|
+
await MicrosoftTeamsReplies.getDashboardLink({
|
|
109
|
+
projectId: projectId,
|
|
110
|
+
route: "/incidents/settings/severity",
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
await MicrosoftTeamsReplies.sendBestEffort(
|
|
114
|
+
turnContext,
|
|
115
|
+
`An incident needs a severity, and this project has no incident severities yet. Add one in OneUptime under ${
|
|
116
|
+
severitySettingsUrl
|
|
117
|
+
? `[Incidents → Settings → Incident Severity](${severitySettingsUrl})`
|
|
118
|
+
: "Incidents → Settings → Incident Severity"
|
|
119
|
+
}, then try again.`,
|
|
120
|
+
);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const createInOneUptimeUrl: string | null =
|
|
125
|
+
await MicrosoftTeamsReplies.getDashboardLink({
|
|
126
|
+
projectId: projectId,
|
|
127
|
+
route: INCIDENT_FORM.dashboardRoute,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
await this.sendForm({
|
|
131
|
+
turnContext: turnContext,
|
|
132
|
+
projectId: projectId,
|
|
133
|
+
form: INCIDENT_FORM,
|
|
134
|
+
createInOneUptimeUrl: createInOneUptimeUrl,
|
|
135
|
+
buildCard: (budgetInBytes: number): JSONObject => {
|
|
136
|
+
return MicrosoftTeamsIncidentActions.buildNewIncidentCardForBudget({
|
|
137
|
+
choices: choices,
|
|
138
|
+
budgetInBytes: budgetInBytes,
|
|
139
|
+
initialTitle: data.initialTitle,
|
|
140
|
+
createInOneUptimeUrl: createInOneUptimeUrl,
|
|
141
|
+
});
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@CaptureSpan()
|
|
147
|
+
public static async handleCreateScheduledMaintenanceCommand(data: {
|
|
148
|
+
turnContext: TurnContext;
|
|
149
|
+
activity: JSONObject;
|
|
150
|
+
projectId: ObjectID;
|
|
151
|
+
initialTitle?: string | undefined;
|
|
152
|
+
}): Promise<void> {
|
|
153
|
+
const { turnContext, activity, projectId } = data;
|
|
154
|
+
|
|
155
|
+
if (
|
|
156
|
+
this.isPersonalConversation(activity) &&
|
|
157
|
+
!(await this.authorizeSender({
|
|
158
|
+
turnContext: turnContext,
|
|
159
|
+
activity: activity,
|
|
160
|
+
projectId: projectId,
|
|
161
|
+
form: SCHEDULED_MAINTENANCE_FORM,
|
|
162
|
+
// Submitting checks the same permission.
|
|
163
|
+
createPermission: {
|
|
164
|
+
modelType: ScheduledMaintenance,
|
|
165
|
+
action: "create a scheduled maintenance event",
|
|
166
|
+
},
|
|
167
|
+
}))
|
|
168
|
+
) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
let choices: MicrosoftTeamsNewScheduledMaintenanceFormChoices;
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
choices =
|
|
176
|
+
await MicrosoftTeamsScheduledMaintenanceActions.getNewScheduledMaintenanceFormChoices(
|
|
177
|
+
projectId,
|
|
178
|
+
);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
await this.replyFormCouldNotLoad({
|
|
181
|
+
turnContext: turnContext,
|
|
182
|
+
projectId: projectId,
|
|
183
|
+
form: SCHEDULED_MAINTENANCE_FORM,
|
|
184
|
+
error: error,
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const createInOneUptimeUrl: string | null =
|
|
190
|
+
await MicrosoftTeamsReplies.getDashboardLink({
|
|
191
|
+
projectId: projectId,
|
|
192
|
+
route: SCHEDULED_MAINTENANCE_FORM.dashboardRoute,
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// The zone the start and end are typed in; see MicrosoftTeamsTimezone.
|
|
196
|
+
const timezone: string | undefined =
|
|
197
|
+
MicrosoftTeamsTimezone.getTimezoneFromActivity(activity);
|
|
198
|
+
|
|
199
|
+
await this.sendForm({
|
|
200
|
+
turnContext: turnContext,
|
|
201
|
+
projectId: projectId,
|
|
202
|
+
form: SCHEDULED_MAINTENANCE_FORM,
|
|
203
|
+
createInOneUptimeUrl: createInOneUptimeUrl,
|
|
204
|
+
buildCard: (budgetInBytes: number): JSONObject => {
|
|
205
|
+
return MicrosoftTeamsScheduledMaintenanceActions.buildNewScheduledMaintenanceCardForBudget(
|
|
206
|
+
{
|
|
207
|
+
choices: choices,
|
|
208
|
+
budgetInBytes: budgetInBytes,
|
|
209
|
+
initialTitle: data.initialTitle,
|
|
210
|
+
createInOneUptimeUrl: createInOneUptimeUrl,
|
|
211
|
+
timezone: timezone,
|
|
212
|
+
},
|
|
213
|
+
);
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// A 1:1 chat with the bot, where whoever asks for a form is the one to submit it.
|
|
219
|
+
private static isPersonalConversation(activity: JSONObject): boolean {
|
|
220
|
+
return (
|
|
221
|
+
((activity["conversation"] as JSONObject | undefined)?.[
|
|
222
|
+
"conversationType"
|
|
223
|
+
] as string | undefined) === "personal"
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/*
|
|
228
|
+
* True when the sender can submit the form. Otherwise the sender is told
|
|
229
|
+
* why (no connected account, not a project member, no permission) and this
|
|
230
|
+
* returns false.
|
|
231
|
+
*/
|
|
232
|
+
private static async authorizeSender(data: {
|
|
233
|
+
turnContext: TurnContext;
|
|
234
|
+
activity: JSONObject;
|
|
235
|
+
projectId: ObjectID;
|
|
236
|
+
form: CreateFormText;
|
|
237
|
+
createPermission?:
|
|
238
|
+
| {
|
|
239
|
+
modelType: DatabaseBaseModelType;
|
|
240
|
+
action: string;
|
|
241
|
+
}
|
|
242
|
+
| undefined;
|
|
243
|
+
}): Promise<boolean> {
|
|
244
|
+
const { turnContext, activity, projectId, form } = data;
|
|
245
|
+
|
|
246
|
+
const teamsUserId: string =
|
|
247
|
+
((activity["from"] as JSONObject | undefined)?.["aadObjectId"] as
|
|
248
|
+
| string
|
|
249
|
+
| undefined) || "";
|
|
250
|
+
|
|
251
|
+
if (!teamsUserId) {
|
|
252
|
+
logger.warn(
|
|
253
|
+
"A Microsoft Teams create command arrived without the sender's AAD object id",
|
|
254
|
+
{
|
|
255
|
+
projectId: projectId.toString(),
|
|
256
|
+
},
|
|
257
|
+
);
|
|
258
|
+
await MicrosoftTeamsReplies.sendBestEffort(
|
|
259
|
+
turnContext,
|
|
260
|
+
`Sorry, I couldn't tell who sent this message, so I can't open the form to create ${form.what}. Please try again.`,
|
|
261
|
+
);
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
const userId: ObjectID =
|
|
267
|
+
await MicrosoftTeamsAuthAction.getOneUptimeUserIdFromTeamsUserId({
|
|
268
|
+
teamsUserId: teamsUserId,
|
|
269
|
+
projectId: projectId,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
const props: DatabaseCommonInteractionProps =
|
|
273
|
+
await WorkspaceActionAuthorization.getProjectMemberProps({
|
|
274
|
+
userId: userId,
|
|
275
|
+
projectId: projectId,
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
if (data.createPermission) {
|
|
279
|
+
await WorkspaceActionAuthorization.assertCanCreate({
|
|
280
|
+
props: props,
|
|
281
|
+
modelType: data.createPermission.modelType,
|
|
282
|
+
action: data.createPermission.action,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return true;
|
|
287
|
+
} catch (error) {
|
|
288
|
+
if (error instanceof MicrosoftTeamsAccountNotLinkedException) {
|
|
289
|
+
await MicrosoftTeamsReplies.sendBestEffort(
|
|
290
|
+
turnContext,
|
|
291
|
+
await MicrosoftTeamsReplies.getAccountNotLinkedMessage({
|
|
292
|
+
projectId: projectId,
|
|
293
|
+
purpose: form.purpose,
|
|
294
|
+
}),
|
|
295
|
+
);
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (error instanceof NotAuthorizedException) {
|
|
300
|
+
await MicrosoftTeamsReplies.sendBestEffort(turnContext, error.message);
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
MicrosoftTeamsReplies.logFailure(
|
|
305
|
+
"Could not check the Microsoft Teams sender of a create command",
|
|
306
|
+
error,
|
|
307
|
+
{
|
|
308
|
+
projectId: projectId.toString(),
|
|
309
|
+
},
|
|
310
|
+
);
|
|
311
|
+
await MicrosoftTeamsReplies.sendBestEffort(
|
|
312
|
+
turnContext,
|
|
313
|
+
`Sorry, I couldn't open the form to create ${form.what} because OneUptime could not check your account just now. Please try again in a minute.`,
|
|
314
|
+
);
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
private static async sendForm(data: {
|
|
320
|
+
turnContext: TurnContext;
|
|
321
|
+
projectId: ObjectID;
|
|
322
|
+
form: CreateFormText;
|
|
323
|
+
createInOneUptimeUrl: string | null;
|
|
324
|
+
buildCard: (budgetInBytes: number) => JSONObject;
|
|
325
|
+
}): Promise<void> {
|
|
326
|
+
try {
|
|
327
|
+
await MicrosoftTeamsReplies.sendCardWithinSizeLimit({
|
|
328
|
+
turnContext: data.turnContext,
|
|
329
|
+
buildCard: data.buildCard,
|
|
330
|
+
});
|
|
331
|
+
} catch (error) {
|
|
332
|
+
MicrosoftTeamsReplies.logFailure(
|
|
333
|
+
`Microsoft Teams did not accept the form to create ${data.form.what}`,
|
|
334
|
+
error,
|
|
335
|
+
{
|
|
336
|
+
projectId: data.projectId.toString(),
|
|
337
|
+
},
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
await MicrosoftTeamsReplies.sendBestEffort(
|
|
341
|
+
data.turnContext,
|
|
342
|
+
this.getFormNotAcceptedMessage({
|
|
343
|
+
form: data.form,
|
|
344
|
+
error: error,
|
|
345
|
+
createInOneUptimeUrl: data.createInOneUptimeUrl,
|
|
346
|
+
}),
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
private static async replyFormCouldNotLoad(data: {
|
|
352
|
+
turnContext: TurnContext;
|
|
353
|
+
projectId: ObjectID;
|
|
354
|
+
form: CreateFormText;
|
|
355
|
+
error: unknown;
|
|
356
|
+
}): Promise<void> {
|
|
357
|
+
MicrosoftTeamsReplies.logFailure(
|
|
358
|
+
`Could not load the Microsoft Teams form to create ${data.form.what}`,
|
|
359
|
+
data.error,
|
|
360
|
+
{
|
|
361
|
+
projectId: data.projectId.toString(),
|
|
362
|
+
},
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
const createInOneUptimeUrl: string | null =
|
|
366
|
+
await MicrosoftTeamsReplies.getDashboardLink({
|
|
367
|
+
projectId: data.projectId,
|
|
368
|
+
route: data.form.dashboardRoute,
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
await MicrosoftTeamsReplies.sendBestEffort(
|
|
372
|
+
data.turnContext,
|
|
373
|
+
`Sorry, I couldn't open the form to create ${data.form.what} because OneUptime could not load the lists it needs just now. Please try again in a minute, ${this.getCreateInOneUptimeHint(
|
|
374
|
+
createInOneUptimeUrl,
|
|
375
|
+
"or create it",
|
|
376
|
+
)}`,
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
public static getFormNotAcceptedMessage(data: {
|
|
381
|
+
form: CreateFormText;
|
|
382
|
+
error: unknown;
|
|
383
|
+
createInOneUptimeUrl: string | null;
|
|
384
|
+
}): string {
|
|
385
|
+
const createInOneUptime: string = this.getCreateInOneUptimeHint(
|
|
386
|
+
data.createInOneUptimeUrl,
|
|
387
|
+
"You can create it",
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
if (MicrosoftTeamsMessageSize.isMessageTooLargeError(data.error)) {
|
|
391
|
+
return `Sorry, I couldn't open the form to create ${data.form.what}: Microsoft Teams refused it as too large, even without the lists of ${data.form.lists}. ${createInOneUptime}`;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const statusCode: number | undefined =
|
|
395
|
+
MicrosoftTeamsMessageSize.getErrorStatusCode(data.error);
|
|
396
|
+
const code: string | undefined = MicrosoftTeamsMessageSize.getErrorCode(
|
|
397
|
+
data.error,
|
|
398
|
+
);
|
|
399
|
+
const teamsReason: string = [statusCode, code]
|
|
400
|
+
.filter((part: string | number | undefined) => {
|
|
401
|
+
return part !== undefined && part !== "";
|
|
402
|
+
})
|
|
403
|
+
.join(" ");
|
|
404
|
+
|
|
405
|
+
return `Sorry, I couldn't open the form to create ${data.form.what}: Microsoft Teams did not accept it${
|
|
406
|
+
teamsReason ? ` (${teamsReason})` : ""
|
|
407
|
+
}. ${createInOneUptime}`;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
private static getCreateInOneUptimeHint(
|
|
411
|
+
createInOneUptimeUrl: string | null,
|
|
412
|
+
lead: string,
|
|
413
|
+
): string {
|
|
414
|
+
return createInOneUptimeUrl
|
|
415
|
+
? `${lead} in OneUptime instead: ${createInOneUptimeUrl}`
|
|
416
|
+
: `${lead} in OneUptime instead.`;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { JSONObject } from "../../../../Types/JSON";
|
|
2
|
+
import { truncateToLength } from "../../Database/TruncateColumnValue";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* How big a message Microsoft Teams takes from a bot.
|
|
6
|
+
*
|
|
7
|
+
* Teams measures a bot message as UTF-16 and refuses one over its limit with
|
|
8
|
+
* HTTP 413 MessageSizeTooBig ("Message size too large."), which the Bot
|
|
9
|
+
* Framework SDK does not retry. The documented limit has moved over the years
|
|
10
|
+
* (28 KB, then 40 KB, now "about 100 KB, keep it within 80 KB"), and Teams
|
|
11
|
+
* checks it against its own internal form of the message rather than the JSON
|
|
12
|
+
* we send, so 413s are reported well under the documented number. Anything we
|
|
13
|
+
* build that grows with the size of a project is therefore kept to a budget
|
|
14
|
+
* with a wide margin, and a card Teams still refuses is sent again, smaller.
|
|
15
|
+
*
|
|
16
|
+
* Issue #4111: the "create incident" and "create maintenance" forms listed
|
|
17
|
+
* every monitor, label and on-call policy of the project, so a few hundred
|
|
18
|
+
* monitors were enough for Teams to refuse the form.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* Budgets for an adaptive card, in the order they are tried. The next one is
|
|
23
|
+
* only tried after Teams refused the card built for the previous one. A budget
|
|
24
|
+
* of 0 leaves every optional list off the card.
|
|
25
|
+
*/
|
|
26
|
+
export const MICROSOFT_TEAMS_CARD_SIZE_BUDGETS_IN_BYTES: ReadonlyArray<number> =
|
|
27
|
+
[40 * 1024, 20 * 1024, 0];
|
|
28
|
+
|
|
29
|
+
// Budget for a plain text reply, such as "show active incidents".
|
|
30
|
+
export const MICROSOFT_TEAMS_TEXT_MESSAGE_BUDGET_IN_BYTES: number = 40 * 1024;
|
|
31
|
+
|
|
32
|
+
const DEFAULT_TRUNCATION_NOTE: string =
|
|
33
|
+
"…\n\n_This reply was shortened to fit in Microsoft Teams. Open OneUptime to see everything._";
|
|
34
|
+
|
|
35
|
+
export default class MicrosoftTeamsMessageSize {
|
|
36
|
+
// Size as Teams counts it: JavaScript strings are UTF-16, two bytes a unit.
|
|
37
|
+
public static getSizeInBytes(value: string | JSONObject): number {
|
|
38
|
+
const text: string =
|
|
39
|
+
typeof value === "string" ? value : JSON.stringify(value);
|
|
40
|
+
|
|
41
|
+
return text.length * 2;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/*
|
|
45
|
+
* Whether Teams refused a message as too large.
|
|
46
|
+
*
|
|
47
|
+
* The Bot Framework connector throws a RestError that carries statusCode
|
|
48
|
+
* 413 and code "MessageSizeTooBig". It is matched on those fields and not
|
|
49
|
+
* on its class: @azure/* is not a dependency of Common (botbuilder brings
|
|
50
|
+
* it), and the error can come from another JavaScript realm, where
|
|
51
|
+
* instanceof is false. The status code alone is enough when a proxy in
|
|
52
|
+
* front of the connector answered 413 with a body that is not JSON.
|
|
53
|
+
*/
|
|
54
|
+
public static isMessageTooLargeError(error: unknown): boolean {
|
|
55
|
+
return (
|
|
56
|
+
this.getErrorStatusCode(error) === 413 ||
|
|
57
|
+
this.getErrorCode(error) === "MessageSizeTooBig"
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// The HTTP status of a failed Bot Framework call, when the error has one.
|
|
62
|
+
public static getErrorStatusCode(error: unknown): number | undefined {
|
|
63
|
+
if (!error || typeof error !== "object") {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const candidate: {
|
|
68
|
+
statusCode?: unknown;
|
|
69
|
+
response?: { status?: unknown } | undefined;
|
|
70
|
+
} = error as {
|
|
71
|
+
statusCode?: unknown;
|
|
72
|
+
response?: { status?: unknown } | undefined;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
if (typeof candidate.statusCode === "number") {
|
|
76
|
+
return candidate.statusCode;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (typeof candidate.response?.status === "number") {
|
|
80
|
+
return candidate.response.status;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// The error code of a failed Bot Framework call, e.g. "MessageSizeTooBig".
|
|
87
|
+
public static getErrorCode(error: unknown): string | undefined {
|
|
88
|
+
if (!error || typeof error !== "object") {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const candidate: {
|
|
93
|
+
code?: unknown;
|
|
94
|
+
details?: { error?: { code?: unknown } | undefined } | undefined;
|
|
95
|
+
} = error as {
|
|
96
|
+
code?: unknown;
|
|
97
|
+
details?: { error?: { code?: unknown } | undefined } | undefined;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
if (typeof candidate.code === "string" && candidate.code) {
|
|
101
|
+
return candidate.code;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (
|
|
105
|
+
typeof candidate.details?.error?.code === "string" &&
|
|
106
|
+
candidate.details.error.code
|
|
107
|
+
) {
|
|
108
|
+
return candidate.details.error.code;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
* A text reply cut down to the budget, with a note that it was shortened
|
|
116
|
+
* when the note fits as well. The cut is made at the last line break that
|
|
117
|
+
* fits, so no markdown line is split, or mid-line (never inside an emoji)
|
|
118
|
+
* when the first line alone is over the budget. The result is never over
|
|
119
|
+
* the budget; text within it is returned as it is.
|
|
120
|
+
*/
|
|
121
|
+
public static fitTextToBudget(data: {
|
|
122
|
+
text: string;
|
|
123
|
+
budgetInBytes?: number | undefined;
|
|
124
|
+
truncationNote?: string | undefined;
|
|
125
|
+
}): string {
|
|
126
|
+
const budgetInBytes: number =
|
|
127
|
+
data.budgetInBytes ?? MICROSOFT_TEAMS_TEXT_MESSAGE_BUDGET_IN_BYTES;
|
|
128
|
+
|
|
129
|
+
if (this.getSizeInBytes(data.text) <= budgetInBytes) {
|
|
130
|
+
return data.text;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const maxUnits: number = Math.max(0, Math.floor(budgetInBytes / 2));
|
|
134
|
+
const requestedNote: string =
|
|
135
|
+
data.truncationNote ?? DEFAULT_TRUNCATION_NOTE;
|
|
136
|
+
|
|
137
|
+
// A note that does not fit leaves the whole budget to the text.
|
|
138
|
+
const truncationNote: string =
|
|
139
|
+
requestedNote.length <= maxUnits ? requestedNote : "";
|
|
140
|
+
const maxLength: number = maxUnits - truncationNote.length;
|
|
141
|
+
|
|
142
|
+
// A line that ends exactly at the cut still fits, so the search includes it.
|
|
143
|
+
const lastLineBreak: number = data.text.lastIndexOf("\n", maxLength);
|
|
144
|
+
|
|
145
|
+
const kept: string =
|
|
146
|
+
lastLineBreak > 0
|
|
147
|
+
? data.text.substring(0, lastLineBreak)
|
|
148
|
+
: truncateToLength(data.text, maxLength);
|
|
149
|
+
|
|
150
|
+
return kept.trimEnd() + truncationNote;
|
|
151
|
+
}
|
|
152
|
+
}
|