@oneuptime/common 12.0.32 → 12.0.34
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/AnalyticsModels/RumSession.ts +117 -1
- package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
- package/Models/AnalyticsModels/Span.ts +14 -0
- package/Models/DatabaseModels/AlertCustomField.ts +77 -3
- package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
- package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
- package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
- package/Models/DatabaseModels/Index.ts +10 -0
- package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
- package/Models/DatabaseModels/Monitor.ts +76 -0
- package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
- package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
- package/Models/DatabaseModels/NetworkDevice.ts +176 -1
- package/Models/DatabaseModels/NetworkSite.ts +201 -2
- package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
- package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
- package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
- package/Models/DatabaseModels/RumApplication.ts +6 -6
- package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
- package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamMember.ts +0 -9
- package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamPermission.ts +3 -24
- package/Models/DatabaseModels/TelemetryException.ts +119 -0
- package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
- package/Models/DatabaseModels/UserTelegram.ts +0 -4
- package/Scripts/benchmark-fanin-capacity.js +181 -0
- package/Server/API/EnterpriseLicenseAPI.ts +391 -64
- package/Server/API/LlmProviderAPI.ts +137 -22
- package/Server/API/TelemetryAPI.ts +1284 -164
- package/Server/API/UserNotificationSettingAPI.ts +55 -0
- package/Server/API/UserTelegramAPI.ts +48 -4
- package/Server/EnvironmentConfig.ts +49 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
- package/Server/Infrastructure/QueueWorker.ts +59 -23
- package/Server/Infrastructure/Semaphore.ts +2 -0
- package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
- package/Server/Middleware/ProjectAuthorization.ts +11 -0
- package/Server/Middleware/SCIMAuthorization.ts +12 -0
- package/Server/Middleware/TelemetryIngest.ts +464 -7
- package/Server/Services/AIBillingService.ts +101 -27
- package/Server/Services/AccessTokenService.ts +1 -0
- package/Server/Services/AlertCustomFieldService.ts +98 -0
- package/Server/Services/AlertService.ts +37 -0
- package/Server/Services/ApiKeyPermissionService.ts +461 -29
- package/Server/Services/CustomFieldMappingService.ts +879 -0
- package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
- package/Server/Services/EnterpriseLicenseService.ts +55 -0
- package/Server/Services/GlobalConfigService.ts +194 -0
- package/Server/Services/IncidentCustomFieldService.ts +98 -0
- package/Server/Services/IncidentService.ts +35 -0
- package/Server/Services/Index.ts +10 -0
- package/Server/Services/MetricService.ts +194 -0
- package/Server/Services/MonitorService.ts +175 -21
- package/Server/Services/MonitorStatusTimelineService.ts +150 -8
- package/Server/Services/MonitorTemplateService.ts +217 -1
- package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
- package/Server/Services/NetworkAlertPolicyService.ts +944 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +87 -35
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
- package/Server/Services/NetworkDeviceService.ts +1032 -73
- package/Server/Services/NetworkSiteService.ts +1502 -129
- package/Server/Services/NetworkSiteTypeService.ts +1216 -0
- package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
- package/Server/Services/NotificationService.ts +118 -28
- package/Server/Services/ProjectService.ts +127 -48
- package/Server/Services/RoutineEmailSettingsService.ts +73 -0
- package/Server/Services/RumSessionReplayViewService.ts +104 -24
- package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
- package/Server/Services/ScheduledMaintenanceService.ts +32 -0
- package/Server/Services/StatusPagePrivateUserService.ts +103 -3
- package/Server/Services/TeamMemberService.ts +78 -0
- package/Server/Services/TeamPermissionService.ts +235 -3
- package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
- package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
- package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
- package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
- package/Server/Services/UserNotificationSettingService.ts +90 -25
- package/Server/Services/UserService.ts +95 -0
- package/Server/Services/UserTelegramService.ts +326 -5
- package/Server/Types/Database/QueryHelper.ts +4 -2
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
- package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
- package/Server/Utils/APIKey/AccessPermission.ts +5 -2
- package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
- package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
- package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
- package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
- package/Server/Utils/DataSource/EgressGuard.ts +177 -8
- package/Server/Utils/DataSource/HttpFetch.ts +9 -2
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +131 -0
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +925 -0
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
- package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
- package/Server/Utils/FrontendEnvironment.ts +40 -0
- package/Server/Utils/LLM/LLMService.ts +78 -0
- package/Server/Utils/LogRedaction.ts +28 -0
- package/Server/Utils/Logger.ts +90 -1
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
- package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
- package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
- package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +159 -15
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
- package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +72 -0
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
- package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
- package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
- package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
- package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
- package/Server/Utils/OutboundUserAgent.ts +152 -0
- package/Server/Utils/SSRFProtection.ts +217 -10
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
- package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
- package/Server/Utils/StartServer.ts +53 -36
- package/Server/Utils/TelegramVerificationToken.ts +185 -0
- package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
- package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
- package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
- package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
- package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
- package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
- package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
- package/Server/Utils/Telemetry.ts +198 -51
- package/Server/Utils/VM/VMAPI.ts +1 -0
- package/Server/Utils/VM/VMRunner.ts +975 -95
- package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
- package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
- package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +134 -33
- package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
- package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
- package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +486 -9
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
- package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
- package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
- package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
- package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
- package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +41 -5
- package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
- package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
- package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
- package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
- package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
- package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
- package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
- package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
- package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
- package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
- package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
- package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
- package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
- package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
- package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
- package/Tests/ResponsiveVisibility.test.ts +115 -0
- package/Tests/ResponsiveVisibility.ts +183 -0
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
- package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
- package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
- package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
- package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
- package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
- package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
- package/Tests/Server/Infrastructure/Postgres/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
- package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -0
- package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
- package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
- package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
- package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
- package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
- package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
- package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
- package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
- package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
- package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
- package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
- package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
- package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
- package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
- package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
- package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
- package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
- package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +273 -5
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
- package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
- package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
- package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
- package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
- package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
- package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
- package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
- package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
- package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
- package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
- package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
- package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
- package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
- package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
- package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
- package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
- package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +472 -0
- package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
- package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +997 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +110 -1
- package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
- package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
- package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
- package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
- package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -0
- package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
- package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
- package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
- package/Tests/Server/Utils/Captcha.test.ts +422 -0
- package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +96 -2
- package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +828 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
- package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
- package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
- package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
- package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
- package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
- package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
- package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
- package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
- package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
- package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
- package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
- package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
- package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
- package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
- package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
- package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
- package/Tests/Server/Utils/Telemetry.test.ts +456 -66
- package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
- package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
- package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
- package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
- package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
- package/Tests/Types/JSONFunctions.test.ts +260 -0
- package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
- package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
- package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
- package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
- package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
- package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
- package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
- package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
- package/Tests/Types/Monitor/MonitorStepDatabaseMonitor.test.ts +243 -0
- package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
- package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
- package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
- package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
- package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
- package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
- package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
- package/Tests/Types/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
- package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
- package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -0
- package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
- package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
- package/Tests/Types/Telemetry/ErrorClass.test.ts +483 -0
- package/Tests/Types/WebsiteRequest.test.ts +285 -3
- package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
- package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
- package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
- package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
- package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
- package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
- package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
- package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
- package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
- package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +43 -12
- package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
- package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
- package/Tests/UI/Components/SideMenuItem.test.tsx +226 -4
- package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
- package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
- package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
- package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
- package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
- package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
- package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
- package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
- package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
- package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
- package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
- package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
- package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
- package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
- package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
- package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
- package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
- package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
- package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
- package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
- package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
- package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
- package/Tests/UI/Utils/PageScrollLock.test.tsx +377 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
- package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
- package/Tests/Utils/API.test.ts +308 -0
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
- package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
- package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
- package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
- package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
- package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
- package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
- package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
- package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
- package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
- package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
- package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
- package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
- package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
- package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
- package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -0
- package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
- package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
- package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
- package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
- package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +145 -0
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
- package/Tests/Utils/ValueFormatter.test.ts +148 -0
- package/Types/AI/ExceptionAIClassification.ts +10 -24
- package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
- package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
- package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
- package/Types/Email/EmailTemplateType.ts +2 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
- package/Types/Exception/ApiException.ts +10 -0
- package/Types/Exception/BadDataException.ts +11 -0
- package/Types/Exception/BadRequestException.ts +11 -0
- package/Types/Exception/Exception.ts +65 -0
- package/Types/Exception/ForbiddenException.ts +10 -0
- package/Types/Exception/NotAuthenticatedException.ts +10 -0
- package/Types/Exception/NotAuthorizedException.ts +10 -0
- package/Types/Exception/NotFoundException.ts +11 -0
- package/Types/Exception/PayloadTooLargeException.ts +11 -0
- package/Types/Exception/PaymentRequiredException.ts +10 -0
- package/Types/Exception/ServiceUnavailableException.ts +10 -0
- package/Types/Exception/SsoAuthorizationException.ts +10 -0
- package/Types/Exception/TenantNotFoundException.ts +11 -0
- package/Types/Exception/TimeoutException.ts +10 -0
- package/Types/Exception/TooManyRequestsException.ts +10 -0
- package/Types/Exception/UnableToReachServer.ts +10 -0
- package/Types/Exception/WebsiteRequestException.ts +10 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/JSONFunctions.ts +189 -43
- package/Types/Monitor/CephAlertTemplates.ts +157 -195
- package/Types/Monitor/CriteriaFilter.ts +60 -2
- package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
- package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
- package/Types/Monitor/DockerAlertTemplates.ts +338 -128
- package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
- package/Types/Monitor/HostAlertTemplates.ts +302 -130
- package/Types/Monitor/IotAlertTemplates.ts +112 -104
- package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
- package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
- package/Types/Monitor/MonitorCriteriaInstance.ts +76 -0
- package/Types/Monitor/MonitorMetricType.ts +71 -0
- package/Types/Monitor/MonitorStep.ts +76 -0
- package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
- package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
- package/Types/Monitor/MonitorType.ts +47 -1
- package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
- package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
- package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
- package/Types/Monitor/RumAlertTemplates.ts +46 -7
- package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
- package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
- package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
- package/Types/Monitor/SqlConnectionConfig.ts +31 -0
- package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
- package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
- package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
- package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
- package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
- package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
- package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
- package/Types/Permission.ts +90 -0
- package/Types/Probe/ProbeMonitorResponse.ts +16 -0
- package/Types/Rum/SessionReplay.ts +209 -0
- package/Types/Rum/SessionReplayApi.ts +722 -0
- package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
- package/Types/Rum/SessionReplayConsentMode.ts +11 -7
- package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
- package/Types/Rum/SessionReplayHealth.ts +238 -0
- package/Types/Telemetry/ErrorClass.ts +274 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
- package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
- package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
- package/Types/Telemetry/UnitOfWork.ts +59 -0
- package/Types/WebsiteRequest.ts +85 -3
- package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
- package/UI/Components/Charts/Line/LineChart.tsx +13 -2
- package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
- package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
- package/UI/Components/Charts/Utils/XAxis.ts +217 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
- package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
- package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
- package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
- package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
- package/UI/Components/Header/Header.tsx +25 -9
- package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
- package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
- package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
- package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
- package/UI/Components/Icon/Icon.tsx +11 -0
- package/UI/Components/JSONTable/JSONTable.tsx +2 -2
- package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
- package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
- package/UI/Components/Modal/Modal.tsx +2 -8
- package/UI/Components/ModelTable/Column.ts +15 -0
- package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
- package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
- package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
- package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +88 -0
- package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
- package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
- package/UI/Components/SideMenu/SideMenu.tsx +123 -5
- package/UI/Components/SideMenu/SideMenuItem.tsx +76 -84
- package/UI/Components/SideMenu/SideMenuSection.tsx +55 -23
- package/UI/Components/SideOver/SideOver.tsx +21 -20
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
- package/UI/Components/Table/CellClassName.ts +81 -0
- package/UI/Components/Table/TableRow.tsx +20 -14
- package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
- package/UI/Components/Table/Types/Column.ts +36 -0
- package/UI/Components/Tooltip/Tooltip.tsx +11 -1
- package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
- package/UI/Components/Workflow/NodePlacement.ts +57 -0
- package/UI/Components/Workflow/Workflow.tsx +47 -18
- package/UI/Config.ts +15 -33
- package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
- package/UI/Utils/PageScrollLock.ts +79 -3
- package/UI/Utils/PermissionGate.ts +61 -0
- package/UI/Utils/SensitiveUrlToken.ts +112 -0
- package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
- package/UI/Utils/Telemetry/Telemetry.ts +10 -8
- package/UI/Utils/TestLLMProvider.ts +11 -0
- package/Utils/API.ts +129 -3
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
- package/Utils/HTTPResponseBodyReader.ts +221 -0
- package/Utils/Monitor/MonitorMetricType.ts +153 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +23 -3
- package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
- package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
- package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
- package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
- package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
- package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
- package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
- package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
- package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
- package/Utils/Rum/ChunkMath.ts +106 -0
- package/Utils/Rum/SessionReplayHealth.ts +732 -0
- package/Utils/Rum/SessionReplayStringMap.ts +226 -0
- package/Utils/Schema/ModelSchema.ts +1 -0
- package/Utils/StatusPage/ResourceSearch.ts +290 -0
- package/Utils/Telemetry/OriginAllowList.ts +355 -0
- package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
- package/Utils/ValueFormatter.ts +35 -1
- package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
- package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Span.js +14 -0
- package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +59 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +10 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +75 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js +713 -0
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +180 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
- package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
- package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
- package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryException.js +123 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js +363 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
- package/build/dist/Server/API/LlmProviderAPI.js +108 -13
- package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +769 -109
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
- package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
- package/build/dist/Server/API/UserTelegramAPI.js +28 -6
- package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +41 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +52 -12
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/BearerTokenAuthorization.js +12 -0
- package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +326 -8
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIBillingService.js +70 -16
- package/build/dist/Server/Services/AIBillingService.js.map +1 -1
- package/build/dist/Server/Services/AccessTokenService.js +1 -0
- package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
- package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
- package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +34 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
- package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
- package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js +167 -0
- package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +133 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +32 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +10 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +163 -0
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +148 -21
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +89 -36
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
- package/build/dist/Server/Services/NotificationService.js +80 -17
- package/build/dist/Server/Services/NotificationService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +88 -30
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
- package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
- package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
- package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +92 -2
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +62 -2
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamPermissionService.js +166 -3
- package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js +76 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js +66 -20
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +90 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/UserTelegramService.js +257 -4
- package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js +59 -0
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +2 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +124 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +733 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
- package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +28 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +73 -1
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js +141 -0
- package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +51 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +125 -13
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +54 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
- package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
- package/build/dist/Server/Utils/OutboundUserAgent.js.map +1 -0
- package/build/dist/Server/Utils/SSRFProtection.js +136 -9
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +41 -28
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
- package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +28 -8
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js +29 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry.js +162 -46
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Types/AI/ExceptionAIClassification.js +10 -24
- package/build/dist/Types/AI/ExceptionAIClassification.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
- package/build/dist/Types/Exception/ApiException.js +9 -0
- package/build/dist/Types/Exception/ApiException.js.map +1 -1
- package/build/dist/Types/Exception/BadDataException.js +10 -0
- package/build/dist/Types/Exception/BadDataException.js.map +1 -1
- package/build/dist/Types/Exception/BadRequestException.js +10 -0
- package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
- package/build/dist/Types/Exception/Exception.js +56 -0
- package/build/dist/Types/Exception/Exception.js.map +1 -1
- package/build/dist/Types/Exception/ForbiddenException.js +9 -0
- package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
- package/build/dist/Types/Exception/NotFoundException.js +10 -0
- package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
- package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
- package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
- package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
- package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
- package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
- package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
- package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
- package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
- package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/TimeoutException.js +9 -0
- package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
- package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
- package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
- package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
- package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
- package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +118 -37
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
- package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +45 -2
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
- package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
- package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
- package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
- package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +70 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +54 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +45 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
- package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
- package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
- package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js.map +1 -0
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
- package/build/dist/Types/Permission.js +80 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplay.js +117 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
- package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
- package/build/dist/Types/Telemetry/ErrorClass.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Types/Telemetry/UnitOfWork.js +59 -0
- package/build/dist/Types/Telemetry/UnitOfWork.js.map +1 -0
- package/build/dist/Types/WebsiteRequest.js +55 -3
- package/build/dist/Types/WebsiteRequest.js.map +1 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +2 -7
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +3 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
- package/build/dist/UI/Components/Header/Header.js +2 -3
- package/build/dist/UI/Components/Header/Header.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +5 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
- package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
- package/build/dist/UI/Components/Modal/Modal.js +2 -7
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +77 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js +12 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenu.js +67 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js +49 -53
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js +25 -7
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
- package/build/dist/UI/Components/Table/CellClassName.js +55 -0
- package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
- package/build/dist/UI/Components/Table/TableRow.js +16 -13
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
- package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Config.js +10 -20
- package/build/dist/UI/Config.js.map +1 -1
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
- package/build/dist/UI/Utils/PageScrollLock.js +31 -3
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +42 -1
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
- package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
- package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/UI/Utils/TestLLMProvider.js +4 -5
- package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -1
- package/build/dist/Utils/API.js +67 -5
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
- package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js +109 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +8 -3
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -0
- package/build/dist/Utils/Rum/ChunkMath.js +76 -0
- package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
- package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
- package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
- package/build/dist/Utils/ValueFormatter.js +32 -1
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import DatabaseService from "./DatabaseService";
|
|
2
2
|
import MonitorService from "./MonitorService";
|
|
3
|
+
import NetworkAlertPolicyEngineService, {
|
|
4
|
+
MAX_INLINE_RECONCILE_DEVICES,
|
|
5
|
+
} from "./NetworkAlertPolicyEngineService";
|
|
3
6
|
import NetworkDeviceLabelRuleEngineService from "./NetworkDeviceLabelRuleEngineService";
|
|
4
7
|
import NetworkDeviceOwnerRuleEngineService from "./NetworkDeviceOwnerRuleEngineService";
|
|
5
8
|
import NetworkSiteAssignmentRuleService from "./NetworkSiteAssignmentRuleService";
|
|
6
9
|
import NetworkSiteService from "./NetworkSiteService";
|
|
10
|
+
import NetworkSnmpCredentialProfileService from "./NetworkSnmpCredentialProfileService";
|
|
11
|
+
import ProbeService from "./ProbeService";
|
|
7
12
|
import Model from "../../Models/DatabaseModels/NetworkDevice";
|
|
8
13
|
import Monitor from "../../Models/DatabaseModels/Monitor";
|
|
9
14
|
import NetworkSite from "../../Models/DatabaseModels/NetworkSite";
|
|
10
15
|
import NetworkSiteAssignmentRule from "../../Models/DatabaseModels/NetworkSiteAssignmentRule";
|
|
16
|
+
import NetworkSnmpCredentialProfile from "../../Models/DatabaseModels/NetworkSnmpCredentialProfile";
|
|
11
17
|
import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
|
|
12
18
|
import CreateBy from "../Types/Database/CreateBy";
|
|
13
19
|
import DeleteBy from "../Types/Database/DeleteBy";
|
|
14
20
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
21
|
+
import PartialEntity from "../../Types/Database/PartialEntity";
|
|
15
22
|
import Query from "../Types/Database/Query";
|
|
16
23
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
17
24
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
@@ -137,8 +144,128 @@ function readOidTemplateIdFromData(
|
|
|
137
144
|
);
|
|
138
145
|
}
|
|
139
146
|
|
|
147
|
+
/*
|
|
148
|
+
* readConsistent for the same reason as the OID template above: the create
|
|
149
|
+
* and update guards validate the id this returns, and TypeORM's precedence
|
|
150
|
+
* between `monitorId` and `monitor` is not a security boundary. A payload
|
|
151
|
+
* that writes both spellings with different ids would have one of them
|
|
152
|
+
* validated and the other persisted, so the contradiction is refused
|
|
153
|
+
* instead of picked from.
|
|
154
|
+
*/
|
|
140
155
|
function readMonitorIdFromData(data: Record<string, unknown>): ObjectID | null {
|
|
141
|
-
return RelationIdUtil.
|
|
156
|
+
return RelationIdUtil.readConsistent(data, MONITOR_KEYS, "Monitor");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* Both spellings of "the probe that polls this device", and of "the SNMP
|
|
161
|
+
* credentials it is walked with".
|
|
162
|
+
*
|
|
163
|
+
* These two are the tenancy boundary of device polling. The probe decides
|
|
164
|
+
* WHO reaches into the customer's network on this device's behalf, and the
|
|
165
|
+
* credential profile decides WHAT is put on the wire when it gets there —
|
|
166
|
+
* so a cross-project value in either is not a mislabelled row, it is one
|
|
167
|
+
* project's infrastructure being pointed at another's. Both are read
|
|
168
|
+
* through readConsistent for the reason the monitor reference above is: a
|
|
169
|
+
* payload writing the FK and the relation at different rows would otherwise
|
|
170
|
+
* have one validated and the other persisted.
|
|
171
|
+
*/
|
|
172
|
+
const PROBE_KEYS: Array<string> = ["probeId", "probe"];
|
|
173
|
+
const PROFILE_KEYS: Array<string> = [
|
|
174
|
+
"snmpCredentialProfileId",
|
|
175
|
+
"snmpCredentialProfile",
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
/*
|
|
179
|
+
* Both spellings of "what kind of thing this device is". A role is one of
|
|
180
|
+
* the three axes a Network Alert Policy's scope selects on, so a write to it
|
|
181
|
+
* can add a device to a policy or take it out of one.
|
|
182
|
+
*/
|
|
183
|
+
const ROLE_KEYS: Array<string> = ["networkDeviceRoleId", "networkDeviceRole"];
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
* Every write that can change which Network Alert Policies cover a device,
|
|
187
|
+
* or whether it may carry a policy monitor at all.
|
|
188
|
+
*
|
|
189
|
+
* The first three are the scope axes (site, role, labels); the last three
|
|
190
|
+
* are provisionability — an archived device, a monitor-backed device and a
|
|
191
|
+
* device with no probe each keep no policy monitors (see the engine).
|
|
192
|
+
*
|
|
193
|
+
* Writing any of them makes onUpdateSuccess reconcile, and reconciling needs
|
|
194
|
+
* each matched device's PROJECT, which only the pre-write snapshot carries
|
|
195
|
+
* for a root caller with no tenant in props. That is why these are named in
|
|
196
|
+
* onBeforeUpdate's early return as well: without them a bulk re-label would
|
|
197
|
+
* skip the snapshot and the success hook would have no project to reconcile
|
|
198
|
+
* against.
|
|
199
|
+
*/
|
|
200
|
+
function isAlertPolicyRelevantWrite(dataKeys: Array<string>): boolean {
|
|
201
|
+
return (
|
|
202
|
+
isSiteWrite(dataKeys) ||
|
|
203
|
+
RelationIdUtil.isWritten(dataKeys, ROLE_KEYS) ||
|
|
204
|
+
dataKeys.includes("labels") ||
|
|
205
|
+
dataKeys.includes("isArchived") ||
|
|
206
|
+
dataKeys.includes("monitoringMethod") ||
|
|
207
|
+
RelationIdUtil.isWritten(dataKeys, PROBE_KEYS)
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function readProbeIdFromData(data: Record<string, unknown>): ObjectID | null {
|
|
212
|
+
return RelationIdUtil.readConsistent(data, PROBE_KEYS, "Probe");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function readSnmpCredentialProfileIdFromData(
|
|
216
|
+
data: Record<string, unknown>,
|
|
217
|
+
): ObjectID | null {
|
|
218
|
+
return RelationIdUtil.readConsistent(
|
|
219
|
+
data,
|
|
220
|
+
PROFILE_KEYS,
|
|
221
|
+
"SNMP Credential Profile",
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/*
|
|
226
|
+
* The poll columns a probe's poll writes and nothing else ever should. On a
|
|
227
|
+
* device switched to monitor-backed they are residue — the last thing a
|
|
228
|
+
* probe found before it stopped asking — and left in place they keep
|
|
229
|
+
* describing a device nothing polls: DeviceReachabilityUtil's legacy branch
|
|
230
|
+
* judges a row with `lastSeenAt` and no `isReachable` by freshness, and the
|
|
231
|
+
* network summary's "degraded" query is `isReachable = true AND
|
|
232
|
+
* interfacesDown > 0`. The SNMP pair goes with them: a monitor-backed device
|
|
233
|
+
* has no walk, so `isSnmpReachable` and `lastSnmpSeenAt` can only ever be
|
|
234
|
+
* what the last walk left behind. Cleared on the Probe -> Monitor transition
|
|
235
|
+
* (onUpdateSuccess) and once on upgrade
|
|
236
|
+
* (BackfillMonitorBackedDeviceReachability), as a root write in both places:
|
|
237
|
+
* these columns are updatable by fewer roles than `monitoringMethod` is, so
|
|
238
|
+
* putting them on the caller's own payload would refuse a project member's
|
|
239
|
+
* legitimate switch.
|
|
240
|
+
*/
|
|
241
|
+
function pollResidueReset(): PartialEntity<Model> {
|
|
242
|
+
return {
|
|
243
|
+
lastSeenAt: null,
|
|
244
|
+
lastPolledAt: null,
|
|
245
|
+
isReachable: null,
|
|
246
|
+
isSnmpReachable: null,
|
|
247
|
+
lastSnmpSeenAt: null,
|
|
248
|
+
interfacesUp: null,
|
|
249
|
+
interfacesDown: null,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/*
|
|
254
|
+
* What onBeforeUpdate hands onUpdateSuccess.
|
|
255
|
+
*
|
|
256
|
+
* `previousDevices` is the pre-write snapshot of every matched device, for
|
|
257
|
+
* the site and identity maintenance. `wasMonitorBackedByDeviceId` is only
|
|
258
|
+
* present on a write that carries `monitoringMethod`, and records which of
|
|
259
|
+
* those devices were monitor-backed BEFORE the write. By the time
|
|
260
|
+
* onUpdateSuccess runs only the NEW method is on the row, and the payload
|
|
261
|
+
* alone cannot tell a real Monitor -> Probe transition from the Settings form
|
|
262
|
+
* re-sending "Probe" on a Probe device — which it does on every save, and
|
|
263
|
+
* which used to wipe the stamp that device's Network Device monitor had put
|
|
264
|
+
* there.
|
|
265
|
+
*/
|
|
266
|
+
interface DeviceUpdateCarryForward {
|
|
267
|
+
previousDevices: Array<Model>;
|
|
268
|
+
wasMonitorBackedByDeviceId?: Record<string, boolean>;
|
|
142
269
|
}
|
|
143
270
|
|
|
144
271
|
/*
|
|
@@ -687,6 +814,14 @@ export class Service extends DatabaseService<Model> {
|
|
|
687
814
|
* first, then deletes their automatic monitors through MonitorService so
|
|
688
815
|
* Monitor delete permissions, workspace cleanup, workflows, audit,
|
|
689
816
|
* realtime, and billing hooks all run before the devices are removed.
|
|
817
|
+
*
|
|
818
|
+
* POLICY-OWNED MONITORS ARE HANDLED SEPARATELY, and deliberately so. A
|
|
819
|
+
* monitor a Network Alert Policy provisioned is system-managed — the API
|
|
820
|
+
* can neither set nor clear its `networkAlertPolicyId` — so nobody chose
|
|
821
|
+
* it individually and nobody should need monitor-delete permission on it
|
|
822
|
+
* individually to remove the device it describes. They are excluded from
|
|
823
|
+
* the caller-authorized preflight below and removed as root by the engine,
|
|
824
|
+
* once every device in the request has cleared that preflight.
|
|
690
825
|
*/
|
|
691
826
|
@CaptureSpan()
|
|
692
827
|
protected override async onBeforeDelete(
|
|
@@ -739,6 +874,13 @@ export class Service extends DatabaseService<Model> {
|
|
|
739
874
|
const automaticMonitorQuery: Query<Monitor> = {
|
|
740
875
|
projectId: device.projectId,
|
|
741
876
|
autoProvisionedNetworkDeviceId: device.id,
|
|
877
|
+
/*
|
|
878
|
+
* Rule-provisioned and hand-made monitors only. A policy's monitors
|
|
879
|
+
* go through the engine as root (see the hook comment), so requiring
|
|
880
|
+
* the caller's permission on them here would refuse a device delete
|
|
881
|
+
* over rows the caller never chose to own.
|
|
882
|
+
*/
|
|
883
|
+
networkAlertPolicyId: QueryHelper.isNull(),
|
|
742
884
|
};
|
|
743
885
|
const monitorDeleteProps: DatabaseCommonInteractionProps = {
|
|
744
886
|
...deleteBy.props,
|
|
@@ -783,6 +925,37 @@ export class Service extends DatabaseService<Model> {
|
|
|
783
925
|
});
|
|
784
926
|
}
|
|
785
927
|
|
|
928
|
+
/*
|
|
929
|
+
* Every device in the request has now proved the caller may delete its
|
|
930
|
+
* ordinary automatic monitors, so nothing after this point can throw for
|
|
931
|
+
* an authorization reason. That is the moment to remove the policy-owned
|
|
932
|
+
* monitors: doing it earlier would let a later device's failed preflight
|
|
933
|
+
* abort the request after a policy's monitors — and their incident
|
|
934
|
+
* history — were already gone from devices that then survived.
|
|
935
|
+
*/
|
|
936
|
+
const devicesByProjectId: Map<string, Array<ObjectID>> = new Map<
|
|
937
|
+
string,
|
|
938
|
+
Array<ObjectID>
|
|
939
|
+
>();
|
|
940
|
+
|
|
941
|
+
for (const device of devices) {
|
|
942
|
+
if (!device.id || !device.projectId) {
|
|
943
|
+
continue;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
const key: string = device.projectId.toString();
|
|
947
|
+
const deviceIds: Array<ObjectID> = devicesByProjectId.get(key) || [];
|
|
948
|
+
deviceIds.push(device.id);
|
|
949
|
+
devicesByProjectId.set(key, deviceIds);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
for (const [projectIdString, deviceIds] of devicesByProjectId) {
|
|
953
|
+
await NetworkAlertPolicyEngineService.deletePolicyMonitorsForDevices({
|
|
954
|
+
projectId: new ObjectID(projectIdString),
|
|
955
|
+
deviceIds: deviceIds,
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
|
|
786
959
|
for (const cleanupPlan of cleanupPlans) {
|
|
787
960
|
/*
|
|
788
961
|
* LIMIT_MAX is a per-service-call cap, not a lifecycle cap. Always
|
|
@@ -913,6 +1086,136 @@ export class Service extends DatabaseService<Model> {
|
|
|
913
1086
|
}
|
|
914
1087
|
}
|
|
915
1088
|
|
|
1089
|
+
/*
|
|
1090
|
+
* The FK behind `probeId` only requires the Probe row to exist. Probe ids
|
|
1091
|
+
* reach the server from the browser — the device create form, the settings
|
|
1092
|
+
* page and the bulk "Set probe" action all post one — so without this
|
|
1093
|
+
* check a device can be pointed at another project's probe, and that probe
|
|
1094
|
+
* then claims it on its next poll: it reads the device's hostname and its
|
|
1095
|
+
* SNMP credentials, and reports status back into this project. That is a
|
|
1096
|
+
* cross-tenant read of both configuration and network position.
|
|
1097
|
+
*
|
|
1098
|
+
* A GLOBAL probe has no project and is attachable anywhere, so this
|
|
1099
|
+
* delegates to ProbeService rather than comparing projectIds — the same
|
|
1100
|
+
* predicate that decides which probes a monitor may use.
|
|
1101
|
+
*
|
|
1102
|
+
* `claimDevicesForPolling` re-checks the pairing in SQL as a backstop, for
|
|
1103
|
+
* rows written before this guard existed. Both halves are load-bearing:
|
|
1104
|
+
* this one gives the operator an error at the point of the mistake, the
|
|
1105
|
+
* other one makes a stale row unpollable rather than merely unwritable.
|
|
1106
|
+
*/
|
|
1107
|
+
@CaptureSpan()
|
|
1108
|
+
private async assertProbeIsAttachableToProject(data: {
|
|
1109
|
+
probeId: ObjectID;
|
|
1110
|
+
projectId: ObjectID | undefined;
|
|
1111
|
+
}): Promise<void> {
|
|
1112
|
+
if (!data.projectId) {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
const isAttachable: boolean = await ProbeService.isProbeAttachableToProject(
|
|
1117
|
+
{
|
|
1118
|
+
probeId: data.probeId,
|
|
1119
|
+
projectId: data.projectId,
|
|
1120
|
+
},
|
|
1121
|
+
);
|
|
1122
|
+
|
|
1123
|
+
if (!isAttachable) {
|
|
1124
|
+
throw new BadDataException(
|
|
1125
|
+
"Probe not found or it does not belong to this project.",
|
|
1126
|
+
);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
/*
|
|
1131
|
+
* Same hole as the probe, on the other half of the poll: a credential
|
|
1132
|
+
* profile is read LIVE at poll time
|
|
1133
|
+
* (NetworkDeviceHydrationUtil.resolveSnmpCredentials), so a device pointed
|
|
1134
|
+
* at another project's profile would be walked with that project's
|
|
1135
|
+
* community string or v3 credentials — put on the wire, inside this
|
|
1136
|
+
* project's network, by this project's probe.
|
|
1137
|
+
*
|
|
1138
|
+
* The resolver drops a mismatched reference as a backstop and pings the
|
|
1139
|
+
* device instead. This is the half that stops the reference being written
|
|
1140
|
+
* at all, and it is the half that tells the operator why.
|
|
1141
|
+
*/
|
|
1142
|
+
@CaptureSpan()
|
|
1143
|
+
private async assertSnmpCredentialProfileBelongsToProject(data: {
|
|
1144
|
+
snmpCredentialProfileId: ObjectID;
|
|
1145
|
+
projectId: ObjectID | undefined;
|
|
1146
|
+
}): Promise<void> {
|
|
1147
|
+
if (!data.projectId) {
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
const profile: NetworkSnmpCredentialProfile | null =
|
|
1152
|
+
await NetworkSnmpCredentialProfileService.findOneById({
|
|
1153
|
+
id: data.snmpCredentialProfileId,
|
|
1154
|
+
select: {
|
|
1155
|
+
_id: true,
|
|
1156
|
+
projectId: true,
|
|
1157
|
+
},
|
|
1158
|
+
props: {
|
|
1159
|
+
isRoot: true,
|
|
1160
|
+
},
|
|
1161
|
+
});
|
|
1162
|
+
|
|
1163
|
+
if (!profile) {
|
|
1164
|
+
throw new BadDataException("SNMP Credential Profile not found.");
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
if (
|
|
1168
|
+
profile.projectId &&
|
|
1169
|
+
profile.projectId.toString() !== data.projectId.toString()
|
|
1170
|
+
) {
|
|
1171
|
+
throw new BadDataException(
|
|
1172
|
+
"SNMP Credential Profile must belong to the same project.",
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
/*
|
|
1178
|
+
* The site's default probe, resolved for a device that is landing in that
|
|
1179
|
+
* site without one of its own — this site's `probeId`, or the nearest
|
|
1180
|
+
* ancestor that has one.
|
|
1181
|
+
*
|
|
1182
|
+
* Returns null rather than throwing when the inherited probe is not
|
|
1183
|
+
* attachable to the device's project. A site row written before the
|
|
1184
|
+
* tenancy guards existed must not be able to fail an unrelated device
|
|
1185
|
+
* write; the honest outcome is that the device is created with NO probe
|
|
1186
|
+
* (it reads Pending, and the operator picks one) rather than silently
|
|
1187
|
+
* copying another project's probe onto it.
|
|
1188
|
+
*/
|
|
1189
|
+
@CaptureSpan()
|
|
1190
|
+
private async resolveInheritedSiteProbeId(data: {
|
|
1191
|
+
siteId: ObjectID;
|
|
1192
|
+
projectIds: Array<ObjectID>;
|
|
1193
|
+
}): Promise<ObjectID | null> {
|
|
1194
|
+
const inheritedProbeId: ObjectID | null =
|
|
1195
|
+
await NetworkSiteService.resolveDefaultProbeIdForSite(data.siteId);
|
|
1196
|
+
|
|
1197
|
+
if (!inheritedProbeId) {
|
|
1198
|
+
return null;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
for (const projectId of data.projectIds) {
|
|
1202
|
+
const isAttachable: boolean =
|
|
1203
|
+
await ProbeService.isProbeAttachableToProject({
|
|
1204
|
+
probeId: inheritedProbeId,
|
|
1205
|
+
projectId: projectId,
|
|
1206
|
+
});
|
|
1207
|
+
|
|
1208
|
+
if (!isAttachable) {
|
|
1209
|
+
logger.error(
|
|
1210
|
+
`Network site ${data.siteId.toString()} names default probe ${inheritedProbeId.toString()}, which is not attachable to project ${projectId.toString()}. Not inheriting it; the device is left without a probe.`,
|
|
1211
|
+
);
|
|
1212
|
+
return null;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
return inheritedProbeId;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
916
1219
|
/*
|
|
917
1220
|
* onBeforeUpdate runs before DatabaseService permission-checks the query,
|
|
918
1221
|
* so reading the raw client query as root would hand the hook rows from
|
|
@@ -952,6 +1255,42 @@ export class Service extends DatabaseService<Model> {
|
|
|
952
1255
|
});
|
|
953
1256
|
}
|
|
954
1257
|
|
|
1258
|
+
/*
|
|
1259
|
+
* DatabaseService stamps the tenant column AFTER this hook runs, so a
|
|
1260
|
+
* device created from the dashboard reaches here with `projectId` still
|
|
1261
|
+
* unset and only `props.tenantId` to go on. The guards below are the
|
|
1262
|
+
* tenancy boundary of polling, so they must not be skipped for the one
|
|
1263
|
+
* write shape every UI create takes.
|
|
1264
|
+
*/
|
|
1265
|
+
const createProjectId: ObjectID | undefined =
|
|
1266
|
+
createBy.data.projectId ||
|
|
1267
|
+
createBy.data.project?.id ||
|
|
1268
|
+
createBy.props.tenantId ||
|
|
1269
|
+
undefined;
|
|
1270
|
+
|
|
1271
|
+
const createProbeId: ObjectID | null = readProbeIdFromData(
|
|
1272
|
+
createBy.data as unknown as Record<string, unknown>,
|
|
1273
|
+
);
|
|
1274
|
+
|
|
1275
|
+
if (createProbeId) {
|
|
1276
|
+
await this.assertProbeIsAttachableToProject({
|
|
1277
|
+
probeId: createProbeId,
|
|
1278
|
+
projectId: createProjectId,
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
const createSnmpCredentialProfileId: ObjectID | null =
|
|
1283
|
+
readSnmpCredentialProfileIdFromData(
|
|
1284
|
+
createBy.data as unknown as Record<string, unknown>,
|
|
1285
|
+
);
|
|
1286
|
+
|
|
1287
|
+
if (createSnmpCredentialProfileId) {
|
|
1288
|
+
await this.assertSnmpCredentialProfileBelongsToProject({
|
|
1289
|
+
snmpCredentialProfileId: createSnmpCredentialProfileId,
|
|
1290
|
+
projectId: createProjectId,
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
|
|
955
1294
|
const createOidTemplateId: ObjectID | null = readOidTemplateIdFromData(
|
|
956
1295
|
createBy.data as unknown as Record<string, unknown>,
|
|
957
1296
|
);
|
|
@@ -976,37 +1315,76 @@ export class Service extends DatabaseService<Model> {
|
|
|
976
1315
|
);
|
|
977
1316
|
}
|
|
978
1317
|
|
|
1318
|
+
const monitorId: ObjectID | null = readMonitorIdFromData(
|
|
1319
|
+
createBy.data as unknown as Record<string, unknown>,
|
|
1320
|
+
);
|
|
1321
|
+
|
|
1322
|
+
/*
|
|
1323
|
+
* The monitor is NOT required. Discovery import is why: a subnet sweep
|
|
1324
|
+
* finds ping-only hosts in bulk and there is no monitor to bind them to
|
|
1325
|
+
* yet. Such a device is still worth recording — it belongs to a site,
|
|
1326
|
+
* carries labels, and appears on the topology map — and its status reads
|
|
1327
|
+
* Pending, tagged "No monitor", which is exactly true until somebody
|
|
1328
|
+
* points a monitor at it.
|
|
1329
|
+
*
|
|
1330
|
+
* But any binding that IS supplied is tenant-checked, whatever the
|
|
1331
|
+
* monitoring method. This guard used to sit inside the monitor-backed
|
|
1332
|
+
* branch below, which left a Probe-method create (or one with the method
|
|
1333
|
+
* omitted) free to persist another project's monitor FK: the FK only
|
|
1334
|
+
* proves the Monitor row exists, a Probe device may legitimately carry a
|
|
1335
|
+
* monitorId (NetworkSiteService.onMonitorStatusChanged stamps from it),
|
|
1336
|
+
* and a nested select through the relation reads that monitor's
|
|
1337
|
+
* configuration. The update path runs the same check.
|
|
1338
|
+
*/
|
|
1339
|
+
if (monitorId) {
|
|
1340
|
+
await this.assertMonitorBelongsToProject({
|
|
1341
|
+
monitorId: monitorId,
|
|
1342
|
+
projectId: createBy.data.projectId,
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
|
|
979
1346
|
if (
|
|
980
1347
|
NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
|
|
981
1348
|
createBy.data.monitoringMethod,
|
|
982
1349
|
)
|
|
983
1350
|
) {
|
|
984
|
-
const monitorId: ObjectID | null = readMonitorIdFromData(
|
|
985
|
-
createBy.data as unknown as Record<string, unknown>,
|
|
986
|
-
);
|
|
987
|
-
|
|
988
1351
|
/*
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
*
|
|
992
|
-
*
|
|
993
|
-
*
|
|
994
|
-
* is exactly true until somebody points a monitor at it.
|
|
1352
|
+
* Not a preference: nothing polls a monitor-backed device — its bound
|
|
1353
|
+
* monitor's status is its status — so leaving polling on would queue
|
|
1354
|
+
* a poll whose verdict nothing may read. claimDevicesForPolling
|
|
1355
|
+
* refuses these rows too — this is the half that keeps the column
|
|
1356
|
+
* honest for anything reading it.
|
|
995
1357
|
*/
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
monitorId: monitorId,
|
|
999
|
-
projectId: createBy.data.projectId,
|
|
1000
|
-
});
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1358
|
+
createBy.data.isPollingEnabled = false;
|
|
1359
|
+
} else if (siteId && !createProbeId) {
|
|
1003
1360
|
/*
|
|
1004
|
-
*
|
|
1005
|
-
*
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
1361
|
+
* Site default probe, COPIED AT WRITE.
|
|
1362
|
+
*
|
|
1363
|
+
* This is what lets an operator register a device with a name and an
|
|
1364
|
+
* address and nothing else: the site (or the nearest ancestor site
|
|
1365
|
+
* that names one) supplies the probe, and the device polls from its
|
|
1366
|
+
* first cycle instead of sitting Pending until somebody notices the
|
|
1367
|
+
* empty field.
|
|
1368
|
+
*
|
|
1369
|
+
* Copied, not read through, and that distinction is the whole design.
|
|
1370
|
+
* Nothing re-reads the site later, so editing a site's default probe
|
|
1371
|
+
* decides where FUTURE devices poll from and never re-points a fleet
|
|
1372
|
+
* that is already polling — a read-through default would turn one
|
|
1373
|
+
* dropdown change into a silent migration of every device in the
|
|
1374
|
+
* subtree onto a probe that may not even reach them.
|
|
1375
|
+
*
|
|
1376
|
+
* A device that names its own probe keeps it: `createProbeId` above is
|
|
1377
|
+
* the caller's explicit choice and always wins.
|
|
1008
1378
|
*/
|
|
1009
|
-
|
|
1379
|
+
const inheritedProbeId: ObjectID | null =
|
|
1380
|
+
await this.resolveInheritedSiteProbeId({
|
|
1381
|
+
siteId: siteId,
|
|
1382
|
+
projectIds: createProjectId ? [createProjectId] : [],
|
|
1383
|
+
});
|
|
1384
|
+
|
|
1385
|
+
if (inheritedProbeId) {
|
|
1386
|
+
createBy.data.probeId = inheritedProbeId;
|
|
1387
|
+
}
|
|
1010
1388
|
}
|
|
1011
1389
|
|
|
1012
1390
|
return { createBy, carryForward: null };
|
|
@@ -1086,8 +1464,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
1086
1464
|
/*
|
|
1087
1465
|
* A device created monitor-backed adopts its monitor's CURRENT
|
|
1088
1466
|
* status right away rather than waiting for that monitor's next
|
|
1089
|
-
* status CHANGE. Skipped for
|
|
1090
|
-
* their own
|
|
1467
|
+
* status CHANGE. Skipped for Probe devices, which are judged by
|
|
1468
|
+
* their own poll.
|
|
1091
1469
|
*/
|
|
1092
1470
|
if (
|
|
1093
1471
|
NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
|
|
@@ -1100,6 +1478,21 @@ export class Service extends DatabaseService<Model> {
|
|
|
1100
1478
|
});
|
|
1101
1479
|
}
|
|
1102
1480
|
})
|
|
1481
|
+
.then(async () => {
|
|
1482
|
+
/*
|
|
1483
|
+
* LAST, and that ordering is the whole point. A Network Alert
|
|
1484
|
+
* Policy can be scoped by site, by role and by LABEL, and the
|
|
1485
|
+
* label and site links above are what put those on a newly
|
|
1486
|
+
* imported device — a discovery import arrives with neither. Asking
|
|
1487
|
+
* the policy engine before they land would reconcile the device
|
|
1488
|
+
* against a scope it does not match yet, provision nothing, and
|
|
1489
|
+
* leave the device uncovered until the five-minute sweep.
|
|
1490
|
+
*/
|
|
1491
|
+
await NetworkAlertPolicyEngineService.reconcileDevice({
|
|
1492
|
+
projectId: createdItem.projectId!,
|
|
1493
|
+
deviceId: createdItem.id!,
|
|
1494
|
+
});
|
|
1495
|
+
})
|
|
1103
1496
|
.catch((error: Error) => {
|
|
1104
1497
|
logger.error(
|
|
1105
1498
|
`Error applying network device rules in NetworkDeviceService.onCreateSuccess: ${error}`,
|
|
@@ -1116,9 +1509,13 @@ export class Service extends DatabaseService<Model> {
|
|
|
1116
1509
|
/*
|
|
1117
1510
|
* Capture the previous state of every matched device when an update
|
|
1118
1511
|
* touches siteId (so onUpdateSuccess can refresh the OLD site's rollup as
|
|
1119
|
-
* well as the new one)
|
|
1512
|
+
* well as the new one), touches one of the columns site assignment rules
|
|
1120
1513
|
* match on (so onUpdateSuccess can tell a real rename from the identical
|
|
1121
|
-
* sysName the SNMP walk rewrites on every poll)
|
|
1514
|
+
* sysName the SNMP walk rewrites on every poll), or touches
|
|
1515
|
+
* monitoringMethod (so onUpdateSuccess can tell a real Monitor -> Probe
|
|
1516
|
+
* transition from a form re-sending the method the device already has).
|
|
1517
|
+
* The same read feeds the tenancy guards on the site, monitor and OID
|
|
1518
|
+
* template references.
|
|
1122
1519
|
*/
|
|
1123
1520
|
@CaptureSpan()
|
|
1124
1521
|
protected override async onBeforeUpdate(
|
|
@@ -1128,15 +1525,17 @@ export class Service extends DatabaseService<Model> {
|
|
|
1128
1525
|
|
|
1129
1526
|
/*
|
|
1130
1527
|
* Switching a device to monitor-backed turns polling off with it. The
|
|
1131
|
-
* two are one decision, not two: a device
|
|
1132
|
-
*
|
|
1133
|
-
*
|
|
1528
|
+
* two are one decision, not two: a monitor-backed device's health is
|
|
1529
|
+
* its bound monitor's, so leaving the flag on would queue a poll per
|
|
1530
|
+
* interval whose verdict nothing may read. The way back is the mirror
|
|
1531
|
+
* image — onUpdateSuccess restores polling on a real Monitor -> Probe
|
|
1532
|
+
* transition, per device, once the write has committed.
|
|
1134
1533
|
*/
|
|
1135
1534
|
const isMethodWrite: boolean = dataKeys.includes("monitoringMethod");
|
|
1136
1535
|
/*
|
|
1137
1536
|
* An update payload is a QueryDeepPartialEntity, so a column can hold a
|
|
1138
1537
|
* raw value OR a SQL-expression function. Only a plain string is a
|
|
1139
|
-
* method we can reason about; anything else falls through to the
|
|
1538
|
+
* method we can reason about; anything else falls through to the Probe
|
|
1140
1539
|
* default, which changes nothing.
|
|
1141
1540
|
*/
|
|
1142
1541
|
const writtenMethod: unknown = (
|
|
@@ -1148,6 +1547,16 @@ export class Service extends DatabaseService<Model> {
|
|
|
1148
1547
|
NetworkDeviceMonitoringMethodUtil.isMonitorBacked(writtenMethod);
|
|
1149
1548
|
|
|
1150
1549
|
if (becomesMonitorBacked) {
|
|
1550
|
+
/*
|
|
1551
|
+
* Only the polling flag is forced onto the payload, deliberately. The
|
|
1552
|
+
* poll residue the device carries over from its probe-polled days has to go
|
|
1553
|
+
* too, but the column-permission check runs on this payload AFTER the
|
|
1554
|
+
* hook, and those columns are updatable by fewer roles than
|
|
1555
|
+
* monitoringMethod is — so adding them here would turn a project
|
|
1556
|
+
* member's legitimate switch into a permission failure.
|
|
1557
|
+
* onUpdateSuccess clears them as root once the transition has
|
|
1558
|
+
* committed; see pollResidueReset.
|
|
1559
|
+
*/
|
|
1151
1560
|
updateBy.data.isPollingEnabled = false;
|
|
1152
1561
|
}
|
|
1153
1562
|
|
|
@@ -1159,37 +1568,36 @@ export class Service extends DatabaseService<Model> {
|
|
|
1159
1568
|
* nothing ever polled it. Only checked when the payload actually asks
|
|
1160
1569
|
* for it, so the ordinary update path costs no extra query.
|
|
1161
1570
|
*/
|
|
1162
|
-
|
|
1571
|
+
const isPollingTurnOn: boolean =
|
|
1163
1572
|
!becomesMonitorBacked &&
|
|
1164
1573
|
dataKeys.includes("isPollingEnabled") &&
|
|
1165
|
-
updateBy.data.isPollingEnabled === true
|
|
1166
|
-
) {
|
|
1167
|
-
const targets: Array<Model> = await this.findBy({
|
|
1168
|
-
query: this.scopeQueryToCallerTenant(updateBy.query, updateBy.props),
|
|
1169
|
-
select: {
|
|
1170
|
-
_id: true,
|
|
1171
|
-
monitoringMethod: true,
|
|
1172
|
-
},
|
|
1173
|
-
limit: LIMIT_MAX,
|
|
1174
|
-
skip: 0,
|
|
1175
|
-
props: {
|
|
1176
|
-
isRoot: true,
|
|
1177
|
-
},
|
|
1178
|
-
});
|
|
1574
|
+
updateBy.data.isPollingEnabled === true;
|
|
1179
1575
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1576
|
+
/*
|
|
1577
|
+
* Read — and, for conflicting spellings, refused — before the early
|
|
1578
|
+
* return below, so a payload that points `monitorId` and `monitor` at
|
|
1579
|
+
* different rows is rejected on every write shape rather than only on
|
|
1580
|
+
* the ones that happen to need the snapshot. Null means the write
|
|
1581
|
+
* unbinds the monitor, or does not mention it; neither needs a lookup.
|
|
1582
|
+
*/
|
|
1583
|
+
const newMonitorId: ObjectID | null = readMonitorIdFromData(
|
|
1584
|
+
updateBy.data as unknown as Record<string, unknown>,
|
|
1585
|
+
);
|
|
1185
1586
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1587
|
+
/*
|
|
1588
|
+
* Read here, above the early return, for the same reason the monitor id
|
|
1589
|
+
* is: a payload that points `probeId` and `probe` (or the two credential
|
|
1590
|
+
* profile spellings) at different rows is a contradiction, and it is
|
|
1591
|
+
* refused on every write shape rather than only on the ones that happen
|
|
1592
|
+
* to need the snapshot below.
|
|
1593
|
+
*/
|
|
1594
|
+
const newProbeId: ObjectID | null = readProbeIdFromData(
|
|
1595
|
+
updateBy.data as unknown as Record<string, unknown>,
|
|
1596
|
+
);
|
|
1597
|
+
const newSnmpCredentialProfileId: ObjectID | null =
|
|
1598
|
+
readSnmpCredentialProfileIdFromData(
|
|
1599
|
+
updateBy.data as unknown as Record<string, unknown>,
|
|
1600
|
+
);
|
|
1193
1601
|
|
|
1194
1602
|
const isSiteChange: boolean = isSiteWrite(dataKeys);
|
|
1195
1603
|
const isIdentityChange: boolean = SITE_RULE_IDENTITY_COLUMNS.some(
|
|
@@ -1218,12 +1626,51 @@ export class Service extends DatabaseService<Model> {
|
|
|
1218
1626
|
OID_TEMPLATE_KEYS,
|
|
1219
1627
|
);
|
|
1220
1628
|
const isDeviceOidsChange: boolean = updateBy.data.snmpOids !== undefined;
|
|
1629
|
+
/*
|
|
1630
|
+
* The polling tenancy pair, named in the early return for exactly the
|
|
1631
|
+
* reason the OID template is: assigning a probe or a credential profile
|
|
1632
|
+
* changes neither site nor identity, so a guard placed below the return
|
|
1633
|
+
* would be dead code on the only writes it exists for — the settings
|
|
1634
|
+
* page's Monitoring section and the device-list bulk actions, which post
|
|
1635
|
+
* precisely these columns and nothing else.
|
|
1636
|
+
*/
|
|
1637
|
+
const isProbeChange: boolean = RelationIdUtil.isWritten(
|
|
1638
|
+
dataKeys,
|
|
1639
|
+
PROBE_KEYS,
|
|
1640
|
+
);
|
|
1641
|
+
const isSnmpCredentialProfileChange: boolean = RelationIdUtil.isWritten(
|
|
1642
|
+
dataKeys,
|
|
1643
|
+
PROFILE_KEYS,
|
|
1644
|
+
);
|
|
1645
|
+
|
|
1646
|
+
/*
|
|
1647
|
+
* One snapshot read serves every guard and carry-forward below, and the
|
|
1648
|
+
* SNMP walk's per-poll column writes — the hot path through here — need
|
|
1649
|
+
* none of them. Binding a monitor is on the list for the same reason the
|
|
1650
|
+
* OID template is: it is exactly the write shape that changes neither
|
|
1651
|
+
* site nor identity, so a tenancy guard placed below a narrower return
|
|
1652
|
+
* would never run on the only write it exists for.
|
|
1653
|
+
*/
|
|
1654
|
+
/*
|
|
1655
|
+
* The alert-policy axes ride the same return, and for the same reason
|
|
1656
|
+
* the OID template does: re-labelling a device or moving it to a role
|
|
1657
|
+
* changes neither its site nor its identity, so a snapshot taken below a
|
|
1658
|
+
* narrower return would be absent on exactly the writes onUpdateSuccess
|
|
1659
|
+
* needs it for. See isAlertPolicyRelevantWrite.
|
|
1660
|
+
*/
|
|
1661
|
+
const isAlertPolicyChange: boolean = isAlertPolicyRelevantWrite(dataKeys);
|
|
1221
1662
|
|
|
1222
1663
|
if (
|
|
1664
|
+
!isMethodWrite &&
|
|
1665
|
+
!isPollingTurnOn &&
|
|
1666
|
+
!newMonitorId &&
|
|
1223
1667
|
!isSiteChange &&
|
|
1224
1668
|
!isIdentityChange &&
|
|
1225
1669
|
!isOidTemplateChange &&
|
|
1226
|
-
!isDeviceOidsChange
|
|
1670
|
+
!isDeviceOidsChange &&
|
|
1671
|
+
!isProbeChange &&
|
|
1672
|
+
!isSnmpCredentialProfileChange &&
|
|
1673
|
+
!isAlertPolicyChange
|
|
1227
1674
|
) {
|
|
1228
1675
|
return { updateBy, carryForward: null };
|
|
1229
1676
|
}
|
|
@@ -1237,9 +1684,18 @@ export class Service extends DatabaseService<Model> {
|
|
|
1237
1684
|
hostname: true,
|
|
1238
1685
|
name: true,
|
|
1239
1686
|
sysName: true,
|
|
1687
|
+
/*
|
|
1688
|
+
* Whether the device already has a probe. The site-default
|
|
1689
|
+
* inheritance below must never overwrite one, and this column is
|
|
1690
|
+
* the only way to tell "no probe yet" from "a probe the operator
|
|
1691
|
+
* chose" once the write has committed.
|
|
1692
|
+
*/
|
|
1693
|
+
probeId: true,
|
|
1240
1694
|
// Decide which OID budget applies below, and whether a link would truncate.
|
|
1241
1695
|
oidTemplateId: true,
|
|
1242
1696
|
snmpOids: true,
|
|
1697
|
+
// The polling guard and the method transition both need the OLD method.
|
|
1698
|
+
monitoringMethod: true,
|
|
1243
1699
|
},
|
|
1244
1700
|
limit: LIMIT_MAX,
|
|
1245
1701
|
skip: 0,
|
|
@@ -1248,6 +1704,47 @@ export class Service extends DatabaseService<Model> {
|
|
|
1248
1704
|
},
|
|
1249
1705
|
});
|
|
1250
1706
|
|
|
1707
|
+
if (isPollingTurnOn) {
|
|
1708
|
+
const isTargetMonitorBacked: boolean = previousDevices.some(
|
|
1709
|
+
(target: Model) => {
|
|
1710
|
+
return NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
|
|
1711
|
+
target.monitoringMethod,
|
|
1712
|
+
);
|
|
1713
|
+
},
|
|
1714
|
+
);
|
|
1715
|
+
|
|
1716
|
+
// Unless the same write is moving it back to Probe, which is allowed.
|
|
1717
|
+
if (isTargetMonitorBacked && !(isMethodWrite && !becomesMonitorBacked)) {
|
|
1718
|
+
throw new BadDataException(
|
|
1719
|
+
"This device is monitor-backed, so there is nothing to poll — its bound monitor's status is its status. Switch its monitoring method to Probe first.",
|
|
1720
|
+
);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/*
|
|
1725
|
+
* Which of the matched devices were monitor-backed BEFORE this write.
|
|
1726
|
+
* Only recorded on a method write, because only a method write can be a
|
|
1727
|
+
* transition; see DeviceUpdateCarryForward for what onUpdateSuccess does
|
|
1728
|
+
* with it and why the payload alone is not enough.
|
|
1729
|
+
*/
|
|
1730
|
+
let wasMonitorBackedByDeviceId: Record<string, boolean> | undefined =
|
|
1731
|
+
undefined;
|
|
1732
|
+
|
|
1733
|
+
if (isMethodWrite) {
|
|
1734
|
+
wasMonitorBackedByDeviceId = {};
|
|
1735
|
+
|
|
1736
|
+
for (const previousDevice of previousDevices) {
|
|
1737
|
+
if (!previousDevice.id) {
|
|
1738
|
+
continue;
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
wasMonitorBackedByDeviceId[previousDevice.id.toString()] =
|
|
1742
|
+
NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
|
|
1743
|
+
previousDevice.monitoringMethod,
|
|
1744
|
+
);
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1251
1748
|
const newSiteId: ObjectID | null = readSiteIdFromData(
|
|
1252
1749
|
updateBy.data as unknown as Record<string, unknown>,
|
|
1253
1750
|
);
|
|
@@ -1271,6 +1768,34 @@ export class Service extends DatabaseService<Model> {
|
|
|
1271
1768
|
}
|
|
1272
1769
|
}
|
|
1273
1770
|
|
|
1771
|
+
/*
|
|
1772
|
+
* The monitor guard on the UPDATE path. Until this existed only
|
|
1773
|
+
* onBeforeCreate checked the binding, so a device could be created
|
|
1774
|
+
* clean and then re-pointed at another project's monitor with a plain
|
|
1775
|
+
* update — and read that monitor's status through the device, since
|
|
1776
|
+
* refreshStampedMonitorStatus stamps whatever `monitorId` names. One
|
|
1777
|
+
* check per distinct project in the matched set, like the site guard
|
|
1778
|
+
* above. An unbind (null) has nothing to check.
|
|
1779
|
+
*/
|
|
1780
|
+
if (newMonitorId) {
|
|
1781
|
+
const checkedMonitorProjectIds: Set<string> = new Set();
|
|
1782
|
+
|
|
1783
|
+
for (const previousDevice of previousDevices) {
|
|
1784
|
+
if (
|
|
1785
|
+
!previousDevice.projectId ||
|
|
1786
|
+
checkedMonitorProjectIds.has(previousDevice.projectId.toString())
|
|
1787
|
+
) {
|
|
1788
|
+
continue;
|
|
1789
|
+
}
|
|
1790
|
+
checkedMonitorProjectIds.add(previousDevice.projectId.toString());
|
|
1791
|
+
|
|
1792
|
+
await this.assertMonitorBelongsToProject({
|
|
1793
|
+
monitorId: newMonitorId,
|
|
1794
|
+
projectId: previousDevice.projectId,
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1274
1799
|
const newOidTemplateId: ObjectID | null = readOidTemplateIdFromData(
|
|
1275
1800
|
updateBy.data as unknown as Record<string, unknown>,
|
|
1276
1801
|
);
|
|
@@ -1299,6 +1824,56 @@ export class Service extends DatabaseService<Model> {
|
|
|
1299
1824
|
}
|
|
1300
1825
|
}
|
|
1301
1826
|
|
|
1827
|
+
/*
|
|
1828
|
+
* The polling tenancy guards on the UPDATE path. A device created clean
|
|
1829
|
+
* and then re-pointed with a plain update is the same breach as one
|
|
1830
|
+
* created that way, so both hooks check both references. One check per
|
|
1831
|
+
* distinct project in the matched set, like the guards above — a single
|
|
1832
|
+
* updateBy can span projects when a root caller issues it, and the
|
|
1833
|
+
* payload names ONE probe and ONE profile for all of them.
|
|
1834
|
+
*
|
|
1835
|
+
* A clear (null) points at nothing and has nothing to check.
|
|
1836
|
+
*/
|
|
1837
|
+
const distinctProjectIds: Array<ObjectID> = [];
|
|
1838
|
+
const seenProjectIds: Set<string> = new Set();
|
|
1839
|
+
|
|
1840
|
+
for (const previousDevice of previousDevices) {
|
|
1841
|
+
if (
|
|
1842
|
+
!previousDevice.projectId ||
|
|
1843
|
+
seenProjectIds.has(previousDevice.projectId.toString())
|
|
1844
|
+
) {
|
|
1845
|
+
continue;
|
|
1846
|
+
}
|
|
1847
|
+
seenProjectIds.add(previousDevice.projectId.toString());
|
|
1848
|
+
distinctProjectIds.push(previousDevice.projectId);
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
for (const projectId of distinctProjectIds) {
|
|
1852
|
+
if (newProbeId) {
|
|
1853
|
+
await this.assertProbeIsAttachableToProject({
|
|
1854
|
+
probeId: newProbeId,
|
|
1855
|
+
projectId: projectId,
|
|
1856
|
+
});
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
if (newSnmpCredentialProfileId) {
|
|
1860
|
+
await this.assertSnmpCredentialProfileBelongsToProject({
|
|
1861
|
+
snmpCredentialProfileId: newSnmpCredentialProfileId,
|
|
1862
|
+
projectId: projectId,
|
|
1863
|
+
});
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
await this.applySiteDefaultProbeOnMove({
|
|
1868
|
+
updateBy: updateBy,
|
|
1869
|
+
previousDevices: previousDevices,
|
|
1870
|
+
distinctProjectIds: distinctProjectIds,
|
|
1871
|
+
newSiteId: newSiteId,
|
|
1872
|
+
isProbeChange: isProbeChange,
|
|
1873
|
+
isMethodWrite: isMethodWrite,
|
|
1874
|
+
becomesMonitorBacked: becomesMonitorBacked,
|
|
1875
|
+
});
|
|
1876
|
+
|
|
1302
1877
|
/*
|
|
1303
1878
|
* How many OIDs a device may carry of its own.
|
|
1304
1879
|
*
|
|
@@ -1351,17 +1926,96 @@ export class Service extends DatabaseService<Model> {
|
|
|
1351
1926
|
);
|
|
1352
1927
|
}
|
|
1353
1928
|
|
|
1929
|
+
const carryForward: DeviceUpdateCarryForward = {
|
|
1930
|
+
previousDevices: previousDevices,
|
|
1931
|
+
};
|
|
1932
|
+
|
|
1933
|
+
if (wasMonitorBackedByDeviceId) {
|
|
1934
|
+
carryForward.wasMonitorBackedByDeviceId = wasMonitorBackedByDeviceId;
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1354
1937
|
return {
|
|
1355
1938
|
updateBy,
|
|
1356
|
-
carryForward:
|
|
1357
|
-
previousDevices: previousDevices,
|
|
1358
|
-
},
|
|
1939
|
+
carryForward: carryForward,
|
|
1359
1940
|
};
|
|
1360
1941
|
}
|
|
1361
1942
|
|
|
1362
1943
|
/*
|
|
1363
|
-
*
|
|
1364
|
-
*
|
|
1944
|
+
* Site default probe on a MOVE: a device with no probe of its own that is
|
|
1945
|
+
* moved into a site inherits that site's default (or the nearest
|
|
1946
|
+
* ancestor's), copied onto this same write.
|
|
1947
|
+
*
|
|
1948
|
+
* The create path's twin, and the same copy-at-write rule: this runs only
|
|
1949
|
+
* because the payload moves the device, never because a site's default
|
|
1950
|
+
* changed. Editing a site's probe re-points nothing — the device-list bulk
|
|
1951
|
+
* "Set probe" action is the deliberate way to move a fleet.
|
|
1952
|
+
*
|
|
1953
|
+
* Three things stop it: the caller writing a probe of its own (their
|
|
1954
|
+
* choice wins, including an explicit clear), the device already having one
|
|
1955
|
+
* (a probe an operator chose must survive being filed under a site), and
|
|
1956
|
+
* the device being monitor-backed after this write (nothing polls it, so a
|
|
1957
|
+
* probe would be a lie on the row).
|
|
1958
|
+
*
|
|
1959
|
+
* "Already having one" is judged across the WHOLE matched set, because a
|
|
1960
|
+
* single payload writes one probeId to every row it matches: if any
|
|
1961
|
+
* matched device has a probe, inheriting would re-point it, so the
|
|
1962
|
+
* inheritance is skipped for the batch rather than applied to some of it.
|
|
1963
|
+
* The bulk path a user actually takes — "move these devices to this site"
|
|
1964
|
+
* — is overwhelmingly devices in the same state.
|
|
1965
|
+
*/
|
|
1966
|
+
private async applySiteDefaultProbeOnMove(data: {
|
|
1967
|
+
updateBy: UpdateBy<Model>;
|
|
1968
|
+
previousDevices: Array<Model>;
|
|
1969
|
+
distinctProjectIds: Array<ObjectID>;
|
|
1970
|
+
newSiteId: ObjectID | null;
|
|
1971
|
+
isProbeChange: boolean;
|
|
1972
|
+
isMethodWrite: boolean;
|
|
1973
|
+
becomesMonitorBacked: boolean;
|
|
1974
|
+
}): Promise<void> {
|
|
1975
|
+
if (
|
|
1976
|
+
!data.newSiteId ||
|
|
1977
|
+
data.isProbeChange ||
|
|
1978
|
+
data.previousDevices.length === 0
|
|
1979
|
+
) {
|
|
1980
|
+
return;
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
for (const previousDevice of data.previousDevices) {
|
|
1984
|
+
if (previousDevice.probeId) {
|
|
1985
|
+
return;
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
/*
|
|
1989
|
+
* The method AFTER this write: what the payload sets when it sets one,
|
|
1990
|
+
* otherwise what the row already says. A device that stays (or
|
|
1991
|
+
* becomes) monitor-backed is not polled by a probe at all.
|
|
1992
|
+
*/
|
|
1993
|
+
const isMonitorBackedAfterWrite: boolean = data.isMethodWrite
|
|
1994
|
+
? data.becomesMonitorBacked
|
|
1995
|
+
: NetworkDeviceMonitoringMethodUtil.isMonitorBacked(
|
|
1996
|
+
previousDevice.monitoringMethod,
|
|
1997
|
+
);
|
|
1998
|
+
|
|
1999
|
+
if (isMonitorBackedAfterWrite) {
|
|
2000
|
+
return;
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
const inheritedProbeId: ObjectID | null =
|
|
2005
|
+
await this.resolveInheritedSiteProbeId({
|
|
2006
|
+
siteId: data.newSiteId,
|
|
2007
|
+
projectIds: data.distinctProjectIds,
|
|
2008
|
+
});
|
|
2009
|
+
|
|
2010
|
+
if (inheritedProbeId) {
|
|
2011
|
+
data.updateBy.data.probeId = inheritedProbeId;
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
/*
|
|
2016
|
+
* Re-derives one device's stamped `currentMonitorStatusId` — and, for a
|
|
2017
|
+
* monitor-backed device, its `isReachable` — from its binding, and
|
|
2018
|
+
* refreshes its site chain if either moved.
|
|
1365
2019
|
*
|
|
1366
2020
|
* The stamp is what every monitor-backed surface reads — the device list
|
|
1367
2021
|
* pill, the site rollup, the topology node — and until this existed the
|
|
@@ -1373,14 +2027,33 @@ export class Service extends DatabaseService<Model> {
|
|
|
1373
2027
|
* OneUptime/oneuptime#3392. Binding is itself an event that decides the
|
|
1374
2028
|
* device's status, so it stamps here.
|
|
1375
2029
|
*
|
|
2030
|
+
* `isReachable` rides along because the device list's summary tiles and
|
|
2031
|
+
* its Status facet count and filter in SQL, over that column alone — they
|
|
2032
|
+
* cannot evaluate the stamp's ladder per row — so a monitor-backed device
|
|
2033
|
+
* whose stamp said Operational still counted as "Pending" there. The
|
|
2034
|
+
* value written is `!MonitorStatus.isOfflineState`: the OFFLINE end of the
|
|
2035
|
+
* ladder, not the operational one, because that is exactly what
|
|
2036
|
+
* DeviceReachabilityUtil reads for the pill (a "Degraded" row is neither
|
|
2037
|
+
* operational nor offline, and reads as reachable on both). NULL when
|
|
2038
|
+
* nothing is bound or the monitor has no status, which is the honest
|
|
2039
|
+
* "Pending" the util renders for `undefined`. For a Probe device the poll
|
|
2040
|
+
* owns `isReachable`, and this method never touches it.
|
|
2041
|
+
*
|
|
1376
2042
|
* `clearWhenNotMonitorBacked` is for the write that moves a device OFF
|
|
1377
2043
|
* monitor-backed: the ping monitor's verdict must not outlive the binding
|
|
1378
2044
|
* (DeviceHealthStateUtil lets a stamped status beat reachability, so a
|
|
1379
2045
|
* stale one would poison the site rollup of a device that is now walked).
|
|
1380
2046
|
* It is deliberately NOT set when a write only touches the monitor
|
|
1381
|
-
* binding of
|
|
1382
|
-
*
|
|
1383
|
-
*
|
|
2047
|
+
* binding of a Probe device, nor when a form re-sends "Probe" on a device
|
|
2048
|
+
* that already is one, because a Probe device's stamp comes from the
|
|
2049
|
+
* Network Device monitor that watches it, and that binding lives in the
|
|
2050
|
+
* monitor's step data rather than in this column. onBeforeUpdate records
|
|
2051
|
+
* the old method so onUpdateSuccess can tell the two apart.
|
|
2052
|
+
*
|
|
2053
|
+
* Idempotent: everything is re-derived from the binding, nothing from what
|
|
2054
|
+
* a previous call wrote, and nothing is written when the row already
|
|
2055
|
+
* agrees — which is what makes it safe from every save, from monitor
|
|
2056
|
+
* deletion, and from a backfill running twice concurrently.
|
|
1384
2057
|
*/
|
|
1385
2058
|
@CaptureSpan()
|
|
1386
2059
|
public async refreshStampedMonitorStatus(data: {
|
|
@@ -1396,6 +2069,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
1396
2069
|
monitoringMethod: true,
|
|
1397
2070
|
monitorId: true,
|
|
1398
2071
|
currentMonitorStatusId: true,
|
|
2072
|
+
isReachable: true,
|
|
2073
|
+
// Read only to decide whether the clear below has anything to clear.
|
|
2074
|
+
isSnmpReachable: true,
|
|
2075
|
+
lastSnmpSeenAt: true,
|
|
1399
2076
|
},
|
|
1400
2077
|
props: {
|
|
1401
2078
|
isRoot: true,
|
|
@@ -1411,13 +2088,64 @@ export class Service extends DatabaseService<Model> {
|
|
|
1411
2088
|
device.monitoringMethod,
|
|
1412
2089
|
);
|
|
1413
2090
|
|
|
1414
|
-
if (!isMonitorBacked
|
|
2091
|
+
if (!isMonitorBacked) {
|
|
2092
|
+
if (!data.clearWhenNotMonitorBacked) {
|
|
2093
|
+
return;
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
/*
|
|
2097
|
+
* The device has just left monitor-backed. While it was monitor-backed
|
|
2098
|
+
* its `isReachable` could only ever be the bound monitor's mirror: the
|
|
2099
|
+
* poll's value was NULLed on the way in (pollResidueReset), and
|
|
2100
|
+
* NetworkInventoryUtil never writes it for a monitor-backed row. So the
|
|
2101
|
+
* mirror goes with the stamp — otherwise a device switched back to
|
|
2102
|
+
* Probe would read "Down — the last poll could not reach it" (or Up)
|
|
2103
|
+
* on every surface, from the verdict of a monitor that no longer
|
|
2104
|
+
* governs it, until a poll happens to land. NULL is the honest answer:
|
|
2105
|
+
* Pending until the first poll decides.
|
|
2106
|
+
*
|
|
2107
|
+
* The SNMP pair is cleared with them for the same reason: nothing
|
|
2108
|
+
* walked the device while it was monitor-backed, so anything on those
|
|
2109
|
+
* two columns predates the binding, and a device switched back to
|
|
2110
|
+
* Probe starts clean — its first poll decides whether SNMP answers.
|
|
2111
|
+
*
|
|
2112
|
+
* Nothing to clear means nothing to write — a null-over-null write
|
|
2113
|
+
* would still recompute the site chain for nothing.
|
|
2114
|
+
*/
|
|
2115
|
+
const hasStamp: boolean = Boolean(device.currentMonitorStatusId);
|
|
2116
|
+
const hasMirroredReachability: boolean =
|
|
2117
|
+
typeof device.isReachable === "boolean";
|
|
2118
|
+
const hasSnmpResidue: boolean =
|
|
2119
|
+
typeof device.isSnmpReachable === "boolean" ||
|
|
2120
|
+
(device.lastSnmpSeenAt !== null && device.lastSnmpSeenAt !== undefined);
|
|
2121
|
+
|
|
2122
|
+
if (!hasStamp && !hasMirroredReachability && !hasSnmpResidue) {
|
|
2123
|
+
return;
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
await this.updateColumnsByIdWithoutHooks({
|
|
2127
|
+
id: data.deviceId,
|
|
2128
|
+
data: {
|
|
2129
|
+
currentMonitorStatusId: null,
|
|
2130
|
+
isReachable: null,
|
|
2131
|
+
isSnmpReachable: null,
|
|
2132
|
+
lastSnmpSeenAt: null,
|
|
2133
|
+
},
|
|
2134
|
+
});
|
|
2135
|
+
|
|
2136
|
+
if (device.siteId) {
|
|
2137
|
+
await NetworkSiteService.recomputeRollupForSiteAndAncestors(
|
|
2138
|
+
device.siteId,
|
|
2139
|
+
);
|
|
2140
|
+
}
|
|
2141
|
+
|
|
1415
2142
|
return;
|
|
1416
2143
|
}
|
|
1417
2144
|
|
|
1418
2145
|
let monitorStatusId: ObjectID | null = null;
|
|
2146
|
+
let nextReachable: boolean | null = null;
|
|
1419
2147
|
|
|
1420
|
-
if (
|
|
2148
|
+
if (device.monitorId) {
|
|
1421
2149
|
/*
|
|
1422
2150
|
* Scoped to the device's project on the read as well as on the write
|
|
1423
2151
|
* path in onBeforeCreate/onBeforeUpdate: a monitor from another
|
|
@@ -1431,6 +2159,9 @@ export class Service extends DatabaseService<Model> {
|
|
|
1431
2159
|
select: {
|
|
1432
2160
|
_id: true,
|
|
1433
2161
|
currentMonitorStatusId: true,
|
|
2162
|
+
currentMonitorStatus: {
|
|
2163
|
+
isOfflineState: true,
|
|
2164
|
+
},
|
|
1434
2165
|
},
|
|
1435
2166
|
props: {
|
|
1436
2167
|
isRoot: true,
|
|
@@ -1438,20 +2169,34 @@ export class Service extends DatabaseService<Model> {
|
|
|
1438
2169
|
});
|
|
1439
2170
|
|
|
1440
2171
|
monitorStatusId = monitor?.currentMonitorStatusId || null;
|
|
2172
|
+
|
|
2173
|
+
if (monitorStatusId) {
|
|
2174
|
+
nextReachable = monitor?.currentMonitorStatus?.isOfflineState !== true;
|
|
2175
|
+
}
|
|
1441
2176
|
}
|
|
1442
2177
|
|
|
1443
2178
|
const currentStampId: string | null =
|
|
1444
2179
|
device.currentMonitorStatusId?.toString() || null;
|
|
1445
2180
|
const nextStampId: string | null = monitorStatusId?.toString() || null;
|
|
1446
2181
|
|
|
1447
|
-
|
|
2182
|
+
/*
|
|
2183
|
+
* A NULL column reads back as undefined on the model; both mean "no
|
|
2184
|
+
* verdict", and comparing them as one keeps a device that already
|
|
2185
|
+
* agrees from being rewritten on every save.
|
|
2186
|
+
*/
|
|
2187
|
+
const currentReachable: boolean | null =
|
|
2188
|
+
typeof device.isReachable === "boolean" ? device.isReachable : null;
|
|
2189
|
+
|
|
2190
|
+
if (currentStampId === nextStampId && currentReachable === nextReachable) {
|
|
1448
2191
|
return;
|
|
1449
2192
|
}
|
|
1450
2193
|
|
|
2194
|
+
// One write, so the two columns can never be seen disagreeing.
|
|
1451
2195
|
await this.updateColumnsByIdWithoutHooks({
|
|
1452
2196
|
id: data.deviceId,
|
|
1453
2197
|
data: {
|
|
1454
2198
|
currentMonitorStatusId: monitorStatusId,
|
|
2199
|
+
isReachable: nextReachable,
|
|
1455
2200
|
},
|
|
1456
2201
|
});
|
|
1457
2202
|
|
|
@@ -1485,10 +2230,116 @@ export class Service extends DatabaseService<Model> {
|
|
|
1485
2230
|
);
|
|
1486
2231
|
|
|
1487
2232
|
if (isMethodWrite || isMonitorWrite) {
|
|
2233
|
+
// Same parse as onBeforeUpdate: only a plain string is a method.
|
|
2234
|
+
const writtenMethod: unknown = (
|
|
2235
|
+
onUpdate.updateBy.data as unknown as Record<string, unknown>
|
|
2236
|
+
)["monitoringMethod"];
|
|
2237
|
+
const becomesMonitorBacked: boolean =
|
|
2238
|
+
isMethodWrite &&
|
|
2239
|
+
typeof writtenMethod === "string" &&
|
|
2240
|
+
NetworkDeviceMonitoringMethodUtil.isMonitorBacked(writtenMethod);
|
|
2241
|
+
|
|
2242
|
+
/*
|
|
2243
|
+
* Recorded by onBeforeUpdate on every method write. Absent on a
|
|
2244
|
+
* binding-only write, where nothing can have transitioned.
|
|
2245
|
+
*/
|
|
2246
|
+
const wasMonitorBackedByDeviceId: Record<string, boolean> =
|
|
2247
|
+
(onUpdate.carryForward as DeviceUpdateCarryForward | null)
|
|
2248
|
+
?.wasMonitorBackedByDeviceId || {};
|
|
2249
|
+
|
|
1488
2250
|
for (const deviceId of updatedItemIds) {
|
|
2251
|
+
const wasMonitorBacked: boolean | undefined =
|
|
2252
|
+
wasMonitorBackedByDeviceId[deviceId.toString()];
|
|
2253
|
+
|
|
2254
|
+
/*
|
|
2255
|
+
* Probe -> Monitor: the probe's last findings are now residue on a
|
|
2256
|
+
* device nothing polls, and they would keep feeding the legacy
|
|
2257
|
+
* staleness rule and the "degraded" query. Cleared as root here
|
|
2258
|
+
* rather than on the caller's payload (see onBeforeUpdate for the
|
|
2259
|
+
* permission reason), and BEFORE the re-stamp, so a device bound
|
|
2260
|
+
* in the same write ends up with its monitor's verdict rather
|
|
2261
|
+
* than the walk's. A device the snapshot did not record is
|
|
2262
|
+
* cleared too: the write is idempotent, and "unknown" must not
|
|
2263
|
+
* mean "keep the residue".
|
|
2264
|
+
*/
|
|
2265
|
+
if (becomesMonitorBacked && wasMonitorBacked !== true) {
|
|
2266
|
+
try {
|
|
2267
|
+
await this.updateColumnsByIdWithoutHooks({
|
|
2268
|
+
id: deviceId,
|
|
2269
|
+
data: pollResidueReset(),
|
|
2270
|
+
});
|
|
2271
|
+
} catch (error) {
|
|
2272
|
+
/*
|
|
2273
|
+
* Bookkeeping, and separable from the re-stamp: the monitor's
|
|
2274
|
+
* verdict below still lands, and a set isReachable keeps the
|
|
2275
|
+
* legacy freshness branch out of play even with the dates
|
|
2276
|
+
* left behind.
|
|
2277
|
+
*/
|
|
2278
|
+
logger.error(
|
|
2279
|
+
`Error in NetworkDeviceService.onUpdateSuccess poll residue reset for device ${deviceId.toString()}: ${error}`,
|
|
2280
|
+
);
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
/*
|
|
2285
|
+
* Monitor -> Probe: the mirror image. Arriving at monitor-backed
|
|
2286
|
+
* turned polling off (onBeforeUpdate), so leaving it turns polling
|
|
2287
|
+
* back on — otherwise the device would sit on "Pending" under a
|
|
2288
|
+
* method whose whole point is that the probe polls it. Decided
|
|
2289
|
+
* per device from the snapshot, never from the payload: one bulk
|
|
2290
|
+
* write of "Probe" also matches devices that already were Probe,
|
|
2291
|
+
* and one of those may have had polling turned off on purpose.
|
|
2292
|
+
* A root write, like the residue reset above, because the two
|
|
2293
|
+
* columns are updatable by fewer roles than the method is.
|
|
2294
|
+
* `nextPollAt = now` makes the device due at once rather than at
|
|
2295
|
+
* whatever moment its last claim — months ago, or never — left
|
|
2296
|
+
* behind. The caller's own word wins when it says the opposite:
|
|
2297
|
+
* a payload writing `isPollingEnabled: false` beside the method
|
|
2298
|
+
* wants a Probe device that is not polled yet. No probe is
|
|
2299
|
+
* required here — the forms require one, the API and Terraform
|
|
2300
|
+
* may assign it in a later write — and a Probe device without one
|
|
2301
|
+
* is simply not claimed until it has one.
|
|
2302
|
+
*/
|
|
2303
|
+
const isMonitorToProbeTransition: boolean =
|
|
2304
|
+
wasMonitorBacked === true && !becomesMonitorBacked;
|
|
2305
|
+
const payloadTurnsPollingOff: boolean =
|
|
2306
|
+
dataKeys.includes("isPollingEnabled") &&
|
|
2307
|
+
(onUpdate.updateBy.data as unknown as Record<string, unknown>)[
|
|
2308
|
+
"isPollingEnabled"
|
|
2309
|
+
] === false;
|
|
2310
|
+
|
|
2311
|
+
if (isMonitorToProbeTransition && !payloadTurnsPollingOff) {
|
|
2312
|
+
try {
|
|
2313
|
+
await this.updateColumnsByIdWithoutHooks({
|
|
2314
|
+
id: deviceId,
|
|
2315
|
+
data: {
|
|
2316
|
+
isPollingEnabled: true,
|
|
2317
|
+
nextPollAt: OneUptimeDate.getCurrentDate(),
|
|
2318
|
+
},
|
|
2319
|
+
});
|
|
2320
|
+
} catch (error) {
|
|
2321
|
+
/*
|
|
2322
|
+
* Bookkeeping, and separable from the re-stamp below: the
|
|
2323
|
+
* stale stamp still goes, and the operator can turn polling
|
|
2324
|
+
* on from Settings if this write was the one that failed.
|
|
2325
|
+
*/
|
|
2326
|
+
logger.error(
|
|
2327
|
+
`Error in NetworkDeviceService.onUpdateSuccess polling restore for device ${deviceId.toString()}: ${error}`,
|
|
2328
|
+
);
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
/*
|
|
2333
|
+
* Only a device that WAS monitor-backed and now is not may have
|
|
2334
|
+
* its stamp cleared. The Settings form re-sends monitoringMethod
|
|
2335
|
+
* on every save, so "the payload says Probe" is not a transition —
|
|
2336
|
+
* treating it as one wiped the stamp a Network Device monitor had
|
|
2337
|
+
* put on every Probe device that was ever saved.
|
|
2338
|
+
*/
|
|
1489
2339
|
await this.refreshStampedMonitorStatus({
|
|
1490
2340
|
deviceId: deviceId,
|
|
1491
|
-
clearWhenNotMonitorBacked:
|
|
2341
|
+
clearWhenNotMonitorBacked:
|
|
2342
|
+
wasMonitorBacked === true && !becomesMonitorBacked,
|
|
1492
2343
|
});
|
|
1493
2344
|
}
|
|
1494
2345
|
}
|
|
@@ -1613,9 +2464,103 @@ export class Service extends DatabaseService<Model> {
|
|
|
1613
2464
|
);
|
|
1614
2465
|
}
|
|
1615
2466
|
|
|
2467
|
+
try {
|
|
2468
|
+
await this.reconcileAlertPoliciesAfterUpdate(onUpdate, updatedItemIds);
|
|
2469
|
+
} catch (error) {
|
|
2470
|
+
/*
|
|
2471
|
+
* Isolated from the site maintenance above for the same reason that is
|
|
2472
|
+
* isolated from the status re-stamp: a policy that cannot provision
|
|
2473
|
+
* must not cost the device its site rollup, and the five-minute sweep
|
|
2474
|
+
* recomputes the same difference either way.
|
|
2475
|
+
*/
|
|
2476
|
+
logger.error(
|
|
2477
|
+
`Error in NetworkDeviceService.onUpdateSuccess alert policy reconciliation: ${error}`,
|
|
2478
|
+
);
|
|
2479
|
+
}
|
|
2480
|
+
|
|
1616
2481
|
return onUpdate;
|
|
1617
2482
|
}
|
|
1618
2483
|
|
|
2484
|
+
/*
|
|
2485
|
+
* Keep the device's policy-provisioned monitors in step with what the
|
|
2486
|
+
* update just changed about it.
|
|
2487
|
+
*
|
|
2488
|
+
* INLINE ONLY FOR A HANDFUL OF DEVICES. Reconciling one device is a few
|
|
2489
|
+
* queries and, at most, one monitor create — worth doing inside the write
|
|
2490
|
+
* so the monitor is there by the operator's next page load. A BULK write is
|
|
2491
|
+
* a different animal: "move 1,200 devices into this site" or "archive the
|
|
2492
|
+
* warehouse" matches thousands of rows, and reconciling thousands of
|
|
2493
|
+
* devices inside the request would turn one statement into an hour of
|
|
2494
|
+
* monitor provisioning with the caller still waiting on it. Past
|
|
2495
|
+
* MAX_INLINE_RECONCILE_DEVICES the write returns and the five-minute sweep
|
|
2496
|
+
* converges the fleet — it computes the same difference from the same
|
|
2497
|
+
* columns, so nothing is lost but latency.
|
|
2498
|
+
*
|
|
2499
|
+
* The project comes from the pre-write snapshot rather than from
|
|
2500
|
+
* props.tenantId, because a root caller (a worker, a data migration) has no
|
|
2501
|
+
* tenant and its update can legitimately span projects.
|
|
2502
|
+
*/
|
|
2503
|
+
private async reconcileAlertPoliciesAfterUpdate(
|
|
2504
|
+
onUpdate: OnUpdate<Model>,
|
|
2505
|
+
updatedItemIds: Array<ObjectID>,
|
|
2506
|
+
): Promise<void> {
|
|
2507
|
+
const dataKeys: Array<string> = Object.keys(onUpdate.updateBy.data || {});
|
|
2508
|
+
|
|
2509
|
+
if (!isAlertPolicyRelevantWrite(dataKeys) || updatedItemIds.length === 0) {
|
|
2510
|
+
return;
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
if (updatedItemIds.length > MAX_INLINE_RECONCILE_DEVICES) {
|
|
2514
|
+
logger.debug(
|
|
2515
|
+
`NetworkDeviceService.onUpdateSuccess: ${updatedItemIds.length} devices changed an alert-policy scope column; leaving reconciliation to the NetworkAlertPolicy sweep.`,
|
|
2516
|
+
);
|
|
2517
|
+
|
|
2518
|
+
return;
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
const previousDevices: Array<Model> =
|
|
2522
|
+
(onUpdate.carryForward?.previousDevices as Array<Model>) || [];
|
|
2523
|
+
|
|
2524
|
+
const projectIdByDeviceId: Map<string, ObjectID> = new Map<
|
|
2525
|
+
string,
|
|
2526
|
+
ObjectID
|
|
2527
|
+
>();
|
|
2528
|
+
|
|
2529
|
+
for (const previousDevice of previousDevices) {
|
|
2530
|
+
if (previousDevice.id && previousDevice.projectId) {
|
|
2531
|
+
projectIdByDeviceId.set(
|
|
2532
|
+
previousDevice.id.toString(),
|
|
2533
|
+
previousDevice.projectId,
|
|
2534
|
+
);
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
|
|
2538
|
+
for (const deviceId of updatedItemIds) {
|
|
2539
|
+
const projectId: ObjectID | undefined =
|
|
2540
|
+
projectIdByDeviceId.get(deviceId.toString()) ||
|
|
2541
|
+
onUpdate.updateBy.props.tenantId ||
|
|
2542
|
+
undefined;
|
|
2543
|
+
|
|
2544
|
+
if (!projectId) {
|
|
2545
|
+
/*
|
|
2546
|
+
* No snapshot row and no tenant: the update matched a device this
|
|
2547
|
+
* hook cannot attribute to a project, so it cannot be reconciled
|
|
2548
|
+
* safely. The sweep, which starts from the policies, will reach it.
|
|
2549
|
+
*/
|
|
2550
|
+
logger.debug(
|
|
2551
|
+
`NetworkDeviceService.onUpdateSuccess: no project known for device ${deviceId.toString()}; leaving its alert-policy monitors to the sweep.`,
|
|
2552
|
+
);
|
|
2553
|
+
|
|
2554
|
+
continue;
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
await NetworkAlertPolicyEngineService.reconcileDevice({
|
|
2558
|
+
projectId: projectId,
|
|
2559
|
+
deviceId: deviceId,
|
|
2560
|
+
});
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
|
|
1619
2564
|
/*
|
|
1620
2565
|
* True when an update that touched an identity column is worth re-running
|
|
1621
2566
|
* the assignment rules for.
|
|
@@ -2014,6 +2959,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
2014
2959
|
* Suspended projects are skipped for the same reason monitor claiming
|
|
2015
2960
|
* skips them; archived devices keep polling on purpose ("archived devices
|
|
2016
2961
|
* keep collecting telemetry").
|
|
2962
|
+
*
|
|
2963
|
+
* The Probe join is a TENANCY backstop rather than a lookup — nothing from
|
|
2964
|
+
* the probe row is selected. See the predicate for why the write-time
|
|
2965
|
+
* guard is not enough on its own.
|
|
2017
2966
|
*/
|
|
2018
2967
|
@CaptureSpan()
|
|
2019
2968
|
public async claimDevicesForPolling(data: {
|
|
@@ -2028,12 +2977,22 @@ export class Service extends DatabaseService<Model> {
|
|
|
2028
2977
|
SELECT nd."_id", nd."pollingIntervalInMinutes"
|
|
2029
2978
|
FROM "NetworkDevice" nd
|
|
2030
2979
|
INNER JOIN "Project" p ON nd."projectId" = p."_id"
|
|
2980
|
+
INNER JOIN "Probe" pr ON nd."probeId" = pr."_id"
|
|
2031
2981
|
WHERE nd."probeId" = $1
|
|
2032
2982
|
AND nd."isPollingEnabled" = true
|
|
2033
2983
|
AND nd."deletedAt" IS NULL
|
|
2034
2984
|
AND nd."hostname" IS NOT NULL
|
|
2035
|
-
--
|
|
2036
|
-
--
|
|
2985
|
+
-- The tenancy backstop. onBeforeCreate/onBeforeUpdate refuse a
|
|
2986
|
+
-- probe that is not attachable to the device's project, but rows
|
|
2987
|
+
-- written before those guards existed are still on disk, and a
|
|
2988
|
+
-- probe that can CLAIM a device reads its hostname and its SNMP
|
|
2989
|
+
-- credentials. A global probe has no project and may poll anyone;
|
|
2990
|
+
-- anything else must match the device's own project or the row is
|
|
2991
|
+
-- simply never handed out. isGlobalProbe is NOT NULL DEFAULT false,
|
|
2992
|
+
-- so there is no third state here to reason about.
|
|
2993
|
+
AND (pr."isGlobalProbe" = true OR pr."projectId" = nd."projectId")
|
|
2994
|
+
-- Nothing polls a monitor-backed device. NULL is every device
|
|
2995
|
+
-- created before the column existed: those are probe-polled.
|
|
2037
2996
|
AND (nd."monitoringMethod" IS NULL OR nd."monitoringMethod" <> 'Monitor')
|
|
2038
2997
|
AND nd."nextPollAt" <= $2
|
|
2039
2998
|
AND p."deletedAt" IS NULL
|