@oneuptime/common 12.0.32 → 12.0.33
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/Span.ts +14 -0
- package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
- package/Models/DatabaseModels/Index.ts +10 -0
- package/Models/DatabaseModels/Monitor.ts +76 -0
- 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/TelemetryException.ts +119 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
- package/Server/API/EnterpriseLicenseAPI.ts +391 -64
- package/Server/API/LlmProviderAPI.ts +137 -22
- package/Server/EnvironmentConfig.ts +14 -0
- 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/Index.ts +12 -0
- package/Server/Infrastructure/QueueWorker.ts +38 -8
- 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 +11 -0
- package/Server/Services/AIBillingService.ts +101 -27
- package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
- package/Server/Services/EnterpriseLicenseService.ts +55 -0
- package/Server/Services/Index.ts +10 -0
- package/Server/Services/MonitorService.ts +143 -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 +9 -10
- 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 +105 -48
- package/Server/Services/StatusPagePrivateUserService.ts +103 -3
- 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 +62 -25
- package/Server/Services/UserService.ts +95 -0
- package/Server/Types/Database/QueryHelper.ts +2 -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/Billing/BillingFailureNoticeThrottle.ts +80 -0
- package/Server/Utils/DataSource/HttpFetch.ts +9 -2
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +98 -0
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +872 -0
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
- package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
- package/Server/Utils/LLM/LLMService.ts +78 -0
- package/Server/Utils/LogRedaction.ts +8 -0
- package/Server/Utils/Logger.ts +79 -1
- package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
- package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +49 -0
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +43 -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/NetworkDevice/DeviceHealthAggregation.ts +31 -18
- package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
- package/Server/Utils/OutboundUserAgent.ts +152 -0
- package/Server/Utils/StartServer.ts +51 -19
- package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
- package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
- package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
- package/Server/Utils/Telemetry.ts +198 -51
- package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -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/DashboardVariablesDiscard.test.tsx +26 -0
- package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +18 -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/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/StatusPageLoginCodeBootstrap.test.ts +9 -4
- package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
- package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -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/UserNotificationEmailRollupTableMigration.test.ts +535 -0
- package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
- package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
- package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -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 +47 -4
- 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/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -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 +856 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +102 -1
- 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/Captcha.test.ts +422 -0
- 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/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +752 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
- package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -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/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -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/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/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
- package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
- package/Tests/Server/Utils/Telemetry.test.ts +456 -66
- package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
- 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/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/Telemetry/ErrorClass.test.ts +483 -0
- package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +15 -0
- package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
- 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/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/EnterpriseLicenseSeats.test.ts +69 -0
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
- package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
- 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/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/Telemetry/CaptureSpanExportGating.test.ts +145 -0
- package/Types/AI/ExceptionAIClassification.ts +10 -24
- 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/Monitor/CriteriaFilter.ts +60 -2
- package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
- package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
- 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/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
- package/Types/Monitor/SqlConnectionConfig.ts +31 -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/Permission.ts +90 -0
- package/Types/Probe/ProbeMonitorResponse.ts +16 -0
- package/Types/Telemetry/ErrorClass.ts +274 -0
- package/Types/Telemetry/UnitOfWork.ts +59 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
- package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
- package/UI/Components/Modal/Modal.tsx +2 -8
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -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/Utils/PageScrollLock.ts +79 -3
- package/UI/Utils/PermissionGate.ts +61 -0
- package/UI/Utils/SensitiveUrlToken.ts +112 -0
- package/UI/Utils/TestLLMProvider.ts +11 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
- 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/PingMonitorBuilder.ts +115 -13
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
- package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
- package/build/dist/Models/AnalyticsModels/Span.js +14 -0
- package/build/dist/Models/AnalyticsModels/Span.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/Index.js +10 -0
- package/build/dist/Models/DatabaseModels/Index.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/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/TelemetryException.js +123 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.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/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/EnvironmentConfig.js +12 -0
- 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/Index.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +33 -5
- package/build/dist/Server/Infrastructure/QueueWorker.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 +11 -0
- 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/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/Index.js +10 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +119 -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 +10 -9
- 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 +66 -30
- package/build/dist/Server/Services/ProjectService.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/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 +46 -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/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/Billing/BillingFailureNoticeThrottle.js +59 -0
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
- 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 +91 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +691 -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/LLM/LLMService.js +64 -1
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +8 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +63 -1
- package/build/dist/Server/Utils/Logger.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/SnmpMonitorCriteria.js +51 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.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 +37 -0
- 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/MonitorMetricUtil.js +33 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +32 -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/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/StartServer.js +38 -14
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- 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/SpanUtil.js +29 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +162 -46
- package/build/dist/Server/Utils/Telemetry.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/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/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/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/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/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/Permission.js +80 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
- package/build/dist/Types/Telemetry/ErrorClass.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/UI/Components/CommandPalette/CommandPalette.js +2 -7
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
- 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/Modal/Modal.js +2 -7
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +39 -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/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/TestLLMProvider.js +4 -5
- package/build/dist/UI/Utils/TestLLMProvider.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/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/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/package.json +2 -2
|
@@ -0,0 +1,752 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Contract under test — WHERE the Network Alert Policy engine is called from,
|
|
3
|
+
* and with what.
|
|
4
|
+
*
|
|
5
|
+
* NetworkAlertPolicyEngineService.test.ts pins what the engine does once it
|
|
6
|
+
* is running. This file pins the seams, because every one of them is a place
|
|
7
|
+
* where a wrong condition means monitors that silently never appear, or a
|
|
8
|
+
* request that hangs for minutes, or a policy row deleted while the monitors
|
|
9
|
+
* it explained stay behind and keep being billed:
|
|
10
|
+
*
|
|
11
|
+
* - A DEVICE WRITE reconciles inline only for a HANDFUL of devices. One
|
|
12
|
+
* device is a few queries; a bulk write ("move 1,200 devices into this
|
|
13
|
+
* site", "archive the warehouse") matches thousands of rows, and
|
|
14
|
+
* reconciling thousands inside the request would turn one statement into
|
|
15
|
+
* an hour of monitor provisioning with the caller still waiting. Past the
|
|
16
|
+
* threshold the write returns and the five-minute sweep converges.
|
|
17
|
+
* - A DEVICE WRITE reconciles for the SCOPE AXES and for PROVISIONABILITY —
|
|
18
|
+
* site, role, labels, isArchived, monitoringMethod, probeId — and for
|
|
19
|
+
* nothing else. A poll writing sysName every five minutes must not start
|
|
20
|
+
* a reconciliation per device per cycle.
|
|
21
|
+
* - A DEVICE CREATE reconciles LAST in its out-of-band chain, after the
|
|
22
|
+
* label and site rules have run. A policy can be scoped by label, and a
|
|
23
|
+
* discovery import arrives with no labels at all: asking first would
|
|
24
|
+
* provision nothing and leave the device uncovered until the sweep.
|
|
25
|
+
* - A POLICY SAVE hands the work over DETACHED. Provisioning a warehouse is
|
|
26
|
+
* hundreds of monitor creates; doing it inside the save would time out.
|
|
27
|
+
* - A POLICY DELETE does NOT detach: the monitors go before the row does,
|
|
28
|
+
* or nothing is left that knows they were the policy's.
|
|
29
|
+
* - DISABLING pauses, ENABLING resumes, and neither fires when the payload
|
|
30
|
+
* merely re-sends the value the row already had — the settings form does
|
|
31
|
+
* that on every save, and it would be a write per monitor each time.
|
|
32
|
+
* - A TEMPLATE A POLICY USES CANNOT BE DELETED. Both foreign keys are SET
|
|
33
|
+
* NULL, so without the guard the delete succeeds and the policy quietly
|
|
34
|
+
* stops covering anything new.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
jest.mock("../../../Server/Services/NetworkAlertPolicyEngineService", () => {
|
|
38
|
+
return {
|
|
39
|
+
__esModule: true,
|
|
40
|
+
MAX_INLINE_RECONCILE_DEVICES: 5,
|
|
41
|
+
MAX_MONITORS_PER_POLICY_SYNC: 500,
|
|
42
|
+
default: {
|
|
43
|
+
reconcileDevice: jest.fn(),
|
|
44
|
+
reconcileDevices: jest.fn(),
|
|
45
|
+
syncPolicy: jest.fn(),
|
|
46
|
+
deleteMonitorsOwnedByPolicy: jest.fn(),
|
|
47
|
+
deletePolicyMonitorsForDevices: jest.fn(),
|
|
48
|
+
setPolicyMonitorsPaused: jest.fn(),
|
|
49
|
+
onMonitorTemplateSynced: jest.fn(),
|
|
50
|
+
createRunContext: jest.fn(),
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
import NetworkAlertPolicyEngineService from "../../../Server/Services/NetworkAlertPolicyEngineService";
|
|
56
|
+
import NetworkAlertPolicyService from "../../../Server/Services/NetworkAlertPolicyService";
|
|
57
|
+
import NetworkDeviceService from "../../../Server/Services/NetworkDeviceService";
|
|
58
|
+
import NetworkDeviceLabelRuleEngineService from "../../../Server/Services/NetworkDeviceLabelRuleEngineService";
|
|
59
|
+
import NetworkDeviceOwnerRuleEngineService from "../../../Server/Services/NetworkDeviceOwnerRuleEngineService";
|
|
60
|
+
import NetworkSiteService from "../../../Server/Services/NetworkSiteService";
|
|
61
|
+
import MonitorTemplateService from "../../../Server/Services/MonitorTemplateService";
|
|
62
|
+
import NetworkDeviceAutoImportRuleService from "../../../Server/Services/NetworkDeviceAutoImportRuleService";
|
|
63
|
+
import ModelPermission from "../../../Server/Types/Database/Permissions/Index";
|
|
64
|
+
import MonitorTemplate from "../../../Models/DatabaseModels/MonitorTemplate";
|
|
65
|
+
import NetworkAlertPolicy from "../../../Models/DatabaseModels/NetworkAlertPolicy";
|
|
66
|
+
import NetworkDevice from "../../../Models/DatabaseModels/NetworkDevice";
|
|
67
|
+
import NetworkDeviceAutoImportRule from "../../../Models/DatabaseModels/NetworkDeviceAutoImportRule";
|
|
68
|
+
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
69
|
+
import Query from "../../../Server/Types/Database/Query";
|
|
70
|
+
import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
71
|
+
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
72
|
+
import NetworkDeviceMonitoringMethod from "../../../Types/NetworkDevice/NetworkDeviceMonitoringMethod";
|
|
73
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
74
|
+
import { afterEach, describe, expect, it, jest } from "@jest/globals";
|
|
75
|
+
import type { SpyInstance } from "jest-mock";
|
|
76
|
+
|
|
77
|
+
const PROJECT_ID: ObjectID = new ObjectID(
|
|
78
|
+
"11111111-1111-4111-8111-111111111111",
|
|
79
|
+
);
|
|
80
|
+
const OTHER_PROJECT_ID: ObjectID = new ObjectID(
|
|
81
|
+
"1b1b1b1b-1b1b-4b1b-8b1b-1b1b1b1b1b1b",
|
|
82
|
+
);
|
|
83
|
+
const DEVICE_ID: ObjectID = new ObjectID(
|
|
84
|
+
"22222222-2222-4222-8222-222222222222",
|
|
85
|
+
);
|
|
86
|
+
const POLICY_ID: ObjectID = new ObjectID(
|
|
87
|
+
"33333333-3333-4333-8333-333333333333",
|
|
88
|
+
);
|
|
89
|
+
const TEMPLATE_ID: ObjectID = new ObjectID(
|
|
90
|
+
"44444444-4444-4444-8444-444444444444",
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const reconcileDeviceMock: jest.Mock =
|
|
94
|
+
NetworkAlertPolicyEngineService.reconcileDevice as unknown as jest.Mock;
|
|
95
|
+
const syncPolicyMock: jest.Mock =
|
|
96
|
+
NetworkAlertPolicyEngineService.syncPolicy as unknown as jest.Mock;
|
|
97
|
+
const deletePolicyMonitorsMock: jest.Mock =
|
|
98
|
+
NetworkAlertPolicyEngineService.deleteMonitorsOwnedByPolicy as unknown as jest.Mock;
|
|
99
|
+
const setPausedMock: jest.Mock =
|
|
100
|
+
NetworkAlertPolicyEngineService.setPolicyMonitorsPaused as unknown as jest.Mock;
|
|
101
|
+
|
|
102
|
+
/*
|
|
103
|
+
* The device create and the policy update hand their work to the engine
|
|
104
|
+
* DETACHED, so the assertions have to wait for the microtask chain to drain.
|
|
105
|
+
*/
|
|
106
|
+
async function flushDetachedWork(): Promise<void> {
|
|
107
|
+
await new Promise((resolve: (value: unknown) => void) => {
|
|
108
|
+
setTimeout(resolve, 0);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function deviceRow(overrides: Partial<NetworkDevice> = {}): NetworkDevice {
|
|
113
|
+
const device: NetworkDevice = new NetworkDevice();
|
|
114
|
+
device.id = DEVICE_ID;
|
|
115
|
+
device.projectId = PROJECT_ID;
|
|
116
|
+
device.monitoringMethod = NetworkDeviceMonitoringMethod.Probe;
|
|
117
|
+
Object.assign(device, overrides);
|
|
118
|
+
|
|
119
|
+
return device;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
afterEach(() => {
|
|
123
|
+
jest.restoreAllMocks();
|
|
124
|
+
/*
|
|
125
|
+
* reset, not clear. The engine's methods are jest.fn()s from the module
|
|
126
|
+
* factory rather than spies, so restoreAllMocks does not touch them and a
|
|
127
|
+
* mockRejectedValue set by one case would still be in place for the next —
|
|
128
|
+
* where it would abort a loop and make an assertion pass for entirely the
|
|
129
|
+
* wrong reason.
|
|
130
|
+
*/
|
|
131
|
+
jest.resetAllMocks();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe("NetworkDeviceService.onCreateSuccess hands the new device to the engine", () => {
|
|
135
|
+
function silenceTheRestOfTheChain(): void {
|
|
136
|
+
jest
|
|
137
|
+
.spyOn(NetworkDeviceLabelRuleEngineService, "applyRulesToNetworkDevice")
|
|
138
|
+
.mockResolvedValue(undefined as never);
|
|
139
|
+
jest
|
|
140
|
+
.spyOn(NetworkDeviceOwnerRuleEngineService, "applyRulesToNetworkDevice")
|
|
141
|
+
.mockResolvedValue(undefined as never);
|
|
142
|
+
jest
|
|
143
|
+
.spyOn(NetworkSiteService, "recomputeRollupForSiteAndAncestors")
|
|
144
|
+
.mockResolvedValue(undefined as never);
|
|
145
|
+
jest
|
|
146
|
+
.spyOn(NetworkDeviceService, "applySiteAssignmentRulesToDevice")
|
|
147
|
+
.mockResolvedValue(undefined as never);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
it("reconciles the created device", async () => {
|
|
151
|
+
silenceTheRestOfTheChain();
|
|
152
|
+
|
|
153
|
+
await (NetworkDeviceService as any).onCreateSuccess(
|
|
154
|
+
{ createBy: { data: {}, props: {} }, carryForward: null },
|
|
155
|
+
deviceRow(),
|
|
156
|
+
);
|
|
157
|
+
await flushDetachedWork();
|
|
158
|
+
|
|
159
|
+
expect(reconcileDeviceMock).toHaveBeenCalledWith({
|
|
160
|
+
projectId: PROJECT_ID,
|
|
161
|
+
deviceId: DEVICE_ID,
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
* ORDER MATTERS. A policy can be scoped by LABEL, and a discovery import
|
|
167
|
+
* creates a device with none — the label rules in this same chain are what
|
|
168
|
+
* put them on. Reconciling before them would evaluate the device against a
|
|
169
|
+
* scope it does not match yet, provision nothing, and leave it uncovered
|
|
170
|
+
* until the five-minute sweep noticed.
|
|
171
|
+
*/
|
|
172
|
+
it("reconciles only after the label rules have run", async () => {
|
|
173
|
+
const order: Array<string> = [];
|
|
174
|
+
|
|
175
|
+
jest
|
|
176
|
+
.spyOn(NetworkDeviceLabelRuleEngineService, "applyRulesToNetworkDevice")
|
|
177
|
+
.mockImplementation(async (): Promise<void> => {
|
|
178
|
+
order.push("labels");
|
|
179
|
+
});
|
|
180
|
+
jest
|
|
181
|
+
.spyOn(NetworkDeviceOwnerRuleEngineService, "applyRulesToNetworkDevice")
|
|
182
|
+
.mockResolvedValue(undefined as never);
|
|
183
|
+
jest
|
|
184
|
+
.spyOn(NetworkDeviceService, "applySiteAssignmentRulesToDevice")
|
|
185
|
+
.mockImplementation(async (): Promise<void> => {
|
|
186
|
+
order.push("site");
|
|
187
|
+
});
|
|
188
|
+
reconcileDeviceMock.mockImplementation(async (): Promise<void> => {
|
|
189
|
+
order.push("policies");
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
await (NetworkDeviceService as any).onCreateSuccess(
|
|
193
|
+
{ createBy: { data: {}, props: {} }, carryForward: null },
|
|
194
|
+
deviceRow(),
|
|
195
|
+
);
|
|
196
|
+
await flushDetachedWork();
|
|
197
|
+
|
|
198
|
+
expect(order).toEqual(["labels", "site", "policies"]);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
/*
|
|
202
|
+
* Detached, so a policy that cannot provision — a deleted template, Redis
|
|
203
|
+
* down — must never turn into a failed device import.
|
|
204
|
+
*/
|
|
205
|
+
it("does not fail the create when the engine throws", async () => {
|
|
206
|
+
silenceTheRestOfTheChain();
|
|
207
|
+
reconcileDeviceMock.mockRejectedValue(new Error("engine is unhappy"));
|
|
208
|
+
|
|
209
|
+
await expect(
|
|
210
|
+
(NetworkDeviceService as any).onCreateSuccess(
|
|
211
|
+
{ createBy: { data: {}, props: {} }, carryForward: null },
|
|
212
|
+
deviceRow(),
|
|
213
|
+
),
|
|
214
|
+
).resolves.toBeDefined();
|
|
215
|
+
await flushDetachedWork();
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe("NetworkDeviceService.onUpdateSuccess reconciles the right writes", () => {
|
|
220
|
+
function runUpdateSuccess(
|
|
221
|
+
data: Record<string, unknown>,
|
|
222
|
+
updatedItemIds: Array<ObjectID>,
|
|
223
|
+
previousDevices: Array<NetworkDevice> = [deviceRow()],
|
|
224
|
+
): Promise<unknown> {
|
|
225
|
+
return (NetworkDeviceService as any).onUpdateSuccess(
|
|
226
|
+
{
|
|
227
|
+
updateBy: { data: data, query: {}, props: { tenantId: PROJECT_ID } },
|
|
228
|
+
carryForward: { previousDevices: previousDevices },
|
|
229
|
+
},
|
|
230
|
+
updatedItemIds,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
it.each([
|
|
235
|
+
["siteId", { siteId: ObjectID.generate() }],
|
|
236
|
+
["the site relation", { site: { _id: ObjectID.generate().toString() } }],
|
|
237
|
+
["networkDeviceRoleId", { networkDeviceRoleId: ObjectID.generate() }],
|
|
238
|
+
["labels", { labels: [] }],
|
|
239
|
+
["isArchived", { isArchived: true }],
|
|
240
|
+
[
|
|
241
|
+
"monitoringMethod",
|
|
242
|
+
{ monitoringMethod: NetworkDeviceMonitoringMethod.Monitor },
|
|
243
|
+
],
|
|
244
|
+
["probeId", { probeId: ObjectID.generate() }],
|
|
245
|
+
])(
|
|
246
|
+
"reconciles when the write touches %s",
|
|
247
|
+
async (_name: string, data: Record<string, unknown>) => {
|
|
248
|
+
await runUpdateSuccess(data, [DEVICE_ID]);
|
|
249
|
+
|
|
250
|
+
expect(reconcileDeviceMock).toHaveBeenCalledWith({
|
|
251
|
+
projectId: PROJECT_ID,
|
|
252
|
+
deviceId: DEVICE_ID,
|
|
253
|
+
});
|
|
254
|
+
},
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
/*
|
|
258
|
+
* Every successful SNMP walk rewrites sysName and the poll columns. If
|
|
259
|
+
* those started a reconciliation, an 80,000-device fleet would run 80,000
|
|
260
|
+
* policy passes every five-minute cycle for no change at all.
|
|
261
|
+
*/
|
|
262
|
+
it.each([
|
|
263
|
+
["sysName", { sysName: "core-sw-1" }],
|
|
264
|
+
["poll columns", { lastPolledAt: new Date(), isReachable: true }],
|
|
265
|
+
["the name", { name: "Renamed" }],
|
|
266
|
+
])(
|
|
267
|
+
"does not reconcile for a write that only touches %s",
|
|
268
|
+
async (_name: string, data: Record<string, unknown>) => {
|
|
269
|
+
await runUpdateSuccess(data, [DEVICE_ID]);
|
|
270
|
+
|
|
271
|
+
expect(reconcileDeviceMock).not.toHaveBeenCalled();
|
|
272
|
+
},
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
/*
|
|
276
|
+
* THE THRESHOLD. Five devices is a form save or a small bulk action and is
|
|
277
|
+
* worth doing inline, so the monitor is there by the next page load. Six is
|
|
278
|
+
* a bulk action whose size nobody bounded, and reconciling it inline is how
|
|
279
|
+
* a one-statement update becomes a request that never returns.
|
|
280
|
+
*/
|
|
281
|
+
it("reconciles inline for up to five devices", async () => {
|
|
282
|
+
const deviceIds: Array<ObjectID> = [1, 2, 3, 4, 5].map((): ObjectID => {
|
|
283
|
+
return ObjectID.generate();
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
await runUpdateSuccess({ isArchived: true }, deviceIds, []);
|
|
287
|
+
|
|
288
|
+
expect(reconcileDeviceMock).toHaveBeenCalledTimes(5);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it("leaves a larger bulk write entirely to the sweep", async () => {
|
|
292
|
+
const deviceIds: Array<ObjectID> = [1, 2, 3, 4, 5, 6].map((): ObjectID => {
|
|
293
|
+
return ObjectID.generate();
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
await runUpdateSuccess({ isArchived: true }, deviceIds, []);
|
|
297
|
+
|
|
298
|
+
expect(reconcileDeviceMock).not.toHaveBeenCalled();
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
/*
|
|
302
|
+
* The project comes from the pre-write snapshot, not from props: a root
|
|
303
|
+
* caller (a worker, a data migration) has no tenant and its update can
|
|
304
|
+
* legitimately span projects, so using props.tenantId alone would
|
|
305
|
+
* reconcile a device against the wrong project's policies.
|
|
306
|
+
*/
|
|
307
|
+
it("takes each device's project from the pre-write snapshot", async () => {
|
|
308
|
+
const foreignDevice: NetworkDevice = deviceRow({
|
|
309
|
+
projectId: OTHER_PROJECT_ID,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
await (NetworkDeviceService as any).onUpdateSuccess(
|
|
313
|
+
{
|
|
314
|
+
updateBy: { data: { isArchived: true }, query: {}, props: {} },
|
|
315
|
+
carryForward: { previousDevices: [foreignDevice] },
|
|
316
|
+
},
|
|
317
|
+
[DEVICE_ID],
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
expect(reconcileDeviceMock).toHaveBeenCalledWith({
|
|
321
|
+
projectId: OTHER_PROJECT_ID,
|
|
322
|
+
deviceId: DEVICE_ID,
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
/*
|
|
327
|
+
* ...and a device the hook cannot attribute to any project is skipped
|
|
328
|
+
* rather than guessed at. The sweep starts from the policies and will
|
|
329
|
+
* reach it.
|
|
330
|
+
*/
|
|
331
|
+
it("skips a device whose project it cannot determine", async () => {
|
|
332
|
+
await (NetworkDeviceService as any).onUpdateSuccess(
|
|
333
|
+
{
|
|
334
|
+
updateBy: { data: { isArchived: true }, query: {}, props: {} },
|
|
335
|
+
carryForward: { previousDevices: [] },
|
|
336
|
+
},
|
|
337
|
+
[DEVICE_ID],
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
expect(reconcileDeviceMock).not.toHaveBeenCalled();
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it("does not fail the update when the engine throws", async () => {
|
|
344
|
+
reconcileDeviceMock.mockRejectedValue(new Error("engine is unhappy"));
|
|
345
|
+
|
|
346
|
+
await expect(
|
|
347
|
+
runUpdateSuccess({ isArchived: true }, [DEVICE_ID]),
|
|
348
|
+
).resolves.toBeDefined();
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
describe("NetworkAlertPolicyService hands its own writes to the engine", () => {
|
|
353
|
+
function createdPolicy(): NetworkAlertPolicy {
|
|
354
|
+
const created: NetworkAlertPolicy = new NetworkAlertPolicy();
|
|
355
|
+
created.id = POLICY_ID;
|
|
356
|
+
created.projectId = PROJECT_ID;
|
|
357
|
+
|
|
358
|
+
return created;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
it("syncs a newly created policy", async () => {
|
|
362
|
+
const created: NetworkAlertPolicy = createdPolicy();
|
|
363
|
+
|
|
364
|
+
await (NetworkAlertPolicyService as any).onCreateSuccess(
|
|
365
|
+
{ createBy: { data: created, props: { tenantId: PROJECT_ID } } },
|
|
366
|
+
created,
|
|
367
|
+
);
|
|
368
|
+
await flushDetachedWork();
|
|
369
|
+
|
|
370
|
+
expect(syncPolicyMock).toHaveBeenCalledWith({
|
|
371
|
+
policyId: POLICY_ID,
|
|
372
|
+
/*
|
|
373
|
+
* A brand new policy has no monitors, so every monitor its first pass
|
|
374
|
+
* makes comes from the template it names — which is what
|
|
375
|
+
* templateSyncedAt claims.
|
|
376
|
+
*/
|
|
377
|
+
stampTemplateSyncedOnCleanPass: true,
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
/*
|
|
382
|
+
* ...and the save does not WAIT for it. Provisioning a warehouse is
|
|
383
|
+
* hundreds of monitor creates; holding the operator's request open for that
|
|
384
|
+
* would time out. The engine here never finishes, and the hook still
|
|
385
|
+
* returns.
|
|
386
|
+
*/
|
|
387
|
+
it("does not hold the save open while the engine provisions", async () => {
|
|
388
|
+
let releaseEngine: () => void = (): void => {
|
|
389
|
+
return undefined;
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
syncPolicyMock.mockImplementation((): Promise<null> => {
|
|
393
|
+
return new Promise<null>((resolve: (value: null) => void): void => {
|
|
394
|
+
releaseEngine = (): void => {
|
|
395
|
+
return resolve(null);
|
|
396
|
+
};
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
const created: NetworkAlertPolicy = createdPolicy();
|
|
401
|
+
|
|
402
|
+
await expect(
|
|
403
|
+
(NetworkAlertPolicyService as any).onCreateSuccess(
|
|
404
|
+
{ createBy: { data: created, props: { tenantId: PROJECT_ID } } },
|
|
405
|
+
created,
|
|
406
|
+
),
|
|
407
|
+
).resolves.toBe(created);
|
|
408
|
+
|
|
409
|
+
releaseEngine();
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it("does not fail the save when the engine throws", async () => {
|
|
413
|
+
syncPolicyMock.mockRejectedValue(new Error("engine is unhappy"));
|
|
414
|
+
|
|
415
|
+
const created: NetworkAlertPolicy = createdPolicy();
|
|
416
|
+
|
|
417
|
+
await expect(
|
|
418
|
+
(NetworkAlertPolicyService as any).onCreateSuccess(
|
|
419
|
+
{ createBy: { data: created, props: { tenantId: PROJECT_ID } } },
|
|
420
|
+
created,
|
|
421
|
+
),
|
|
422
|
+
).resolves.toBe(created);
|
|
423
|
+
await flushDetachedWork();
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
function previousPolicy(
|
|
427
|
+
overrides: Partial<NetworkAlertPolicy> = {},
|
|
428
|
+
): NetworkAlertPolicy {
|
|
429
|
+
const policy: NetworkAlertPolicy = new NetworkAlertPolicy();
|
|
430
|
+
policy.id = POLICY_ID;
|
|
431
|
+
policy.projectId = PROJECT_ID;
|
|
432
|
+
policy.isEnabled = true;
|
|
433
|
+
policy.monitorTemplateId = TEMPLATE_ID;
|
|
434
|
+
Object.assign(policy, overrides);
|
|
435
|
+
|
|
436
|
+
return policy;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
async function runPolicyUpdateSuccess(
|
|
440
|
+
data: Record<string, unknown>,
|
|
441
|
+
previousPolicies: Array<NetworkAlertPolicy>,
|
|
442
|
+
): Promise<void> {
|
|
443
|
+
await (NetworkAlertPolicyService as any).onUpdateSuccess(
|
|
444
|
+
{
|
|
445
|
+
updateBy: { data: data, query: {}, props: { tenantId: PROJECT_ID } },
|
|
446
|
+
carryForward: { previousPolicies: previousPolicies },
|
|
447
|
+
},
|
|
448
|
+
[POLICY_ID],
|
|
449
|
+
);
|
|
450
|
+
await flushDetachedWork();
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
it("does no engine work for a rename", async () => {
|
|
454
|
+
await runPolicyUpdateSuccess({ name: "New name" }, [previousPolicy()]);
|
|
455
|
+
|
|
456
|
+
expect(syncPolicyMock).not.toHaveBeenCalled();
|
|
457
|
+
expect(setPausedMock).not.toHaveBeenCalled();
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it("syncs after a scope change", async () => {
|
|
461
|
+
await runPolicyUpdateSuccess({ scope: { siteIds: [] } }, [
|
|
462
|
+
previousPolicy(),
|
|
463
|
+
]);
|
|
464
|
+
|
|
465
|
+
expect(syncPolicyMock).toHaveBeenCalledWith({
|
|
466
|
+
policyId: POLICY_ID,
|
|
467
|
+
stampTemplateSyncedOnCleanPass: false,
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
it("pauses the policy's monitors when it is really disabled", async () => {
|
|
472
|
+
await runPolicyUpdateSuccess({ isEnabled: false }, [previousPolicy()]);
|
|
473
|
+
|
|
474
|
+
expect(setPausedMock).toHaveBeenCalledWith({
|
|
475
|
+
projectId: PROJECT_ID,
|
|
476
|
+
policyId: POLICY_ID,
|
|
477
|
+
isPaused: true,
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
/*
|
|
482
|
+
* The settings form re-sends `isEnabled` on every save. Treating that as a
|
|
483
|
+
* transition would be one write per monitor every time somebody fixed a
|
|
484
|
+
* typo in the policy's description.
|
|
485
|
+
*/
|
|
486
|
+
it("does not re-pause a policy that was already disabled", async () => {
|
|
487
|
+
await runPolicyUpdateSuccess({ isEnabled: false }, [
|
|
488
|
+
previousPolicy({ isEnabled: false }),
|
|
489
|
+
]);
|
|
490
|
+
|
|
491
|
+
expect(setPausedMock).not.toHaveBeenCalled();
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
it("resumes the monitors when a disabled policy is enabled again", async () => {
|
|
495
|
+
await runPolicyUpdateSuccess({ isEnabled: true }, [
|
|
496
|
+
previousPolicy({ isEnabled: false }),
|
|
497
|
+
]);
|
|
498
|
+
|
|
499
|
+
expect(setPausedMock).toHaveBeenCalledWith({
|
|
500
|
+
projectId: PROJECT_ID,
|
|
501
|
+
policyId: POLICY_ID,
|
|
502
|
+
isPaused: false,
|
|
503
|
+
});
|
|
504
|
+
expect(syncPolicyMock).toHaveBeenCalled();
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
/*
|
|
508
|
+
* Resume BEFORE the sync, so a monitor that was paused when the policy went
|
|
509
|
+
* off is running again by the time the sync counts the fleet as covered.
|
|
510
|
+
*/
|
|
511
|
+
it("resumes before it syncs", async () => {
|
|
512
|
+
const order: Array<string> = [];
|
|
513
|
+
setPausedMock.mockImplementation(async (): Promise<number> => {
|
|
514
|
+
order.push("resume");
|
|
515
|
+
|
|
516
|
+
return 0;
|
|
517
|
+
});
|
|
518
|
+
syncPolicyMock.mockImplementation(async (): Promise<null> => {
|
|
519
|
+
order.push("sync");
|
|
520
|
+
|
|
521
|
+
return null;
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
await runPolicyUpdateSuccess({ isEnabled: true }, [
|
|
525
|
+
previousPolicy({ isEnabled: false }),
|
|
526
|
+
]);
|
|
527
|
+
|
|
528
|
+
expect(order).toEqual(["resume", "sync"]);
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
it("asks for a template stamp only when the template really changed", async () => {
|
|
532
|
+
await runPolicyUpdateSuccess({ monitorTemplateId: ObjectID.generate() }, [
|
|
533
|
+
previousPolicy(),
|
|
534
|
+
]);
|
|
535
|
+
|
|
536
|
+
expect(syncPolicyMock).toHaveBeenCalledWith({
|
|
537
|
+
policyId: POLICY_ID,
|
|
538
|
+
stampTemplateSyncedOnCleanPass: true,
|
|
539
|
+
});
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
/*
|
|
543
|
+
* Re-saving the SAME template has re-synced nothing. Stamping "Template
|
|
544
|
+
* Synced" for it would tell an operator their criteria edit had landed on
|
|
545
|
+
* the fleet when it had not.
|
|
546
|
+
*/
|
|
547
|
+
it("does not ask for a template stamp when the same template is re-sent", async () => {
|
|
548
|
+
await runPolicyUpdateSuccess({ monitorTemplateId: TEMPLATE_ID }, [
|
|
549
|
+
previousPolicy(),
|
|
550
|
+
]);
|
|
551
|
+
|
|
552
|
+
expect(syncPolicyMock).toHaveBeenCalledWith({
|
|
553
|
+
policyId: POLICY_ID,
|
|
554
|
+
stampTemplateSyncedOnCleanPass: false,
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
describe("deleting a policy removes its monitors first", () => {
|
|
560
|
+
it("deletes the monitors before the row, not after", async () => {
|
|
561
|
+
const policy: NetworkAlertPolicy = new NetworkAlertPolicy();
|
|
562
|
+
policy.id = POLICY_ID;
|
|
563
|
+
policy.projectId = PROJECT_ID;
|
|
564
|
+
|
|
565
|
+
jest
|
|
566
|
+
.spyOn(ModelPermission, "checkDeleteQueryPermission")
|
|
567
|
+
.mockImplementation(
|
|
568
|
+
async <TModel extends BaseModel>(
|
|
569
|
+
_modelType: { new (): TModel },
|
|
570
|
+
query: Query<TModel>,
|
|
571
|
+
): Promise<Query<TModel>> => {
|
|
572
|
+
return query;
|
|
573
|
+
},
|
|
574
|
+
);
|
|
575
|
+
jest.spyOn(NetworkAlertPolicyService, "findBy").mockResolvedValue([policy]);
|
|
576
|
+
|
|
577
|
+
await (NetworkAlertPolicyService as any).onBeforeDelete({
|
|
578
|
+
query: { _id: POLICY_ID.toString() },
|
|
579
|
+
limit: 1,
|
|
580
|
+
skip: 0,
|
|
581
|
+
props: { tenantId: PROJECT_ID },
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
/*
|
|
585
|
+
* Already called by the time the hook returns — NOT detached. Deleting
|
|
586
|
+
* them afterwards would leave a window, and after a crash a permanent
|
|
587
|
+
* one, in which billable monitors exist whose owner is a soft-deleted
|
|
588
|
+
* row nothing looks at.
|
|
589
|
+
*/
|
|
590
|
+
expect(deletePolicyMonitorsMock).toHaveBeenCalledWith({
|
|
591
|
+
projectId: PROJECT_ID,
|
|
592
|
+
policyId: POLICY_ID,
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
/*
|
|
597
|
+
* Only policies the caller may actually delete. The hook runs before
|
|
598
|
+
* DatabaseService permission-checks the query, so it re-applies the same
|
|
599
|
+
* check first; otherwise a bulk delete the permission layer will trim could
|
|
600
|
+
* still take another project's monitors with it on the way through.
|
|
601
|
+
*/
|
|
602
|
+
it("cleans up only the rows the caller is authorized to delete", async () => {
|
|
603
|
+
const permissionSpy: SpyInstance<
|
|
604
|
+
typeof ModelPermission.checkDeleteQueryPermission
|
|
605
|
+
> = jest
|
|
606
|
+
.spyOn(ModelPermission, "checkDeleteQueryPermission")
|
|
607
|
+
.mockResolvedValue({ _id: POLICY_ID.toString() } as never);
|
|
608
|
+
const findSpy: SpyInstance<typeof NetworkAlertPolicyService.findBy> = jest
|
|
609
|
+
.spyOn(NetworkAlertPolicyService, "findBy")
|
|
610
|
+
.mockResolvedValue([]);
|
|
611
|
+
|
|
612
|
+
await (NetworkAlertPolicyService as any).onBeforeDelete({
|
|
613
|
+
query: { projectId: PROJECT_ID },
|
|
614
|
+
limit: 10,
|
|
615
|
+
skip: 0,
|
|
616
|
+
props: { tenantId: PROJECT_ID },
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
expect(permissionSpy).toHaveBeenCalled();
|
|
620
|
+
expect(findSpy).toHaveBeenCalledWith(
|
|
621
|
+
expect.objectContaining({
|
|
622
|
+
query: { _id: POLICY_ID.toString() },
|
|
623
|
+
}),
|
|
624
|
+
);
|
|
625
|
+
expect(deletePolicyMonitorsMock).not.toHaveBeenCalled();
|
|
626
|
+
});
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
/*
|
|
630
|
+
* The template delete guard. Both FKs pointing at MonitorTemplate are SET
|
|
631
|
+
* NULL, so without this the delete succeeds and the damage is silent: a
|
|
632
|
+
* policy loses its template and stops covering anything new, and an operator
|
|
633
|
+
* finds out when the switch they added last month turns out never to have
|
|
634
|
+
* been alerted on.
|
|
635
|
+
*/
|
|
636
|
+
describe("MonitorTemplateService refuses to delete a template in use", () => {
|
|
637
|
+
function templateRow(): MonitorTemplate {
|
|
638
|
+
const template: MonitorTemplate = new MonitorTemplate();
|
|
639
|
+
template.id = TEMPLATE_ID;
|
|
640
|
+
template.projectId = PROJECT_ID;
|
|
641
|
+
template.templateName = "Reachability v1";
|
|
642
|
+
|
|
643
|
+
return template;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
function runDelete(
|
|
647
|
+
props: DatabaseCommonInteractionProps = {
|
|
648
|
+
tenantId: PROJECT_ID,
|
|
649
|
+
},
|
|
650
|
+
): Promise<unknown> {
|
|
651
|
+
return (MonitorTemplateService as any).onBeforeDelete({
|
|
652
|
+
query: { _id: TEMPLATE_ID.toString() },
|
|
653
|
+
limit: 1,
|
|
654
|
+
skip: 0,
|
|
655
|
+
props: props,
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
function policiesUsingTemplate(
|
|
660
|
+
names: Array<string>,
|
|
661
|
+
): Array<NetworkAlertPolicy> {
|
|
662
|
+
return names.map((name: string): NetworkAlertPolicy => {
|
|
663
|
+
const policy: NetworkAlertPolicy = new NetworkAlertPolicy();
|
|
664
|
+
policy.id = ObjectID.generate();
|
|
665
|
+
policy.name = name;
|
|
666
|
+
|
|
667
|
+
return policy;
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
it("names the policies that stand in the way", async () => {
|
|
672
|
+
jest
|
|
673
|
+
.spyOn(MonitorTemplateService, "findBy")
|
|
674
|
+
.mockResolvedValue([templateRow()]);
|
|
675
|
+
jest
|
|
676
|
+
.spyOn(NetworkAlertPolicyService, "findBy")
|
|
677
|
+
.mockResolvedValue(policiesUsingTemplate(["Warehouse switches"]));
|
|
678
|
+
jest
|
|
679
|
+
.spyOn(NetworkDeviceAutoImportRuleService, "findBy")
|
|
680
|
+
.mockResolvedValue([]);
|
|
681
|
+
|
|
682
|
+
/*
|
|
683
|
+
* The NAME, not just a count: the operator has to find the policy to
|
|
684
|
+
* detach it, and "1 network alert policy" would send them hunting.
|
|
685
|
+
*/
|
|
686
|
+
await expect(runDelete()).rejects.toThrow(
|
|
687
|
+
/Reachability v1 is used by 1 network alert policy \(Warehouse switches\)/,
|
|
688
|
+
);
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
it("counts and abbreviates when many policies use it", async () => {
|
|
692
|
+
jest
|
|
693
|
+
.spyOn(MonitorTemplateService, "findBy")
|
|
694
|
+
.mockResolvedValue([templateRow()]);
|
|
695
|
+
jest
|
|
696
|
+
.spyOn(NetworkAlertPolicyService, "findBy")
|
|
697
|
+
.mockResolvedValue(policiesUsingTemplate(["A", "B", "C", "D", "E"]));
|
|
698
|
+
jest
|
|
699
|
+
.spyOn(NetworkDeviceAutoImportRuleService, "findBy")
|
|
700
|
+
.mockResolvedValue([]);
|
|
701
|
+
|
|
702
|
+
await expect(runDelete()).rejects.toThrow(/A, B, C and 2 more/);
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
it("refuses for an auto-import rule too", async () => {
|
|
706
|
+
const rule: NetworkDeviceAutoImportRule = new NetworkDeviceAutoImportRule();
|
|
707
|
+
rule.id = ObjectID.generate();
|
|
708
|
+
rule.name = "Import warehouse switches";
|
|
709
|
+
|
|
710
|
+
jest
|
|
711
|
+
.spyOn(MonitorTemplateService, "findBy")
|
|
712
|
+
.mockResolvedValue([templateRow()]);
|
|
713
|
+
jest.spyOn(NetworkAlertPolicyService, "findBy").mockResolvedValue([]);
|
|
714
|
+
jest
|
|
715
|
+
.spyOn(NetworkDeviceAutoImportRuleService, "findBy")
|
|
716
|
+
.mockResolvedValue([rule]);
|
|
717
|
+
|
|
718
|
+
await expect(runDelete()).rejects.toThrow(BadDataException);
|
|
719
|
+
await expect(runDelete()).rejects.toThrow(/Import warehouse switches/);
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
it("allows the delete when nothing provisions from the template", async () => {
|
|
723
|
+
jest
|
|
724
|
+
.spyOn(MonitorTemplateService, "findBy")
|
|
725
|
+
.mockResolvedValue([templateRow()]);
|
|
726
|
+
jest.spyOn(NetworkAlertPolicyService, "findBy").mockResolvedValue([]);
|
|
727
|
+
jest
|
|
728
|
+
.spyOn(NetworkDeviceAutoImportRuleService, "findBy")
|
|
729
|
+
.mockResolvedValue([]);
|
|
730
|
+
|
|
731
|
+
await expect(runDelete()).resolves.toBeDefined();
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
/*
|
|
735
|
+
* The hook runs before DatabaseService permission-checks the query, so its
|
|
736
|
+
* root read is re-scoped to the caller's tenant by hand. Without that, the
|
|
737
|
+
* refusal message could name another project's policies.
|
|
738
|
+
*/
|
|
739
|
+
it("reads the templates it is about to delete within the caller's tenant", async () => {
|
|
740
|
+
const findSpy: SpyInstance<typeof MonitorTemplateService.findBy> = jest
|
|
741
|
+
.spyOn(MonitorTemplateService, "findBy")
|
|
742
|
+
.mockResolvedValue([]);
|
|
743
|
+
|
|
744
|
+
await runDelete();
|
|
745
|
+
|
|
746
|
+
expect(findSpy).toHaveBeenCalledWith(
|
|
747
|
+
expect.objectContaining({
|
|
748
|
+
query: expect.objectContaining({ projectId: PROJECT_ID }),
|
|
749
|
+
}),
|
|
750
|
+
);
|
|
751
|
+
});
|
|
752
|
+
});
|