@oneuptime/common 12.0.12 → 12.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +32 -5
- package/Models/DatabaseModels/NetworkDevice.ts +64 -0
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
- package/Models/DatabaseModels/StatusPage.ts +59 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +2 -0
- package/Models/DatabaseModels/UserCall.ts +94 -3
- package/Models/DatabaseModels/UserEmail.ts +94 -3
- package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
- package/Models/DatabaseModels/UserPush.ts +37 -0
- package/Models/DatabaseModels/UserSMS.ts +94 -3
- package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -2
- package/Server/API/AIChatAPI.ts +55 -56
- package/Server/API/BaseAPI.ts +79 -14
- package/Server/API/CommonAPI.ts +89 -0
- package/Server/API/MicrosoftTeamsAPI.ts +20 -9
- package/Server/API/SlackAPI.ts +13 -10
- package/Server/API/StatusPageAPI.ts +2197 -2128
- package/Server/API/TelemetryAPI.ts +72 -3
- package/Server/API/UserCallAPI.ts +53 -45
- package/Server/API/UserEmailAPI.ts +53 -44
- package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
- package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
- package/Server/API/UserPushAPI.ts +126 -2
- package/Server/API/UserSmsAPI.ts +53 -44
- package/Server/API/UserWhatsAppAPI.ts +53 -50
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/UserAuthorization.ts +11 -2
- package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
- package/Server/Services/AnalyticsDatabaseService.ts +169 -0
- package/Server/Services/ApiKeyPermissionService.ts +116 -2
- package/Server/Services/DatabaseService.ts +118 -6
- package/Server/Services/LogAggregationService.ts +39 -0
- package/Server/Services/LogService.ts +21 -0
- package/Server/Services/NetworkSiteService.ts +12 -0
- package/Server/Services/PushNotificationService.ts +127 -12
- package/Server/Services/SpanService.ts +21 -0
- package/Server/Services/TeamMemberService.ts +53 -13
- package/Server/Services/TraceAggregationService.ts +15 -0
- package/Server/Services/UserCallService.ts +55 -24
- package/Server/Services/UserEmailService.ts +83 -17
- package/Server/Services/UserIncomingCallNumberService.ts +49 -85
- package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
- package/Server/Services/UserNotificationRuleService.ts +26 -0
- package/Server/Services/UserPushService.ts +89 -0
- package/Server/Services/UserSmsService.ts +50 -17
- package/Server/Services/UserWhatsAppService.ts +48 -15
- package/Server/Services/WorkspaceNotificationRuleService.ts +172 -220
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
- package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -16
- package/Server/Types/Database/QueryHelper.ts +30 -0
- package/Server/Utils/APIKey/AccessPermission.ts +16 -40
- package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +144 -0
- package/Server/Utils/ChannelVerification.ts +510 -0
- package/Server/Utils/LogRedaction.ts +576 -0
- package/Server/Utils/Logger.ts +123 -46
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +94 -23
- package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
- package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
- package/Server/Utils/Monitor/MonitorResource.ts +29 -9
- package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +28 -7
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
- package/Server/Utils/SessionReplay/SessionReplayGateCacheStore.ts +56 -10
- package/Server/Utils/StartServer.ts +30 -9
- package/Server/Utils/StatusPageSearchEngineIndexing.ts +33 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +441 -0
- package/Server/Utils/TotpAuth.ts +137 -9
- package/Server/Utils/UserRegistrationToken.ts +182 -0
- package/Server/Utils/VerificationCode.ts +134 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +488 -46
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
- package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
- package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +328 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +130 -0
- package/Tests/Models/DatabaseModels/DatabaseBaseModelToJSONObjectCache.test.ts +180 -0
- package/Tests/Models/StatusPageEnableSearchEngineIndexing.test.ts +157 -0
- package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +23 -1
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +785 -0
- package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +21 -8
- package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +290 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +7 -1
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
- package/Tests/Server/API/StatusPageOverviewCache.test.ts +474 -0
- package/Tests/Server/API/StatusPageSeoSearchEngineIndexing.test.ts +189 -0
- package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
- package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
- package/Tests/Server/API/UserSmsApi.test.ts +107 -14
- package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
- package/Tests/Server/Infrastructure/InMemoryTTLCache.test.ts +158 -0
- package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +9 -60
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +24 -15
- package/Tests/Server/Middleware/UserAuthorization.test.ts +79 -0
- package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +280 -0
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
- package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +347 -0
- package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
- package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
- package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
- package/Tests/Server/Services/DatabaseServiceUpdateDebugLogging.test.ts +282 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
- package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
- package/Tests/Server/Services/NetworkSiteService.test.ts +56 -2
- package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
- package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
- package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +267 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
- package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
- package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
- package/Tests/Server/Services/WorkspaceNotificationRuleTestRuleChannels.test.ts +702 -0
- package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
- package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +165 -0
- package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
- package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
- package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
- package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
- package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +48 -36
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +213 -0
- package/Tests/Server/Utils/Browser.test.ts +162 -0
- package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
- package/Tests/Server/Utils/Express.test.ts +371 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +415 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +245 -0
- package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +374 -4
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
- package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +455 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
- package/Tests/Server/Utils/Monitor/NetworkDeviceReachabilityRoundTrip.test.ts +369 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +86 -8
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
- package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +64 -0
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCacheStore.test.ts +207 -0
- package/Tests/Server/Utils/StartServerBodyVerify.test.ts +335 -0
- package/Tests/Server/Utils/StatusPageSearchEngineIndexing.test.ts +60 -0
- package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +435 -0
- package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
- package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
- package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +607 -62
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsInstalledTeamIdSpace.test.ts +778 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +44 -10
- package/Tests/Types/API/HostnameFromAuthority.test.ts +164 -0
- package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
- package/Tests/Types/Call/CallRequest.test.ts +189 -0
- package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
- package/Tests/Types/Database/AccessControl/ColumnAccessControlCache.test.ts +344 -0
- package/Tests/Types/Database/DatabasePropertyFindOperator.test.ts +518 -0
- package/Tests/Types/Database/TableColumnMetadataCache.test.ts +286 -0
- package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
- package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
- package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
- package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
- package/Tests/Types/Monitor/MonitorStep.test.ts +100 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +360 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
- package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
- package/Tests/Types/StatusPage/SearchEngineIndexing.test.ts +86 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +254 -0
- package/Tests/Types/TextRandomGeneration.test.ts +211 -0
- package/Tests/UI/Components/Button.test.tsx +175 -1
- package/Tests/UI/Components/CardSelect.test.tsx +1021 -0
- package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
- package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
- package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
- package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
- package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
- package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
- package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
- package/Tests/UI/Components/List.test.tsx +9 -2
- package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
- package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
- package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
- package/Tests/UI/Components/MasterPage.test.tsx +36 -1
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
- package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
- package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
- package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
- package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
- package/Tests/UI/Components/Skeleton.test.tsx +71 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
- package/Tests/UI/Components/Tabs.test.tsx +24 -0
- package/Tests/UI/Components/Toast.test.tsx +130 -7
- package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
- package/Tests/UI/Utils/Dropdown.test.ts +423 -0
- package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
- package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
- package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
- package/Tests/Utils/API.test.ts +16 -2
- package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
- package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +66 -1
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +115 -6
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +610 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +114 -45
- package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
- package/Types/API/Hostname.ts +79 -0
- package/Types/Database/AccessControl/ColumnAccessControl.ts +33 -11
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +33 -11
- package/Types/Database/DatabaseProperty.ts +38 -0
- package/Types/Database/TableColumn.ts +34 -7
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Events/Recurring.ts +16 -1
- package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
- package/Types/Monitor/MonitorStep.ts +13 -1
- package/Types/Monitor/MonitorType.ts +345 -40
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
- package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +43 -0
- package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
- package/Types/Permission.ts +35 -0
- package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
- package/Types/PushNotification/PushNotificationMessage.ts +15 -0
- package/Types/PushNotification/PushNotificationRequest.ts +8 -16
- package/Types/Service/ServiceLanguage.ts +144 -0
- package/Types/StatusPage/SearchEngineIndexing.ts +61 -0
- package/Types/Telemetry/ResourceEntityFacet.ts +211 -0
- package/Types/Text.ts +111 -19
- package/UI/Components/Button/Button.tsx +27 -14
- package/UI/Components/CardSelect/CardSelect.tsx +714 -105
- package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
- package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
- package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
- package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
- package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
- package/UI/Components/CommandPalette/Types.ts +49 -0
- package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
- package/UI/Components/Dropdown/Dropdown.tsx +6 -1
- package/UI/Components/EmptyState/EmptyState.tsx +8 -1
- package/UI/Components/Feed/FeedItem.tsx +1 -1
- package/UI/Components/Footer/Footer.tsx +32 -6
- package/UI/Components/Forms/Fields/FormField.tsx +3 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/List/List.tsx +37 -5
- package/UI/Components/List/ListSkeleton.tsx +54 -0
- package/UI/Components/Loader/PageLoader.tsx +29 -8
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +26 -4
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +23 -2
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
- package/UI/Components/MasterPage/MasterPage.tsx +24 -11
- package/UI/Components/Modal/Modal.tsx +2 -2
- package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
- package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
- package/UI/Components/Navbar/NavBar.tsx +14 -1
- package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
- package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
- package/UI/Components/SideOver/SideOver.tsx +37 -2
- package/UI/Components/Skeleton/Skeleton.tsx +53 -0
- package/UI/Components/Table/Table.tsx +74 -44
- package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
- package/UI/Components/Tabs/Tab.tsx +1 -1
- package/UI/Components/Toast/Toast.tsx +118 -53
- package/UI/Components/Toast/ToastInit.tsx +82 -32
- package/UI/Styles/Theme.css +40 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
- package/UI/Utils/ModelListCache.ts +188 -0
- package/UI/Utils/Project.ts +29 -0
- package/Utils/API.ts +6 -1
- package/Utils/Monitor/MonitorMetricType.ts +16 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +60 -8
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +262 -0
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +41 -24
- package/Utils/Telemetry/CrossSignalScope.ts +75 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +20 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +66 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +60 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +2 -0
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +48 -35
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +69 -13
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +59 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +20 -6
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +13 -10
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +745 -673
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +34 -3
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserCallAPI.js +42 -38
- package/build/dist/Server/API/UserCallAPI.js.map +1 -1
- package/build/dist/Server/API/UserEmailAPI.js +42 -38
- package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
- package/build/dist/Server/API/UserPushAPI.js +95 -2
- package/build/dist/Server/API/UserPushAPI.js.map +1 -1
- package/build/dist/Server/API/UserSmsAPI.js +42 -38
- package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
- package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
- package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +6 -2
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +90 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +89 -6
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +7 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/LogService.js +16 -0
- package/build/dist/Server/Services/LogService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +12 -0
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +69 -30
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +16 -0
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +43 -7
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +2 -0
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +54 -22
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +78 -17
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
- package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +77 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +50 -17
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +137 -164
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +21 -13
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +9 -32
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +87 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/ChannelVerification.js +348 -0
- package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
- package/build/dist/Server/Utils/LogRedaction.js +449 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -0
- package/build/dist/Server/Utils/Logger.js +98 -45
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +65 -13
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +20 -3
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +27 -7
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js +29 -10
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +10 -7
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js +24 -0
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +311 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -0
- package/build/dist/Server/Utils/TotpAuth.js +127 -8
- package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
- package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
- package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
- package/build/dist/Server/Utils/VerificationCode.js +120 -0
- package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +366 -37
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +63 -0
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/DatabaseProperty.js +38 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/TableColumn.js +24 -6
- package/build/dist/Types/Database/TableColumn.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/Events/Recurring.js +13 -1
- package/build/dist/Types/Events/Recurring.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +9 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +330 -31
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
- package/build/dist/Types/Permission.js +33 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
- package/build/dist/Types/Service/ServiceLanguage.js +96 -0
- package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js +55 -0
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js.map +1 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js +156 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -0
- package/build/dist/Types/Text.js +82 -17
- package/build/dist/Types/Text.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +22 -14
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/CardSelect/CardSelect.js +360 -40
- package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
- package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
- package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/Footer/Footer.js +7 -4
- package/build/dist/UI/Components/Footer/Footer.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/List/List.js +19 -5
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
- package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
- package/build/dist/UI/Components/Loader/PageLoader.js +15 -5
- package/build/dist/UI/Components/Loader/PageLoader.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +16 -3
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js +13 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +10 -2
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -2
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
- package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +35 -24
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
- package/build/dist/UI/Components/Tabs/Tab.js +1 -1
- package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
- package/build/dist/UI/Components/Toast/Toast.js +77 -23
- package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
- package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
- package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelListCache.js +126 -0
- package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
- package/build/dist/UI/Utils/Project.js +24 -1
- package/build/dist/UI/Utils/Project.js.map +1 -1
- package/build/dist/Utils/API.js +6 -1
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +13 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +34 -7
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +177 -0
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +23 -27
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +44 -4
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
- package/jest.config.json +1 -1
- package/package.json +2 -3
- package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
- package/Tests/__mocks__/otpauth.js +0 -30
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
|
|
2
|
+
import NetworkInventoryUtil from "../../../../Server/Utils/Monitor/NetworkInventoryUtil";
|
|
3
|
+
import NetworkDeviceService from "../../../../Server/Services/NetworkDeviceService";
|
|
4
|
+
import NetworkEndpointService from "../../../../Server/Services/NetworkEndpointService";
|
|
5
|
+
import NetworkInterfaceService from "../../../../Server/Services/NetworkInterfaceService";
|
|
6
|
+
import NetworkDevice from "../../../../Models/DatabaseModels/NetworkDevice";
|
|
7
|
+
import NetworkInterface from "../../../../Models/DatabaseModels/NetworkInterface";
|
|
8
|
+
import DeviceReachabilityUtil, {
|
|
9
|
+
NetworkDeviceReachability,
|
|
10
|
+
} from "../../../../Utils/NetworkDevice/DeviceReachabilityUtil";
|
|
11
|
+
import SiteStatusRollupUtil, {
|
|
12
|
+
RollupStatusOption,
|
|
13
|
+
} from "../../../../Utils/NetworkSite/SiteStatusRollupUtil";
|
|
14
|
+
import NetworkTopologyUtil, {
|
|
15
|
+
TopologyBuildResult,
|
|
16
|
+
} from "../../../../Utils/Monitor/NetworkTopologyUtil";
|
|
17
|
+
import { NetworkTopologyNode } from "../../../../Types/Monitor/SnmpMonitor/NetworkTopology";
|
|
18
|
+
import ObjectID from "../../../../Types/ObjectID";
|
|
19
|
+
import OneUptimeDate from "../../../../Types/Date";
|
|
20
|
+
import SnmpInterface from "../../../../Types/Monitor/SnmpMonitor/SnmpInterface";
|
|
21
|
+
import SnmpMonitorResponse from "../../../../Types/Monitor/SnmpMonitor/SnmpMonitorResponse";
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* Issue #3220, end to end.
|
|
25
|
+
*
|
|
26
|
+
* "Network Device shown as Down (unreachable) despite device responding to
|
|
27
|
+
* ping and interfaces showing Up." A router that answered SNMP fine — its
|
|
28
|
+
* own Interfaces tab listed 14 ports up, written by that very walk — was
|
|
29
|
+
* listed as Down, with "last seen 21 minutes ago" underneath. 323 of 980
|
|
30
|
+
* devices in that project were in the same state, and the topology graph
|
|
31
|
+
* and network map drew all of them red.
|
|
32
|
+
*
|
|
33
|
+
* The two halves of the cause:
|
|
34
|
+
*
|
|
35
|
+
* 1. a probe is handed a bounded batch of devices per one-minute fetch,
|
|
36
|
+
* so a fleet of ~1000 devices took ~20 minutes to poll all the way
|
|
37
|
+
* round however short the configured interval was; and
|
|
38
|
+
* 2. every reader decided up/down from `lastSeenAt` being newer than a
|
|
39
|
+
* fixed 15 minutes, which a 20-minute cycle can never satisfy.
|
|
40
|
+
*
|
|
41
|
+
* The unit suites cover each layer on its own. What this file does is join
|
|
42
|
+
* them: it drives the REAL write path with a walk exactly like the reported
|
|
43
|
+
* one, and then asks every reader — the device pill, the site rollup and
|
|
44
|
+
* the topology graph — what it makes of the row that was actually written.
|
|
45
|
+
* A regression in either the writer or any single reader shows up here.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
const PROJECT_ID: string = "1c9d4a7b-0000-4000-8000-000000000011";
|
|
49
|
+
const DEVICE_ID: string = "8f2c1f0e-0000-4000-8000-0000000000aa";
|
|
50
|
+
|
|
51
|
+
// The moment the probe finally got round to UN1234WANRTR01.
|
|
52
|
+
const WALKED_AT: Date = new Date("2026-08-17T18:12:00.000Z");
|
|
53
|
+
// The moment the operator was looking at the screen: 21 minutes later.
|
|
54
|
+
const OBSERVED_AT: Date = new Date("2026-08-17T18:33:00.000Z");
|
|
55
|
+
|
|
56
|
+
const OPERATIONAL: RollupStatusOption = {
|
|
57
|
+
monitorStatusId: "status-operational",
|
|
58
|
+
priority: 1,
|
|
59
|
+
};
|
|
60
|
+
const OFFLINE: RollupStatusOption = {
|
|
61
|
+
monitorStatusId: "status-offline",
|
|
62
|
+
priority: 3,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
let deviceUpdateSpy: jest.SpyInstance;
|
|
66
|
+
|
|
67
|
+
function mockServices(): void {
|
|
68
|
+
const ownedDevice: NetworkDevice = new NetworkDevice();
|
|
69
|
+
ownedDevice.id = new ObjectID(DEVICE_ID);
|
|
70
|
+
|
|
71
|
+
jest
|
|
72
|
+
.spyOn(NetworkDeviceService, "findOneBy")
|
|
73
|
+
.mockResolvedValue(ownedDevice as never);
|
|
74
|
+
deviceUpdateSpy = jest
|
|
75
|
+
.spyOn(NetworkDeviceService, "updateOneById")
|
|
76
|
+
.mockResolvedValue(1 as never);
|
|
77
|
+
jest.spyOn(NetworkInterfaceService, "findBy").mockResolvedValue([] as never);
|
|
78
|
+
jest
|
|
79
|
+
.spyOn(NetworkInterfaceService, "updateOneById")
|
|
80
|
+
.mockResolvedValue(1 as never);
|
|
81
|
+
jest
|
|
82
|
+
.spyOn(NetworkInterfaceService, "create")
|
|
83
|
+
.mockResolvedValue(new NetworkInterface() as never);
|
|
84
|
+
jest
|
|
85
|
+
.spyOn(NetworkEndpointService, "upsertDiscoveredEndpoints")
|
|
86
|
+
.mockResolvedValue(undefined as never);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 14 ports up and 12 down — the mix the reported device's Interfaces tab showed.
|
|
90
|
+
function reportedInterfaces(): Array<SnmpInterface> {
|
|
91
|
+
const interfaces: Array<SnmpInterface> = [];
|
|
92
|
+
|
|
93
|
+
for (let index: number = 1; index <= 26; index++) {
|
|
94
|
+
interfaces.push({
|
|
95
|
+
interfaceIndex: index,
|
|
96
|
+
name: `Gi0/${index}`,
|
|
97
|
+
isAdministrativelyUp: true,
|
|
98
|
+
isOperationallyUp: index <= 14,
|
|
99
|
+
} as SnmpInterface);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return interfaces;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/*
|
|
106
|
+
* Runs the real writer and returns the device row as it would then be read
|
|
107
|
+
* back — the columns the update wrote, nothing invented.
|
|
108
|
+
*/
|
|
109
|
+
async function walkAndReadBackDevice(data: {
|
|
110
|
+
isOnline: boolean;
|
|
111
|
+
interfaces: Array<SnmpInterface>;
|
|
112
|
+
}): Promise<Record<string, unknown>> {
|
|
113
|
+
const snmpResponse: SnmpMonitorResponse = {
|
|
114
|
+
isOnline: data.isOnline,
|
|
115
|
+
responseTimeInMs: 274,
|
|
116
|
+
failureCause: "",
|
|
117
|
+
oidResponses: [],
|
|
118
|
+
interfaces: data.interfaces,
|
|
119
|
+
systemInfo: { sysName: "UN1234WANRTR01" },
|
|
120
|
+
} as SnmpMonitorResponse;
|
|
121
|
+
|
|
122
|
+
await NetworkInventoryUtil.updateFromWalk({
|
|
123
|
+
projectId: new ObjectID(PROJECT_ID),
|
|
124
|
+
deviceId: new ObjectID(DEVICE_ID),
|
|
125
|
+
snmpResponse: snmpResponse,
|
|
126
|
+
isOnline: data.isOnline,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
expect(deviceUpdateSpy).toHaveBeenCalled();
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
// The device's configured schedule, unchanged by the walk.
|
|
133
|
+
pollingIntervalInMinutes: 5,
|
|
134
|
+
...(deviceUpdateSpy.mock.calls[0]![0].data as Record<string, unknown>),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
beforeEach(() => {
|
|
139
|
+
jest.useFakeTimers({
|
|
140
|
+
doNotFake: [
|
|
141
|
+
"performance",
|
|
142
|
+
"hrtime",
|
|
143
|
+
"queueMicrotask",
|
|
144
|
+
"requestAnimationFrame",
|
|
145
|
+
"cancelAnimationFrame",
|
|
146
|
+
"requestIdleCallback",
|
|
147
|
+
"cancelIdleCallback",
|
|
148
|
+
"setImmediate",
|
|
149
|
+
"clearImmediate",
|
|
150
|
+
"setInterval",
|
|
151
|
+
"clearInterval",
|
|
152
|
+
"setTimeout",
|
|
153
|
+
"clearTimeout",
|
|
154
|
+
],
|
|
155
|
+
});
|
|
156
|
+
// The walk lands at 18:12; every reader below looks at 18:33.
|
|
157
|
+
jest.setSystemTime(WALKED_AT);
|
|
158
|
+
mockServices();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
afterEach(() => {
|
|
162
|
+
jest.useRealTimers();
|
|
163
|
+
jest.restoreAllMocks();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe("issue #3220 — a device that answered 21 minutes ago", () => {
|
|
167
|
+
test("the walk records that it answered, and when it was asked", async () => {
|
|
168
|
+
const row: Record<string, unknown> = await walkAndReadBackDevice({
|
|
169
|
+
isOnline: true,
|
|
170
|
+
interfaces: reportedInterfaces(),
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
expect(row["isReachable"]).toBe(true);
|
|
174
|
+
expect(row["lastPolledAt"]).toEqual(WALKED_AT);
|
|
175
|
+
expect(row["lastSeenAt"]).toEqual(WALKED_AT);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("the same walk is what put 14 up / 12 down on the Interfaces tab", async () => {
|
|
179
|
+
const row: Record<string, unknown> = await walkAndReadBackDevice({
|
|
180
|
+
isOnline: true,
|
|
181
|
+
interfaces: reportedInterfaces(),
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
/*
|
|
185
|
+
* The contradiction the report was really about: these counts and the
|
|
186
|
+
* reachability verdict come out of ONE walk, so they cannot honestly
|
|
187
|
+
* disagree.
|
|
188
|
+
*/
|
|
189
|
+
expect(row["interfacesUp"]).toBe(14);
|
|
190
|
+
expect(row["interfacesDown"]).toBe(12);
|
|
191
|
+
expect(row["isReachable"]).toBe(true);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("the device pill reads Up, 21 minutes later", async () => {
|
|
195
|
+
const row: Record<string, unknown> = await walkAndReadBackDevice({
|
|
196
|
+
isOnline: true,
|
|
197
|
+
interfaces: reportedInterfaces(),
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
expect(DeviceReachabilityUtil.getStatus(row, OBSERVED_AT)).toBe(
|
|
201
|
+
NetworkDeviceReachability.Up,
|
|
202
|
+
);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("the site rollup above it stays operational", async () => {
|
|
206
|
+
const row: Record<string, unknown> = await walkAndReadBackDevice({
|
|
207
|
+
isOnline: true,
|
|
208
|
+
interfaces: reportedInterfaces(),
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
expect(
|
|
212
|
+
SiteStatusRollupUtil.worstStatus({
|
|
213
|
+
deviceStates: [row],
|
|
214
|
+
operationalStatus: OPERATIONAL,
|
|
215
|
+
offlineStatus: OFFLINE,
|
|
216
|
+
now: OBSERVED_AT,
|
|
217
|
+
}),
|
|
218
|
+
).toBe(OPERATIONAL.monitorStatusId);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
test("the topology graph draws it up, not red", async () => {
|
|
222
|
+
const row: Record<string, unknown> = await walkAndReadBackDevice({
|
|
223
|
+
isOnline: true,
|
|
224
|
+
interfaces: reportedInterfaces(),
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const result: TopologyBuildResult = NetworkTopologyUtil.buildTopology(
|
|
228
|
+
[
|
|
229
|
+
{
|
|
230
|
+
id: DEVICE_ID,
|
|
231
|
+
name: "UN1234WANRTR01",
|
|
232
|
+
hostname: "10.15.128.165",
|
|
233
|
+
isReachable: row["isReachable"] as boolean,
|
|
234
|
+
lastPolledAt: row["lastPolledAt"] as Date,
|
|
235
|
+
lastSeenAt: row["lastSeenAt"] as Date,
|
|
236
|
+
pollingIntervalInMinutes: 5,
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
OBSERVED_AT,
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
const node: NetworkTopologyNode | undefined = result.nodes.find(
|
|
243
|
+
(candidate: NetworkTopologyNode) => {
|
|
244
|
+
return candidate.id === DEVICE_ID;
|
|
245
|
+
},
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
expect(node?.status).toBe("up");
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
/*
|
|
253
|
+
* The fix must not have bought its way out of false positives with false
|
|
254
|
+
* negatives. A device that genuinely stops answering has to go down — and
|
|
255
|
+
* go down on the very next poll, not after a timeout.
|
|
256
|
+
*/
|
|
257
|
+
describe("a device that genuinely stops answering still goes down", () => {
|
|
258
|
+
test("the failing walk records the failure and leaves lastSeenAt behind", async () => {
|
|
259
|
+
const row: Record<string, unknown> = await walkAndReadBackDevice({
|
|
260
|
+
isOnline: false,
|
|
261
|
+
interfaces: [],
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
expect(row["isReachable"]).toBe(false);
|
|
265
|
+
expect(row["lastPolledAt"]).toEqual(WALKED_AT);
|
|
266
|
+
expect(row).not.toHaveProperty("lastSeenAt");
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test("every reader calls it down, immediately", async () => {
|
|
270
|
+
const written: Record<string, unknown> = await walkAndReadBackDevice({
|
|
271
|
+
isOnline: false,
|
|
272
|
+
interfaces: [],
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// The row as it now stands: last answered before the failing poll.
|
|
276
|
+
const row: Record<string, unknown> = {
|
|
277
|
+
...written,
|
|
278
|
+
lastSeenAt: OneUptimeDate.addRemoveMinutes(WALKED_AT, -5),
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// One second after the failed walk — no waiting for a window to expire.
|
|
282
|
+
const justAfter: Date = new Date(WALKED_AT.getTime() + 1000);
|
|
283
|
+
|
|
284
|
+
expect(DeviceReachabilityUtil.getStatus(row, justAfter)).toBe(
|
|
285
|
+
NetworkDeviceReachability.Down,
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
expect(
|
|
289
|
+
SiteStatusRollupUtil.worstStatus({
|
|
290
|
+
deviceStates: [row],
|
|
291
|
+
operationalStatus: OPERATIONAL,
|
|
292
|
+
offlineStatus: OFFLINE,
|
|
293
|
+
now: justAfter,
|
|
294
|
+
}),
|
|
295
|
+
).toBe(OFFLINE.monitorStatusId);
|
|
296
|
+
|
|
297
|
+
const result: TopologyBuildResult = NetworkTopologyUtil.buildTopology(
|
|
298
|
+
[
|
|
299
|
+
{
|
|
300
|
+
id: DEVICE_ID,
|
|
301
|
+
name: "UN1234WANRTR01",
|
|
302
|
+
isReachable: row["isReachable"] as boolean,
|
|
303
|
+
lastPolledAt: row["lastPolledAt"] as Date,
|
|
304
|
+
lastSeenAt: row["lastSeenAt"] as Date,
|
|
305
|
+
pollingIntervalInMinutes: 5,
|
|
306
|
+
},
|
|
307
|
+
],
|
|
308
|
+
justAfter,
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
expect(
|
|
312
|
+
result.nodes.find((candidate: NetworkTopologyNode) => {
|
|
313
|
+
return candidate.id === DEVICE_ID;
|
|
314
|
+
})?.status,
|
|
315
|
+
).toBe("down");
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
/*
|
|
320
|
+
* And the polling pipeline going silent. The fleet keeps its last known
|
|
321
|
+
* verdicts — manufacturing an outage nobody observed is the failure this
|
|
322
|
+
* change removes — but every device is flagged stale, which is what sends
|
|
323
|
+
* the operator to the probe instead of to 300 devices.
|
|
324
|
+
*/
|
|
325
|
+
describe("a fleet whose probe has gone silent is flagged, not condemned", () => {
|
|
326
|
+
test("a good verdict nobody has refreshed for hours stays Up and reads stale", async () => {
|
|
327
|
+
const row: Record<string, unknown> = await walkAndReadBackDevice({
|
|
328
|
+
isOnline: true,
|
|
329
|
+
interfaces: reportedInterfaces(),
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
const hoursLater: Date = new Date(WALKED_AT.getTime() + 4 * 60 * 60 * 1000);
|
|
333
|
+
|
|
334
|
+
const reachability: {
|
|
335
|
+
status: NetworkDeviceReachability;
|
|
336
|
+
isStale: boolean;
|
|
337
|
+
} = DeviceReachabilityUtil.getReachability(row, hoursLater);
|
|
338
|
+
|
|
339
|
+
expect(reachability.status).toBe(NetworkDeviceReachability.Up);
|
|
340
|
+
/*
|
|
341
|
+
* isStale is what puts the amber "Stale" pill next to the verdict and
|
|
342
|
+
* points the tooltip at the probe — a different investigation from
|
|
343
|
+
* "this device is down", and the reason it is not expressed as Down.
|
|
344
|
+
*/
|
|
345
|
+
expect(reachability.isStale).toBe(true);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
/*
|
|
349
|
+
* The property that keeps the device list self-consistent: the summary
|
|
350
|
+
* tiles and the Status chip are SQL over `isReachable`, so whatever the
|
|
351
|
+
* clock says, the pill has to be reproducible from that column alone.
|
|
352
|
+
*/
|
|
353
|
+
test("the verdict stays reproducible from the stored column alone", async () => {
|
|
354
|
+
const row: Record<string, unknown> = await walkAndReadBackDevice({
|
|
355
|
+
isOnline: true,
|
|
356
|
+
interfaces: reportedInterfaces(),
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
for (const hoursLater of [0, 1, 4, 24, 24 * 30]) {
|
|
360
|
+
const at: Date = new Date(WALKED_AT.getTime() + hoursLater * 3600 * 1000);
|
|
361
|
+
|
|
362
|
+
expect(DeviceReachabilityUtil.getStatus(row, at)).toBe(
|
|
363
|
+
row["isReachable"] === true
|
|
364
|
+
? NetworkDeviceReachability.Up
|
|
365
|
+
: NetworkDeviceReachability.Down,
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
@@ -236,8 +236,33 @@ describe("NetworkInventoryUtil.updateFromWalk — project-membership guard", ()
|
|
|
236
236
|
});
|
|
237
237
|
});
|
|
238
238
|
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
/*
|
|
240
|
+
* The three columns this util writes on every walk are what the whole
|
|
241
|
+
* up/down story rests on, so they get their own block:
|
|
242
|
+
*
|
|
243
|
+
* lastPolledAt - when we ASKED (always)
|
|
244
|
+
* isReachable - what we got back (always)
|
|
245
|
+
* lastSeenAt - when it ANSWERED (successful walks only)
|
|
246
|
+
*
|
|
247
|
+
* The bug this pins (issue #3220) was that only lastSeenAt existed, so a
|
|
248
|
+
* device that answered its last poll 21 minutes ago was indistinguishable
|
|
249
|
+
* from one that had failed its last poll — and the UI, having to guess,
|
|
250
|
+
* called both of them Down.
|
|
251
|
+
*/
|
|
252
|
+
describe("NetworkInventoryUtil.updateFromWalk — reachability recording", () => {
|
|
253
|
+
test("a reachable poll stamps all three columns", async () => {
|
|
254
|
+
mockServices();
|
|
255
|
+
|
|
256
|
+
await runWalk();
|
|
257
|
+
|
|
258
|
+
const update: DeviceUpdatePayload = deviceUpdatePayload();
|
|
259
|
+
|
|
260
|
+
expect(update["lastPolledAt"]).toEqual(NOW);
|
|
261
|
+
expect(update["isReachable"]).toBe(true);
|
|
262
|
+
expect(update["lastSeenAt"]).toEqual(NOW);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test("an unreachable poll with no walk data still records the attempt", async () => {
|
|
241
266
|
mockServices();
|
|
242
267
|
|
|
243
268
|
await runWalk(
|
|
@@ -249,8 +274,17 @@ describe("NetworkInventoryUtil.updateFromWalk — reachability gating", () => {
|
|
|
249
274
|
{ isOnline: false },
|
|
250
275
|
);
|
|
251
276
|
|
|
252
|
-
|
|
253
|
-
|
|
277
|
+
const update: DeviceUpdatePayload = deviceUpdatePayload();
|
|
278
|
+
|
|
279
|
+
/*
|
|
280
|
+
* This write used to be skipped entirely ("nothing worth writing"),
|
|
281
|
+
* which is exactly what left the reader unable to tell a failing device
|
|
282
|
+
* from one nothing had got round to polling.
|
|
283
|
+
*/
|
|
284
|
+
expect(update["lastPolledAt"]).toEqual(NOW);
|
|
285
|
+
expect(update["isReachable"]).toBe(false);
|
|
286
|
+
// The device did not answer, so its last contact must not move.
|
|
287
|
+
expect(update).not.toHaveProperty("lastSeenAt");
|
|
254
288
|
});
|
|
255
289
|
|
|
256
290
|
test("an unreachable poll with walk data still enriches but never stamps lastSeenAt", async () => {
|
|
@@ -267,15 +301,54 @@ describe("NetworkInventoryUtil.updateFromWalk — reachability gating", () => {
|
|
|
267
301
|
const update: DeviceUpdatePayload = deviceUpdatePayload();
|
|
268
302
|
|
|
269
303
|
expect(update["sysName"]).toBe("core-sw-01");
|
|
304
|
+
expect(update["isReachable"]).toBe(false);
|
|
305
|
+
expect(update["lastPolledAt"]).toEqual(NOW);
|
|
270
306
|
expect(update).not.toHaveProperty("lastSeenAt");
|
|
271
307
|
});
|
|
272
308
|
|
|
273
|
-
test("a walk that reports no reachability at all is treated as
|
|
309
|
+
test("a walk that reports no reachability at all is treated as answered", async () => {
|
|
274
310
|
mockServices();
|
|
275
311
|
|
|
276
312
|
await runWalk(undefined, { isOnline: undefined });
|
|
277
313
|
|
|
278
|
-
|
|
314
|
+
const update: DeviceUpdatePayload = deviceUpdatePayload();
|
|
315
|
+
|
|
316
|
+
expect(update["isReachable"]).toBe(true);
|
|
317
|
+
expect(update["lastPolledAt"]).toEqual(NOW);
|
|
318
|
+
expect(update["lastSeenAt"]).toEqual(NOW);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test("lastPolledAt and lastSeenAt are the SAME instant on a good walk", async () => {
|
|
322
|
+
mockServices();
|
|
323
|
+
|
|
324
|
+
await runWalk();
|
|
325
|
+
|
|
326
|
+
const update: DeviceUpdatePayload = deviceUpdatePayload();
|
|
327
|
+
|
|
328
|
+
/*
|
|
329
|
+
* The reader treats "polled later than seen" as evidence of a failed
|
|
330
|
+
* attempt, so a successful walk must not leave even a millisecond of
|
|
331
|
+
* skew between the two.
|
|
332
|
+
*/
|
|
333
|
+
expect((update["lastPolledAt"] as Date).getTime()).toBe(
|
|
334
|
+
(update["lastSeenAt"] as Date).getTime(),
|
|
335
|
+
);
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
test("a failed poll after a successful one leaves lastSeenAt behind lastPolledAt", async () => {
|
|
339
|
+
mockServices();
|
|
340
|
+
|
|
341
|
+
await runWalk();
|
|
342
|
+
const good: DeviceUpdatePayload = deviceUpdatePayload();
|
|
343
|
+
|
|
344
|
+
deviceUpdateSpy.mockClear();
|
|
345
|
+
await runWalk({ isOnline: false }, { isOnline: false });
|
|
346
|
+
const bad: DeviceUpdatePayload = deviceUpdatePayload();
|
|
347
|
+
|
|
348
|
+
expect(bad["isReachable"]).toBe(false);
|
|
349
|
+
expect(bad).not.toHaveProperty("lastSeenAt");
|
|
350
|
+
// The previous success stays the device's last contact.
|
|
351
|
+
expect(good["lastSeenAt"]).toEqual(NOW);
|
|
279
352
|
});
|
|
280
353
|
});
|
|
281
354
|
|
|
@@ -690,7 +763,7 @@ describe("NetworkInventoryUtil.updateFromWalk — walks without interfaces", ()
|
|
|
690
763
|
expect(interfaceCreateSpy).not.toHaveBeenCalled();
|
|
691
764
|
});
|
|
692
765
|
|
|
693
|
-
test("a walk with no snmpResponse at all still
|
|
766
|
+
test("a walk with no snmpResponse at all still records the poll", async () => {
|
|
694
767
|
mockServices();
|
|
695
768
|
|
|
696
769
|
await NetworkInventoryUtil.updateFromWalk({
|
|
@@ -700,7 +773,12 @@ describe("NetworkInventoryUtil.updateFromWalk — walks without interfaces", ()
|
|
|
700
773
|
isOnline: true,
|
|
701
774
|
});
|
|
702
775
|
|
|
703
|
-
|
|
776
|
+
// Exactly the reachability columns and nothing else — no walk, no data.
|
|
777
|
+
expect(deviceUpdatePayload()).toEqual({
|
|
778
|
+
lastPolledAt: NOW,
|
|
779
|
+
isReachable: true,
|
|
780
|
+
lastSeenAt: NOW,
|
|
781
|
+
});
|
|
704
782
|
expect(interfaceFindSpy).not.toHaveBeenCalled();
|
|
705
783
|
});
|
|
706
784
|
});
|
|
@@ -36,8 +36,9 @@ import SeriesResourceLinker, {
|
|
|
36
36
|
} from "../../../../Server/Utils/Monitor/SeriesResourceLinker";
|
|
37
37
|
import Includes from "../../../../Types/BaseDatabase/Includes";
|
|
38
38
|
import { JSONObject } from "../../../../Types/JSON";
|
|
39
|
+
import MonitorType from "../../../../Types/Monitor/MonitorType";
|
|
39
40
|
import ObjectID from "../../../../Types/ObjectID";
|
|
40
|
-
|
|
41
|
+
|
|
41
42
|
import {
|
|
42
43
|
afterEach,
|
|
43
44
|
beforeEach,
|
|
@@ -176,8 +177,13 @@ function includesValues(value: unknown): Array<string> {
|
|
|
176
177
|
});
|
|
177
178
|
}
|
|
178
179
|
|
|
179
|
-
function
|
|
180
|
+
function emptyResourceContext(): SeriesResolvedResourceIds {
|
|
180
181
|
return {
|
|
182
|
+
hostIds: [],
|
|
183
|
+
dockerHostIds: [],
|
|
184
|
+
podmanHostIds: [],
|
|
185
|
+
kubernetesClusterIds: [],
|
|
186
|
+
serviceIds: [],
|
|
181
187
|
proxmoxClusterIds: [],
|
|
182
188
|
cephClusterIds: [],
|
|
183
189
|
dockerSwarmClusterIds: [],
|
|
@@ -356,6 +362,73 @@ describe("SeriesResourceLinker.linkSeriesResourcesToModel", () => {
|
|
|
356
362
|
},
|
|
357
363
|
);
|
|
358
364
|
|
|
365
|
+
test.each([[MonitorType.Docker], [MonitorType.Podman]])(
|
|
366
|
+
"a %s monitor's host.name label links no Host",
|
|
367
|
+
async (monitorType: MonitorType) => {
|
|
368
|
+
/*
|
|
369
|
+
* The container agents stamp the box their containers run on under
|
|
370
|
+
* the generic `resource.host.name`, which the label key map hands
|
|
371
|
+
* to Host. On a Docker/Podman monitor that value names a
|
|
372
|
+
* DockerHost / PodmanHost row, so honouring the map would attach an
|
|
373
|
+
* unrelated Host and surface the event on that host's Activity tab.
|
|
374
|
+
* The step-config path (MonitorStepResourceIdentity) links the
|
|
375
|
+
* right model instead.
|
|
376
|
+
*/
|
|
377
|
+
rowsByRelation.set("hosts", [{ _id: "host-1" }]);
|
|
378
|
+
|
|
379
|
+
const alert: Alert = new Alert();
|
|
380
|
+
|
|
381
|
+
await SeriesResourceLinker.linkSeriesResourcesToModel({
|
|
382
|
+
model: alert,
|
|
383
|
+
seriesLabels: { "host.name": "docker-prod-01" },
|
|
384
|
+
projectId: PROJECT_ID,
|
|
385
|
+
monitorType: monitorType,
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
expect(alert.hosts).toBeUndefined();
|
|
389
|
+
expect(HostService.findBy).not.toHaveBeenCalled();
|
|
390
|
+
},
|
|
391
|
+
);
|
|
392
|
+
|
|
393
|
+
test("a host.name label still links a Host for every other monitor type", async () => {
|
|
394
|
+
// The suppression must be scoped to the two container types only.
|
|
395
|
+
rowsByRelation.set("hosts", [{ _id: "host-1" }]);
|
|
396
|
+
|
|
397
|
+
const alert: Alert = new Alert();
|
|
398
|
+
|
|
399
|
+
await SeriesResourceLinker.linkSeriesResourcesToModel({
|
|
400
|
+
model: alert,
|
|
401
|
+
seriesLabels: { "host.name": "prod-01" },
|
|
402
|
+
projectId: PROJECT_ID,
|
|
403
|
+
monitorType: MonitorType.Host,
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
expect(idsOn(alert, "hosts")).toEqual(["host-1"]);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
test("a Docker monitor still links the docker host its labels name", async () => {
|
|
410
|
+
/*
|
|
411
|
+
* Suppression must drop ONLY the host refs — the DockerHost the
|
|
412
|
+
* series actually identifies has to survive.
|
|
413
|
+
*/
|
|
414
|
+
rowsByRelation.set("dockerHosts", [{ _id: "docker-1" }]);
|
|
415
|
+
|
|
416
|
+
const alert: Alert = new Alert();
|
|
417
|
+
|
|
418
|
+
await SeriesResourceLinker.linkSeriesResourcesToModel({
|
|
419
|
+
model: alert,
|
|
420
|
+
seriesLabels: {
|
|
421
|
+
"host.name": "docker-prod-01",
|
|
422
|
+
"oneuptime.docker.host.name": "docker-prod-01",
|
|
423
|
+
},
|
|
424
|
+
projectId: PROJECT_ID,
|
|
425
|
+
monitorType: MonitorType.Docker,
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
expect(alert.hosts).toBeUndefined();
|
|
429
|
+
expect(idsOn(alert, "dockerHosts")).toEqual(["docker-1"]);
|
|
430
|
+
});
|
|
431
|
+
|
|
359
432
|
test("a bare host name never resolves a docker or podman host", async () => {
|
|
360
433
|
/*
|
|
361
434
|
* Docker/Podman hosts are deliberately addressed only by their own
|
|
@@ -596,13 +669,14 @@ describe("SeriesResourceLinker.resolveResourcesFromSeriesLabels", () => {
|
|
|
596
669
|
});
|
|
597
670
|
});
|
|
598
671
|
|
|
599
|
-
describe("SeriesResourceLinker.
|
|
600
|
-
test("attaches the monitor-step
|
|
672
|
+
describe("SeriesResourceLinker.attachResolvedResources", () => {
|
|
673
|
+
test("attaches the monitor-step resources", () => {
|
|
601
674
|
const alert: Alert = new Alert();
|
|
602
675
|
|
|
603
|
-
SeriesResourceLinker.
|
|
676
|
+
SeriesResourceLinker.attachResolvedResources({
|
|
604
677
|
model: alert,
|
|
605
|
-
|
|
678
|
+
resolved: {
|
|
679
|
+
...emptyResourceContext(),
|
|
606
680
|
proxmoxClusterIds: ["pve-1"],
|
|
607
681
|
cephClusterIds: ["ceph-1"],
|
|
608
682
|
dockerSwarmClusterIds: ["swarm-1"],
|
|
@@ -633,10 +707,10 @@ describe("SeriesResourceLinker.attachClusterContext", () => {
|
|
|
633
707
|
projectId: PROJECT_ID,
|
|
634
708
|
});
|
|
635
709
|
|
|
636
|
-
SeriesResourceLinker.
|
|
710
|
+
SeriesResourceLinker.attachResolvedResources({
|
|
637
711
|
model: alert,
|
|
638
|
-
|
|
639
|
-
...
|
|
712
|
+
resolved: {
|
|
713
|
+
...emptyResourceContext(),
|
|
640
714
|
proxmoxClusterIds: ["pve-from-step-config"],
|
|
641
715
|
},
|
|
642
716
|
});
|
|
@@ -658,10 +732,10 @@ describe("SeriesResourceLinker.attachClusterContext", () => {
|
|
|
658
732
|
projectId: PROJECT_ID,
|
|
659
733
|
});
|
|
660
734
|
|
|
661
|
-
SeriesResourceLinker.
|
|
735
|
+
SeriesResourceLinker.attachResolvedResources({
|
|
662
736
|
model: alert,
|
|
663
|
-
|
|
664
|
-
...
|
|
737
|
+
resolved: {
|
|
738
|
+
...emptyResourceContext(),
|
|
665
739
|
cephClusterIds: ["ceph-1"],
|
|
666
740
|
},
|
|
667
741
|
});
|
|
@@ -669,12 +743,12 @@ describe("SeriesResourceLinker.attachClusterContext", () => {
|
|
|
669
743
|
expect(idsOn(alert, "cephClusters")).toEqual(["ceph-1"]);
|
|
670
744
|
});
|
|
671
745
|
|
|
672
|
-
test("leaves every relation untouched when the monitor
|
|
746
|
+
test("leaves every relation untouched when the monitor names no resource", () => {
|
|
673
747
|
const alert: Alert = new Alert();
|
|
674
748
|
|
|
675
|
-
SeriesResourceLinker.
|
|
749
|
+
SeriesResourceLinker.attachResolvedResources({
|
|
676
750
|
model: alert,
|
|
677
|
-
|
|
751
|
+
resolved: emptyResourceContext(),
|
|
678
752
|
});
|
|
679
753
|
|
|
680
754
|
expect(alert.proxmoxClusters).toBeUndefined();
|
|
@@ -686,10 +760,10 @@ describe("SeriesResourceLinker.attachClusterContext", () => {
|
|
|
686
760
|
test("attaches to an incident the same way", () => {
|
|
687
761
|
const incident: Incident = new Incident();
|
|
688
762
|
|
|
689
|
-
SeriesResourceLinker.
|
|
763
|
+
SeriesResourceLinker.attachResolvedResources({
|
|
690
764
|
model: incident,
|
|
691
|
-
|
|
692
|
-
...
|
|
765
|
+
resolved: {
|
|
766
|
+
...emptyResourceContext(),
|
|
693
767
|
dockerSwarmClusterIds: ["swarm-1"],
|
|
694
768
|
},
|
|
695
769
|
});
|