@oneuptime/common 11.6.1 → 11.7.0
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/Index.ts +4 -0
- package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
- package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
- package/Models/AnalyticsModels/SloHistory.ts +243 -0
- package/Models/DatabaseModels/Index.ts +20 -0
- package/Models/DatabaseModels/NetworkDevice.ts +453 -6
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
- package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
- package/Models/DatabaseModels/NetworkSite.ts +1155 -0
- package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
- package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
- package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
- package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
- package/Models/DatabaseModels/ServiceLevelObjective.ts +1115 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
- package/Server/Services/AnalyticsDatabaseService.ts +25 -9
- package/Server/Services/Index.ts +24 -0
- package/Server/Services/KubernetesCostAllocationService.ts +14 -0
- package/Server/Services/MetricService.ts +21 -2
- package/Server/Services/MonitorService.ts +22 -0
- package/Server/Services/NetworkDeviceService.ts +438 -2
- package/Server/Services/NetworkEndpointService.ts +414 -0
- package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
- package/Server/Services/NetworkSiteLinkService.ts +10 -0
- package/Server/Services/NetworkSiteService.ts +1254 -0
- package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
- package/Server/Services/NetworkSiteTypeService.ts +10 -0
- package/Server/Services/ProjectService.ts +122 -2
- package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
- package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
- package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
- package/Server/Services/ServiceLevelObjectiveService.ts +685 -0
- package/Server/Services/SloHistoryService.ts +101 -0
- package/Server/Services/UserNotificationSettingService.ts +37 -0
- package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
- package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +87 -48
- package/Server/Utils/Memory.ts +9 -1
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
- package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
- package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
- package/Server/Utils/Monitor/MonitorResource.ts +4 -30
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
- package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
- package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
- package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
- package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
- package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
- package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
- package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
- package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
- package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
- package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
- package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
- package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
- package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +404 -0
- package/Tests/Server/Utils/Encryption.test.ts +70 -0
- package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
- package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
- package/Tests/Server/Utils/LocalFile.test.ts +258 -0
- package/Tests/Server/Utils/Memory.test.ts +213 -0
- package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
- package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
- package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
- package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
- package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
- package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
- package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
- package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
- package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
- package/Tests/Server/Utils/Stream.test.ts +87 -0
- package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
- package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
- package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
- package/Tests/Types/Email.test.ts +198 -0
- package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
- package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
- package/Tests/Types/Monitor/MonitorCriteria.test.ts +155 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +465 -0
- package/Tests/Types/Monitor/MonitorStep.test.ts +183 -0
- package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
- package/Tests/Types/Monitor/MonitorSteps.test.ts +183 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
- package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
- package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
- package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
- package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
- package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
- package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
- package/Tests/Types/WebsiteRequest.test.ts +230 -0
- package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
- package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
- package/Tests/UI/Utils/LogExport.test.ts +159 -0
- package/Tests/UI/Utils/Navigation.test.ts +183 -0
- package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
- package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
- package/Tests/Utils/Base64.test.ts +51 -0
- package/Tests/Utils/Boolean.test.ts +76 -0
- package/Tests/Utils/Crypto.test.ts +48 -0
- package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
- package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
- package/Tests/Utils/Enum.test.ts +54 -0
- package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
- package/Tests/Utils/Memory.test.ts +44 -0
- package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
- package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
- package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
- package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
- package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
- package/Tests/Utils/ObjectUtil.test.ts +30 -0
- package/Tests/Utils/Slo/SloBurnRateRuleState.test.ts +124 -0
- package/Tests/Utils/Slo/SloDuration.test.ts +148 -0
- package/Tests/Utils/Slo/SloHealth.test.ts +334 -0
- package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
- package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
- package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
- package/Tests/Utils/TechStack.test.ts +50 -0
- package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
- package/Types/BaseDatabase/EqualTo.ts +9 -1
- package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
- package/Types/BaseDatabase/NotEqual.ts +9 -1
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
- package/Types/Dashboard/DashboardTemplates.ts +214 -0
- package/Types/Email/EmailTemplateType.ts +2 -0
- package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
- package/Types/Monitor/CriteriaFilter.ts +9 -0
- package/Types/Monitor/MonitorStep.ts +5 -8
- package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
- package/Types/Monitor/MonitorType.ts +15 -5
- package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
- package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
- package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
- package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
- package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
- package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
- package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
- package/Types/Permission.ts +449 -0
- package/Types/ServiceLevelObjective/SliType.ts +6 -0
- package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
- package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
- package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
- package/Types/Telemetry/ServiceType.ts +1 -0
- package/UI/Components/Filters/EntityFilter.tsx +16 -0
- package/UI/Components/Filters/FilterViewer.tsx +22 -5
- package/UI/Components/List/List.tsx +8 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
- package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
- package/UI/Components/Navbar/NavBar.tsx +16 -2
- package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
- package/UI/Utils/Navigation.ts +10 -0
- package/UI/Utils/TableFilterUrlState.ts +204 -17
- package/UI/Utils/TableViewUrlState.ts +165 -0
- package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/IpCanonicalUtil.ts +134 -0
- package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
- package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
- package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
- package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
- package/Utils/Slo/SloBurnRateRuleState.ts +91 -0
- package/Utils/Slo/SloDuration.ts +165 -0
- package/Utils/Slo/SloEvaluation.ts +22 -0
- package/Utils/Slo/SloHealth.ts +302 -0
- package/Utils/Slo/SloStatusColor.ts +54 -0
- package/Utils/Slo/SloUtil.ts +637 -0
- package/Utils/Slo/SloWidgetFormat.ts +383 -0
- package/build/dist/Models/AnalyticsModels/Index.js +4 -0
- package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/SloHistory.js +218 -0
- package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +20 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
- package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
- package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1134 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js +21 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +23 -6
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +24 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
- package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
- package/build/dist/Server/Services/MetricService.js +21 -3
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +19 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
- package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
- package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
- package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
- package/build/dist/Server/Services/ProjectService.js +98 -2
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +588 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
- package/build/dist/Server/Services/SloHistoryService.js +77 -0
- package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +76 -48
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/Memory.js +9 -1
- package/build/dist/Server/Utils/Memory.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
- package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
- package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
- package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
- package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
- package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
- package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
- package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
- package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
- package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
- package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
- package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
- package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +5 -5
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
- package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +15 -5
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
- package/build/dist/Types/Permission.js +409 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
- package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
- package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
- package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
- package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
- package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
- package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
- package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
- package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
- package/build/dist/UI/Components/List/List.js +1 -1
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
- package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
- package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +9 -0
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
- package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
- package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
- package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
- package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/IpCanonicalUtil.js +110 -0
- package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
- package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
- package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
- package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
- package/build/dist/Utils/Slo/SloBurnRateRuleState.js +35 -0
- package/build/dist/Utils/Slo/SloBurnRateRuleState.js.map +1 -0
- package/build/dist/Utils/Slo/SloDuration.js +87 -0
- package/build/dist/Utils/Slo/SloDuration.js.map +1 -0
- package/build/dist/Utils/Slo/SloEvaluation.js +21 -0
- package/build/dist/Utils/Slo/SloEvaluation.js.map +1 -0
- package/build/dist/Utils/Slo/SloHealth.js +179 -0
- package/build/dist/Utils/Slo/SloHealth.js.map +1 -0
- package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
- package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
- package/build/dist/Utils/Slo/SloUtil.js +393 -0
- package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
- package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
- package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
- package/package.json +2 -2
- package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
- package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
- package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
|
@@ -7,6 +7,7 @@ import NetworkTopology, {
|
|
|
7
7
|
} from "../../Types/Monitor/SnmpMonitor/NetworkTopology";
|
|
8
8
|
import LldpNeighbor from "../../Types/Monitor/SnmpMonitor/LldpNeighbor";
|
|
9
9
|
import CdpNeighbor from "../../Types/Monitor/SnmpMonitor/CdpNeighbor";
|
|
10
|
+
import { normalizeMac } from "./EndpointAttachmentUtil";
|
|
10
11
|
|
|
11
12
|
export interface TopologyDeviceInput {
|
|
12
13
|
id: string;
|
|
@@ -39,6 +40,36 @@ export interface TopologyInterfaceInput {
|
|
|
39
40
|
errorsPerSecond?: number | undefined;
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
/*
|
|
44
|
+
* One discovered endpoint row (NetworkEndpoint), reduced to what rendering
|
|
45
|
+
* needs. Endpoints attach to their switch via an "fdb" edge; rows without a
|
|
46
|
+
* resolvable attachment are dropped (and counted) rather than floated.
|
|
47
|
+
*/
|
|
48
|
+
export interface TopologyEndpointInput {
|
|
49
|
+
id: string;
|
|
50
|
+
macAddress: string;
|
|
51
|
+
ipAddress?: string | undefined;
|
|
52
|
+
vendor?: string | undefined;
|
|
53
|
+
classification?: string | undefined;
|
|
54
|
+
vlanId?: number | undefined;
|
|
55
|
+
attachedNetworkDeviceId?: string | undefined;
|
|
56
|
+
attachedInterfaceIndex?: number | undefined;
|
|
57
|
+
attachedPortName?: string | undefined;
|
|
58
|
+
lastSeenAt?: Date | undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* buildTopology's result: the wire-format NetworkTopology plus endpoint
|
|
63
|
+
* bookkeeping. The extra fields are optional on the wire type, so older
|
|
64
|
+
* readers are unaffected.
|
|
65
|
+
*/
|
|
66
|
+
export interface TopologyBuildResult extends NetworkTopology {
|
|
67
|
+
// Endpoints skipped because they had no attachment in the graph.
|
|
68
|
+
droppedEndpointCount?: number | undefined;
|
|
69
|
+
// True when more attachable endpoints existed than the render cap allows.
|
|
70
|
+
endpointsTruncated?: boolean | undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
42
73
|
/*
|
|
43
74
|
* A neighbor claim from either discovery protocol, normalized so LLDP and
|
|
44
75
|
* CDP entries flow through the same match/dedupe/enrich pipeline.
|
|
@@ -56,6 +87,9 @@ interface NeighborClaim {
|
|
|
56
87
|
// A device not seen within this window is treated as not currently up.
|
|
57
88
|
const FRESH_WINDOW_MS: number = 15 * 60 * 1000;
|
|
58
89
|
|
|
90
|
+
// Endpoint nodes rendered per graph; the slice is deterministic (by MAC).
|
|
91
|
+
const ENDPOINT_RENDER_CAP: number = 2000;
|
|
92
|
+
|
|
59
93
|
export default class NetworkTopologyUtil {
|
|
60
94
|
/*
|
|
61
95
|
* Builds the topology graph from every device in a project. Nodes are the
|
|
@@ -66,13 +100,17 @@ export default class NetworkTopologyUtil {
|
|
|
66
100
|
* both protocols, appears once with the union of what each report knew
|
|
67
101
|
* (ports, protocols, per-end interface state). When `interfaces` rows are
|
|
68
102
|
* provided, each edge end whose interface is identifiable carries its
|
|
69
|
-
* operational state (up/down, utilization, rates).
|
|
103
|
+
* operational state (up/down, utilization, rates). When `endpoints` rows
|
|
104
|
+
* are provided, each one that attaches to a device in the graph becomes an
|
|
105
|
+
* "endpoint" node linked by an "fdb" edge (capped, deterministic by MAC);
|
|
106
|
+
* the rest are dropped and counted in droppedEndpointCount.
|
|
70
107
|
*/
|
|
71
108
|
public static buildTopology(
|
|
72
109
|
devices: Array<TopologyDeviceInput>,
|
|
73
110
|
now: Date,
|
|
74
111
|
interfaces: Array<TopologyInterfaceInput> = [],
|
|
75
|
-
|
|
112
|
+
endpoints: Array<TopologyEndpointInput> = [],
|
|
113
|
+
): TopologyBuildResult {
|
|
76
114
|
const nodes: Array<NetworkTopologyNode> = [];
|
|
77
115
|
|
|
78
116
|
// Index managed devices by the identifiers neighbor entries reference.
|
|
@@ -106,6 +144,7 @@ export default class NetworkTopologyUtil {
|
|
|
106
144
|
id: device.id,
|
|
107
145
|
name: device.name,
|
|
108
146
|
isManaged: true,
|
|
147
|
+
kind: "device",
|
|
109
148
|
status: NetworkTopologyUtil.deviceStatus(device, now),
|
|
110
149
|
interfacesUp: device.interfacesUp,
|
|
111
150
|
interfacesDown: device.interfacesDown,
|
|
@@ -145,6 +184,7 @@ export default class NetworkTopologyUtil {
|
|
|
145
184
|
id: toNodeId,
|
|
146
185
|
name: claim.displayName || "Unknown device",
|
|
147
186
|
isManaged: false,
|
|
187
|
+
kind: "unmanaged",
|
|
148
188
|
status: "unknown",
|
|
149
189
|
deviceModel: claim.remotePlatform,
|
|
150
190
|
};
|
|
@@ -262,7 +302,111 @@ export default class NetworkTopologyUtil {
|
|
|
262
302
|
}
|
|
263
303
|
}
|
|
264
304
|
|
|
265
|
-
|
|
305
|
+
const edges: Array<NetworkTopologyEdge> = Array.from(edgeByKey.values());
|
|
306
|
+
|
|
307
|
+
// --- Endpoint nodes + fdb edges ---
|
|
308
|
+
|
|
309
|
+
const deviceNodeIds: Set<string> = new Set(
|
|
310
|
+
devices.map((device: TopologyDeviceInput) => {
|
|
311
|
+
return device.id;
|
|
312
|
+
}),
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
/*
|
|
316
|
+
* Deterministic render order: by normalized MAC, then id, so the capped
|
|
317
|
+
* slice is stable across rebuilds regardless of query order.
|
|
318
|
+
*/
|
|
319
|
+
const sortedEndpoints: Array<TopologyEndpointInput> = [...endpoints].sort(
|
|
320
|
+
(a: TopologyEndpointInput, b: TopologyEndpointInput) => {
|
|
321
|
+
const aMac: string = normalizeMac(a.macAddress) || a.macAddress;
|
|
322
|
+
const bMac: string = normalizeMac(b.macAddress) || b.macAddress;
|
|
323
|
+
if (aMac !== bMac) {
|
|
324
|
+
return aMac < bMac ? -1 : 1;
|
|
325
|
+
}
|
|
326
|
+
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
327
|
+
},
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
let droppedEndpointCount: number = 0;
|
|
331
|
+
let renderedEndpointCount: number = 0;
|
|
332
|
+
let endpointsTruncated: boolean = false;
|
|
333
|
+
|
|
334
|
+
for (const endpoint of sortedEndpoints) {
|
|
335
|
+
if (
|
|
336
|
+
!endpoint.attachedNetworkDeviceId ||
|
|
337
|
+
!deviceNodeIds.has(endpoint.attachedNetworkDeviceId)
|
|
338
|
+
) {
|
|
339
|
+
// No attachment in this graph — nothing to hang the node off.
|
|
340
|
+
droppedEndpointCount++;
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (renderedEndpointCount >= ENDPOINT_RENDER_CAP) {
|
|
345
|
+
endpointsTruncated = true;
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
renderedEndpointCount++;
|
|
349
|
+
|
|
350
|
+
const nodeId: string = `endpoint:${endpoint.id}`;
|
|
351
|
+
nodes.push({
|
|
352
|
+
id: nodeId,
|
|
353
|
+
name:
|
|
354
|
+
endpoint.classification ||
|
|
355
|
+
endpoint.vendor ||
|
|
356
|
+
endpoint.ipAddress ||
|
|
357
|
+
endpoint.macAddress,
|
|
358
|
+
isManaged: false,
|
|
359
|
+
kind: "endpoint",
|
|
360
|
+
status: NetworkTopologyUtil.statusFromLastSeen(
|
|
361
|
+
endpoint.lastSeenAt,
|
|
362
|
+
now,
|
|
363
|
+
),
|
|
364
|
+
vendor: endpoint.vendor,
|
|
365
|
+
macAddress: endpoint.macAddress,
|
|
366
|
+
ipAddress: endpoint.ipAddress,
|
|
367
|
+
classification: endpoint.classification,
|
|
368
|
+
vlanId: endpoint.vlanId,
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// Port label + interface state on the switch end, when identifiable.
|
|
372
|
+
let switchInterface: TopologyInterfaceInput | undefined = undefined;
|
|
373
|
+
if (endpoint.attachedInterfaceIndex !== undefined) {
|
|
374
|
+
switchInterface = interfaceByDeviceAndIndex.get(
|
|
375
|
+
`${endpoint.attachedNetworkDeviceId}::${endpoint.attachedInterfaceIndex}`,
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
let fromPort: string | undefined =
|
|
379
|
+
endpoint.attachedPortName || switchInterface?.name;
|
|
380
|
+
if (!fromPort && endpoint.attachedInterfaceIndex !== undefined) {
|
|
381
|
+
fromPort = `if${endpoint.attachedInterfaceIndex}`;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
edges.push({
|
|
385
|
+
fromNodeId: endpoint.attachedNetworkDeviceId,
|
|
386
|
+
toNodeId: nodeId,
|
|
387
|
+
fromPort: fromPort,
|
|
388
|
+
protocols: ["fdb"],
|
|
389
|
+
fromInterface: switchInterface
|
|
390
|
+
? {
|
|
391
|
+
interfaceIndex: switchInterface.interfaceIndex,
|
|
392
|
+
interfaceName: switchInterface.name,
|
|
393
|
+
isOperationallyUp: switchInterface.isOperationallyUp,
|
|
394
|
+
isAdministrativelyUp: switchInterface.isAdministrativelyUp,
|
|
395
|
+
utilizationPercent: switchInterface.utilizationPercent,
|
|
396
|
+
inRateMbps: switchInterface.inRateMbps,
|
|
397
|
+
outRateMbps: switchInterface.outRateMbps,
|
|
398
|
+
errorsPerSecond: switchInterface.errorsPerSecond,
|
|
399
|
+
}
|
|
400
|
+
: undefined,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return {
|
|
405
|
+
nodes,
|
|
406
|
+
edges,
|
|
407
|
+
droppedEndpointCount,
|
|
408
|
+
endpointsTruncated,
|
|
409
|
+
};
|
|
266
410
|
}
|
|
267
411
|
|
|
268
412
|
/*
|
|
@@ -359,10 +503,18 @@ export default class NetworkTopologyUtil {
|
|
|
359
503
|
device: TopologyDeviceInput,
|
|
360
504
|
now: Date,
|
|
361
505
|
): NetworkTopologyNodeStatus {
|
|
362
|
-
|
|
506
|
+
return NetworkTopologyUtil.statusFromLastSeen(device.lastSeenAt, now);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// The shared freshness rule: seen within the window = up, stale = down.
|
|
510
|
+
private static statusFromLastSeen(
|
|
511
|
+
lastSeenAt: Date | undefined,
|
|
512
|
+
now: Date,
|
|
513
|
+
): NetworkTopologyNodeStatus {
|
|
514
|
+
if (!lastSeenAt) {
|
|
363
515
|
return "unknown";
|
|
364
516
|
}
|
|
365
|
-
const ageMs: number = now.getTime() - new Date(
|
|
517
|
+
const ageMs: number = now.getTime() - new Date(lastSeenAt).getTime();
|
|
366
518
|
if (ageMs > FRESH_WINDOW_MS) {
|
|
367
519
|
return "down";
|
|
368
520
|
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Matching helpers for NetworkSite auto-assignment rules: IPv4 CIDR
|
|
3
|
+
* containment, case-insensitive '*' wildcard hostname patterns, and the
|
|
4
|
+
* highest-priority-wins rule picker. Pure and dependency-free so the rule
|
|
5
|
+
* engine's decisions are unit-testable.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// The shape NetworkSiteAssignmentRule rows are matched with.
|
|
9
|
+
export interface AssignmentRuleCandidate {
|
|
10
|
+
subnetCidr?: string | null | undefined;
|
|
11
|
+
hostnamePattern?: string | null | undefined;
|
|
12
|
+
priority?: number | null | undefined;
|
|
13
|
+
createdAt?: Date | null | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// The device attributes a rule is evaluated against.
|
|
17
|
+
export interface RuleMatchTarget {
|
|
18
|
+
ip?: string | null | undefined;
|
|
19
|
+
hostname?: string | null | undefined;
|
|
20
|
+
sysName?: string | null | undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class CidrMatchUtil {
|
|
24
|
+
/*
|
|
25
|
+
* Longest hostname pattern we will evaluate. The column itself is
|
|
26
|
+
* ShortText (100), and a DNS name tops out at 253 characters, so anything
|
|
27
|
+
* longer is either a mistake or an attempt to make matching expensive.
|
|
28
|
+
*/
|
|
29
|
+
public static readonly MAX_HOSTNAME_PATTERN_LENGTH: number = 253;
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
* Hoisted out of the call sites so the literals are not the object of a
|
|
33
|
+
* member expression, which `wrap-regex` and Prettier cannot agree on.
|
|
34
|
+
*/
|
|
35
|
+
private static readonly PREFIX_LENGTH_PATTERN: RegExp = /^\d{1,2}$/;
|
|
36
|
+
|
|
37
|
+
private static readonly OCTET_PATTERN: RegExp = /^\d{1,3}$/;
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
* True when the IPv4 address `ip` falls inside `cidr` ('10.0.0.0/8').
|
|
41
|
+
* Prefixes /0 through /32 are supported; a bare address is treated as /32.
|
|
42
|
+
* Any invalid input returns false instead of throwing.
|
|
43
|
+
*/
|
|
44
|
+
public static ipInCidr(ip: string, cidr: string): boolean {
|
|
45
|
+
const ipValue: number | null = CidrMatchUtil.parseIpv4(ip);
|
|
46
|
+
if (ipValue === null) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (typeof cidr !== "string" || cidr.trim().length === 0) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const parts: Array<string> = cidr.trim().split("/");
|
|
55
|
+
if (parts.length > 2) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const baseValue: number | null = CidrMatchUtil.parseIpv4(parts[0] || "");
|
|
60
|
+
if (baseValue === null) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let prefixLength: number = 32;
|
|
65
|
+
if (parts.length === 2) {
|
|
66
|
+
const prefixText: string = parts[1] || "";
|
|
67
|
+
if (!CidrMatchUtil.PREFIX_LENGTH_PATTERN.test(prefixText)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
prefixLength = parseInt(prefixText, 10);
|
|
71
|
+
if (prefixLength < 0 || prefixLength > 32) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/*
|
|
77
|
+
* JS bitwise ops are 32-bit signed; >>> 0 keeps the mask and the masked
|
|
78
|
+
* addresses unsigned. A shift by 32 is a no-op in JS, so /0 is special
|
|
79
|
+
* cased to the all-zero mask (matches everything).
|
|
80
|
+
*/
|
|
81
|
+
const mask: number =
|
|
82
|
+
prefixLength === 0 ? 0 : (0xffffffff << (32 - prefixLength)) >>> 0;
|
|
83
|
+
|
|
84
|
+
return (ipValue & mask) >>> 0 === (baseValue & mask) >>> 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// True when `cidr` is a well-formed IPv4 CIDR (or bare address == /32).
|
|
88
|
+
public static isValidCidr(cidr: string): boolean {
|
|
89
|
+
if (typeof cidr !== "string" || cidr.trim().length === 0) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const parts: Array<string> = cidr.trim().split("/");
|
|
93
|
+
if (parts.length > 2) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (CidrMatchUtil.parseIpv4(parts[0] || "") === null) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
if (parts.length === 2) {
|
|
100
|
+
const prefixText: string = parts[1] || "";
|
|
101
|
+
if (!CidrMatchUtil.PREFIX_LENGTH_PATTERN.test(prefixText)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const prefixLength: number = parseInt(prefixText, 10);
|
|
105
|
+
if (prefixLength < 0 || prefixLength > 32) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
* Case-insensitive wildcard match where '*' matches any run of characters
|
|
114
|
+
* (including none) and every other character is literal. The pattern must
|
|
115
|
+
* cover the whole hostname. Non-string or missing inputs never match, and
|
|
116
|
+
* so does an over-long pattern.
|
|
117
|
+
*
|
|
118
|
+
* Deliberately NOT a regex: compiling a user-authored pattern into
|
|
119
|
+
* /^.*a.*a.*a...$/ makes the backtracking engine explore an exponential
|
|
120
|
+
* number of split points on a long homogeneous input, which blocks the
|
|
121
|
+
* event loop for minutes. This matcher is O(hostname x pattern) worst case
|
|
122
|
+
* with no recursion, so a hostile rule cannot hang the process.
|
|
123
|
+
*/
|
|
124
|
+
public static hostnameMatchesWildcard(
|
|
125
|
+
hostname: string,
|
|
126
|
+
pattern: string,
|
|
127
|
+
): boolean {
|
|
128
|
+
if (typeof hostname !== "string" || typeof pattern !== "string") {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const text: string = hostname.trim().toLowerCase();
|
|
133
|
+
const glob: string = pattern.trim().toLowerCase();
|
|
134
|
+
|
|
135
|
+
if (glob.length > CidrMatchUtil.MAX_HOSTNAME_PATTERN_LENGTH) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/*
|
|
140
|
+
* Greedy two-pointer glob match. On a mismatch we rewind only to the
|
|
141
|
+
* most recent '*' and advance the character it consumed by one, so each
|
|
142
|
+
* character of the hostname is revisited at most once per '*'.
|
|
143
|
+
*/
|
|
144
|
+
let textIndex: number = 0;
|
|
145
|
+
let globIndex: number = 0;
|
|
146
|
+
let lastStarIndex: number = -1;
|
|
147
|
+
let textIndexAtLastStar: number = 0;
|
|
148
|
+
|
|
149
|
+
while (textIndex < text.length) {
|
|
150
|
+
if (globIndex < glob.length && glob[globIndex] === "*") {
|
|
151
|
+
lastStarIndex = globIndex;
|
|
152
|
+
textIndexAtLastStar = textIndex;
|
|
153
|
+
globIndex++;
|
|
154
|
+
} else if (
|
|
155
|
+
globIndex < glob.length &&
|
|
156
|
+
glob[globIndex] === text[textIndex]
|
|
157
|
+
) {
|
|
158
|
+
globIndex++;
|
|
159
|
+
textIndex++;
|
|
160
|
+
} else if (lastStarIndex !== -1) {
|
|
161
|
+
globIndex = lastStarIndex + 1;
|
|
162
|
+
textIndexAtLastStar++;
|
|
163
|
+
textIndex = textIndexAtLastStar;
|
|
164
|
+
} else {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Any trailing '*' in the pattern can still match the empty remainder.
|
|
170
|
+
while (globIndex < glob.length && glob[globIndex] === "*") {
|
|
171
|
+
globIndex++;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return globIndex === glob.length;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/*
|
|
178
|
+
* True when the rule's populated criteria all match the target. A CIDR
|
|
179
|
+
* criterion matches the target's ip; a hostname pattern matches either the
|
|
180
|
+
* hostname or the SNMP sysName. A rule with no criteria never matches.
|
|
181
|
+
*/
|
|
182
|
+
public static ruleMatches(
|
|
183
|
+
rule: AssignmentRuleCandidate,
|
|
184
|
+
target: RuleMatchTarget,
|
|
185
|
+
): boolean {
|
|
186
|
+
const hasCidr: boolean = Boolean(
|
|
187
|
+
rule.subnetCidr && rule.subnetCidr.trim().length > 0,
|
|
188
|
+
);
|
|
189
|
+
const hasPattern: boolean = Boolean(
|
|
190
|
+
rule.hostnamePattern && rule.hostnamePattern.trim().length > 0,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
if (!hasCidr && !hasPattern) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (hasCidr) {
|
|
198
|
+
if (!target.ip || !CidrMatchUtil.ipInCidr(target.ip, rule.subnetCidr!)) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (hasPattern) {
|
|
204
|
+
const matchesHostname: boolean = Boolean(
|
|
205
|
+
target.hostname &&
|
|
206
|
+
CidrMatchUtil.hostnameMatchesWildcard(
|
|
207
|
+
target.hostname,
|
|
208
|
+
rule.hostnamePattern!,
|
|
209
|
+
),
|
|
210
|
+
);
|
|
211
|
+
const matchesSysName: boolean = Boolean(
|
|
212
|
+
target.sysName &&
|
|
213
|
+
CidrMatchUtil.hostnameMatchesWildcard(
|
|
214
|
+
target.sysName,
|
|
215
|
+
rule.hostnamePattern!,
|
|
216
|
+
),
|
|
217
|
+
);
|
|
218
|
+
if (!matchesHostname && !matchesSysName) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/*
|
|
227
|
+
* Picks the winning rule for a target: among matching rules the highest
|
|
228
|
+
* priority number wins; ties go to the earlier createdAt when both rows
|
|
229
|
+
* carry one, otherwise the earlier rule in the input order (stable).
|
|
230
|
+
* Returns null when nothing matches.
|
|
231
|
+
*/
|
|
232
|
+
public static pickRule<T extends AssignmentRuleCandidate>(
|
|
233
|
+
rules: Array<T>,
|
|
234
|
+
target: RuleMatchTarget,
|
|
235
|
+
): T | null {
|
|
236
|
+
let best: T | null = null;
|
|
237
|
+
|
|
238
|
+
for (const rule of rules) {
|
|
239
|
+
if (!CidrMatchUtil.ruleMatches(rule, target)) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (!best) {
|
|
244
|
+
best = rule;
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const bestPriority: number = best.priority || 0;
|
|
249
|
+
const rulePriority: number = rule.priority || 0;
|
|
250
|
+
|
|
251
|
+
if (rulePriority > bestPriority) {
|
|
252
|
+
best = rule;
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (
|
|
257
|
+
rulePriority === bestPriority &&
|
|
258
|
+
rule.createdAt &&
|
|
259
|
+
best.createdAt &&
|
|
260
|
+
rule.createdAt.getTime() < best.createdAt.getTime()
|
|
261
|
+
) {
|
|
262
|
+
best = rule;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return best;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// '10.0.0.1' -> unsigned 32-bit value; anything malformed -> null.
|
|
270
|
+
private static parseIpv4(ip: string): number | null {
|
|
271
|
+
if (typeof ip !== "string") {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const octets: Array<string> = ip.trim().split(".");
|
|
276
|
+
if (octets.length !== 4) {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
let value: number = 0;
|
|
281
|
+
for (const octetText of octets) {
|
|
282
|
+
if (!CidrMatchUtil.OCTET_PATTERN.test(octetText)) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
const octet: number = parseInt(octetText, 10);
|
|
286
|
+
if (octet > 255) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
value = (value * 256 + octet) >>> 0;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return value;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export default CidrMatchUtil;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Materialized-path helpers for the NetworkSite hierarchy.
|
|
3
|
+
*
|
|
4
|
+
* A site's path is the slash-separated list of its ancestor IDs ending with
|
|
5
|
+
* its own ID, in '/rootId/childId/.../ownId/' form. Root sites have the path
|
|
6
|
+
* '/ownId/'. All helpers are pure string operations so the tree math is
|
|
7
|
+
* unit-testable without a database.
|
|
8
|
+
*/
|
|
9
|
+
export class MaterializedPathUtil {
|
|
10
|
+
/*
|
|
11
|
+
* Builds the path for a site given its parent's path (null/undefined/empty
|
|
12
|
+
* for root sites). Tolerates a parent path missing its leading or trailing
|
|
13
|
+
* slash so a hand-edited row cannot poison every child path built from it.
|
|
14
|
+
*/
|
|
15
|
+
public static buildPath(
|
|
16
|
+
parentPath: string | null | undefined,
|
|
17
|
+
siteId: string,
|
|
18
|
+
): string {
|
|
19
|
+
const normalizedParent: string = MaterializedPathUtil.normalizePath(
|
|
20
|
+
parentPath || "",
|
|
21
|
+
);
|
|
22
|
+
return `${normalizedParent || "/"}${siteId}/`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// '/a/b/' -> ['a', 'b']; invalid/empty input -> [].
|
|
26
|
+
public static segmentsOf(path: string | null | undefined): Array<string> {
|
|
27
|
+
if (!path || typeof path !== "string") {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
return path.split("/").filter((segment: string) => {
|
|
31
|
+
return segment.length > 0;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
* Number of ancestors above the site this path belongs to: '/a/' -> 0,
|
|
37
|
+
* '/a/b/' -> 1. Empty/invalid paths report 0.
|
|
38
|
+
*/
|
|
39
|
+
public static depthOf(path: string | null | undefined): number {
|
|
40
|
+
const segments: Array<string> = MaterializedPathUtil.segmentsOf(path);
|
|
41
|
+
return segments.length > 0 ? segments.length - 1 : 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/*
|
|
45
|
+
* True when `path` belongs to a strict descendant of the site that owns
|
|
46
|
+
* `ancestorPath` (a site is not its own descendant).
|
|
47
|
+
*/
|
|
48
|
+
public static isDescendant(
|
|
49
|
+
path: string | null | undefined,
|
|
50
|
+
ancestorPath: string | null | undefined,
|
|
51
|
+
): boolean {
|
|
52
|
+
if (!path || !ancestorPath) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const normalizedPath: string = MaterializedPathUtil.normalizePath(path);
|
|
56
|
+
const normalizedAncestor: string =
|
|
57
|
+
MaterializedPathUtil.normalizePath(ancestorPath);
|
|
58
|
+
return (
|
|
59
|
+
normalizedPath.startsWith(normalizedAncestor) &&
|
|
60
|
+
normalizedPath !== normalizedAncestor
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
* True when making the site with `siteId` a child of the site whose path is
|
|
66
|
+
* `newParentPath` would create a cycle - i.e. the proposed parent is the
|
|
67
|
+
* site itself or one of its descendants (its own ID appears anywhere in the
|
|
68
|
+
* parent's path). A null/empty parent path (becoming a root) can never
|
|
69
|
+
* create a cycle.
|
|
70
|
+
*/
|
|
71
|
+
public static wouldCreateCycle(
|
|
72
|
+
siteId: string,
|
|
73
|
+
newParentPath: string | null | undefined,
|
|
74
|
+
): boolean {
|
|
75
|
+
if (!siteId || !newParentPath) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
const segments: Array<string> =
|
|
79
|
+
MaterializedPathUtil.segmentsOf(newParentPath);
|
|
80
|
+
return segments.includes(siteId);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/*
|
|
84
|
+
* Rewrites subtree paths for a move: every affected path that starts with
|
|
85
|
+
* `oldParentPath` gets that prefix replaced with `newParentPath`. Paths
|
|
86
|
+
* outside the moved subtree are returned unchanged, in input order.
|
|
87
|
+
*/
|
|
88
|
+
public static rebasePaths(
|
|
89
|
+
oldParentPath: string,
|
|
90
|
+
newParentPath: string,
|
|
91
|
+
affectedPaths: Array<string>,
|
|
92
|
+
): Array<string> {
|
|
93
|
+
const oldPrefix: string = MaterializedPathUtil.normalizePath(oldParentPath);
|
|
94
|
+
const newPrefix: string = MaterializedPathUtil.normalizePath(newParentPath);
|
|
95
|
+
|
|
96
|
+
return affectedPaths.map((path: string) => {
|
|
97
|
+
const normalized: string = MaterializedPathUtil.normalizePath(path);
|
|
98
|
+
if (!oldPrefix || !normalized.startsWith(oldPrefix)) {
|
|
99
|
+
return path;
|
|
100
|
+
}
|
|
101
|
+
return `${newPrefix}${normalized.slice(oldPrefix.length)}`;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Ensures '/a/b/' form: leading + trailing slash, no empty segments.
|
|
106
|
+
private static normalizePath(path: string): string {
|
|
107
|
+
const segments: Array<string> = MaterializedPathUtil.segmentsOf(path);
|
|
108
|
+
if (segments.length === 0) {
|
|
109
|
+
return "";
|
|
110
|
+
}
|
|
111
|
+
return `/${segments.join("/")}/`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export default MaterializedPathUtil;
|