@oneuptime/common 12.0.7 → 12.0.9
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/MetricItemAggMV1mByK8sCluster.ts +1 -1
- package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +1 -1
- package/Models/DatabaseModels/AIConversation.ts +32 -0
- package/Models/DatabaseModels/AIConversationMessage.ts +41 -0
- package/Models/DatabaseModels/AlertEpisodeMember.ts +27 -0
- package/Models/DatabaseModels/IncidentEpisodeMember.ts +28 -0
- package/Models/DatabaseModels/Index.ts +12 -4
- package/Models/DatabaseModels/{TelemetryEntity.ts → InventoryItem.ts} +184 -9
- package/Models/DatabaseModels/InventoryItemCustomField.ts +434 -0
- package/Models/DatabaseModels/{TelemetryEntityRelationship.ts → InventoryItemRelationship.ts} +33 -7
- package/Models/DatabaseModels/NetworkDevice.ts +141 -0
- package/Models/DatabaseModels/NetworkDeviceLink.ts +699 -0
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +467 -0
- package/Models/DatabaseModels/NetworkTopologySuppression.ts +429 -0
- package/Models/DatabaseModels/OnCallDutyPolicyFeed.ts +9 -0
- package/Models/DatabaseModels/Project.ts +78 -0
- package/Models/DatabaseModels/UserCall.ts +42 -0
- package/Models/DatabaseModels/UserEmail.ts +44 -0
- package/Models/DatabaseModels/UserNotificationRule.ts +425 -55
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +24 -2
- package/Models/DatabaseModels/UserPush.ts +49 -0
- package/Models/DatabaseModels/UserSMS.ts +43 -0
- package/Models/DatabaseModels/UserTelegram.ts +59 -0
- package/Models/DatabaseModels/UserWebhook.ts +52 -0
- package/Models/DatabaseModels/UserWhatsApp.ts +41 -0
- package/Models/DatabaseModels/WorkflowLog.ts +38 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +12 -0
- package/Server/API/AIChatAPI.ts +315 -1
- package/Server/API/DashboardAPI.ts +217 -1
- package/Server/API/OnCallReadinessAPI.ts +841 -0
- package/Server/API/TeamComplianceAPI.ts +69 -17
- package/Server/API/TelemetryAPI.ts +220 -12
- package/Server/API/UserAPI.ts +16 -1
- package/Server/EnvironmentConfig.ts +52 -0
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +22 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +4 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +5 -5
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.ts +82 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.ts +91 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.ts +255 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.ts +107 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.ts +90 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +24 -0
- package/Server/Infrastructure/Queue.ts +78 -13
- package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
- package/Server/Middleware/PublicDashboardRateLimit.ts +593 -0
- package/Server/Services/AIService.ts +7 -0
- package/Server/Services/AlertEpisodeStateTimelineService.ts +29 -0
- package/Server/Services/AlertSeverityService.ts +63 -0
- package/Server/Services/DashboardService.ts +9 -10
- package/Server/Services/DatabaseService.ts +32 -2
- package/Server/Services/IncidentEpisodeStateTimelineService.ts +29 -0
- package/Server/Services/IncidentSeverityService.ts +76 -0
- package/Server/Services/Index.ts +12 -4
- package/Server/Services/InventoryItemCustomFieldService.ts +9 -0
- package/Server/Services/{TelemetryEntityRelationshipService.ts → InventoryItemRelationshipService.ts} +7 -4
- package/Server/Services/{TelemetryEntityService.ts → InventoryItemService.ts} +203 -21
- package/Server/Services/LogAggregationService.ts +45 -8
- package/Server/Services/MetricAggregationService.ts +121 -0
- package/Server/Services/MetricService.ts +7 -7
- package/Server/Services/NetworkDeviceLinkRuleService.ts +10 -0
- package/Server/Services/NetworkDeviceLinkService.ts +84 -0
- package/Server/Services/NetworkDeviceService.ts +140 -0
- package/Server/Services/NetworkSiteService.ts +77 -25
- package/Server/Services/NetworkTopologySuppressionService.ts +84 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +41 -29
- package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +8 -0
- package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +62 -13
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +61 -1
- package/Server/Services/OnCallNotificationAlertingService.ts +742 -0
- package/Server/Services/OnCallReadinessService.ts +2803 -0
- package/Server/Services/OnCallSetupReminderService.ts +955 -0
- package/Server/Services/ProfileAggregationService.ts +123 -0
- package/Server/Services/StatusPageService.ts +9 -10
- package/Server/Services/TeamComplianceService.ts +429 -252
- package/Server/Services/UserCallService.ts +26 -1
- package/Server/Services/UserEmailService.ts +26 -1
- package/Server/Services/UserNotificationRuleAdminService.ts +1183 -0
- package/Server/Services/UserNotificationRuleService.ts +3812 -333
- package/Server/Services/UserOnCallLogService.ts +561 -48
- package/Server/Services/UserPushService.ts +29 -0
- package/Server/Services/UserService.ts +11 -0
- package/Server/Services/UserSmsService.ts +26 -1
- package/Server/Services/UserTelegramService.ts +24 -1
- package/Server/Services/UserWebhookService.ts +28 -1
- package/Server/Services/UserWhatsAppService.ts +24 -1
- package/Server/Types/Database/Permissions/BasePermission.ts +19 -0
- package/Server/Types/Database/Permissions/CreatePermission.ts +164 -0
- package/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.ts +340 -0
- package/Server/Types/Database/Permissions/QueryPermission.ts +48 -0
- package/Server/Types/Database/Permissions/TenantPermission.ts +8 -1
- package/Server/Types/Workflow/Components/API/Delete.ts +1 -1
- package/Server/Types/Workflow/Components/API/Get.ts +1 -1
- package/Server/Types/Workflow/Components/API/Patch.ts +1 -1
- package/Server/Types/Workflow/Components/API/Post.ts +1 -1
- package/Server/Types/Workflow/Components/API/Put.ts +1 -1
- package/Server/Types/Workflow/Components/API/Utils.ts +44 -1
- package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +29 -5
- package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +18 -10
- package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +55 -0
- package/Server/Types/Workflow/Components/Conditions/IfElse.ts +3 -17
- package/Server/Types/Workflow/Components/Email.ts +25 -7
- package/Server/Types/Workflow/Components/JavaScript.ts +10 -3
- package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +1 -1
- package/Server/Types/Workflow/TriggerCode.ts +12 -0
- package/Server/Types/Workflow/Workflow.ts +5 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +643 -48
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +32 -3
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +20 -6
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +7 -0
- package/Server/Utils/AI/Toolbox/AIActionTools.ts +2 -2
- package/Server/Utils/AI/Toolbox/AIMetaTools.ts +863 -0
- package/Server/Utils/AI/Toolbox/AlertTools.ts +177 -15
- package/Server/Utils/AI/Toolbox/IncidentTools.ts +191 -10
- package/Server/Utils/AI/Toolbox/Index.ts +48 -0
- package/Server/Utils/AI/Toolbox/MonitorTools.ts +298 -11
- package/Server/Utils/AI/Toolbox/NoteWriteTools.ts +295 -0
- package/Server/Utils/AI/Toolbox/OnCallTools.ts +1246 -0
- package/Server/Utils/AI/Toolbox/RunbookTools.ts +424 -0
- package/Server/Utils/AI/Toolbox/SloTools.ts +456 -0
- package/Server/Utils/AI/Toolbox/StatusPageTools.ts +559 -0
- package/Server/Utils/AI/Toolbox/TeamTools.ts +327 -0
- package/Server/Utils/AI/Toolbox/TimelineTools.ts +615 -0
- package/Server/Utils/AI/Toolbox/WorkflowProbeTools.ts +664 -0
- package/Server/Utils/ClientIp.ts +221 -0
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +47 -0
- package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +163 -0
- package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +147 -0
- package/Server/Utils/Express.ts +12 -17
- package/Server/Utils/LLM/LLMService.ts +85 -8
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +204 -10
- package/Server/Utils/SSRFProtection.ts +98 -23
- package/Server/Utils/StartServer.ts +12 -3
- package/Server/Utils/Telemetry/EntityRegistry.ts +205 -18
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +160 -52
- package/Server/Utils/VM/VMAPI.ts +56 -8
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +7 -3
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +2146 -0
- package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +561 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +2470 -0
- package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +1897 -0
- package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +3606 -0
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +784 -0
- package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +1119 -0
- package/Tests/App/Dashboard/SloWidgetFetching.test.tsx +531 -0
- package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +1312 -0
- package/Tests/App/Dashboard/UserSettingsSetupChecklistPage.test.tsx +1390 -0
- package/Tests/Models/InventoryItemModel.test.ts +174 -0
- package/Tests/Models/InventoryItemNaming.test.ts +302 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +437 -0
- package/Tests/Server/API/DashboardPublicRateLimit.test.ts +659 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +18 -0
- package/Tests/Server/API/DashboardPublicSloAPI.test.ts +880 -0
- package/Tests/Server/API/Helpers.ts +24 -15
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +2680 -0
- package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +915 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
- package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +533 -0
- package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +213 -0
- package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +432 -0
- package/Tests/Server/Infrastructure/Queue.test.ts +293 -0
- package/Tests/Server/Middleware/PublicDashboardRateLimit.test.ts +1645 -0
- package/Tests/Server/Services/AdminRuleEditGuards.test.ts +2848 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1393 -0
- package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +1802 -0
- package/Tests/Server/Services/EpisodeStateTimelineNote.test.ts +304 -0
- package/Tests/Server/Services/InventoryItemDisplayName.test.ts +339 -0
- package/Tests/Server/Services/InventoryItemManualCreate.test.ts +248 -0
- package/Tests/Server/Services/IpAllowlistSpoofing.test.ts +450 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +235 -1
- package/Tests/Server/Services/MetricAggregationService.test.ts +231 -0
- package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +80 -29
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +30 -30
- package/Tests/Server/Services/NetworkSiteService.test.ts +18 -3
- package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +1728 -0
- package/Tests/Server/Services/NotificationDeletionImpact.test.ts +2402 -0
- package/Tests/Server/Services/OnCallDutyPolicyExecutionLogTimelineGapFeed.test.ts +394 -0
- package/Tests/Server/Services/OnCallNotificationFallback.test.ts +1744 -0
- package/Tests/Server/Services/OnCallReadinessService.test.ts +4295 -0
- package/Tests/Server/Services/OnCallSetupReminder.test.ts +1272 -0
- package/Tests/Server/Services/OnCallWeeklyReadinessDigest.test.ts +1021 -0
- package/Tests/Server/Services/ProfileAggregationService.test.ts +296 -0
- package/Tests/Server/Services/SeverityCreationRuleBackfill.test.ts +1536 -0
- package/Tests/Server/Services/SeverityRuleBackfill.test.ts +1818 -0
- package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +1845 -0
- package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +1394 -0
- package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +1166 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1468 -0
- package/Tests/Server/Services/UserOnCallLogNoNotificationRules.test.ts +1457 -0
- package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +1546 -0
- package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +529 -0
- package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +1219 -0
- package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +1089 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +2 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
- package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +190 -0
- package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +44 -14
- package/Tests/Server/Types/Workflow/Components/Email.test.ts +151 -0
- package/Tests/Server/Types/Workflow/Components/IfElse.test.ts +98 -0
- package/Tests/Server/Types/Workflow/Components/JavaScript.test.ts +51 -0
- package/Tests/Server/Utils/AI/AIMetaTools.test.ts +586 -0
- package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +582 -0
- package/Tests/Server/Utils/AI/ChatAgentRunner.test.ts +726 -0
- package/Tests/Server/Utils/AI/IncidentToolsFilters.test.ts +315 -0
- package/Tests/Server/Utils/AI/LLMServiceStopReason.test.ts +314 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +26 -3
- package/Tests/Server/Utils/AI/NoteWriteTools.test.ts +268 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +169 -0
- package/Tests/Server/Utils/AI/OnCallTools.test.ts +664 -0
- package/Tests/Server/Utils/AI/RunbookTools.test.ts +325 -0
- package/Tests/Server/Utils/AI/SloTools.test.ts +306 -0
- package/Tests/Server/Utils/AI/StatusPageTools.test.ts +391 -0
- package/Tests/Server/Utils/AI/TeamTools.test.ts +257 -0
- package/Tests/Server/Utils/AI/TimelineTools.test.ts +472 -0
- package/Tests/Server/Utils/AI/WorkflowProbeTools.test.ts +428 -0
- package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
- package/Tests/Server/Utils/ClientIp.test.ts +438 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +171 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +383 -0
- package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +23 -25
- package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +6 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.test.ts +307 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +468 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorTelemetryDeepLinks.test.ts +460 -0
- package/Tests/Server/Utils/ResponseRateLimitStatusCodes.test.ts +137 -0
- package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +40 -8
- package/Tests/Server/Utils/SSRFProtectionUserInfo.test.ts +351 -0
- package/Tests/Server/Utils/Telemetry/EntityRegistryRetirement.test.ts +531 -0
- package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +356 -39
- package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
- package/Tests/Types/IP/IP.test.ts +263 -0
- package/Tests/Types/IP/IPWhitelist.test.ts +197 -0
- package/Tests/Types/IP/IPv6.test.ts +12 -1
- package/Tests/Types/Monitor/SnmpOid.test.ts +64 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +110 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +106 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeDifferential.test.ts +511 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageEndToEnd.test.ts +489 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageGapTolerance.test.ts +479 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageState.test.ts +822 -0
- package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
- package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
- package/Tests/Types/Workflow/BaseModelComponents.test.ts +429 -0
- package/Tests/Types/Workflow/Components/BaseModel.test.ts +225 -0
- package/Tests/Types/Workflow/IntegrationCredentialMetadata.test.ts +100 -0
- package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
- package/Tests/Types/Workflow/TemplateSyntax.test.ts +491 -0
- package/Tests/Types/Workflow/Templates.test.ts +1218 -0
- package/Tests/UI/Components/ActiveFilterChipsOpenRoute.test.tsx +82 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +564 -7
- package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
- package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
- package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
- package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
- package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
- package/Tests/UI/Components/KeyboardShortcut.test.tsx +95 -0
- package/Tests/UI/Components/LogDetailsPanelCrossSignal.test.tsx +448 -0
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +42 -0
- package/Tests/UI/Components/LogsTableCrossLinks.test.tsx +263 -0
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +90 -0
- package/Tests/UI/Components/PendingProjectInvitations.test.tsx +913 -0
- package/Tests/UI/Components/SimpleLogViewer.test.tsx +228 -0
- package/Tests/UI/Components/TableRowSelectability.test.tsx +312 -0
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +49 -7
- package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
- package/Tests/UI/Components/Workflow/GraphLint.test.ts +893 -0
- package/Tests/UI/Components/Workflow/GraphLintSummary.test.ts +755 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +522 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +193 -0
- package/Tests/UI/Components/Workflow/ModelSchema.test.ts +388 -0
- package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +210 -0
- package/Tests/UI/Components/Workflow/StepTraceViewer.test.tsx +256 -0
- package/Tests/UI/Components/Workflow/UseRunWatch.test.tsx +665 -0
- package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
- package/Tests/UI/Components/Workflow/WorkflowIssuesModal.test.tsx +485 -0
- package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +478 -0
- package/Tests/UI/Components/Workflow/WorkflowStatusBar.test.tsx +379 -0
- package/Tests/UI/EsbuildConfig.test.ts +607 -0
- package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +11 -4
- package/Tests/UI/Utils/ModelAPICreateMiscData.test.ts +94 -0
- package/Tests/UI/Utils/Platform.test.ts +147 -0
- package/Tests/UI/Utils/ProjectInvitationDisplay.test.ts +357 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +198 -0
- package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +727 -0
- package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
- package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
- package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +698 -0
- package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
- package/Tests/__mocks__/bullmq.js +55 -0
- package/Types/AI/AIChatMessageStatus.ts +8 -1
- package/Types/AI/AIChatTypes.ts +12 -0
- package/Types/Database/AccessControl/OwnerOnlyColumn.ts +88 -0
- package/Types/Exception/ExceptionCode.ts +2 -0
- package/Types/Exception/ServiceUnavailableException.ts +8 -0
- package/Types/Exception/TooManyRequestsException.ts +8 -0
- package/Types/IP/IP.ts +93 -47
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +80 -3
- package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +55 -0
- package/Types/OnCallDutyPolicy/Layer.ts +203 -149
- package/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.ts +13 -0
- package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +155 -10
- package/Types/Permission.ts +193 -0
- package/Types/SerializableObjectDictionary.ts +133 -39
- package/Types/Telemetry/EntityRelationshipType.ts +1 -1
- package/Types/Telemetry/EntitySource.ts +40 -0
- package/Types/Telemetry/EntityType.ts +28 -1
- package/Types/Telemetry/EntityTypeGroups.ts +65 -0
- package/Types/Workflow/Component.ts +29 -0
- package/Types/Workflow/Components/API.ts +35 -0
- package/Types/Workflow/Components/BaseModel.ts +77 -27
- package/Types/Workflow/Components/Discord.ts +1 -0
- package/Types/Workflow/Components/Email.ts +12 -3
- package/Types/Workflow/Components/JavaScript.ts +7 -0
- package/Types/Workflow/Components/MicrosoftTeams.ts +3 -2
- package/Types/Workflow/Components/Slack.ts +1 -0
- package/Types/Workflow/Components/Telegram.ts +1 -0
- package/Types/Workflow/StepTrace.ts +181 -0
- package/Types/Workflow/TemplateSyntax.ts +543 -0
- package/Types/Workflow/Templates.ts +2368 -0
- package/UI/Components/Calendar/Calendar.css +43 -0
- package/UI/Components/Calendar/Calendar.tsx +8 -0
- package/UI/Components/Card/Card.tsx +2 -2
- package/UI/Components/Checkbox/Checkbox.tsx +16 -0
- package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
- package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
- package/UI/Components/Dictionary/Dictionary.tsx +71 -15
- package/UI/Components/FormModal/BasicFormModal.tsx +2 -1
- package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
- package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
- package/UI/Components/Forms/Types/Field.ts +7 -0
- package/UI/Components/Forms/Validation.ts +63 -1
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +53 -3
- package/UI/Components/Input/Input.tsx +32 -3
- package/UI/Components/KeyboardShortcut/KeyboardKey.ts +185 -0
- package/UI/Components/KeyboardShortcut/KeyboardShortcut.tsx +87 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +28 -0
- package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +31 -0
- package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +18 -18
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +363 -14
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +11 -0
- package/UI/Components/LogsViewer/components/LogsTable.tsx +155 -12
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +29 -0
- package/UI/Components/LogsViewer/types.ts +23 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +9 -2
- package/UI/Components/Modal/Modal.tsx +37 -4
- package/UI/Components/Navbar/NavBarMenuModal.tsx +15 -30
- package/UI/Components/ProjectInvitations/PendingProjectInvitations.tsx +442 -0
- package/UI/Components/SimpleLogViewer/SimpleLogViewer.tsx +23 -1
- package/UI/Components/Table/Table.tsx +49 -16
- package/UI/Components/Table/TableBody.tsx +53 -28
- package/UI/Components/Table/TableHeader.tsx +13 -0
- package/UI/Components/Table/TableRow.tsx +58 -26
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
- package/UI/Components/Workflow/ArgumentsForm.tsx +341 -8
- package/UI/Components/Workflow/Component.tsx +28 -26
- package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +26 -0
- package/UI/Components/Workflow/ComponentSettingsModal.tsx +79 -9
- package/UI/Components/Workflow/ComponentValuePickerModal.tsx +135 -7
- package/UI/Components/Workflow/ComponentsModal.tsx +116 -22
- package/UI/Components/Workflow/DocumentationViewer.tsx +59 -9
- package/UI/Components/Workflow/GraphLint.ts +628 -0
- package/UI/Components/Workflow/GraphLintSummary.ts +390 -0
- package/UI/Components/Workflow/ModelColumnEditor.tsx +528 -0
- package/UI/Components/Workflow/ModelSchema.ts +278 -0
- package/UI/Components/Workflow/RunForm.tsx +41 -7
- package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
- package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
- package/UI/Components/Workflow/UseRunWatch.ts +212 -0
- package/UI/Components/Workflow/Utils.ts +93 -1
- package/UI/Components/Workflow/VariableModal.tsx +6 -2
- package/UI/Components/Workflow/Workflow.tsx +126 -7
- package/UI/Components/Workflow/WorkflowIssuesModal.tsx +255 -0
- package/UI/Components/Workflow/WorkflowLogModal.tsx +128 -0
- package/UI/Components/Workflow/WorkflowStatusBar.tsx +224 -0
- package/UI/Types/LayeredDismissal.ts +31 -0
- package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
- package/UI/Utils/AIChatExport/ConversationMarkdown.ts +10 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +7 -1
- package/UI/Utils/Platform.ts +149 -0
- package/UI/Utils/ProjectInvitationDisplay.ts +118 -0
- package/UI/esbuild-config.js +22 -1
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +187 -0
- package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +917 -155
- package/Utils/Telemetry/CrossSignalScope.ts +502 -0
- package/Utils/Telemetry/EntityKey.ts +71 -5
- package/Utils/Telemetry/EntityRelationship.ts +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +1 -1
- package/build/dist/Models/DatabaseModels/AIConversation.js +32 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js +42 -0
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +28 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +29 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +12 -4
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/{TelemetryEntity.js → InventoryItem.js} +212 -29
- package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +454 -0
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -0
- package/build/dist/Models/DatabaseModels/{TelemetryEntityRelationship.js → InventoryItemRelationship.js} +52 -25
- package/build/dist/Models/DatabaseModels/InventoryItemRelationship.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +141 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +719 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +475 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js +446 -0
- package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js.map +1 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js +9 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +80 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +46 -2
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +48 -2
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js +424 -55
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +24 -2
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +51 -1
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +47 -2
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTelegram.js +65 -3
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebhook.js +56 -2
- package/build/dist/Models/DatabaseModels/UserWebhook.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +45 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
- package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +12 -0
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +237 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +165 -13
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallReadinessAPI.js +599 -0
- package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -0
- package/build/dist/Server/API/TeamComplianceAPI.js +68 -9
- package/build/dist/Server/API/TeamComplianceAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +129 -18
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +16 -1
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +45 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +4 -4
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js +39 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js +150 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js +57 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js +69 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js +32 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js +48 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +72 -13
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/PublicDashboardRateLimit.js +399 -0
- package/build/dist/Server/Middleware/PublicDashboardRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AIService.js +1 -0
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +24 -3
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +54 -0
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/DashboardService.js +10 -9
- package/build/dist/Server/Services/DashboardService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +24 -2
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +24 -3
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +67 -0
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +12 -4
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemCustomFieldService.js +9 -0
- package/build/dist/Server/Services/InventoryItemCustomFieldService.js.map +1 -0
- package/build/dist/Server/Services/{TelemetryEntityRelationshipService.js → InventoryItemRelationshipService.js} +9 -6
- package/build/dist/Server/Services/InventoryItemRelationshipService.js.map +1 -0
- package/build/dist/Server/Services/{TelemetryEntityService.js → InventoryItemService.js} +158 -23
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -0
- package/build/dist/Server/Services/LogAggregationService.js +27 -8
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +80 -0
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +6 -6
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js +9 -0
- package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceLinkService.js +71 -0
- package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceService.js +113 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +53 -13
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkTopologySuppressionService.js +85 -0
- package/build/dist/Server/Services/NetworkTopologySuppressionService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +48 -32
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +8 -0
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +51 -12
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +57 -13
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js +548 -0
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -0
- package/build/dist/Server/Services/OnCallReadinessService.js +1961 -0
- package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js +738 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -0
- package/build/dist/Server/Services/ProfileAggregationService.js +68 -4
- package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +11 -10
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceService.js +312 -160
- package/build/dist/Server/Services/TeamComplianceService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +24 -1
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +24 -1
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +858 -0
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +2830 -175
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserOnCallLogService.js +488 -43
- package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +26 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +10 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +24 -1
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserTelegramService.js +22 -1
- package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
- package/build/dist/Server/Services/UserWebhookService.js +25 -1
- package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +22 -1
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +12 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +126 -0
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js +254 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js.map +1 -0
- package/build/dist/Server/Types/Database/Permissions/QueryPermission.js +47 -2
- package/build/dist/Server/Types/Database/Permissions/QueryPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +7 -0
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js +28 -0
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +21 -5
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +14 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +31 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js +3 -9
- package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Email.js +15 -4
- package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/JavaScript.js +7 -2
- package/build/dist/Server/Types/Workflow/Components/JavaScript.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +514 -56
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +20 -3
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +19 -6
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +7 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +2 -2
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js +692 -0
- package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +148 -12
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +157 -10
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +37 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +259 -14
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js +235 -0
- package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +1000 -0
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js +356 -0
- package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +394 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js +465 -0
- package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js +280 -0
- package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +527 -0
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js +548 -0
- package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js.map +1 -0
- package/build/dist/Server/Utils/ClientIp.js +137 -0
- package/build/dist/Server/Utils/ClientIp.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +38 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +89 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +77 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -0
- package/build/dist/Server/Utils/Express.js +12 -12
- package/build/dist/Server/Utils/Express.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +70 -7
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +121 -11
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +82 -21
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +12 -4
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +165 -18
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +122 -47
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +7 -3
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIChatMessageStatus.js +8 -1
- package/build/dist/Types/AI/AIChatMessageStatus.js.map +1 -1
- package/build/dist/Types/AI/AIChatTypes.js +12 -0
- package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +60 -0
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -0
- package/build/dist/Types/Exception/ExceptionCode.js +2 -0
- package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
- package/build/dist/Types/Exception/ServiceUnavailableException.js +8 -0
- package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js +8 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -0
- package/build/dist/Types/IP/IP.js +87 -43
- package/build/dist/Types/IP/IP.js.map +1 -1
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +50 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +186 -123
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js +13 -0
- package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +105 -11
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
- package/build/dist/Types/Permission.js +174 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/SerializableObjectDictionary.js +133 -39
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityRelationshipType.js +1 -1
- package/build/dist/Types/Telemetry/EntitySource.js +39 -0
- package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +28 -1
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
- package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
- package/build/dist/Types/Workflow/Component.js +21 -0
- package/build/dist/Types/Workflow/Component.js.map +1 -1
- package/build/dist/Types/Workflow/Components/API.js +35 -0
- package/build/dist/Types/Workflow/Components/API.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +68 -26
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Discord.js +1 -0
- package/build/dist/Types/Workflow/Components/Discord.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Email.js +12 -3
- package/build/dist/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Types/Workflow/Components/JavaScript.js +7 -0
- package/build/dist/Types/Workflow/Components/JavaScript.js.map +1 -1
- package/build/dist/Types/Workflow/Components/MicrosoftTeams.js +3 -2
- package/build/dist/Types/Workflow/Components/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Slack.js +1 -0
- package/build/dist/Types/Workflow/Components/Slack.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Telegram.js +1 -0
- package/build/dist/Types/Workflow/Components/Telegram.js.map +1 -1
- package/build/dist/Types/Workflow/StepTrace.js +104 -0
- package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js +338 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
- package/build/dist/Types/Workflow/Templates.js +2111 -0
- package/build/dist/Types/Workflow/Templates.js.map +1 -0
- package/build/dist/UI/Components/Calendar/Calendar.js +1 -1
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
- package/build/dist/UI/Components/Dictionary/Dictionary.js +47 -17
- package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +44 -0
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +27 -4
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +13 -4
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js +163 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js.map +1 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js +47 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +4 -4
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +11 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +10 -8
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +227 -14
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +5 -0
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +69 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +8 -0
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +9 -2
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +31 -5
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +8 -21
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js +251 -0
- package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js.map +1 -0
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js +9 -2
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js.map +1 -1
- package/build/dist/UI/Components/Table/Table.js +27 -15
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +24 -18
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +9 -1
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +29 -21
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js +261 -14
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Component.js +20 -19
- package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +10 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +35 -7
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js +57 -7
- package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +53 -18
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/DocumentationViewer.js +19 -6
- package/build/dist/UI/Components/Workflow/DocumentationViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/GraphLint.js +425 -0
- package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
- package/build/dist/UI/Components/Workflow/GraphLintSummary.js +231 -0
- package/build/dist/UI/Components/Workflow/GraphLintSummary.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +320 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js +156 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
- package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
- package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
- package/build/dist/UI/Components/Workflow/UseRunWatch.js +123 -0
- package/build/dist/UI/Components/Workflow/UseRunWatch.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Utils.js +73 -1
- package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
- package/build/dist/UI/Components/Workflow/VariableModal.js +3 -2
- package/build/dist/UI/Components/Workflow/VariableModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +92 -7
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js +99 -0
- package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js.map +1 -0
- package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +56 -0
- package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -0
- package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js +92 -0
- package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js.map +1 -0
- package/build/dist/UI/Types/LayeredDismissal.js +21 -0
- package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +9 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/Platform.js +118 -0
- package/build/dist/UI/Utils/Platform.js.map +1 -0
- package/build/dist/UI/Utils/ProjectInvitationDisplay.js +106 -0
- package/build/dist/UI/Utils/ProjectInvitationDisplay.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +108 -0
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +661 -126
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +328 -0
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +57 -5
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityRelationship.js +1 -1
- package/jest.config.json +1 -0
- package/package.json +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +0 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +0 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +0 -1
- package/build/dist/Server/Services/TelemetryEntityService.js.map +0 -1
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
import { normalizeMac } from "./EndpointAttachmentUtil";
|
|
2
|
+
import { classifyDeviceRole, classifyEndpointRole, } from "./NetworkDeviceRoleUtil";
|
|
3
|
+
const MATCH_KEY_KINDS_STRONGEST_FIRST = [
|
|
4
|
+
"name",
|
|
5
|
+
"serial",
|
|
6
|
+
"mac",
|
|
7
|
+
"shortHost",
|
|
8
|
+
];
|
|
9
|
+
/*
|
|
10
|
+
* The kinds strong enough to say "these two reports describe one peer".
|
|
11
|
+
*
|
|
12
|
+
* shortHost is excluded on purpose: `sw01.site-a` and `sw01.site-b` share
|
|
13
|
+
* one, and merging those would invent a device nobody owns. Against a
|
|
14
|
+
* MANAGED device the same key is safe, because a key two devices both
|
|
15
|
+
* claim is dropped from the index entirely rather than guessed at.
|
|
16
|
+
*/
|
|
17
|
+
const PEER_IDENTITY_KINDS = new Set([
|
|
18
|
+
"name",
|
|
19
|
+
"serial",
|
|
20
|
+
"mac",
|
|
21
|
+
]);
|
|
22
|
+
/*
|
|
23
|
+
* Hoisted so the literal is not the object of a member expression, which
|
|
24
|
+
* `wrap-regex` and Prettier cannot agree on.
|
|
25
|
+
*/
|
|
26
|
+
const IPV4_PATTERN = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
|
2
27
|
// A device not seen within this window is treated as not currently up.
|
|
3
28
|
const FRESH_WINDOW_MS = 15 * 60 * 1000;
|
|
4
29
|
// Endpoint nodes rendered per graph; the slice is deterministic (by MAC).
|
|
@@ -6,9 +31,11 @@ const ENDPOINT_RENDER_CAP = 2000;
|
|
|
6
31
|
export default class NetworkTopologyUtil {
|
|
7
32
|
/*
|
|
8
33
|
* Builds the topology graph from every device in a project. Nodes are the
|
|
9
|
-
* devices; LLDP and CDP neighbors that match another device (by
|
|
10
|
-
*
|
|
11
|
-
*
|
|
34
|
+
* devices; LLDP and CDP neighbors that match another device (by name,
|
|
35
|
+
* serial, interface MAC or FQDN short form — see MatchKeyKind) become
|
|
36
|
+
* edges, and neighbors that match nothing become lightweight "unmanaged"
|
|
37
|
+
* nodes so links don't dead-end. Reports that share an identity-grade
|
|
38
|
+
* alias are one unmanaged node, however many switches saw it. Edges are
|
|
12
39
|
* undirected and deduplicated — a link reported from both ends, or by
|
|
13
40
|
* both protocols, appears once with the union of what each report knew
|
|
14
41
|
* (ports, protocols, per-end interface state). When `interfaces` rows are
|
|
@@ -18,15 +45,32 @@ export default class NetworkTopologyUtil {
|
|
|
18
45
|
* "endpoint" node linked by an "fdb" edge (capped, deterministic by MAC);
|
|
19
46
|
* the rest are dropped and counted in droppedEndpointCount.
|
|
20
47
|
*/
|
|
21
|
-
static buildTopology(devices, now, interfaces = [], endpoints = []) {
|
|
48
|
+
static buildTopology(devices, now, interfaces = [], endpoints = [], manualLinks = [], suppressedNodeKeys = new Set()) {
|
|
49
|
+
var _a;
|
|
22
50
|
const nodes = [];
|
|
23
|
-
|
|
51
|
+
/*
|
|
52
|
+
* Index managed devices by every identifier a neighbor entry could
|
|
53
|
+
* reference. A key TWO devices both claim is deleted rather than
|
|
54
|
+
* resolved: last-writer-wins would quietly draw the link to whichever
|
|
55
|
+
* device happened to be indexed second, and a wrong cable on a network
|
|
56
|
+
* map is worse than a missing one.
|
|
57
|
+
*/
|
|
24
58
|
const deviceByMatchKey = new Map();
|
|
59
|
+
const ambiguousMatchKeyIds = new Set();
|
|
25
60
|
for (const device of devices) {
|
|
26
61
|
for (const key of NetworkTopologyUtil.matchKeysForDevice(device)) {
|
|
27
|
-
|
|
62
|
+
const keyId = NetworkTopologyUtil.matchKeyId(key);
|
|
63
|
+
const existing = deviceByMatchKey.get(keyId);
|
|
64
|
+
if (existing && existing.id !== device.id) {
|
|
65
|
+
ambiguousMatchKeyIds.add(keyId);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
deviceByMatchKey.set(keyId, device);
|
|
28
69
|
}
|
|
29
70
|
}
|
|
71
|
+
for (const keyId of ambiguousMatchKeyIds) {
|
|
72
|
+
deviceByMatchKey.delete(keyId);
|
|
73
|
+
}
|
|
30
74
|
// Index interface rows by (device, index) and by (device, name).
|
|
31
75
|
const interfaceByDeviceAndIndex = new Map();
|
|
32
76
|
const interfaceByDeviceAndName = new Map();
|
|
@@ -37,12 +81,23 @@ export default class NetworkTopologyUtil {
|
|
|
37
81
|
interfaceByDeviceAndName.set(`${row.networkDeviceId}::${nameKey}`, row);
|
|
38
82
|
}
|
|
39
83
|
}
|
|
84
|
+
// Kept aside so the diagnostics pass below can read it back per node.
|
|
85
|
+
const isNeighborDiscoveryEnabledById = new Map();
|
|
40
86
|
for (const device of devices) {
|
|
87
|
+
isNeighborDiscoveryEnabledById.set(device.id, device.isNeighborDiscoveryEnabled);
|
|
41
88
|
nodes.push({
|
|
42
89
|
id: device.id,
|
|
43
90
|
name: device.name,
|
|
44
91
|
isManaged: true,
|
|
45
92
|
kind: "device",
|
|
93
|
+
role: classifyDeviceRole({
|
|
94
|
+
sysDescr: device.sysDescr,
|
|
95
|
+
sysObjectId: device.sysObjectId,
|
|
96
|
+
vendor: device.vendor,
|
|
97
|
+
deviceModel: device.deviceModel,
|
|
98
|
+
name: device.name,
|
|
99
|
+
sysName: device.sysName || device.hostname,
|
|
100
|
+
}),
|
|
46
101
|
status: NetworkTopologyUtil.deviceStatus(device, now),
|
|
47
102
|
interfacesUp: device.interfacesUp,
|
|
48
103
|
interfacesDown: device.interfacesDown,
|
|
@@ -51,128 +106,242 @@ export default class NetworkTopologyUtil {
|
|
|
51
106
|
deviceModel: device.deviceModel,
|
|
52
107
|
});
|
|
53
108
|
}
|
|
54
|
-
const unmanagedNodeById = new Map();
|
|
55
109
|
const edgeByKey = new Map();
|
|
110
|
+
/*
|
|
111
|
+
* Resolve every neighbor report before drawing anything.
|
|
112
|
+
*
|
|
113
|
+
* A managed match is decidable from one report, but the IDENTITY of an
|
|
114
|
+
* unmanaged peer is not: the switch at one end may know its neighbor's
|
|
115
|
+
* sysName while the switch at the other end knows only its chassis MAC,
|
|
116
|
+
* and only the whole set of reports says those two describe one box.
|
|
117
|
+
*/
|
|
118
|
+
const resolvedClaims = [];
|
|
56
119
|
for (const device of devices) {
|
|
57
120
|
for (const claim of NetworkTopologyUtil.neighborClaimsForDevice(device)) {
|
|
58
|
-
|
|
121
|
+
const candidates = NetworkTopologyUtil.candidateKeysForClaim(claim);
|
|
122
|
+
if (candidates.length === 0) {
|
|
59
123
|
continue;
|
|
60
124
|
}
|
|
61
|
-
|
|
62
|
-
let
|
|
125
|
+
// Candidates arrive strongest-first, so the first hit is the best one.
|
|
126
|
+
let matched = undefined;
|
|
127
|
+
for (const candidate of candidates) {
|
|
128
|
+
matched = deviceByMatchKey.get(NetworkTopologyUtil.matchKeyId(candidate));
|
|
129
|
+
if (matched) {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
63
133
|
if (matched) {
|
|
64
134
|
if (matched.id === device.id) {
|
|
65
135
|
// Self-referential neighbor entry; skip.
|
|
66
136
|
continue;
|
|
67
137
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (!existingUnmanaged) {
|
|
74
|
-
const unmanagedNode = {
|
|
75
|
-
id: toNodeId,
|
|
76
|
-
name: claim.displayName || "Unknown device",
|
|
77
|
-
isManaged: false,
|
|
78
|
-
kind: "unmanaged",
|
|
79
|
-
status: "unknown",
|
|
80
|
-
deviceModel: claim.remotePlatform,
|
|
81
|
-
};
|
|
82
|
-
unmanagedNodeById.set(toNodeId, unmanagedNode);
|
|
83
|
-
nodes.push(unmanagedNode);
|
|
84
|
-
}
|
|
85
|
-
else if (!existingUnmanaged.deviceModel && claim.remotePlatform) {
|
|
86
|
-
// A later CDP claim may know the platform the first one didn't.
|
|
87
|
-
existingUnmanaged.deviceModel = claim.remotePlatform;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
// The reporting device's own end, enriched from its interface row.
|
|
91
|
-
let localEndpoint = undefined;
|
|
92
|
-
let localPortLabel = undefined;
|
|
93
|
-
if (claim.localInterfaceIndex !== undefined) {
|
|
94
|
-
const localInterface = interfaceByDeviceAndIndex.get(`${device.id}::${claim.localInterfaceIndex}`);
|
|
95
|
-
localEndpoint = {
|
|
96
|
-
interfaceIndex: claim.localInterfaceIndex,
|
|
97
|
-
interfaceName: localInterface === null || localInterface === void 0 ? void 0 : localInterface.name,
|
|
98
|
-
isOperationallyUp: localInterface === null || localInterface === void 0 ? void 0 : localInterface.isOperationallyUp,
|
|
99
|
-
isAdministrativelyUp: localInterface === null || localInterface === void 0 ? void 0 : localInterface.isAdministrativelyUp,
|
|
100
|
-
utilizationPercent: localInterface === null || localInterface === void 0 ? void 0 : localInterface.utilizationPercent,
|
|
101
|
-
inRateMbps: localInterface === null || localInterface === void 0 ? void 0 : localInterface.inRateMbps,
|
|
102
|
-
outRateMbps: localInterface === null || localInterface === void 0 ? void 0 : localInterface.outRateMbps,
|
|
103
|
-
errorsPerSecond: localInterface === null || localInterface === void 0 ? void 0 : localInterface.errorsPerSecond,
|
|
104
|
-
};
|
|
105
|
-
localPortLabel =
|
|
106
|
-
(localInterface === null || localInterface === void 0 ? void 0 : localInterface.name) || `if${claim.localInterfaceIndex}`;
|
|
107
|
-
}
|
|
108
|
-
/*
|
|
109
|
-
* The far end: best-effort — the advertised remote port id often
|
|
110
|
-
* matches the remote device's interface name (e.g. "GigabitEthernet
|
|
111
|
-
* 0/1"). Only attach data when it does; a bare port id string stays
|
|
112
|
-
* in toPort.
|
|
113
|
-
*/
|
|
114
|
-
let remoteEndpoint = undefined;
|
|
115
|
-
if (matched && claim.remotePortId) {
|
|
116
|
-
const remotePortKey = NetworkTopologyUtil.normalizeKey(claim.remotePortId);
|
|
117
|
-
const remoteInterface = remotePortKey
|
|
118
|
-
? interfaceByDeviceAndName.get(`${matched.id}::${remotePortKey}`)
|
|
119
|
-
: undefined;
|
|
120
|
-
if (remoteInterface) {
|
|
121
|
-
remoteEndpoint = {
|
|
122
|
-
interfaceIndex: remoteInterface.interfaceIndex,
|
|
123
|
-
interfaceName: remoteInterface.name,
|
|
124
|
-
isOperationallyUp: remoteInterface.isOperationallyUp,
|
|
125
|
-
isAdministrativelyUp: remoteInterface.isAdministrativelyUp,
|
|
126
|
-
utilizationPercent: remoteInterface.utilizationPercent,
|
|
127
|
-
inRateMbps: remoteInterface.inRateMbps,
|
|
128
|
-
outRateMbps: remoteInterface.outRateMbps,
|
|
129
|
-
errorsPerSecond: remoteInterface.errorsPerSecond,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
// Undirected dedupe: canonicalize the endpoint pair.
|
|
134
|
-
const edgeKey = [device.id, toNodeId].sort().join("::");
|
|
135
|
-
const existing = edgeByKey.get(edgeKey);
|
|
136
|
-
if (!existing) {
|
|
137
|
-
edgeByKey.set(edgeKey, {
|
|
138
|
-
fromNodeId: device.id,
|
|
139
|
-
toNodeId: toNodeId,
|
|
140
|
-
fromPort: localPortLabel,
|
|
141
|
-
toPort: claim.remotePortId,
|
|
142
|
-
protocols: [claim.protocol],
|
|
143
|
-
fromInterface: localEndpoint,
|
|
144
|
-
toInterface: remoteEndpoint,
|
|
138
|
+
resolvedClaims.push({
|
|
139
|
+
device: device,
|
|
140
|
+
claim: claim,
|
|
141
|
+
matchedDeviceId: matched.id,
|
|
142
|
+
peerAliases: [],
|
|
145
143
|
});
|
|
146
144
|
continue;
|
|
147
145
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
146
|
+
resolvedClaims.push({
|
|
147
|
+
device: device,
|
|
148
|
+
claim: claim,
|
|
149
|
+
matchedDeviceId: undefined,
|
|
150
|
+
peerAliases: candidates.filter((candidate) => {
|
|
151
|
+
return PEER_IDENTITY_KINDS.has(candidate.kind);
|
|
152
|
+
}),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const peerNodeIdByClaim = NetworkTopologyUtil.buildUnmanagedPeerNodes(resolvedClaims, nodes);
|
|
157
|
+
for (const resolved of resolvedClaims) {
|
|
158
|
+
const device = resolved.device;
|
|
159
|
+
const claim = resolved.claim;
|
|
160
|
+
const matchedId = resolved.matchedDeviceId;
|
|
161
|
+
const toNodeId = matchedId || peerNodeIdByClaim.get(resolved);
|
|
162
|
+
if (!toNodeId) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
// The reporting device's own end, enriched from its interface row.
|
|
166
|
+
let localEndpoint = undefined;
|
|
167
|
+
let localPortLabel = undefined;
|
|
168
|
+
if (claim.localInterfaceIndex !== undefined) {
|
|
169
|
+
const localInterface = interfaceByDeviceAndIndex.get(`${device.id}::${claim.localInterfaceIndex}`);
|
|
170
|
+
localEndpoint = {
|
|
171
|
+
interfaceIndex: claim.localInterfaceIndex,
|
|
172
|
+
interfaceName: localInterface === null || localInterface === void 0 ? void 0 : localInterface.name,
|
|
173
|
+
isOperationallyUp: localInterface === null || localInterface === void 0 ? void 0 : localInterface.isOperationallyUp,
|
|
174
|
+
isAdministrativelyUp: localInterface === null || localInterface === void 0 ? void 0 : localInterface.isAdministrativelyUp,
|
|
175
|
+
utilizationPercent: localInterface === null || localInterface === void 0 ? void 0 : localInterface.utilizationPercent,
|
|
176
|
+
inRateMbps: localInterface === null || localInterface === void 0 ? void 0 : localInterface.inRateMbps,
|
|
177
|
+
outRateMbps: localInterface === null || localInterface === void 0 ? void 0 : localInterface.outRateMbps,
|
|
178
|
+
errorsPerSecond: localInterface === null || localInterface === void 0 ? void 0 : localInterface.errorsPerSecond,
|
|
179
|
+
};
|
|
180
|
+
localPortLabel =
|
|
181
|
+
(localInterface === null || localInterface === void 0 ? void 0 : localInterface.name) || `if${claim.localInterfaceIndex}`;
|
|
182
|
+
}
|
|
183
|
+
/*
|
|
184
|
+
* The far end: best-effort — the advertised remote port id often
|
|
185
|
+
* matches the remote device's interface name (e.g. "GigabitEthernet
|
|
186
|
+
* 0/1"). Only attach data when it does; a bare port id string stays
|
|
187
|
+
* in toPort.
|
|
188
|
+
*/
|
|
189
|
+
let remoteEndpoint = undefined;
|
|
190
|
+
if (matchedId && claim.remotePortId) {
|
|
191
|
+
const remotePortKey = NetworkTopologyUtil.normalizeKey(claim.remotePortId);
|
|
192
|
+
const remoteInterface = remotePortKey
|
|
193
|
+
? interfaceByDeviceAndName.get(`${matchedId}::${remotePortKey}`)
|
|
194
|
+
: undefined;
|
|
195
|
+
if (remoteInterface) {
|
|
196
|
+
remoteEndpoint = {
|
|
197
|
+
interfaceIndex: remoteInterface.interfaceIndex,
|
|
198
|
+
interfaceName: remoteInterface.name,
|
|
199
|
+
isOperationallyUp: remoteInterface.isOperationallyUp,
|
|
200
|
+
isAdministrativelyUp: remoteInterface.isAdministrativelyUp,
|
|
201
|
+
utilizationPercent: remoteInterface.utilizationPercent,
|
|
202
|
+
inRateMbps: remoteInterface.inRateMbps,
|
|
203
|
+
outRateMbps: remoteInterface.outRateMbps,
|
|
204
|
+
errorsPerSecond: remoteInterface.errorsPerSecond,
|
|
205
|
+
};
|
|
168
206
|
}
|
|
169
207
|
}
|
|
208
|
+
// Undirected dedupe: canonicalize the endpoint pair.
|
|
209
|
+
const edgeKey = [device.id, toNodeId].sort().join("::");
|
|
210
|
+
const existing = edgeByKey.get(edgeKey);
|
|
211
|
+
if (!existing) {
|
|
212
|
+
edgeByKey.set(edgeKey, {
|
|
213
|
+
fromNodeId: device.id,
|
|
214
|
+
toNodeId: toNodeId,
|
|
215
|
+
fromPort: localPortLabel,
|
|
216
|
+
toPort: claim.remotePortId,
|
|
217
|
+
protocols: [claim.protocol],
|
|
218
|
+
fromInterface: localEndpoint,
|
|
219
|
+
toInterface: remoteEndpoint,
|
|
220
|
+
});
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
/*
|
|
224
|
+
* Same link reported again — from the other end, or by the other
|
|
225
|
+
* protocol. Merge instead of dropping so both ends keep the best
|
|
226
|
+
* data anyone reported about them.
|
|
227
|
+
*/
|
|
228
|
+
if (existing.protocols && !existing.protocols.includes(claim.protocol)) {
|
|
229
|
+
existing.protocols.push(claim.protocol);
|
|
230
|
+
}
|
|
231
|
+
if (existing.fromNodeId === device.id) {
|
|
232
|
+
existing.fromPort = existing.fromPort || localPortLabel;
|
|
233
|
+
existing.toPort = existing.toPort || claim.remotePortId;
|
|
234
|
+
existing.fromInterface = NetworkTopologyUtil.mergeEndpoints(existing.fromInterface, localEndpoint);
|
|
235
|
+
existing.toInterface = NetworkTopologyUtil.mergeEndpoints(existing.toInterface, remoteEndpoint);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
existing.toPort = existing.toPort || localPortLabel;
|
|
239
|
+
existing.fromPort = existing.fromPort || claim.remotePortId;
|
|
240
|
+
existing.toInterface = NetworkTopologyUtil.mergeEndpoints(existing.toInterface, localEndpoint);
|
|
241
|
+
existing.fromInterface = NetworkTopologyUtil.mergeEndpoints(existing.fromInterface, remoteEndpoint);
|
|
242
|
+
}
|
|
170
243
|
}
|
|
171
|
-
const edges = Array.from(edgeByKey.values());
|
|
172
|
-
// --- Endpoint nodes + fdb edges ---
|
|
173
244
|
const deviceNodeIds = new Set(devices.map((device) => {
|
|
174
245
|
return device.id;
|
|
175
246
|
}));
|
|
247
|
+
/*
|
|
248
|
+
* --- Operator-declared links ---
|
|
249
|
+
*
|
|
250
|
+
* Merged into the SAME edge map the discovery protocols write to, so a
|
|
251
|
+
* cable somebody drew by hand and the same cable LLDP later reports are
|
|
252
|
+
* one line carrying both protocols — not two lines between one pair of
|
|
253
|
+
* boxes, which is exactly the duplicate an operator would read as a
|
|
254
|
+
* second physical link.
|
|
255
|
+
*
|
|
256
|
+
* Ends outside this graph are skipped rather than drawn: a link to a
|
|
257
|
+
* device in another site (or one since archived) has nothing to attach
|
|
258
|
+
* to here.
|
|
259
|
+
*/
|
|
260
|
+
for (const link of manualLinks) {
|
|
261
|
+
if (!deviceNodeIds.has(link.fromDeviceId) ||
|
|
262
|
+
!deviceNodeIds.has(link.toDeviceId) ||
|
|
263
|
+
link.fromDeviceId === link.toDeviceId) {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
const edgeKey = [link.fromDeviceId, link.toDeviceId]
|
|
267
|
+
.sort()
|
|
268
|
+
.join("::");
|
|
269
|
+
const existing = edgeByKey.get(edgeKey);
|
|
270
|
+
if (!existing) {
|
|
271
|
+
edgeByKey.set(edgeKey, {
|
|
272
|
+
fromNodeId: link.fromDeviceId,
|
|
273
|
+
toNodeId: link.toDeviceId,
|
|
274
|
+
fromPort: link.fromPortName,
|
|
275
|
+
toPort: link.toPortName,
|
|
276
|
+
protocols: ["manual"],
|
|
277
|
+
monitorState: link.monitorStatus,
|
|
278
|
+
name: link.name,
|
|
279
|
+
});
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (existing.protocols && !existing.protocols.includes("manual")) {
|
|
283
|
+
existing.protocols.push("manual");
|
|
284
|
+
}
|
|
285
|
+
/*
|
|
286
|
+
* Discovered data wins on the shared fields — it is measured, and the
|
|
287
|
+
* hand-typed port is a best recollection. The operator's name and the
|
|
288
|
+
* monitor's verdict have no discovered counterpart, so they always
|
|
289
|
+
* apply.
|
|
290
|
+
*/
|
|
291
|
+
if (existing.fromNodeId === link.fromDeviceId) {
|
|
292
|
+
existing.fromPort = existing.fromPort || link.fromPortName;
|
|
293
|
+
existing.toPort = existing.toPort || link.toPortName;
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
existing.toPort = existing.toPort || link.fromPortName;
|
|
297
|
+
existing.fromPort = existing.fromPort || link.toPortName;
|
|
298
|
+
}
|
|
299
|
+
existing.name = existing.name || link.name;
|
|
300
|
+
existing.monitorState = (_a = existing.monitorState) !== null && _a !== void 0 ? _a : link.monitorStatus;
|
|
301
|
+
}
|
|
302
|
+
const edges = Array.from(edgeByKey.values());
|
|
303
|
+
/*
|
|
304
|
+
* --- Why a device has no links ---
|
|
305
|
+
*
|
|
306
|
+
* Attached to every managed node, so the detail panel can answer "the
|
|
307
|
+
* router is not linked to anything" with a cause instead of a shrug.
|
|
308
|
+
* Built from the claims that were just resolved: the unmatched ones are
|
|
309
|
+
* the actionable evidence — a renamed peer, a device nobody has added
|
|
310
|
+
* yet — and they are otherwise thrown away here.
|
|
311
|
+
*/
|
|
312
|
+
const reportedNeighborCountByDeviceId = new Map();
|
|
313
|
+
const unmatchedIdentifiersByDeviceId = new Map();
|
|
314
|
+
for (const resolved of resolvedClaims) {
|
|
315
|
+
const deviceId = resolved.device.id;
|
|
316
|
+
reportedNeighborCountByDeviceId.set(deviceId, (reportedNeighborCountByDeviceId.get(deviceId) || 0) + 1);
|
|
317
|
+
if (resolved.matchedDeviceId) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
const identifier = resolved.claim.displayName || resolved.claim.identifiers[0];
|
|
321
|
+
if (!identifier) {
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
const bucket = unmatchedIdentifiersByDeviceId.get(deviceId);
|
|
325
|
+
if (bucket) {
|
|
326
|
+
if (!bucket.includes(identifier)) {
|
|
327
|
+
bucket.push(identifier);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
unmatchedIdentifiersByDeviceId.set(deviceId, [identifier]);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
for (const node of nodes) {
|
|
335
|
+
if (node.kind !== "device") {
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
node.diagnostics = {
|
|
339
|
+
isNeighborDiscoveryEnabled: isNeighborDiscoveryEnabledById.get(node.id),
|
|
340
|
+
reportedNeighborCount: reportedNeighborCountByDeviceId.get(node.id) || 0,
|
|
341
|
+
unmatchedNeighborIdentifiers: unmatchedIdentifiersByDeviceId.get(node.id) || [],
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
// --- Endpoint nodes + fdb edges ---
|
|
176
345
|
/*
|
|
177
346
|
* Deterministic render order: by normalized MAC, then id, so the capped
|
|
178
347
|
* slice is stable across rebuilds regardless of query order.
|
|
@@ -201,14 +370,20 @@ export default class NetworkTopologyUtil {
|
|
|
201
370
|
}
|
|
202
371
|
renderedEndpointCount++;
|
|
203
372
|
const nodeId = `endpoint:${endpoint.id}`;
|
|
373
|
+
const endpointName = endpoint.classification ||
|
|
374
|
+
endpoint.vendor ||
|
|
375
|
+
endpoint.ipAddress ||
|
|
376
|
+
endpoint.macAddress;
|
|
204
377
|
nodes.push({
|
|
205
378
|
id: nodeId,
|
|
206
|
-
name:
|
|
207
|
-
endpoint.vendor ||
|
|
208
|
-
endpoint.ipAddress ||
|
|
209
|
-
endpoint.macAddress,
|
|
379
|
+
name: endpointName,
|
|
210
380
|
isManaged: false,
|
|
211
381
|
kind: "endpoint",
|
|
382
|
+
role: classifyEndpointRole({
|
|
383
|
+
classification: endpoint.classification,
|
|
384
|
+
vendor: endpoint.vendor,
|
|
385
|
+
name: endpointName,
|
|
386
|
+
}),
|
|
212
387
|
status: NetworkTopologyUtil.statusFromLastSeen(endpoint.lastSeenAt, now),
|
|
213
388
|
vendor: endpoint.vendor,
|
|
214
389
|
macAddress: endpoint.macAddress,
|
|
@@ -244,11 +419,39 @@ export default class NetworkTopologyUtil {
|
|
|
244
419
|
: undefined,
|
|
245
420
|
});
|
|
246
421
|
}
|
|
422
|
+
/*
|
|
423
|
+
* --- Hidden nodes ---
|
|
424
|
+
*
|
|
425
|
+
* Applied last, on the finished graph, so a suppressed node cannot
|
|
426
|
+
* change how anything else resolved. Hiding a switch must not silently
|
|
427
|
+
* re-route its neighbours' links or turn its peers into strangers — it
|
|
428
|
+
* takes the box off the map and nothing more. Its edges go with it,
|
|
429
|
+
* because a line to a node that is not drawn is a line into empty space.
|
|
430
|
+
*/
|
|
431
|
+
if (suppressedNodeKeys.size === 0) {
|
|
432
|
+
return {
|
|
433
|
+
nodes,
|
|
434
|
+
edges,
|
|
435
|
+
droppedEndpointCount,
|
|
436
|
+
endpointsTruncated,
|
|
437
|
+
suppressedNodeCount: 0,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
const visibleNodes = nodes.filter((node) => {
|
|
441
|
+
return !suppressedNodeKeys.has(node.id);
|
|
442
|
+
});
|
|
443
|
+
const visibleNodeIds = new Set(visibleNodes.map((node) => {
|
|
444
|
+
return node.id;
|
|
445
|
+
}));
|
|
247
446
|
return {
|
|
248
|
-
nodes,
|
|
249
|
-
edges
|
|
447
|
+
nodes: visibleNodes,
|
|
448
|
+
edges: edges.filter((edge) => {
|
|
449
|
+
return (visibleNodeIds.has(edge.fromNodeId) &&
|
|
450
|
+
visibleNodeIds.has(edge.toNodeId));
|
|
451
|
+
}),
|
|
250
452
|
droppedEndpointCount,
|
|
251
453
|
endpointsTruncated,
|
|
454
|
+
suppressedNodeCount: nodes.length - visibleNodes.length,
|
|
252
455
|
};
|
|
253
456
|
}
|
|
254
457
|
/*
|
|
@@ -259,11 +462,25 @@ export default class NetworkTopologyUtil {
|
|
|
259
462
|
static neighborClaimsForDevice(device) {
|
|
260
463
|
const claims = [];
|
|
261
464
|
for (const neighbor of device.lldpNeighbors || []) {
|
|
465
|
+
/*
|
|
466
|
+
* Both identifiers are carried, not just the first non-empty one.
|
|
467
|
+
* The chassis id used to be a fallback that only applied when the
|
|
468
|
+
* peer advertised no sysName; it is in fact an identifier in its own
|
|
469
|
+
* right — a MAC or a serial — and the device it names is very often
|
|
470
|
+
* one we already manage.
|
|
471
|
+
*/
|
|
472
|
+
const identifiers = [];
|
|
473
|
+
if (neighbor.remoteSysName) {
|
|
474
|
+
identifiers.push(neighbor.remoteSysName);
|
|
475
|
+
}
|
|
476
|
+
if (neighbor.remoteChassisId) {
|
|
477
|
+
identifiers.push(neighbor.remoteChassisId);
|
|
478
|
+
}
|
|
262
479
|
claims.push({
|
|
263
480
|
protocol: "lldp",
|
|
264
|
-
|
|
265
|
-
NetworkTopologyUtil.normalizeKey(neighbor.remoteChassisId),
|
|
481
|
+
identifiers: identifiers,
|
|
266
482
|
displayName: neighbor.remoteSysName || neighbor.remoteChassisId,
|
|
483
|
+
hasAdvertisedName: Boolean(neighbor.remoteSysName),
|
|
267
484
|
localInterfaceIndex: neighbor.localInterfaceIndex,
|
|
268
485
|
remotePortId: neighbor.remotePortId,
|
|
269
486
|
remotePlatform: undefined,
|
|
@@ -272,8 +489,9 @@ export default class NetworkTopologyUtil {
|
|
|
272
489
|
for (const neighbor of device.cdpNeighbors || []) {
|
|
273
490
|
claims.push({
|
|
274
491
|
protocol: "cdp",
|
|
275
|
-
|
|
492
|
+
identifiers: neighbor.remoteDeviceId ? [neighbor.remoteDeviceId] : [],
|
|
276
493
|
displayName: neighbor.remoteDeviceId,
|
|
494
|
+
hasAdvertisedName: Boolean(neighbor.remoteDeviceId),
|
|
277
495
|
localInterfaceIndex: neighbor.localInterfaceIndex,
|
|
278
496
|
remotePortId: neighbor.remotePortId,
|
|
279
497
|
remotePlatform: neighbor.remotePlatform,
|
|
@@ -281,6 +499,84 @@ export default class NetworkTopologyUtil {
|
|
|
281
499
|
}
|
|
282
500
|
return claims;
|
|
283
501
|
}
|
|
502
|
+
/*
|
|
503
|
+
* Every key a claim could be resolved by, strongest kind first and, within
|
|
504
|
+
* a kind, strongest SOURCE first (an advertised sysName ahead of a chassis
|
|
505
|
+
* id). Sorting by kind before source is deliberate: a MAC read off a
|
|
506
|
+
* chassis id identifies a box far more precisely than the first label of
|
|
507
|
+
* somebody's FQDN, whichever field it arrived in.
|
|
508
|
+
*/
|
|
509
|
+
static candidateKeysForClaim(claim) {
|
|
510
|
+
const byKind = new Map();
|
|
511
|
+
const seen = new Set();
|
|
512
|
+
for (const identifier of claim.identifiers) {
|
|
513
|
+
for (const key of NetworkTopologyUtil.candidateKeysForIdentifier(identifier)) {
|
|
514
|
+
const keyId = NetworkTopologyUtil.matchKeyId(key);
|
|
515
|
+
if (seen.has(keyId)) {
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
seen.add(keyId);
|
|
519
|
+
const bucket = byKind.get(key.kind);
|
|
520
|
+
if (bucket) {
|
|
521
|
+
bucket.push(key);
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
byKind.set(key.kind, [key]);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
const ordered = [];
|
|
529
|
+
for (const kind of MATCH_KEY_KINDS_STRONGEST_FIRST) {
|
|
530
|
+
ordered.push(...(byKind.get(kind) || []));
|
|
531
|
+
}
|
|
532
|
+
return ordered;
|
|
533
|
+
}
|
|
534
|
+
/*
|
|
535
|
+
* One identifier string, offered as every kind it could be.
|
|
536
|
+
*
|
|
537
|
+
* A chassis id is just bytes on the wire — nothing in the protocol says
|
|
538
|
+
* whether it is a name, a serial or a MAC — so it is offered as all of
|
|
539
|
+
* them, and only a key some device actually published can match.
|
|
540
|
+
*/
|
|
541
|
+
static candidateKeysForIdentifier(raw) {
|
|
542
|
+
const normalized = NetworkTopologyUtil.normalizeKey(raw);
|
|
543
|
+
if (!normalized) {
|
|
544
|
+
return [];
|
|
545
|
+
}
|
|
546
|
+
const keys = [
|
|
547
|
+
{ kind: "name", value: normalized },
|
|
548
|
+
{ kind: "serial", value: normalized },
|
|
549
|
+
];
|
|
550
|
+
const mac = normalizeMac(normalized);
|
|
551
|
+
if (mac) {
|
|
552
|
+
keys.push({ kind: "mac", value: mac });
|
|
553
|
+
}
|
|
554
|
+
const shortHost = NetworkTopologyUtil.shortHostKey(normalized);
|
|
555
|
+
if (shortHost) {
|
|
556
|
+
keys.push({ kind: "shortHost", value: shortHost });
|
|
557
|
+
}
|
|
558
|
+
return keys;
|
|
559
|
+
}
|
|
560
|
+
/*
|
|
561
|
+
* The first label of a hostname, or undefined when taking one would be
|
|
562
|
+
* nonsense. An IPv4 literal would shorten to "10" and a MAC to its first
|
|
563
|
+
* octet pair — both of which would collide half the estate into one node,
|
|
564
|
+
* so both are refused outright.
|
|
565
|
+
*/
|
|
566
|
+
static shortHostKey(normalized) {
|
|
567
|
+
if (IPV4_PATTERN.test(normalized) || normalizeMac(normalized)) {
|
|
568
|
+
return undefined;
|
|
569
|
+
}
|
|
570
|
+
const firstLabel = normalized.split(".")[0] || "";
|
|
571
|
+
return firstLabel.length > 0 ? firstLabel : undefined;
|
|
572
|
+
}
|
|
573
|
+
static matchKeyId(key) {
|
|
574
|
+
/*
|
|
575
|
+
* A NUL separator, because every kind shares one namespace and a
|
|
576
|
+
* hostname may legitimately contain a colon-ish character.
|
|
577
|
+
*/
|
|
578
|
+
return `${key.kind}\u0000${key.value}`;
|
|
579
|
+
}
|
|
284
580
|
// Existing fields win; the incoming report only fills what's missing.
|
|
285
581
|
static mergeEndpoints(existing, incoming) {
|
|
286
582
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -301,21 +597,251 @@ export default class NetworkTopologyUtil {
|
|
|
301
597
|
errorsPerSecond: (_h = existing.errorsPerSecond) !== null && _h !== void 0 ? _h : incoming.errorsPerSecond,
|
|
302
598
|
};
|
|
303
599
|
}
|
|
600
|
+
/*
|
|
601
|
+
* Every key this device answers to.
|
|
602
|
+
*
|
|
603
|
+
* Unlike a claim's candidates, these are NOT speculative: we know which
|
|
604
|
+
* column each value came from, so a serial is only ever registered as a
|
|
605
|
+
* serial. That asymmetry is the whole point — a claim may offer its
|
|
606
|
+
* chassis id as a name, a serial and a MAC, but only the kind a device
|
|
607
|
+
* actually published can be the one that matches.
|
|
608
|
+
*/
|
|
304
609
|
static matchKeysForDevice(device) {
|
|
305
|
-
/*
|
|
306
|
-
* sysName / hostname / name — the identifiers LLDP remoteSysName and
|
|
307
|
-
* CDP remoteDeviceId advertise. Order matters only across devices
|
|
308
|
-
* (last writer wins on a collision), not within one device.
|
|
309
|
-
*/
|
|
310
610
|
const keys = [];
|
|
611
|
+
const seen = new Set();
|
|
612
|
+
const add = (key) => {
|
|
613
|
+
const keyId = NetworkTopologyUtil.matchKeyId(key);
|
|
614
|
+
if (seen.has(keyId)) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
seen.add(keyId);
|
|
618
|
+
keys.push(key);
|
|
619
|
+
};
|
|
620
|
+
// sysName / hostname / name — what both protocols advertise.
|
|
311
621
|
for (const candidate of [device.sysName, device.hostname, device.name]) {
|
|
312
|
-
const
|
|
313
|
-
if (
|
|
314
|
-
|
|
622
|
+
const normalized = NetworkTopologyUtil.normalizeKey(candidate);
|
|
623
|
+
if (!normalized) {
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
add({ kind: "name", value: normalized });
|
|
627
|
+
/*
|
|
628
|
+
* The short form is registered for EVERY name, dotted or not, so the
|
|
629
|
+
* two halves of the comparison meet: an FQDN on the wire has to be
|
|
630
|
+
* able to find a bare sysName here, and a bare name on the wire has
|
|
631
|
+
* to be able to find an FQDN.
|
|
632
|
+
*/
|
|
633
|
+
const shortHost = NetworkTopologyUtil.shortHostKey(normalized);
|
|
634
|
+
if (shortHost) {
|
|
635
|
+
add({ kind: "shortHost", value: shortHost });
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
const serial = NetworkTopologyUtil.normalizeKey(device.serialNumber);
|
|
639
|
+
if (serial) {
|
|
640
|
+
add({ kind: "serial", value: serial });
|
|
641
|
+
}
|
|
642
|
+
for (const rawMac of device.macAddresses || []) {
|
|
643
|
+
const mac = normalizeMac(rawMac);
|
|
644
|
+
if (mac) {
|
|
645
|
+
add({ kind: "mac", value: mac });
|
|
315
646
|
}
|
|
316
647
|
}
|
|
317
648
|
return keys;
|
|
318
649
|
}
|
|
650
|
+
/*
|
|
651
|
+
* Turns the unmatched claims into unmanaged peer NODES, one per box.
|
|
652
|
+
*
|
|
653
|
+
* Reports are merged when they share any identity-grade alias, so the
|
|
654
|
+
* neighbor one switch knows as "ap-lobby" and another knows only by its
|
|
655
|
+
* chassis MAC lands on a single node instead of the two strangers the map
|
|
656
|
+
* used to draw. Appends the nodes it mints to `nodes` and returns the node
|
|
657
|
+
* id each claim should draw its edge to.
|
|
658
|
+
*/
|
|
659
|
+
static buildUnmanagedPeerNodes(resolvedClaims, nodes) {
|
|
660
|
+
const unmanagedClaims = resolvedClaims.filter((resolved) => {
|
|
661
|
+
return !resolved.matchedDeviceId && resolved.peerAliases.length > 0;
|
|
662
|
+
});
|
|
663
|
+
const rootByAliasId = NetworkTopologyUtil.groupPeerAliases(unmanagedClaims);
|
|
664
|
+
// Claims per peer, in first-encounter order so the output is stable.
|
|
665
|
+
const claimsByRoot = new Map();
|
|
666
|
+
for (const resolved of unmanagedClaims) {
|
|
667
|
+
const root = rootByAliasId.get(NetworkTopologyUtil.matchKeyId(resolved.peerAliases[0]));
|
|
668
|
+
if (!root) {
|
|
669
|
+
continue;
|
|
670
|
+
}
|
|
671
|
+
const bucket = claimsByRoot.get(root);
|
|
672
|
+
if (bucket) {
|
|
673
|
+
bucket.push(resolved);
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
claimsByRoot.set(root, [resolved]);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
const nodeIdByClaim = new Map();
|
|
680
|
+
const usedNodeIds = new Set();
|
|
681
|
+
for (const groupClaims of claimsByRoot.values()) {
|
|
682
|
+
/*
|
|
683
|
+
* The nicest label anyone reported: a name the peer advertises about
|
|
684
|
+
* itself beats a bare chassis id, whichever report arrived first.
|
|
685
|
+
*/
|
|
686
|
+
let displayName = undefined;
|
|
687
|
+
let platform = undefined;
|
|
688
|
+
for (const resolved of groupClaims) {
|
|
689
|
+
if (!displayName && resolved.claim.hasAdvertisedName) {
|
|
690
|
+
displayName = resolved.claim.displayName;
|
|
691
|
+
}
|
|
692
|
+
if (!platform && resolved.claim.remotePlatform) {
|
|
693
|
+
platform = resolved.claim.remotePlatform;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
if (!displayName) {
|
|
697
|
+
for (const resolved of groupClaims) {
|
|
698
|
+
if (resolved.claim.displayName) {
|
|
699
|
+
displayName = resolved.claim.displayName;
|
|
700
|
+
break;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
/*
|
|
705
|
+
* The id keeps its historic `unmanaged:<value>` shape — it is the key
|
|
706
|
+
* saved arrangements are stored under, so changing it would scatter
|
|
707
|
+
* every pinned peer on the map. It is named after the label wherever
|
|
708
|
+
* that label is one of the peer's own aliases, so merging a report
|
|
709
|
+
* that knew a sysName with one that knew only a chassis MAC still
|
|
710
|
+
* produces `unmanaged:ap-lobby` rather than an id made of hex.
|
|
711
|
+
*/
|
|
712
|
+
const nodeId = NetworkTopologyUtil.uniqueNodeId(`unmanaged:${NetworkTopologyUtil.canonicalPeerValue(groupClaims, displayName)}`, usedNodeIds);
|
|
713
|
+
usedNodeIds.add(nodeId);
|
|
714
|
+
const unmanagedName = displayName || "Unknown device";
|
|
715
|
+
nodes.push({
|
|
716
|
+
id: nodeId,
|
|
717
|
+
name: unmanagedName,
|
|
718
|
+
isManaged: false,
|
|
719
|
+
kind: "unmanaged",
|
|
720
|
+
/*
|
|
721
|
+
* Classified from the whole group rather than from whichever
|
|
722
|
+
* report happened to be first: the platform string is usually the
|
|
723
|
+
* only real evidence about a peer, and it may well arrive on the
|
|
724
|
+
* second report of it.
|
|
725
|
+
*/
|
|
726
|
+
role: classifyDeviceRole({
|
|
727
|
+
platform: platform,
|
|
728
|
+
name: unmanagedName,
|
|
729
|
+
}),
|
|
730
|
+
status: "unknown",
|
|
731
|
+
deviceModel: platform,
|
|
732
|
+
});
|
|
733
|
+
for (const resolved of groupClaims) {
|
|
734
|
+
nodeIdByClaim.set(resolved, nodeId);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
return nodeIdByClaim;
|
|
738
|
+
}
|
|
739
|
+
/*
|
|
740
|
+
* The alias a merged peer is named after.
|
|
741
|
+
*
|
|
742
|
+
* The chosen label wins whenever it is genuinely one of the peer's own
|
|
743
|
+
* aliases; otherwise the strongest kind present decides, and within it
|
|
744
|
+
* the lexicographically smallest value, so the id never depends on which
|
|
745
|
+
* switch happened to be polled first.
|
|
746
|
+
*/
|
|
747
|
+
static canonicalPeerValue(groupClaims, displayName) {
|
|
748
|
+
const valuesByKind = new Map();
|
|
749
|
+
for (const resolved of groupClaims) {
|
|
750
|
+
for (const alias of resolved.peerAliases) {
|
|
751
|
+
const bucket = valuesByKind.get(alias.kind);
|
|
752
|
+
if (bucket) {
|
|
753
|
+
if (!bucket.includes(alias.value)) {
|
|
754
|
+
bucket.push(alias.value);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
else {
|
|
758
|
+
valuesByKind.set(alias.kind, [alias.value]);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
const preferred = NetworkTopologyUtil.normalizeKey(displayName);
|
|
763
|
+
if (preferred && (valuesByKind.get("name") || []).includes(preferred)) {
|
|
764
|
+
return preferred;
|
|
765
|
+
}
|
|
766
|
+
for (const kind of MATCH_KEY_KINDS_STRONGEST_FIRST) {
|
|
767
|
+
const values = valuesByKind.get(kind);
|
|
768
|
+
if (values && values.length > 0) {
|
|
769
|
+
return [...values].sort()[0];
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return "unknown-peer";
|
|
773
|
+
}
|
|
774
|
+
/*
|
|
775
|
+
* Two peers could in principle canonicalize to the same string (one by
|
|
776
|
+
* name, one by serial). Suffixing rather than merging keeps them the
|
|
777
|
+
* distinct boxes they are.
|
|
778
|
+
*/
|
|
779
|
+
static uniqueNodeId(preferred, used) {
|
|
780
|
+
if (!used.has(preferred)) {
|
|
781
|
+
return preferred;
|
|
782
|
+
}
|
|
783
|
+
let suffix = 2;
|
|
784
|
+
while (used.has(`${preferred}#${suffix}`)) {
|
|
785
|
+
suffix++;
|
|
786
|
+
}
|
|
787
|
+
return `${preferred}#${suffix}`;
|
|
788
|
+
}
|
|
789
|
+
/*
|
|
790
|
+
* Union-find over peer aliases: two reports that share ANY identity-grade
|
|
791
|
+
* alias describe one box. Returns the representative alias id for every
|
|
792
|
+
* alias seen.
|
|
793
|
+
*/
|
|
794
|
+
static groupPeerAliases(unmanagedClaims) {
|
|
795
|
+
const parent = new Map();
|
|
796
|
+
const find = (key) => {
|
|
797
|
+
let root = key;
|
|
798
|
+
let next = parent.get(root);
|
|
799
|
+
while (next !== undefined && next !== root) {
|
|
800
|
+
root = next;
|
|
801
|
+
next = parent.get(root);
|
|
802
|
+
}
|
|
803
|
+
// Path compression, so repeated lookups stay flat.
|
|
804
|
+
let cursor = key;
|
|
805
|
+
while (cursor !== root) {
|
|
806
|
+
const following = parent.get(cursor) || root;
|
|
807
|
+
parent.set(cursor, root);
|
|
808
|
+
cursor = following;
|
|
809
|
+
}
|
|
810
|
+
return root;
|
|
811
|
+
};
|
|
812
|
+
const union = (a, b) => {
|
|
813
|
+
const rootA = find(a);
|
|
814
|
+
const rootB = find(b);
|
|
815
|
+
if (rootA === rootB) {
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
// Lexicographic tie-break, so the result ignores input order.
|
|
819
|
+
if (rootA < rootB) {
|
|
820
|
+
parent.set(rootB, rootA);
|
|
821
|
+
}
|
|
822
|
+
else {
|
|
823
|
+
parent.set(rootA, rootB);
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
for (const resolved of unmanagedClaims) {
|
|
827
|
+
const aliasIds = resolved.peerAliases.map((alias) => {
|
|
828
|
+
return NetworkTopologyUtil.matchKeyId(alias);
|
|
829
|
+
});
|
|
830
|
+
for (const aliasId of aliasIds) {
|
|
831
|
+
if (!parent.has(aliasId)) {
|
|
832
|
+
parent.set(aliasId, aliasId);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
for (let index = 1; index < aliasIds.length; index++) {
|
|
836
|
+
union(aliasIds[0], aliasIds[index]);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
const rootByAliasId = new Map();
|
|
840
|
+
for (const aliasId of parent.keys()) {
|
|
841
|
+
rootByAliasId.set(aliasId, find(aliasId));
|
|
842
|
+
}
|
|
843
|
+
return rootByAliasId;
|
|
844
|
+
}
|
|
319
845
|
static normalizeKey(value) {
|
|
320
846
|
if (!value) {
|
|
321
847
|
return undefined;
|
|
@@ -323,7 +849,16 @@ export default class NetworkTopologyUtil {
|
|
|
323
849
|
const trimmed = value.trim().toLowerCase();
|
|
324
850
|
return trimmed.length > 0 ? trimmed : undefined;
|
|
325
851
|
}
|
|
852
|
+
/*
|
|
853
|
+
* A stamped monitor status beats SNMP freshness, and freshness is the
|
|
854
|
+
* fallback — the same precedence SiteStatusRollupUtil already applies when
|
|
855
|
+
* it rolls devices up into a site, so a device cannot read "up" on the map
|
|
856
|
+
* and "down" on the site card above it.
|
|
857
|
+
*/
|
|
326
858
|
static deviceStatus(device, now) {
|
|
859
|
+
if (device.monitorStatus) {
|
|
860
|
+
return device.monitorStatus;
|
|
861
|
+
}
|
|
327
862
|
return NetworkTopologyUtil.statusFromLastSeen(device.lastSeenAt, now);
|
|
328
863
|
}
|
|
329
864
|
// The shared freshness rule: seen within the window = up, stale = down.
|