@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
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import KubernetesCostAllocation from "../../../Models/AnalyticsModels/KubernetesCostAllocation";
|
|
2
|
+
import AnalyticsTableColumn from "../../../Types/AnalyticsDatabase/TableColumn";
|
|
3
|
+
import TableColumnType from "../../../Types/AnalyticsDatabase/TableColumnType";
|
|
4
|
+
import Permission from "../../../Types/Permission";
|
|
5
|
+
|
|
6
|
+
describe("Analytics KubernetesCostAllocation model", () => {
|
|
7
|
+
const model: KubernetesCostAllocation = new KubernetesCostAllocation();
|
|
8
|
+
|
|
9
|
+
test("has the expected table identity and API path", () => {
|
|
10
|
+
expect(model.tableName).toBe("KubernetesCostAllocationV1");
|
|
11
|
+
expect(model.crudApiPath?.toString()).toBe("/kubernetes-cost-allocation");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("sorts and partitions by cluster and window", () => {
|
|
15
|
+
expect(model.sortKeys).toEqual([
|
|
16
|
+
"projectId",
|
|
17
|
+
"kubernetesClusterId",
|
|
18
|
+
"windowStart",
|
|
19
|
+
"namespace",
|
|
20
|
+
]);
|
|
21
|
+
expect(model.primaryKeys).toEqual(model.sortKeys);
|
|
22
|
+
expect(model.partitionKey).toBe("toYYYYMMDD(windowStart)");
|
|
23
|
+
expect(model.shardingKey).toBe(
|
|
24
|
+
"cityHash64(projectId, kubernetesClusterId)",
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("expires rows via the retentionDate TTL", () => {
|
|
29
|
+
expect(model.ttlExpression).toBe("retentionDate DELETE");
|
|
30
|
+
const retentionDate: AnalyticsTableColumn | null =
|
|
31
|
+
model.getTableColumn("retentionDate");
|
|
32
|
+
expect(retentionDate?.type).toBe(TableColumnType.Date);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("declares every cost / usage / efficiency measure as a required Decimal", () => {
|
|
36
|
+
const measures: Array<string> = [
|
|
37
|
+
"cpuCoreHours",
|
|
38
|
+
"cpuCoreRequestAverage",
|
|
39
|
+
"cpuCoreUsageAverage",
|
|
40
|
+
"cpuCost",
|
|
41
|
+
"gpuHours",
|
|
42
|
+
"gpuCost",
|
|
43
|
+
"ramByteHours",
|
|
44
|
+
"ramBytesRequestAverage",
|
|
45
|
+
"ramBytesUsageAverage",
|
|
46
|
+
"ramCost",
|
|
47
|
+
"pvByteHours",
|
|
48
|
+
"pvCost",
|
|
49
|
+
"networkCost",
|
|
50
|
+
"loadBalancerCost",
|
|
51
|
+
"sharedCost",
|
|
52
|
+
"externalCost",
|
|
53
|
+
"totalCost",
|
|
54
|
+
"cpuEfficiency",
|
|
55
|
+
"ramEfficiency",
|
|
56
|
+
"totalEfficiency",
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
for (const key of measures) {
|
|
60
|
+
const column: AnalyticsTableColumn | null = model.getTableColumn(key);
|
|
61
|
+
expect(column).not.toBeNull();
|
|
62
|
+
expect(column?.type).toBe(TableColumnType.Decimal);
|
|
63
|
+
expect(column?.required).toBe(true);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("declares the workload identity dimensions", () => {
|
|
68
|
+
const dimensions: Array<string> = [
|
|
69
|
+
"clusterName",
|
|
70
|
+
"k8sClusterEntityKey",
|
|
71
|
+
"namespace",
|
|
72
|
+
"controllerKind",
|
|
73
|
+
"controllerName",
|
|
74
|
+
"podName",
|
|
75
|
+
"containerName",
|
|
76
|
+
"nodeName",
|
|
77
|
+
"providerId",
|
|
78
|
+
"currency",
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
for (const key of dimensions) {
|
|
82
|
+
const column: AnalyticsTableColumn | null = model.getTableColumn(key);
|
|
83
|
+
expect(column).not.toBeNull();
|
|
84
|
+
expect(column?.type).toBe(TableColumnType.Text);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
expect(model.getTableColumn("windowStart")?.type).toBe(
|
|
88
|
+
TableColumnType.DateTime64,
|
|
89
|
+
);
|
|
90
|
+
expect(model.getTableColumn("windowEnd")?.type).toBe(
|
|
91
|
+
TableColumnType.DateTime64,
|
|
92
|
+
);
|
|
93
|
+
expect(model.getTableColumn("kubernetesClusterId")?.type).toBe(
|
|
94
|
+
TableColumnType.ObjectID,
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("stores labels as a map with an extracted key column", () => {
|
|
99
|
+
const labels: AnalyticsTableColumn | null = model.getTableColumn("labels");
|
|
100
|
+
expect(labels?.type).toBe(TableColumnType.MapStringString);
|
|
101
|
+
expect(labels?.mapKeysColumn).toBe("labelKeys");
|
|
102
|
+
|
|
103
|
+
const labelKeys: AnalyticsTableColumn | null =
|
|
104
|
+
model.getTableColumn("labelKeys");
|
|
105
|
+
expect(labelKeys?.type).toBe(TableColumnType.ArrayText);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("access control mirrors the KubernetesCluster model", () => {
|
|
109
|
+
expect(model.accessControl?.read).toContain(
|
|
110
|
+
Permission.ReadKubernetesCluster,
|
|
111
|
+
);
|
|
112
|
+
expect(model.accessControl?.create).toContain(
|
|
113
|
+
Permission.CreateKubernetesCluster,
|
|
114
|
+
);
|
|
115
|
+
expect(model.accessControl?.delete).toContain(
|
|
116
|
+
Permission.DeleteKubernetesCluster,
|
|
117
|
+
);
|
|
118
|
+
// Cost rows are immutable facts — nothing may update them.
|
|
119
|
+
expect(model.accessControl?.update).toEqual([]);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("deserializes ClickHouse DateTime64 window values as Dates", () => {
|
|
123
|
+
const row: KubernetesCostAllocation = KubernetesCostAllocation.fromJSON(
|
|
124
|
+
{
|
|
125
|
+
windowStart: "2026-07-24 10:00:00.000000000",
|
|
126
|
+
windowEnd: "2026-07-24 11:00:00.000000000",
|
|
127
|
+
},
|
|
128
|
+
KubernetesCostAllocation,
|
|
129
|
+
) as KubernetesCostAllocation;
|
|
130
|
+
|
|
131
|
+
expect(row.windowStart).toBeInstanceOf(Date);
|
|
132
|
+
expect(row.windowStart?.toISOString()).toBe("2026-07-24T10:00:00.000Z");
|
|
133
|
+
expect(row.windowEnd?.toISOString()).toBe("2026-07-24T11:00:00.000Z");
|
|
134
|
+
});
|
|
135
|
+
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NetworkSite hierarchy model contracts.
|
|
3
|
+
*
|
|
4
|
+
* NetworkSite is the schema's first self-nesting container: parentSite is a
|
|
5
|
+
* ManyToOne pointing back at NetworkSite itself. That self-reference is easy
|
|
6
|
+
* to break silently — a lazy-arrow typo or a decorator reorder leaves tsc
|
|
7
|
+
* green while TypeORM builds a relation to the wrong target. The FK actions
|
|
8
|
+
* are pinned too, because they carry the deletion semantics of the whole
|
|
9
|
+
* hierarchy: deleting a parent must orphan (SET NULL) its children, not
|
|
10
|
+
* cascade the subtree away, while timelines/links/rules die with their site.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import NetworkDevice from "../../Models/DatabaseModels/NetworkDevice";
|
|
14
|
+
import NetworkEndpoint from "../../Models/DatabaseModels/NetworkEndpoint";
|
|
15
|
+
import NetworkSite from "../../Models/DatabaseModels/NetworkSite";
|
|
16
|
+
import NetworkSiteAssignmentRule from "../../Models/DatabaseModels/NetworkSiteAssignmentRule";
|
|
17
|
+
import NetworkSiteLink from "../../Models/DatabaseModels/NetworkSiteLink";
|
|
18
|
+
import NetworkSiteStatusTimeline from "../../Models/DatabaseModels/NetworkSiteStatusTimeline";
|
|
19
|
+
import { TableColumnMetadata } from "../../Types/Database/TableColumn";
|
|
20
|
+
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
21
|
+
import { getUniqueColumnBy } from "../../Types/Database/UniqueColumnBy";
|
|
22
|
+
import GenericFunction from "../../Types/GenericFunction";
|
|
23
|
+
import { describe, expect, test } from "@jest/globals";
|
|
24
|
+
import { getMetadataArgsStorage } from "typeorm";
|
|
25
|
+
import { RelationMetadataArgs } from "typeorm/metadata-args/RelationMetadataArgs";
|
|
26
|
+
|
|
27
|
+
function relationArgs(
|
|
28
|
+
target: GenericFunction,
|
|
29
|
+
propertyName: string,
|
|
30
|
+
): RelationMetadataArgs | undefined {
|
|
31
|
+
return getMetadataArgsStorage().relations.find(
|
|
32
|
+
(relation: RelationMetadataArgs) => {
|
|
33
|
+
return (
|
|
34
|
+
relation.target === target && relation.propertyName === propertyName
|
|
35
|
+
);
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function relationTarget(
|
|
41
|
+
relation: RelationMetadataArgs | undefined,
|
|
42
|
+
): GenericFunction | undefined {
|
|
43
|
+
const type: unknown = relation?.type;
|
|
44
|
+
if (typeof type === "function" && type.prototype === undefined) {
|
|
45
|
+
return (type as () => GenericFunction)();
|
|
46
|
+
}
|
|
47
|
+
return type as GenericFunction | undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
describe("NetworkSite self-nesting hierarchy", () => {
|
|
51
|
+
test("parentSite is an Entity relation back to NetworkSite", () => {
|
|
52
|
+
const metadata: TableColumnMetadata =
|
|
53
|
+
new NetworkSite().getTableColumnMetadata("parentSite");
|
|
54
|
+
|
|
55
|
+
expect(metadata).toBeDefined();
|
|
56
|
+
expect(metadata.type).toBe(TableColumnType.Entity);
|
|
57
|
+
expect(metadata.modelType).toBe(NetworkSite);
|
|
58
|
+
expect(metadata.manyToOneRelationColumn).toBe("parentSiteId");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("parentSite FK resolves to NetworkSite and orphans children with SET NULL", () => {
|
|
62
|
+
const relation: RelationMetadataArgs | undefined = relationArgs(
|
|
63
|
+
NetworkSite,
|
|
64
|
+
"parentSite",
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
expect(relation).toBeDefined();
|
|
68
|
+
expect(relationTarget(relation)).toBe(NetworkSite);
|
|
69
|
+
expect(relation?.options.onDelete).toBe("SET NULL");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("NetworkDevice.site relation targets NetworkSite with SET NULL", () => {
|
|
73
|
+
const metadata: TableColumnMetadata =
|
|
74
|
+
new NetworkDevice().getTableColumnMetadata("site");
|
|
75
|
+
|
|
76
|
+
expect(metadata.modelType).toBe(NetworkSite);
|
|
77
|
+
expect(metadata.manyToOneRelationColumn).toBe("siteId");
|
|
78
|
+
|
|
79
|
+
const relation: RelationMetadataArgs | undefined = relationArgs(
|
|
80
|
+
NetworkDevice,
|
|
81
|
+
"site",
|
|
82
|
+
);
|
|
83
|
+
expect(relationTarget(relation)).toBe(NetworkSite);
|
|
84
|
+
expect(relation?.options.onDelete).toBe("SET NULL");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("child rows die with their site: CASCADE from timeline, link and rule", () => {
|
|
88
|
+
expect(
|
|
89
|
+
relationArgs(NetworkSiteStatusTimeline, "site")?.options.onDelete,
|
|
90
|
+
).toBe("CASCADE");
|
|
91
|
+
expect(relationArgs(NetworkSiteLink, "fromSite")?.options.onDelete).toBe(
|
|
92
|
+
"CASCADE",
|
|
93
|
+
);
|
|
94
|
+
expect(relationArgs(NetworkSiteLink, "toSite")?.options.onDelete).toBe(
|
|
95
|
+
"CASCADE",
|
|
96
|
+
);
|
|
97
|
+
expect(
|
|
98
|
+
relationArgs(NetworkSiteAssignmentRule, "site")?.options.onDelete,
|
|
99
|
+
).toBe("CASCADE");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("endpoints detach from sites (SET NULL) but die with their device (CASCADE)", () => {
|
|
103
|
+
expect(relationArgs(NetworkEndpoint, "site")?.options.onDelete).toBe(
|
|
104
|
+
"SET NULL",
|
|
105
|
+
);
|
|
106
|
+
expect(
|
|
107
|
+
relationArgs(NetworkEndpoint, "attachedNetworkDevice")?.options.onDelete,
|
|
108
|
+
).toBe("CASCADE");
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("endpoints are unique per MAC per project", () => {
|
|
112
|
+
expect(getUniqueColumnBy(new NetworkEndpoint(), "macAddress")).toBe(
|
|
113
|
+
"projectId",
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("crud api routes are registered", () => {
|
|
118
|
+
expect(new NetworkSite().getCrudApiPath()?.toString()).toBe(
|
|
119
|
+
"/network-site",
|
|
120
|
+
);
|
|
121
|
+
expect(new NetworkEndpoint().getCrudApiPath()?.toString()).toBe(
|
|
122
|
+
"/network-endpoint",
|
|
123
|
+
);
|
|
124
|
+
expect(new NetworkSiteStatusTimeline().getCrudApiPath()?.toString()).toBe(
|
|
125
|
+
"/network-site-status-timeline",
|
|
126
|
+
);
|
|
127
|
+
expect(new NetworkSiteLink().getCrudApiPath()?.toString()).toBe(
|
|
128
|
+
"/network-site-link",
|
|
129
|
+
);
|
|
130
|
+
expect(new NetworkSiteAssignmentRule().getCrudApiPath()?.toString()).toBe(
|
|
131
|
+
"/network-site-assignment-rule",
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
@@ -11,11 +11,15 @@ import AnalyticsTableEngine from "../../../Types/AnalyticsDatabase/AnalyticsTabl
|
|
|
11
11
|
import AnalyticsTableColumn from "../../../Types/AnalyticsDatabase/TableColumn";
|
|
12
12
|
import TableColumnType from "../../../Types/AnalyticsDatabase/TableColumnType";
|
|
13
13
|
import AggregationType from "../../../Types/BaseDatabase/AggregationType";
|
|
14
|
+
import GreaterThan from "../../../Types/BaseDatabase/GreaterThan";
|
|
15
|
+
import InBetween from "../../../Types/BaseDatabase/InBetween";
|
|
14
16
|
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
|
15
17
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
16
18
|
import GenericObject from "../../../Types/GenericObject";
|
|
17
19
|
import ObjectID from "../../../Types/ObjectID";
|
|
18
20
|
import OneUptimeDate from "../../../Types/Date";
|
|
21
|
+
import PositiveNumber from "../../../Types/PositiveNumber";
|
|
22
|
+
import ModelPermission from "../../../Server/Types/AnalyticsDatabase/ModelPermission";
|
|
19
23
|
import {
|
|
20
24
|
describe,
|
|
21
25
|
expect,
|
|
@@ -417,6 +421,98 @@ describe("AnalyticsDatabaseService", () => {
|
|
|
417
421
|
// A grouped query never needs the empty-window guard.
|
|
418
422
|
expect(query).not.toContain("HAVING count() > 0");
|
|
419
423
|
});
|
|
424
|
+
|
|
425
|
+
test("table-qualifies WHERE references so SELECT aliases cannot capture them", () => {
|
|
426
|
+
/*
|
|
427
|
+
* Regression for the Kubernetes Costs page 500: under Total the
|
|
428
|
+
* timestamp is selected as `min(col) as col`, and ClickHouse
|
|
429
|
+
* substitutes that alias into same-level unqualified WHERE
|
|
430
|
+
* references — `WHERE col >= ...` became
|
|
431
|
+
* `WHERE min(col) >= ...` (ILLEGAL_AGGREGATION). Qualified
|
|
432
|
+
* references (`table.col`) always resolve to the real column.
|
|
433
|
+
*/
|
|
434
|
+
const result: { statement: Statement; columns: Array<string> } =
|
|
435
|
+
service.toAggregateStatement(
|
|
436
|
+
makeBaseAggregateBy({
|
|
437
|
+
aggregationInterval: "Total",
|
|
438
|
+
groupBy: { column_1: true },
|
|
439
|
+
query: { column_1: "<cluster>" },
|
|
440
|
+
}),
|
|
441
|
+
);
|
|
442
|
+
const query: string = result.statement.query;
|
|
443
|
+
|
|
444
|
+
expect(query).toContain("min(column_ObjectID) as column_ObjectID");
|
|
445
|
+
expect(query).toMatch(
|
|
446
|
+
/AND \{p\d+_t:Identifier\}\.\{p\d+_c:Identifier\} = \{p\d+:String\}/,
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
const params: Record<string, unknown> = result.statement.query_params;
|
|
450
|
+
const qualifierEntries: Array<[string, unknown]> = Object.entries(
|
|
451
|
+
params,
|
|
452
|
+
).filter(([key]: [string, unknown]) => {
|
|
453
|
+
return key.endsWith("_t");
|
|
454
|
+
});
|
|
455
|
+
expect(qualifierEntries).toHaveLength(1);
|
|
456
|
+
expect(qualifierEntries[0]![1]).toBe("<table-name>");
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
test("bucketed queries qualify the window filter so it reads raw timestamps", () => {
|
|
460
|
+
/*
|
|
461
|
+
* Before qualification the bucket alias (`date_trunc(...) as col`)
|
|
462
|
+
* was substituted into WHERE, silently snapping the window edges
|
|
463
|
+
* to bucket boundaries. The filter must read the real column.
|
|
464
|
+
*/
|
|
465
|
+
const result: { statement: Statement; columns: Array<string> } =
|
|
466
|
+
service.toAggregateStatement(
|
|
467
|
+
makeBaseAggregateBy({
|
|
468
|
+
query: {
|
|
469
|
+
column_ObjectID: new InBetween(
|
|
470
|
+
new Date("2024-01-01"),
|
|
471
|
+
new Date("2024-01-02"),
|
|
472
|
+
),
|
|
473
|
+
},
|
|
474
|
+
}),
|
|
475
|
+
);
|
|
476
|
+
const query: string = result.statement.query;
|
|
477
|
+
|
|
478
|
+
expect(query).toContain("toStartOfInterval(column_ObjectID");
|
|
479
|
+
// Both InBetween bounds reference the qualified real column.
|
|
480
|
+
expect(query).toMatch(
|
|
481
|
+
/AND \{p\d+_t:Identifier\}\.\{p\d+_c:Identifier\} >= \{p\d+:String\} AND \{p\d+_t:Identifier\}\.\{p\d+_c:Identifier\} <= \{p\d+:String\}/,
|
|
482
|
+
);
|
|
483
|
+
// The GROUP BY / ORDER BY keep targeting the bare bucket alias.
|
|
484
|
+
expect(query).toContain("GROUP BY column_ObjectID");
|
|
485
|
+
|
|
486
|
+
const qualifiers: Array<unknown> = Object.entries(
|
|
487
|
+
result.statement.query_params,
|
|
488
|
+
)
|
|
489
|
+
.filter(([key]: [string, unknown]) => {
|
|
490
|
+
return key.endsWith("_t");
|
|
491
|
+
})
|
|
492
|
+
.map(([, value]: [string, unknown]) => {
|
|
493
|
+
return value;
|
|
494
|
+
});
|
|
495
|
+
expect(qualifiers).toStrictEqual(["<table-name>", "<table-name>"]);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
test("filters on the aggregated measure column stay on the real column", () => {
|
|
499
|
+
/*
|
|
500
|
+
* `sum(column_2) as column_2` shadows the measure column too — a
|
|
501
|
+
* WHERE on it would otherwise also become an aggregate reference.
|
|
502
|
+
*/
|
|
503
|
+
const result: { statement: Statement; columns: Array<string> } =
|
|
504
|
+
service.toAggregateStatement(
|
|
505
|
+
makeBaseAggregateBy({
|
|
506
|
+
query: { column_2: new GreaterThan(5) },
|
|
507
|
+
}),
|
|
508
|
+
);
|
|
509
|
+
const query: string = result.statement.query;
|
|
510
|
+
|
|
511
|
+
expect(query).toContain("sum(column_2) as column_2");
|
|
512
|
+
expect(query).toMatch(
|
|
513
|
+
/AND \{p\d+_t:Identifier\}\.\{p\d+_c:Identifier\} > \{p\d+:Int32\}/,
|
|
514
|
+
);
|
|
515
|
+
});
|
|
420
516
|
});
|
|
421
517
|
|
|
422
518
|
describe("toDeleteStatement", () => {
|
|
@@ -619,6 +715,149 @@ describe("AnalyticsDatabaseService", () => {
|
|
|
619
715
|
});
|
|
620
716
|
});
|
|
621
717
|
|
|
718
|
+
/*
|
|
719
|
+
* countBy parses the count() aggregate out of ClickHouse's JSON response.
|
|
720
|
+
* Whether that UInt64 arrives as a JSON string or a JSON number depends on
|
|
721
|
+
* the server's output_format_json_quote_64bit_integers setting — quoted
|
|
722
|
+
* (string) was the default until ClickHouse 25.x flipped it to numbers.
|
|
723
|
+
* A string-only typeof check silently read every count as 0 on modern
|
|
724
|
+
* servers, which made telemetry monitors (Logs / Traces / Exceptions)
|
|
725
|
+
* never meet their count-threshold criteria — monitors stuck "Operational"
|
|
726
|
+
* forever. These tests pin the parsing for both wire formats and every
|
|
727
|
+
* degraded-response shape.
|
|
728
|
+
*/
|
|
729
|
+
describe("countBy result parsing", () => {
|
|
730
|
+
let checkReadPermissionMock: jest.Mock;
|
|
731
|
+
|
|
732
|
+
const mockCountResponse: (response: unknown) => void = (
|
|
733
|
+
response: unknown,
|
|
734
|
+
): void => {
|
|
735
|
+
jest.spyOn(service, "executeQuery").mockResolvedValue({
|
|
736
|
+
json: () => {
|
|
737
|
+
return Promise.resolve(response);
|
|
738
|
+
},
|
|
739
|
+
} as never);
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
beforeEach(() => {
|
|
743
|
+
checkReadPermissionMock = jest
|
|
744
|
+
.spyOn(ModelPermission, "checkReadPermission")
|
|
745
|
+
.mockImplementation((_modelType: unknown, query: unknown) => {
|
|
746
|
+
return Promise.resolve({
|
|
747
|
+
query,
|
|
748
|
+
select: null,
|
|
749
|
+
} as never);
|
|
750
|
+
}) as unknown as jest.Mock;
|
|
751
|
+
jest.spyOn(logger, "debug").mockImplementation(() => {
|
|
752
|
+
return undefined!;
|
|
753
|
+
});
|
|
754
|
+
jest.spyOn(logger, "warn").mockImplementation(() => {
|
|
755
|
+
return undefined!;
|
|
756
|
+
});
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
afterEach(() => {
|
|
760
|
+
jest.restoreAllMocks();
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
const countBy: () => Promise<number> = async (): Promise<number> => {
|
|
764
|
+
const result: PositiveNumber = await service.countBy({
|
|
765
|
+
query: {},
|
|
766
|
+
props: { isRoot: true },
|
|
767
|
+
});
|
|
768
|
+
return result.toNumber();
|
|
769
|
+
};
|
|
770
|
+
|
|
771
|
+
test("parses count returned as a JSON number (ClickHouse >= 25.x default)", async () => {
|
|
772
|
+
mockCountResponse({ data: [{ count: 42 }] });
|
|
773
|
+
expect(await countBy()).toBe(42);
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
test("parses count returned as a JSON string (quoted 64-bit integers)", async () => {
|
|
777
|
+
mockCountResponse({ data: [{ count: "42" }] });
|
|
778
|
+
expect(await countBy()).toBe(42);
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
test("parses a numeric zero count as 0", async () => {
|
|
782
|
+
mockCountResponse({ data: [{ count: 0 }] });
|
|
783
|
+
expect(await countBy()).toBe(0);
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
test("parses a string zero count as 0", async () => {
|
|
787
|
+
mockCountResponse({ data: [{ count: "0" }] });
|
|
788
|
+
expect(await countBy()).toBe(0);
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
test("parses a count of 1 — the smallest value that can cross a monitor threshold", async () => {
|
|
792
|
+
// The default log-monitor offline criteria is "Log Count >= 1".
|
|
793
|
+
mockCountResponse({ data: [{ count: 1 }] });
|
|
794
|
+
expect(await countBy()).toBe(1);
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
test("parses a large count", async () => {
|
|
798
|
+
mockCountResponse({ data: [{ count: "6718284" }] });
|
|
799
|
+
expect(await countBy()).toBe(6718284);
|
|
800
|
+
});
|
|
801
|
+
|
|
802
|
+
test("defaults to 0 when the response has no data field", async () => {
|
|
803
|
+
mockCountResponse({});
|
|
804
|
+
expect(await countBy()).toBe(0);
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
test("defaults to 0 when the data array is empty", async () => {
|
|
808
|
+
mockCountResponse({ data: [] });
|
|
809
|
+
expect(await countBy()).toBe(0);
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
test("defaults to 0 when the row has no count key", async () => {
|
|
813
|
+
mockCountResponse({ data: [{ other: 5 }] });
|
|
814
|
+
expect(await countBy()).toBe(0);
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
test("defaults to 0 when the count value is null", async () => {
|
|
818
|
+
mockCountResponse({ data: [{ count: null }] });
|
|
819
|
+
expect(await countBy()).toBe(0);
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
test("defaults to 0 (with a warning) when the response body is unparseable", async () => {
|
|
823
|
+
/*
|
|
824
|
+
* timeout_overflow_mode='break' can truncate a count() response —
|
|
825
|
+
* json() then rejects. countBy must degrade to 0, not throw.
|
|
826
|
+
*/
|
|
827
|
+
jest.spyOn(service, "executeQuery").mockResolvedValue({
|
|
828
|
+
json: () => {
|
|
829
|
+
return Promise.reject(new Error("truncated response"));
|
|
830
|
+
},
|
|
831
|
+
} as never);
|
|
832
|
+
expect(await countBy()).toBe(0);
|
|
833
|
+
expect(logger.warn).toHaveBeenCalled();
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
test("uses the permission-checked query for the count statement", async () => {
|
|
837
|
+
mockCountResponse({ data: [{ count: 7 }] });
|
|
838
|
+
|
|
839
|
+
// Must be a real model column: the where-statement compiler rejects unknown keys.
|
|
840
|
+
const rewrittenQuery: GenericObject = { column_1: "tenant-scoped" };
|
|
841
|
+
checkReadPermissionMock.mockImplementation(() => {
|
|
842
|
+
return Promise.resolve({
|
|
843
|
+
query: rewrittenQuery,
|
|
844
|
+
select: null,
|
|
845
|
+
} as never);
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
const toCountStatementSpy: jest.Mock = jest.spyOn(
|
|
849
|
+
service,
|
|
850
|
+
"toCountStatement",
|
|
851
|
+
) as unknown as jest.Mock;
|
|
852
|
+
|
|
853
|
+
await countBy();
|
|
854
|
+
|
|
855
|
+
expect(toCountStatementSpy).toHaveBeenCalledWith(
|
|
856
|
+
expect.objectContaining({ query: rewrittenQuery }),
|
|
857
|
+
);
|
|
858
|
+
});
|
|
859
|
+
});
|
|
860
|
+
|
|
622
861
|
describe("execute / executeQuery per-call options", () => {
|
|
623
862
|
let exec: ReturnType<typeof jest.fn>;
|
|
624
863
|
let query: ReturnType<typeof jest.fn>;
|