@oneuptime/common 11.6.1 → 11.6.2
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 +240 -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 +1106 -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/Index.ts +10 -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 +677 -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/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
- 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/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/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/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 +215 -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 +1124 -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/Index.js +10 -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 +582 -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/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
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
|
|
2
|
+
import NetworkDeviceWalkUtil from "../../../../Server/Utils/Monitor/NetworkDeviceWalkUtil";
|
|
3
|
+
import MonitorResourceUtil from "../../../../Server/Utils/Monitor/MonitorResource";
|
|
4
|
+
import NetworkDeviceMetricUtil from "../../../../Server/Utils/Monitor/NetworkDeviceMetricUtil";
|
|
5
|
+
import NetworkInventoryUtil from "../../../../Server/Utils/Monitor/NetworkInventoryUtil";
|
|
6
|
+
import SnmpInterfaceRateUtil from "../../../../Server/Utils/Monitor/SnmpInterfaceRateUtil";
|
|
7
|
+
import MonitorService from "../../../../Server/Services/MonitorService";
|
|
8
|
+
import NetworkDeviceService from "../../../../Server/Services/NetworkDeviceService";
|
|
9
|
+
import Monitor from "../../../../Models/DatabaseModels/Monitor";
|
|
10
|
+
import NetworkDevice from "../../../../Models/DatabaseModels/NetworkDevice";
|
|
11
|
+
import MonitorStep from "../../../../Types/Monitor/MonitorStep";
|
|
12
|
+
import MonitorSteps from "../../../../Types/Monitor/MonitorSteps";
|
|
13
|
+
import MonitorType from "../../../../Types/Monitor/MonitorType";
|
|
14
|
+
import SnmpMonitorResponse from "../../../../Types/Monitor/SnmpMonitor/SnmpMonitorResponse";
|
|
15
|
+
import ProbeMonitorResponse from "../../../../Types/Probe/ProbeMonitorResponse";
|
|
16
|
+
import { JSONObject } from "../../../../Types/JSON";
|
|
17
|
+
import ObjectID from "../../../../Types/ObjectID";
|
|
18
|
+
import OneUptimeDate from "../../../../Types/Date";
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* NetworkDeviceWalkUtil is the server half of device-owned polling: the
|
|
22
|
+
* device's assigned probe reports each SNMP walk here, and this util
|
|
23
|
+
* computes interface rates against the previous walk, persists the new
|
|
24
|
+
* delta baseline, syncs inventory, emits device-scoped metrics, and fans
|
|
25
|
+
* the walk out to every Network Device monitor referencing the device.
|
|
26
|
+
*
|
|
27
|
+
* These tests mock every collaborator and pin the orchestration contract:
|
|
28
|
+
* the probe-scoping security guard, what flows into each collaborator (and
|
|
29
|
+
* in what order), the lastWalkLog persistence gating, the fan-out
|
|
30
|
+
* filtering, the synthesized ProbeMonitorResponse shape, and the
|
|
31
|
+
* fault-isolation guarantees (metrics/criteria failures never break the
|
|
32
|
+
* pipeline).
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
const DEVICE_ID: string = "8f2c1f0e-0000-4000-8000-0000000000aa";
|
|
36
|
+
const OTHER_DEVICE_ID: string = "9a1b2c3d-0000-4000-8000-0000000000bb";
|
|
37
|
+
const PROJECT_ID: ObjectID = new ObjectID(
|
|
38
|
+
"22222222-2222-4222-8222-222222222222",
|
|
39
|
+
);
|
|
40
|
+
const PROBE_ID: ObjectID = new ObjectID("33333333-3333-4333-8333-333333333333");
|
|
41
|
+
const NOW: Date = new Date("2026-07-16T12:00:00.000Z");
|
|
42
|
+
const MONITORED_AT: Date = new Date("2026-07-16T11:59:58.000Z");
|
|
43
|
+
|
|
44
|
+
const PREVIOUS_WALK_LOG: JSONObject = {
|
|
45
|
+
snmpResponse: {
|
|
46
|
+
interfaces: [{ interfaceIndex: 1, inOctets: 1000, outOctets: 2000 }],
|
|
47
|
+
},
|
|
48
|
+
monitoredAt: "2026-07-16T11:55:00.000Z",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
let deviceFindSpy: jest.SpyInstance;
|
|
52
|
+
let deviceUpdateSpy: jest.SpyInstance;
|
|
53
|
+
let monitorFindSpy: jest.SpyInstance;
|
|
54
|
+
let monitorResourceSpy: jest.SpyInstance;
|
|
55
|
+
let inventorySpy: jest.SpyInstance;
|
|
56
|
+
let metricsSpy: jest.SpyInstance;
|
|
57
|
+
let rateSpy: jest.SpyInstance;
|
|
58
|
+
|
|
59
|
+
function buildDevice(): NetworkDevice {
|
|
60
|
+
const device: NetworkDevice = new NetworkDevice();
|
|
61
|
+
device.id = new ObjectID(DEVICE_ID);
|
|
62
|
+
device.projectId = PROJECT_ID;
|
|
63
|
+
device.name = "core-sw-01";
|
|
64
|
+
device.lastWalkLog = PREVIOUS_WALK_LOG;
|
|
65
|
+
return device;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function mockPipeline(options?: {
|
|
69
|
+
device?: NetworkDevice | null | undefined;
|
|
70
|
+
monitors?: Array<Monitor> | undefined;
|
|
71
|
+
}): void {
|
|
72
|
+
deviceFindSpy = jest
|
|
73
|
+
.spyOn(NetworkDeviceService, "findOneBy")
|
|
74
|
+
.mockResolvedValue(
|
|
75
|
+
options && "device" in options ? options.device ?? null : buildDevice(),
|
|
76
|
+
);
|
|
77
|
+
deviceUpdateSpy = jest
|
|
78
|
+
.spyOn(NetworkDeviceService, "updateOneById")
|
|
79
|
+
.mockResolvedValue(undefined);
|
|
80
|
+
monitorFindSpy = jest
|
|
81
|
+
.spyOn(MonitorService, "findBy")
|
|
82
|
+
.mockResolvedValue(options?.monitors || []);
|
|
83
|
+
monitorResourceSpy = jest
|
|
84
|
+
.spyOn(MonitorResourceUtil, "monitorResource")
|
|
85
|
+
.mockResolvedValue(undefined as never);
|
|
86
|
+
inventorySpy = jest
|
|
87
|
+
.spyOn(NetworkInventoryUtil, "updateFromWalk")
|
|
88
|
+
.mockResolvedValue(undefined);
|
|
89
|
+
metricsSpy = jest
|
|
90
|
+
.spyOn(NetworkDeviceMetricUtil, "saveWalkMetrics")
|
|
91
|
+
.mockResolvedValue(undefined);
|
|
92
|
+
rateSpy = jest
|
|
93
|
+
.spyOn(SnmpInterfaceRateUtil, "attachInterfaceRates")
|
|
94
|
+
.mockImplementation(() => {
|
|
95
|
+
return undefined;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function buildSnmpResponse(
|
|
100
|
+
overrides?: Partial<SnmpMonitorResponse>,
|
|
101
|
+
): SnmpMonitorResponse {
|
|
102
|
+
return {
|
|
103
|
+
isOnline: true,
|
|
104
|
+
responseTimeInMs: 42,
|
|
105
|
+
failureCause: "",
|
|
106
|
+
oidResponses: [],
|
|
107
|
+
isTimeout: false,
|
|
108
|
+
interfaces: [
|
|
109
|
+
{
|
|
110
|
+
interfaceIndex: 1,
|
|
111
|
+
name: "GigabitEthernet0/1",
|
|
112
|
+
isOperationallyUp: true,
|
|
113
|
+
isAdministrativelyUp: true,
|
|
114
|
+
inOctets: 5000,
|
|
115
|
+
outOctets: 7000,
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
...overrides,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function buildStep(networkDeviceId: string | undefined): MonitorStep {
|
|
123
|
+
const step: MonitorStep = new MonitorStep();
|
|
124
|
+
step.data = {
|
|
125
|
+
...step.data,
|
|
126
|
+
networkDeviceMonitor:
|
|
127
|
+
networkDeviceId === undefined
|
|
128
|
+
? undefined
|
|
129
|
+
: {
|
|
130
|
+
networkDeviceId: networkDeviceId,
|
|
131
|
+
monitorInterfaces: true,
|
|
132
|
+
oids: [],
|
|
133
|
+
},
|
|
134
|
+
} as MonitorStep["data"];
|
|
135
|
+
return step;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function buildMonitor(options: {
|
|
139
|
+
steps: Array<MonitorStep>;
|
|
140
|
+
disableActiveMonitoring?: boolean | undefined;
|
|
141
|
+
disabledByIncident?: boolean | undefined;
|
|
142
|
+
disabledByMaintenance?: boolean | undefined;
|
|
143
|
+
}): Monitor {
|
|
144
|
+
const monitorSteps: MonitorSteps = new MonitorSteps();
|
|
145
|
+
monitorSteps.data = {
|
|
146
|
+
monitorStepsInstanceArray: options.steps,
|
|
147
|
+
defaultMonitorStatusId: undefined,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const monitor: Monitor = new Monitor();
|
|
151
|
+
monitor.id = ObjectID.generate();
|
|
152
|
+
monitor.projectId = PROJECT_ID;
|
|
153
|
+
monitor.monitorSteps = monitorSteps;
|
|
154
|
+
monitor.disableActiveMonitoring = options.disableActiveMonitoring || false;
|
|
155
|
+
monitor.disableActiveMonitoringBecauseOfManualIncident =
|
|
156
|
+
options.disabledByIncident || false;
|
|
157
|
+
monitor.disableActiveMonitoringBecauseOfScheduledMaintenanceEvent =
|
|
158
|
+
options.disabledByMaintenance || false;
|
|
159
|
+
return monitor;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function runWalk(snmpResponse: SnmpMonitorResponse): Promise<void> {
|
|
163
|
+
await NetworkDeviceWalkUtil.processWalkResult({
|
|
164
|
+
probeId: PROBE_ID,
|
|
165
|
+
networkDeviceId: new ObjectID(DEVICE_ID),
|
|
166
|
+
snmpResponse: snmpResponse,
|
|
167
|
+
monitoredAt: MONITORED_AT,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
beforeEach(() => {
|
|
172
|
+
jest.spyOn(OneUptimeDate, "getCurrentDate").mockReturnValue(NOW);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
afterEach(() => {
|
|
176
|
+
jest.restoreAllMocks();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
describe("NetworkDeviceWalkUtil.processWalkResult — probe-scoping guard", () => {
|
|
180
|
+
test("the device lookup is scoped to the reporting probe", async () => {
|
|
181
|
+
mockPipeline();
|
|
182
|
+
|
|
183
|
+
await runWalk(buildSnmpResponse());
|
|
184
|
+
|
|
185
|
+
expect(deviceFindSpy).toHaveBeenCalledTimes(1);
|
|
186
|
+
const query: JSONObject = deviceFindSpy.mock.calls[0][0].query;
|
|
187
|
+
expect((query["_id"] as ObjectID).toString()).toBe(DEVICE_ID);
|
|
188
|
+
expect((query["probeId"] as ObjectID).toString()).toBe(PROBE_ID.toString());
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
/*
|
|
192
|
+
* The auth middleware only proves the caller is SOME valid probe; a walk
|
|
193
|
+
* for a device the probe is not assigned to must be dropped before any
|
|
194
|
+
* write, or a compromised probe could overwrite another project's
|
|
195
|
+
* inventory and trigger its monitors.
|
|
196
|
+
*/
|
|
197
|
+
test("a walk from a probe the device is not assigned to is ignored entirely", async () => {
|
|
198
|
+
mockPipeline({ device: null });
|
|
199
|
+
|
|
200
|
+
await runWalk(buildSnmpResponse());
|
|
201
|
+
|
|
202
|
+
expect(rateSpy).not.toHaveBeenCalled();
|
|
203
|
+
expect(deviceUpdateSpy).not.toHaveBeenCalled();
|
|
204
|
+
expect(inventorySpy).not.toHaveBeenCalled();
|
|
205
|
+
expect(metricsSpy).not.toHaveBeenCalled();
|
|
206
|
+
expect(monitorFindSpy).not.toHaveBeenCalled();
|
|
207
|
+
expect(monitorResourceSpy).not.toHaveBeenCalled();
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
describe("NetworkDeviceWalkUtil.processWalkResult — happy path", () => {
|
|
212
|
+
test("rates are computed against the device's stored lastWalkLog, before the new baseline is persisted", async () => {
|
|
213
|
+
mockPipeline();
|
|
214
|
+
const snmpResponse: SnmpMonitorResponse = buildSnmpResponse();
|
|
215
|
+
|
|
216
|
+
await runWalk(snmpResponse);
|
|
217
|
+
|
|
218
|
+
expect(rateSpy).toHaveBeenCalledTimes(1);
|
|
219
|
+
// Rates work on the very object the rest of the pipeline consumes.
|
|
220
|
+
expect(rateSpy.mock.calls[0][0].snmpResponse).toBe(snmpResponse);
|
|
221
|
+
expect(rateSpy.mock.calls[0][0].previousWalkLog).toBe(PREVIOUS_WALK_LOG);
|
|
222
|
+
|
|
223
|
+
/*
|
|
224
|
+
* Persisting first would make the delta baseline the walk itself —
|
|
225
|
+
* every rate would compute to zero.
|
|
226
|
+
*/
|
|
227
|
+
expect(rateSpy.mock.invocationCallOrder[0]).toBeLessThan(
|
|
228
|
+
deviceUpdateSpy.mock.invocationCallOrder[0] as number,
|
|
229
|
+
);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test("a walk with interfaces persists itself as the next delta baseline", async () => {
|
|
233
|
+
mockPipeline();
|
|
234
|
+
const snmpResponse: SnmpMonitorResponse = buildSnmpResponse();
|
|
235
|
+
|
|
236
|
+
await runWalk(snmpResponse);
|
|
237
|
+
|
|
238
|
+
expect(deviceUpdateSpy).toHaveBeenCalledTimes(1);
|
|
239
|
+
const updateArgs: JSONObject = deviceUpdateSpy.mock.calls[0][0];
|
|
240
|
+
expect((updateArgs["id"] as ObjectID).toString()).toBe(DEVICE_ID);
|
|
241
|
+
|
|
242
|
+
const lastWalkLog: JSONObject = (updateArgs["data"] as JSONObject)[
|
|
243
|
+
"lastWalkLog"
|
|
244
|
+
] as JSONObject;
|
|
245
|
+
// A plain-JSON snapshot of the walk, not the live object.
|
|
246
|
+
expect(lastWalkLog["snmpResponse"]).toEqual(
|
|
247
|
+
JSON.parse(JSON.stringify(snmpResponse)),
|
|
248
|
+
);
|
|
249
|
+
expect(lastWalkLog["snmpResponse"]).not.toBe(snmpResponse);
|
|
250
|
+
expect(lastWalkLog["monitoredAt"]).toEqual(NOW);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test("inventory is synced with the device's own projectId/deviceId and the in-flight response", async () => {
|
|
254
|
+
mockPipeline();
|
|
255
|
+
const snmpResponse: SnmpMonitorResponse = buildSnmpResponse();
|
|
256
|
+
|
|
257
|
+
await runWalk(snmpResponse);
|
|
258
|
+
|
|
259
|
+
expect(inventorySpy).toHaveBeenCalledTimes(1);
|
|
260
|
+
const inventoryArgs: JSONObject = inventorySpy.mock.calls[0][0];
|
|
261
|
+
expect((inventoryArgs["projectId"] as ObjectID).toString()).toBe(
|
|
262
|
+
PROJECT_ID.toString(),
|
|
263
|
+
);
|
|
264
|
+
expect((inventoryArgs["deviceId"] as ObjectID).toString()).toBe(DEVICE_ID);
|
|
265
|
+
expect(inventoryArgs["snmpResponse"]).toBe(snmpResponse);
|
|
266
|
+
expect(inventoryArgs["isOnline"]).toBe(true);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test("device-scoped metrics are emitted with the device and probe identity", async () => {
|
|
270
|
+
mockPipeline();
|
|
271
|
+
const snmpResponse: SnmpMonitorResponse = buildSnmpResponse();
|
|
272
|
+
|
|
273
|
+
await runWalk(snmpResponse);
|
|
274
|
+
|
|
275
|
+
expect(metricsSpy).toHaveBeenCalledTimes(1);
|
|
276
|
+
const metricArgs: JSONObject = metricsSpy.mock.calls[0][0];
|
|
277
|
+
expect((metricArgs["projectId"] as ObjectID).toString()).toBe(
|
|
278
|
+
PROJECT_ID.toString(),
|
|
279
|
+
);
|
|
280
|
+
expect((metricArgs["networkDeviceId"] as ObjectID).toString()).toBe(
|
|
281
|
+
DEVICE_ID,
|
|
282
|
+
);
|
|
283
|
+
expect(metricArgs["deviceName"]).toBe("core-sw-01");
|
|
284
|
+
expect((metricArgs["probeId"] as ObjectID).toString()).toBe(
|
|
285
|
+
PROBE_ID.toString(),
|
|
286
|
+
);
|
|
287
|
+
expect(metricArgs["snmpResponse"]).toBe(snmpResponse);
|
|
288
|
+
expect(metricArgs["responseTimeInMs"]).toBe(42);
|
|
289
|
+
expect(metricArgs["isOnline"]).toBe(true);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
describe("NetworkDeviceWalkUtil.processWalkResult — failed poll", () => {
|
|
294
|
+
/*
|
|
295
|
+
* Keeping the last GOOD counters across failed polls means rates resume
|
|
296
|
+
* with a correct (longer-window) delta instead of losing a cycle.
|
|
297
|
+
*/
|
|
298
|
+
test("a poll that walked no interfaces never overwrites the stored baseline", async () => {
|
|
299
|
+
mockPipeline();
|
|
300
|
+
|
|
301
|
+
await runWalk(
|
|
302
|
+
buildSnmpResponse({
|
|
303
|
+
isOnline: false,
|
|
304
|
+
isTimeout: true,
|
|
305
|
+
failureCause: "Device did not respond",
|
|
306
|
+
interfaces: undefined,
|
|
307
|
+
}),
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
expect(deviceUpdateSpy).not.toHaveBeenCalled();
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
test("an empty interface array is treated the same as no interfaces", async () => {
|
|
314
|
+
mockPipeline();
|
|
315
|
+
|
|
316
|
+
await runWalk(buildSnmpResponse({ interfaces: [] }));
|
|
317
|
+
|
|
318
|
+
expect(deviceUpdateSpy).not.toHaveBeenCalled();
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test("inventory and metrics still run on a failed poll (lastSeenAt gating is inventory's job)", async () => {
|
|
322
|
+
mockPipeline();
|
|
323
|
+
|
|
324
|
+
await runWalk(
|
|
325
|
+
buildSnmpResponse({
|
|
326
|
+
isOnline: false,
|
|
327
|
+
isTimeout: true,
|
|
328
|
+
failureCause: "Device did not respond",
|
|
329
|
+
interfaces: undefined,
|
|
330
|
+
}),
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
expect(inventorySpy).toHaveBeenCalledTimes(1);
|
|
334
|
+
expect(inventorySpy.mock.calls[0][0]["isOnline"]).toBe(false);
|
|
335
|
+
expect(metricsSpy).toHaveBeenCalledTimes(1);
|
|
336
|
+
expect(metricsSpy.mock.calls[0][0]["isOnline"]).toBe(false);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
describe("NetworkDeviceWalkUtil.processWalkResult — fault isolation", () => {
|
|
341
|
+
test("a metrics failure does not break the pipeline: fan-out still happens", async () => {
|
|
342
|
+
const watching: Monitor = buildMonitor({ steps: [buildStep(DEVICE_ID)] });
|
|
343
|
+
mockPipeline({ monitors: [watching] });
|
|
344
|
+
metricsSpy.mockRejectedValue(new Error("clickhouse is down"));
|
|
345
|
+
|
|
346
|
+
await expect(runWalk(buildSnmpResponse())).resolves.toBeUndefined();
|
|
347
|
+
|
|
348
|
+
expect(monitorFindSpy).toHaveBeenCalledTimes(1);
|
|
349
|
+
expect(monitorResourceSpy).toHaveBeenCalledTimes(1);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
test("one monitor's evaluation failure does not prevent evaluating the next", async () => {
|
|
353
|
+
const first: Monitor = buildMonitor({ steps: [buildStep(DEVICE_ID)] });
|
|
354
|
+
const second: Monitor = buildMonitor({ steps: [buildStep(DEVICE_ID)] });
|
|
355
|
+
mockPipeline({ monitors: [first, second] });
|
|
356
|
+
monitorResourceSpy.mockRejectedValueOnce(
|
|
357
|
+
new Error("criteria evaluation exploded"),
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
await expect(runWalk(buildSnmpResponse())).resolves.toBeUndefined();
|
|
361
|
+
|
|
362
|
+
expect(monitorResourceSpy).toHaveBeenCalledTimes(2);
|
|
363
|
+
expect(
|
|
364
|
+
(
|
|
365
|
+
monitorResourceSpy.mock.calls[1][0] as ProbeMonitorResponse
|
|
366
|
+
).monitorId.toString(),
|
|
367
|
+
).toBe(second.id!.toString());
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
describe("NetworkDeviceWalkUtil.processWalkResult — monitor fan-out", () => {
|
|
372
|
+
test("only enabled monitors' steps referencing the walked device are evaluated", async () => {
|
|
373
|
+
const watching: Monitor = buildMonitor({ steps: [buildStep(DEVICE_ID)] });
|
|
374
|
+
const disabled: Monitor = buildMonitor({
|
|
375
|
+
steps: [buildStep(DEVICE_ID)],
|
|
376
|
+
disableActiveMonitoring: true,
|
|
377
|
+
});
|
|
378
|
+
const disabledByIncident: Monitor = buildMonitor({
|
|
379
|
+
steps: [buildStep(DEVICE_ID)],
|
|
380
|
+
disabledByIncident: true,
|
|
381
|
+
});
|
|
382
|
+
const disabledByMaintenance: Monitor = buildMonitor({
|
|
383
|
+
steps: [buildStep(DEVICE_ID)],
|
|
384
|
+
disabledByMaintenance: true,
|
|
385
|
+
});
|
|
386
|
+
const watchingOtherDevice: Monitor = buildMonitor({
|
|
387
|
+
steps: [buildStep(OTHER_DEVICE_ID)],
|
|
388
|
+
});
|
|
389
|
+
const watchingTwice: Monitor = buildMonitor({
|
|
390
|
+
steps: [buildStep(DEVICE_ID), buildStep(DEVICE_ID)],
|
|
391
|
+
});
|
|
392
|
+
const watchingBoth: Monitor = buildMonitor({
|
|
393
|
+
steps: [buildStep(DEVICE_ID), buildStep(OTHER_DEVICE_ID)],
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
mockPipeline({
|
|
397
|
+
monitors: [
|
|
398
|
+
watching,
|
|
399
|
+
disabled,
|
|
400
|
+
disabledByIncident,
|
|
401
|
+
disabledByMaintenance,
|
|
402
|
+
watchingOtherDevice,
|
|
403
|
+
watchingTwice,
|
|
404
|
+
watchingBoth,
|
|
405
|
+
],
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
await runWalk(buildSnmpResponse());
|
|
409
|
+
|
|
410
|
+
// watching(1) + watchingTwice(2) + watchingBoth's matching step(1).
|
|
411
|
+
expect(monitorResourceSpy).toHaveBeenCalledTimes(4);
|
|
412
|
+
|
|
413
|
+
const evaluatedMonitorIds: Array<string> =
|
|
414
|
+
monitorResourceSpy.mock.calls.map((call: Array<ProbeMonitorResponse>) => {
|
|
415
|
+
return call[0]!.monitorId.toString();
|
|
416
|
+
});
|
|
417
|
+
expect(evaluatedMonitorIds).toEqual([
|
|
418
|
+
watching.id!.toString(),
|
|
419
|
+
watchingTwice.id!.toString(),
|
|
420
|
+
watchingTwice.id!.toString(),
|
|
421
|
+
watchingBoth.id!.toString(),
|
|
422
|
+
]);
|
|
423
|
+
|
|
424
|
+
// The two-step monitor is evaluated once per referencing step.
|
|
425
|
+
const twiceStepIds: Array<string> = monitorResourceSpy.mock.calls
|
|
426
|
+
.filter((call: Array<ProbeMonitorResponse>) => {
|
|
427
|
+
return call[0]!.monitorId.toString() === watchingTwice.id!.toString();
|
|
428
|
+
})
|
|
429
|
+
.map((call: Array<ProbeMonitorResponse>) => {
|
|
430
|
+
return call[0]!.monitorStepId.toString();
|
|
431
|
+
});
|
|
432
|
+
expect(twiceStepIds).toEqual(
|
|
433
|
+
watchingTwice.monitorSteps!.data!.monitorStepsInstanceArray.map(
|
|
434
|
+
(step: MonitorStep) => {
|
|
435
|
+
return step.id.toString();
|
|
436
|
+
},
|
|
437
|
+
),
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
// The mixed monitor is only evaluated for the step watching THIS device.
|
|
441
|
+
const mixedCalls: Array<Array<ProbeMonitorResponse>> =
|
|
442
|
+
monitorResourceSpy.mock.calls.filter(
|
|
443
|
+
(call: Array<ProbeMonitorResponse>) => {
|
|
444
|
+
return call[0]!.monitorId.toString() === watchingBoth.id!.toString();
|
|
445
|
+
},
|
|
446
|
+
);
|
|
447
|
+
expect(mixedCalls).toHaveLength(1);
|
|
448
|
+
expect(mixedCalls[0]![0]!.monitorStepId.toString()).toBe(
|
|
449
|
+
watchingBoth.monitorSteps!.data!.monitorStepsInstanceArray[0]!.id.toString(),
|
|
450
|
+
);
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
test("the synthesized response carries the walk verbatim into the criteria pipeline", async () => {
|
|
454
|
+
const step: MonitorStep = buildStep(DEVICE_ID);
|
|
455
|
+
const monitor: Monitor = buildMonitor({ steps: [step] });
|
|
456
|
+
mockPipeline({ monitors: [monitor] });
|
|
457
|
+
|
|
458
|
+
const snmpResponse: SnmpMonitorResponse = buildSnmpResponse({
|
|
459
|
+
isOnline: false,
|
|
460
|
+
responseTimeInMs: 5000,
|
|
461
|
+
isTimeout: true,
|
|
462
|
+
failureCause: "SNMP timed out after 3 attempts",
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
await runWalk(snmpResponse);
|
|
466
|
+
|
|
467
|
+
expect(monitorResourceSpy).toHaveBeenCalledTimes(1);
|
|
468
|
+
const synthesized: ProbeMonitorResponse =
|
|
469
|
+
monitorResourceSpy.mock.calls[0][0];
|
|
470
|
+
|
|
471
|
+
expect(synthesized.projectId.toString()).toBe(PROJECT_ID.toString());
|
|
472
|
+
expect(synthesized.monitorId.toString()).toBe(monitor.id!.toString());
|
|
473
|
+
expect(synthesized.monitorStepId.toString()).toBe(step.id.toString());
|
|
474
|
+
expect(synthesized.probeId.toString()).toBe(PROBE_ID.toString());
|
|
475
|
+
expect(synthesized.snmpResponse).toBe(snmpResponse);
|
|
476
|
+
expect(synthesized.isOnline).toBe(false);
|
|
477
|
+
expect(synthesized.responseTimeInMs).toBe(5000);
|
|
478
|
+
expect(synthesized.isTimeout).toBe(true);
|
|
479
|
+
expect(synthesized.failureCause).toBe("SNMP timed out after 3 attempts");
|
|
480
|
+
expect(synthesized.monitoredAt).toEqual(MONITORED_AT);
|
|
481
|
+
expect(synthesized.ingestedAt).toEqual(NOW);
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
test("a walk with no failure cause synthesizes an empty string, never undefined", async () => {
|
|
485
|
+
mockPipeline({
|
|
486
|
+
monitors: [buildMonitor({ steps: [buildStep(DEVICE_ID)] })],
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
const snmpResponse: SnmpMonitorResponse = buildSnmpResponse();
|
|
490
|
+
delete (snmpResponse as Partial<SnmpMonitorResponse>).failureCause;
|
|
491
|
+
|
|
492
|
+
await runWalk(snmpResponse);
|
|
493
|
+
|
|
494
|
+
expect(
|
|
495
|
+
(monitorResourceSpy.mock.calls[0][0] as ProbeMonitorResponse)
|
|
496
|
+
.failureCause,
|
|
497
|
+
).toBe("");
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
describe("NetworkDeviceWalkUtil.findMonitorsWatchingDevices", () => {
|
|
502
|
+
test("an empty device list short-circuits without querying", async () => {
|
|
503
|
+
mockPipeline();
|
|
504
|
+
|
|
505
|
+
const monitors: Array<Monitor> =
|
|
506
|
+
await NetworkDeviceWalkUtil.findMonitorsWatchingDevices({
|
|
507
|
+
projectId: PROJECT_ID,
|
|
508
|
+
deviceIds: [],
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
expect(monitors).toEqual([]);
|
|
512
|
+
expect(monitorFindSpy).not.toHaveBeenCalled();
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
test("queries the project's Network Device monitors", async () => {
|
|
516
|
+
mockPipeline();
|
|
517
|
+
|
|
518
|
+
await NetworkDeviceWalkUtil.findMonitorsWatchingDevices({
|
|
519
|
+
projectId: PROJECT_ID,
|
|
520
|
+
deviceIds: [DEVICE_ID],
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
expect(monitorFindSpy).toHaveBeenCalledTimes(1);
|
|
524
|
+
const query: JSONObject = monitorFindSpy.mock.calls[0][0].query;
|
|
525
|
+
expect((query["projectId"] as ObjectID).toString()).toBe(
|
|
526
|
+
PROJECT_ID.toString(),
|
|
527
|
+
);
|
|
528
|
+
expect(query["monitorType"]).toBe(MonitorType.NetworkDevice);
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
test("keeps only monitors with at least one step referencing a given device, tolerating malformed steps", async () => {
|
|
532
|
+
const watching: Monitor = buildMonitor({ steps: [buildStep(DEVICE_ID)] });
|
|
533
|
+
const watchingOther: Monitor = buildMonitor({
|
|
534
|
+
steps: [buildStep(OTHER_DEVICE_ID)],
|
|
535
|
+
});
|
|
536
|
+
const mixedSteps: Monitor = buildMonitor({
|
|
537
|
+
steps: [buildStep(undefined), buildStep(DEVICE_ID)],
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
// Degenerate rows must be skipped, not crash the filter.
|
|
541
|
+
const noSteps: Monitor = new Monitor();
|
|
542
|
+
noSteps.id = ObjectID.generate();
|
|
543
|
+
noSteps.projectId = PROJECT_ID;
|
|
544
|
+
|
|
545
|
+
const stepsWithoutData: Monitor = buildMonitor({ steps: [] });
|
|
546
|
+
stepsWithoutData.monitorSteps!.data = undefined;
|
|
547
|
+
|
|
548
|
+
const stepWithoutData: MonitorStep = new MonitorStep();
|
|
549
|
+
stepWithoutData.data = undefined;
|
|
550
|
+
const stepDataMissing: Monitor = buildMonitor({
|
|
551
|
+
steps: [stepWithoutData],
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
const noDeviceReference: Monitor = buildMonitor({
|
|
555
|
+
steps: [buildStep(undefined)],
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
mockPipeline({
|
|
559
|
+
monitors: [
|
|
560
|
+
watching,
|
|
561
|
+
watchingOther,
|
|
562
|
+
mixedSteps,
|
|
563
|
+
noSteps,
|
|
564
|
+
stepsWithoutData,
|
|
565
|
+
stepDataMissing,
|
|
566
|
+
noDeviceReference,
|
|
567
|
+
],
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
const monitors: Array<Monitor> =
|
|
571
|
+
await NetworkDeviceWalkUtil.findMonitorsWatchingDevices({
|
|
572
|
+
projectId: PROJECT_ID,
|
|
573
|
+
deviceIds: [DEVICE_ID],
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
expect(
|
|
577
|
+
monitors.map((monitor: Monitor) => {
|
|
578
|
+
return monitor.id!.toString();
|
|
579
|
+
}),
|
|
580
|
+
).toEqual([watching.id!.toString(), mixedSteps.id!.toString()]);
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
test("matches monitors referencing ANY of the given devices", async () => {
|
|
584
|
+
const watchingFirst: Monitor = buildMonitor({
|
|
585
|
+
steps: [buildStep(DEVICE_ID)],
|
|
586
|
+
});
|
|
587
|
+
const watchingSecond: Monitor = buildMonitor({
|
|
588
|
+
steps: [buildStep(OTHER_DEVICE_ID)],
|
|
589
|
+
});
|
|
590
|
+
mockPipeline({ monitors: [watchingFirst, watchingSecond] });
|
|
591
|
+
|
|
592
|
+
const monitors: Array<Monitor> =
|
|
593
|
+
await NetworkDeviceWalkUtil.findMonitorsWatchingDevices({
|
|
594
|
+
projectId: PROJECT_ID,
|
|
595
|
+
deviceIds: [DEVICE_ID, OTHER_DEVICE_ID],
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
expect(monitors).toHaveLength(2);
|
|
599
|
+
});
|
|
600
|
+
});
|