@oneuptime/common 11.5.8 → 11.5.10
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 +13 -0
- package/Models/AnalyticsModels/MetricItemAggMV1mByContainer.ts +178 -0
- package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +179 -0
- package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +179 -0
- package/Models/AnalyticsModels/NetworkFlow.ts +397 -0
- package/Models/DatabaseModels/AIAgentTaskPullRequest.ts +15 -6
- package/Models/DatabaseModels/AIRun.ts +37 -0
- package/Models/DatabaseModels/AIRunEvent.ts +34 -1
- package/Models/DatabaseModels/EnterpriseLicenseInstance.ts +18 -0
- package/Models/DatabaseModels/GlobalConfig.ts +36 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/MarketingConversion.ts +198 -0
- package/Models/DatabaseModels/MetricSavedView.ts +34 -0
- package/Models/DatabaseModels/MetricType.ts +74 -0
- package/Models/DatabaseModels/NetworkDevice.ts +332 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +328 -0
- package/Models/DatabaseModels/NetworkInterface.ts +58 -0
- package/Models/DatabaseModels/Project.ts +62 -0
- package/Models/DatabaseModels/StatusPage.ts +42 -0
- package/Models/DatabaseModels/User.ts +37 -0
- package/Server/API/AIAgentTaskAPI.ts +38 -12
- package/Server/API/AIAgentTaskLogAPI.ts +49 -0
- package/Server/API/AIChatAPI.ts +16 -0
- package/Server/API/AIReadinessAPI.ts +84 -0
- package/Server/API/BaseAnalyticsAPI.ts +23 -0
- package/Server/API/CodeFixRunAPI.ts +182 -0
- package/Server/API/EnterpriseLicenseAPI.ts +14 -0
- package/Server/API/TelemetryExceptionAPI.ts +6 -1
- package/Server/EnvironmentConfig.ts +84 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784124919694-AddAITaskNumberAndRunTranscript.ts +95 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784135099754-AllowNullAiAgentOnPullRequest.ts +52 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784137457184-AddEnableMcpServerToStatusPage.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.ts +38 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan.ts +49 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.ts +108 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
- package/Server/Services/AIRunEventService.ts +15 -1
- package/Server/Services/AIRunService.ts +38 -1
- package/Server/Services/AnalyticsDatabaseService.ts +70 -1
- package/Server/Services/IncidentService.ts +13 -0
- package/Server/Services/Index.ts +10 -0
- package/Server/Services/LlmProviderService.ts +2 -0
- package/Server/Services/MarketingConversionService.ts +10 -0
- package/Server/Services/MetricItemAggMV1mByContainerService.ts +31 -0
- package/Server/Services/MetricItemAggMV1mByK8sClusterService.ts +31 -0
- package/Server/Services/MetricItemAggMV1mByServiceService.ts +31 -0
- package/Server/Services/MetricService.ts +970 -122
- package/Server/Services/MonitorService.ts +14 -0
- package/Server/Services/NetworkDeviceOwnerTeamService.ts +42 -0
- package/Server/Services/NetworkDeviceOwnerUserService.ts +106 -0
- package/Server/Services/NetworkFlowService.ts +11 -0
- package/Server/Services/OnCallDutyPolicyService.ts +11 -1
- package/Server/Services/ProjectService.ts +178 -0
- package/Server/Services/SpanService.ts +13 -9
- package/Server/Services/StatusPageService.ts +97 -0
- package/Server/Services/TeamMemberService.ts +11 -0
- package/Server/Services/TelemetryExceptionService.ts +19 -90
- package/Server/Services/UserService.ts +59 -0
- package/Server/Types/AnalyticsDatabase/AggregateBy.ts +37 -7
- package/Server/Types/Markdown.ts +9 -9
- package/Server/Types/MarkdownSlugify.ts +47 -0
- package/Server/Utils/AI/AIRunTranscript.ts +240 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +9 -0
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +119 -5
- package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +75 -0
- package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +235 -0
- package/Server/Utils/AI/SRE/Insights/FixRouting.ts +2 -3
- package/Server/Utils/AI/Toolbox/CodeTools.ts +883 -0
- package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +519 -0
- package/Server/Utils/AI/Toolbox/Index.ts +27 -0
- package/Server/Utils/AI/Toolbox/ScheduledMaintenanceTools.ts +279 -0
- package/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.ts +19 -1
- package/Server/Utils/Attribution.ts +99 -0
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +600 -0
- package/Server/Utils/CodeRepository/StackTraceRepoResolver.ts +7 -2
- package/Server/Utils/LLM/LLMService.ts +397 -18
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +103 -0
- package/Server/Utils/Marketing/ConversionUploadProviders.ts +22 -0
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +270 -0
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +147 -0
- package/Server/Utils/Marketing/Providers/Meta.ts +148 -0
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +196 -0
- package/Server/Utils/Marketing/Providers/Reddit.ts +178 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +71 -7
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +31 -19
- package/Server/Utils/Monitor/MonitorIncident.ts +71 -7
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +57 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +94 -0
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +19 -11
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +125 -14
- package/Server/Utils/ProductAnalytics.ts +133 -0
- package/Server/Utils/Telemetry/Telemetry.ts +39 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +21 -0
- package/Tests/Models/StatusPageEnableMcpServer.test.ts +125 -0
- package/Tests/Server/API/BaseAnalyticsAPI.test.ts +72 -0
- package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +9 -1
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +21 -2
- package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +173 -0
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +1391 -0
- package/Tests/Server/Services/NetworkDeviceOwnerServices.test.ts +260 -0
- package/Tests/Server/Services/StatusPageServiceMcp.test.ts +223 -0
- package/Tests/Server/Services/TelemetryExceptionAIFixReadiness.test.ts +26 -3
- package/Tests/Server/Services/TelemetryExceptionCodeFixRun.test.ts +12 -0
- package/Tests/Server/Types/Markdown.test.ts +106 -0
- package/Tests/Server/Utils/AI/AIRunTranscript.test.ts +182 -0
- package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +411 -0
- package/Tests/Server/Utils/AI/CodeTools.test.ts +596 -0
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +475 -0
- package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +548 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +142 -0
- package/Tests/Server/Utils/AI/ScheduledMaintenanceTools.test.ts +176 -0
- package/Tests/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.test.ts +63 -0
- package/Tests/Server/Utils/GitHubGetFileContent.test.ts +197 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilNetworkDevice.test.ts +389 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +502 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +764 -0
- package/Tests/Types/AI/AIAgentTaskStatus.test.ts +7 -6
- package/Tests/Types/AI/AIChatPageContext.test.ts +0 -0
- package/Tests/Types/AI/AIRunStatus.test.ts +42 -0
- package/Tests/Types/BaseDatabase/AggregationIntervalUtil.test.ts +111 -2
- package/Tests/Types/Database/EndsWith.test.ts +64 -0
- package/Tests/Types/Database/GreaterThan.test.ts +62 -0
- package/Tests/Types/Database/GreaterThanOrEqual.test.ts +65 -0
- package/Tests/Types/Database/GreaterThanOrNull.test.ts +63 -0
- package/Tests/Types/Database/Includes.test.ts +65 -0
- package/Tests/Types/Database/IncludesAll.test.ts +65 -0
- package/Tests/Types/Database/IncludesNone.test.ts +65 -0
- package/Tests/Types/Database/IsNull.test.ts +44 -0
- package/Tests/Types/Database/LessThan.test.ts +62 -0
- package/Tests/Types/Database/LessThanOrEqual.test.ts +62 -0
- package/Tests/Types/Database/LessThanOrNull.test.ts +62 -0
- package/Tests/Types/Database/MultiSearch.test.ts +81 -0
- package/Tests/Types/Database/NotContains.test.ts +64 -0
- package/Tests/Types/Database/NotNull.test.ts +44 -0
- package/Tests/Types/Database/StartsWith.test.ts +64 -0
- package/Tests/Types/Log/LogSeverity.test.ts +78 -0
- package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +83 -1
- package/Tests/Types/Monitor/SnmpV3EnumParsing.test.ts +247 -0
- package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +263 -0
- package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +167 -0
- package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +66 -0
- package/Tests/UI/Components/XAxis.test.ts +5 -3
- package/Tests/UI/Utils/AIChatExport/ChatWidgetData.test.ts +319 -0
- package/Tests/UI/Utils/AIChatExport/ChatWidgetMarkdown.test.ts +188 -0
- package/Tests/Utils/EnterpriseLicenseUsage.test.ts +76 -0
- package/Tests/Utils/Metrics/MetricExplorerUrl.test.ts +622 -0
- package/Tests/Utils/Metrics/MetricFormulaEvaluator.test.ts +474 -0
- package/Tests/Utils/Telemetry/HeartbeatAvailability.test.ts +52 -4
- package/Types/AI/AIAgentTaskStatus.ts +13 -0
- package/Types/AI/AIChatPageContext.ts +137 -0
- package/Types/AI/AIChatTypes.ts +44 -0
- package/Types/AI/AIFixReadiness.ts +46 -0
- package/Types/AI/AIRunStatus.ts +11 -0
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +11 -0
- package/Types/BaseDatabase/AggregateBy.ts +31 -2
- package/Types/BaseDatabase/AggregatedResult.ts +22 -0
- package/Types/BaseDatabase/AggregationInterval.ts +11 -0
- package/Types/BaseDatabase/AggregationIntervalUtil.ts +30 -5
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +16 -0
- package/Types/Email/EmailTemplateType.ts +3 -0
- package/Types/Log/LogSeverity.ts +61 -0
- package/Types/Marketing/MarketingConversion.ts +11 -0
- package/Types/Metrics/MetricQueryConfigData.ts +21 -0
- package/Types/Metrics/MetricQueryData.ts +8 -0
- package/Types/Metrics/MetricViewData.ts +8 -0
- package/Types/Monitor/MonitorMetricType.ts +8 -0
- package/Types/Monitor/MonitorStep.ts +9 -0
- package/Types/Monitor/MonitorStepSqlMonitor.ts +12 -0
- package/Types/Monitor/MonitorType.ts +2 -1
- package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +17 -12
- package/Types/Monitor/SnmpMonitor/CdpNeighbor.ts +13 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +37 -3
- package/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.ts +46 -0
- package/Types/Monitor/SnmpMonitor/SnmpEntityInfo.ts +15 -0
- package/Types/Monitor/SnmpMonitor/SnmpInterface.ts +8 -0
- package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +17 -8
- package/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.ts +53 -0
- package/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.ts +43 -0
- package/Types/Monitor/SnmpMonitor/SnmpSystemInfo.ts +16 -0
- package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +119 -3
- package/Types/Monitor/SnmpMonitor/SnmpVersion.ts +40 -0
- package/Types/NetFlow/NetworkFlowRecord.ts +25 -0
- package/Types/Syslog/SyslogMessage.ts +18 -0
- package/Types/Telemetry/TelemetrySavedViewState.ts +9 -0
- package/Types/Telemetry/TelemetrySavedViewType.ts +12 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +51 -0
- package/UI/Components/Charts/Bar/BarChart.tsx +51 -1
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +97 -26
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +336 -3
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +118 -1
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +336 -3
- package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +7 -0
- package/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.ts +15 -0
- package/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.ts +13 -0
- package/UI/Components/Charts/Line/LineChart.tsx +51 -0
- package/UI/Components/Charts/Types/ReferenceRegionProps.ts +12 -0
- package/UI/Components/Charts/Types/TimeReferenceLineProps.ts +12 -0
- package/UI/Components/Charts/Types/XAxis/XAxisPrecision.ts +1 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +0 -0
- package/UI/Components/Charts/Utils/TimeAnnotation.ts +169 -0
- package/UI/Components/Charts/Utils/XAxis.ts +28 -4
- package/UI/Components/Forms/BasicForm.tsx +26 -8
- package/UI/Components/Icon/Icon.tsx +33 -13
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +9 -0
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +67 -0
- package/UI/Components/Page/ModelPage.tsx +6 -1
- package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +33 -4
- package/UI/Styles/Theme.css +1324 -0
- package/UI/Utils/AIChatExport/ChatWidgetData.ts +316 -0
- package/UI/Utils/AIChatExport/ChatWidgetMarkdown.ts +349 -0
- package/UI/Utils/AIChatExport/ConversationMarkdown.ts +177 -0
- package/UI/Utils/AIChatExport/MarkdownBlocks.ts +327 -0
- package/UI/Utils/AIChatExport/MarkdownSafety.ts +215 -0
- package/UI/Utils/DownloadFile.ts +54 -0
- package/UI/Utils/User.ts +41 -2
- package/Utils/Analytics.ts +8 -6
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +74 -0
- package/Utils/Metrics/MetricExplorerUrl.ts +771 -0
- package/Utils/Metrics/MetricFormulaEvaluator.ts +410 -46
- package/Utils/Monitor/NetworkTopologyUtil.ts +261 -49
- package/Utils/ValueFormatter.ts +22 -1
- package/build/dist/Models/AnalyticsModels/Index.js +13 -0
- package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js +159 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +158 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +160 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js +351 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +15 -7
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIRun.js +38 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIRunEvent.js +31 -0
- package/build/dist/Models/DatabaseModels/AIRunEvent.js.map +1 -1
- package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js +19 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +38 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +219 -0
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MetricSavedView.js +35 -0
- package/build/dist/Models/DatabaseModels/MetricSavedView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MetricType.js +76 -0
- package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +341 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +341 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkInterface.js +60 -0
- package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +65 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +43 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +38 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskAPI.js +37 -11
- package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskLogAPI.js +32 -7
- package/build/dist/Server/API/AIAgentTaskLogAPI.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +9 -0
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIReadinessAPI.js +57 -0
- package/build/dist/Server/API/AIReadinessAPI.js.map +1 -0
- package/build/dist/Server/API/BaseAnalyticsAPI.js +19 -0
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/CodeFixRunAPI.js +142 -0
- package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -1
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +8 -0
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryExceptionAPI.js +4 -0
- package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +51 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784124919694-AddAITaskNumberAndRunTranscript.js +80 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784124919694-AddAITaskNumberAndRunTranscript.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784135099754-AllowNullAiAgentOnPullRequest.js +37 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784135099754-AllowNullAiAgentOnPullRequest.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784137457184-AddEnableMcpServerToStatusPage.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784137457184-AddEnableMcpServerToStatusPage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js +27 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js +21 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js +47 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AIRunEventService.js +8 -0
- package/build/dist/Server/Services/AIRunEventService.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +29 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +58 -4
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +12 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +10 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LlmProviderService.js +2 -0
- package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
- package/build/dist/Server/Services/MarketingConversionService.js +9 -0
- package/build/dist/Server/Services/MarketingConversionService.js.map +1 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js +29 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js.map +1 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js +29 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js.map +1 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js +29 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js.map +1 -0
- package/build/dist/Server/Services/MetricService.js +761 -125
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +18 -5
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js +44 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js +88 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/NetworkFlowService.js +9 -0
- package/build/dist/Server/Services/NetworkFlowService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyService.js +15 -6
- package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +146 -6
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +8 -6
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +91 -0
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +11 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryExceptionService.js +14 -61
- package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +52 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +33 -7
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +8 -8
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Types/MarkdownSlugify.js +47 -0
- package/build/dist/Server/Types/MarkdownSlugify.js.map +1 -0
- package/build/dist/Server/Utils/AI/AIRunTranscript.js +180 -0
- package/build/dist/Server/Utils/AI/AIRunTranscript.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +103 -5
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +55 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +211 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +654 -0
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +389 -0
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +19 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/ScheduledMaintenanceTools.js +239 -0
- package/build/dist/Server/Utils/AI/Toolbox/ScheduledMaintenanceTools.js.map +1 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js +19 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js.map +1 -1
- package/build/dist/Server/Utils/Attribution.js +74 -0
- package/build/dist/Server/Utils/Attribution.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +439 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js +1 -1
- package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +275 -19
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +40 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +20 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +177 -0
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +113 -0
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +109 -0
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +130 -0
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +126 -0
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +53 -9
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -10
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +54 -11
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +43 -3
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +68 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +17 -11
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +100 -15
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/ProductAnalytics.js +111 -0
- package/build/dist/Server/Utils/ProductAnalytics.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +32 -5
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Types/AI/AIAgentTaskStatus.js +12 -0
- package/build/dist/Types/AI/AIAgentTaskStatus.js.map +1 -1
- package/build/dist/Types/AI/AIChatPageContext.js +101 -0
- package/build/dist/Types/AI/AIChatPageContext.js.map +1 -0
- package/build/dist/Types/AI/AIChatTypes.js +2 -0
- package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
- package/build/dist/Types/AI/AIFixReadiness.js +9 -0
- package/build/dist/Types/AI/AIFixReadiness.js.map +1 -0
- package/build/dist/Types/AI/AIRunStatus.js +11 -0
- package/build/dist/Types/AI/AIRunStatus.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +11 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
- package/build/dist/Types/BaseDatabase/AggregationInterval.js +11 -0
- package/build/dist/Types/BaseDatabase/AggregationInterval.js.map +1 -1
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +33 -5
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +2 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Log/LogSeverity.js +56 -0
- package/build/dist/Types/Log/LogSeverity.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingConversion.js +13 -0
- package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +6 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +3 -0
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +2 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js +41 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js +48 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js +38 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +96 -3
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVersion.js +38 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVersion.js.map +1 -1
- package/build/dist/Types/NetFlow/NetworkFlowRecord.js +2 -0
- package/build/dist/Types/NetFlow/NetworkFlowRecord.js.map +1 -0
- package/build/dist/Types/Syslog/SyslogMessage.js +2 -0
- package/build/dist/Types/Syslog/SyslogMessage.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetrySavedViewState.js +0 -7
- package/build/dist/Types/Telemetry/TelemetrySavedViewState.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetrySavedViewType.js +13 -0
- package/build/dist/Types/Telemetry/TelemetrySavedViewType.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +25 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +26 -2
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +36 -12
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +217 -8
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +55 -4
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +217 -8
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +6 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js +2 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js +2 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +25 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js +2 -0
- package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js.map +1 -0
- package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js +2 -0
- package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js.map +1 -0
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js +1 -0
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +0 -0
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +121 -0
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +27 -4
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +24 -6
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +15 -8
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +58 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +7 -1
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +10 -4
- package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetData.js +217 -0
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetData.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetMarkdown.js +234 -0
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetMarkdown.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +111 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownBlocks.js +233 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownBlocks.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownSafety.js +134 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownSafety.js.map +1 -0
- package/build/dist/UI/Utils/DownloadFile.js +41 -0
- package/build/dist/UI/Utils/DownloadFile.js.map +1 -0
- package/build/dist/UI/Utils/User.js +35 -2
- package/build/dist/UI/Utils/User.js.map +1 -1
- package/build/dist/Utils/Analytics.js +8 -5
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +57 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/Metrics/MetricExplorerUrl.js +418 -0
- package/build/dist/Utils/Metrics/MetricExplorerUrl.js.map +1 -0
- package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js +296 -37
- package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +176 -40
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/ValueFormatter.js +20 -1
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { describe, expect, test } from "@jest/globals";
|
|
2
|
+
import SnmpAuthProtocol, {
|
|
3
|
+
SnmpAuthProtocolUtil,
|
|
4
|
+
} from "../../../Types/Monitor/SnmpMonitor/SnmpAuthProtocol";
|
|
5
|
+
import SnmpPrivProtocol, {
|
|
6
|
+
SnmpPrivProtocolUtil,
|
|
7
|
+
} from "../../../Types/Monitor/SnmpMonitor/SnmpPrivProtocol";
|
|
8
|
+
import SnmpSecurityLevel, {
|
|
9
|
+
SnmpSecurityLevelUtil,
|
|
10
|
+
} from "../../../Types/Monitor/SnmpMonitor/SnmpSecurityLevel";
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* These three columns are free text with no check constraint, so the parsers
|
|
14
|
+
* are the only thing standing between a hand-written row and a silent security
|
|
15
|
+
* downgrade. Two properties matter and are tested separately throughout:
|
|
16
|
+
*
|
|
17
|
+
* - parse() recognizes every spelling a human or API caller plausibly writes,
|
|
18
|
+
* so a legitimate value is never mistaken for garbage.
|
|
19
|
+
* - parse() returns undefined for anything else, and isUnrecognized() tells
|
|
20
|
+
* "unset" apart from "unreadable", so callers can refuse to guess.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
describe("SnmpSecurityLevelUtil.parse", () => {
|
|
24
|
+
test.each([
|
|
25
|
+
["noAuthNoPriv", SnmpSecurityLevel.NoAuthNoPriv],
|
|
26
|
+
["authNoPriv", SnmpSecurityLevel.AuthNoPriv],
|
|
27
|
+
["authPriv", SnmpSecurityLevel.AuthPriv],
|
|
28
|
+
])(
|
|
29
|
+
"reads the stored value %s",
|
|
30
|
+
(stored: string, expected: SnmpSecurityLevel) => {
|
|
31
|
+
expect(SnmpSecurityLevelUtil.parse(stored)).toBe(expected);
|
|
32
|
+
},
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
* The enum KEYS differ from the values only in the first letter's case, and
|
|
37
|
+
* the API reference documents the level in prose, so "AuthPriv" is exactly
|
|
38
|
+
* what a hand-written row tends to contain. Reading it as unrecognized would
|
|
39
|
+
* be survivable; reading it as noAuthNoPriv — which the old bare cast did —
|
|
40
|
+
* strips the device's credentials and polls it in cleartext.
|
|
41
|
+
*/
|
|
42
|
+
test.each([
|
|
43
|
+
["NoAuthNoPriv", SnmpSecurityLevel.NoAuthNoPriv],
|
|
44
|
+
["AuthNoPriv", SnmpSecurityLevel.AuthNoPriv],
|
|
45
|
+
["AuthPriv", SnmpSecurityLevel.AuthPriv],
|
|
46
|
+
])(
|
|
47
|
+
"reads the enum key spelling %s",
|
|
48
|
+
(stored: string, expected: SnmpSecurityLevel) => {
|
|
49
|
+
expect(SnmpSecurityLevelUtil.parse(stored)).toBe(expected);
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
test.each([
|
|
54
|
+
["AUTHPRIV", SnmpSecurityLevel.AuthPriv],
|
|
55
|
+
["authpriv", SnmpSecurityLevel.AuthPriv],
|
|
56
|
+
["AuThPrIv", SnmpSecurityLevel.AuthPriv],
|
|
57
|
+
[" authPriv ", SnmpSecurityLevel.AuthPriv],
|
|
58
|
+
["\tauthPriv\n", SnmpSecurityLevel.AuthPriv],
|
|
59
|
+
])(
|
|
60
|
+
"tolerates case and surrounding whitespace in %j",
|
|
61
|
+
(stored: string, expected: SnmpSecurityLevel) => {
|
|
62
|
+
expect(SnmpSecurityLevelUtil.parse(stored)).toBe(expected);
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
test.each([[undefined], [null], [""], [" "]])(
|
|
67
|
+
"returns undefined for the unset value %j",
|
|
68
|
+
(stored: string | undefined | null) => {
|
|
69
|
+
expect(SnmpSecurityLevelUtil.parse(stored)).toBeUndefined();
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
test.each([["nonsense"], ["auth"], ["priv"], ["authpriv2"], ["no"], ["0"]])(
|
|
74
|
+
"returns undefined for the unrecognized value %j",
|
|
75
|
+
(stored: string) => {
|
|
76
|
+
expect(SnmpSecurityLevelUtil.parse(stored)).toBeUndefined();
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("SnmpAuthProtocolUtil.parse", () => {
|
|
82
|
+
test.each([
|
|
83
|
+
["MD5", SnmpAuthProtocol.MD5],
|
|
84
|
+
["SHA", SnmpAuthProtocol.SHA],
|
|
85
|
+
["SHA256", SnmpAuthProtocol.SHA256],
|
|
86
|
+
["SHA512", SnmpAuthProtocol.SHA512],
|
|
87
|
+
])(
|
|
88
|
+
"reads the stored value %s",
|
|
89
|
+
(stored: string, expected: SnmpAuthProtocol) => {
|
|
90
|
+
expect(SnmpAuthProtocolUtil.parse(stored)).toBe(expected);
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
/*
|
|
95
|
+
* The form labels these "SHA-256" and "SHA-512" while storing them without
|
|
96
|
+
* the hyphen, so the label spelling is the most likely near-miss. SHA-1 is
|
|
97
|
+
* the same algorithm as the bare "SHA" of RFC 3414.
|
|
98
|
+
*/
|
|
99
|
+
test.each([
|
|
100
|
+
["SHA-256", SnmpAuthProtocol.SHA256],
|
|
101
|
+
["sha-256", SnmpAuthProtocol.SHA256],
|
|
102
|
+
["SHA-512", SnmpAuthProtocol.SHA512],
|
|
103
|
+
["SHA1", SnmpAuthProtocol.SHA],
|
|
104
|
+
["SHA-1", SnmpAuthProtocol.SHA],
|
|
105
|
+
[" md5 ", SnmpAuthProtocol.MD5],
|
|
106
|
+
["Sha256", SnmpAuthProtocol.SHA256],
|
|
107
|
+
])(
|
|
108
|
+
"tolerates the near-miss spelling %j",
|
|
109
|
+
(stored: string, expected: SnmpAuthProtocol) => {
|
|
110
|
+
expect(SnmpAuthProtocolUtil.parse(stored)).toBe(expected);
|
|
111
|
+
},
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
test.each([[undefined], [null], [""], [" "]])(
|
|
115
|
+
"returns undefined for the unset value %j",
|
|
116
|
+
(stored: string | undefined | null) => {
|
|
117
|
+
expect(SnmpAuthProtocolUtil.parse(stored)).toBeUndefined();
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
test.each([["sha3"], ["sha-384"], ["hmac"], ["none"], ["md4"], ["nonsense"]])(
|
|
122
|
+
"returns undefined for the unrecognized value %j",
|
|
123
|
+
(stored: string) => {
|
|
124
|
+
expect(SnmpAuthProtocolUtil.parse(stored)).toBeUndefined();
|
|
125
|
+
},
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe("SnmpPrivProtocolUtil.parse", () => {
|
|
130
|
+
test.each([
|
|
131
|
+
["DES", SnmpPrivProtocol.DES],
|
|
132
|
+
["AES", SnmpPrivProtocol.AES],
|
|
133
|
+
["AES256", SnmpPrivProtocol.AES256],
|
|
134
|
+
])(
|
|
135
|
+
"reads the stored value %s",
|
|
136
|
+
(stored: string, expected: SnmpPrivProtocol) => {
|
|
137
|
+
expect(SnmpPrivProtocolUtil.parse(stored)).toBe(expected);
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
/*
|
|
142
|
+
* "AES-256" is the label the form shows for the value it stores as
|
|
143
|
+
* "AES256". Under the old bare cast that near-miss encrypted with DES.
|
|
144
|
+
*/
|
|
145
|
+
test.each([
|
|
146
|
+
["AES-256", SnmpPrivProtocol.AES256],
|
|
147
|
+
["aes-256", SnmpPrivProtocol.AES256],
|
|
148
|
+
["aes256", SnmpPrivProtocol.AES256],
|
|
149
|
+
["AES128", SnmpPrivProtocol.AES],
|
|
150
|
+
["AES-128", SnmpPrivProtocol.AES],
|
|
151
|
+
["des", SnmpPrivProtocol.DES],
|
|
152
|
+
[" Des ", SnmpPrivProtocol.DES],
|
|
153
|
+
])(
|
|
154
|
+
"tolerates the near-miss spelling %j",
|
|
155
|
+
(stored: string, expected: SnmpPrivProtocol) => {
|
|
156
|
+
expect(SnmpPrivProtocolUtil.parse(stored)).toBe(expected);
|
|
157
|
+
},
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
test.each([[undefined], [null], [""], [" "]])(
|
|
161
|
+
"returns undefined for the unset value %j",
|
|
162
|
+
(stored: string | undefined | null) => {
|
|
163
|
+
expect(SnmpPrivProtocolUtil.parse(stored)).toBeUndefined();
|
|
164
|
+
},
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
test.each([
|
|
168
|
+
["3des"],
|
|
169
|
+
["aes192"],
|
|
170
|
+
["rc4"],
|
|
171
|
+
["none"],
|
|
172
|
+
["nonsense"],
|
|
173
|
+
["AES512"],
|
|
174
|
+
])("returns undefined for the unrecognized value %j", (stored: string) => {
|
|
175
|
+
expect(SnmpPrivProtocolUtil.parse(stored)).toBeUndefined();
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
describe("isUnrecognized — telling unset apart from unreadable", () => {
|
|
180
|
+
/*
|
|
181
|
+
* The distinction the probe depends on. An unset protocol keeps its historic
|
|
182
|
+
* default so devices configured before these columns were mandatory keep
|
|
183
|
+
* polling; an unreadable one is refused, because there is no safe guess and
|
|
184
|
+
* defaulting is what silently downgrades the cipher.
|
|
185
|
+
*/
|
|
186
|
+
test.each([[undefined], [null], [""], [" "], ["\t"]])(
|
|
187
|
+
"an unset value %j is not unrecognized",
|
|
188
|
+
(stored: string | undefined | null) => {
|
|
189
|
+
expect(SnmpSecurityLevelUtil.isUnrecognized(stored)).toBe(false);
|
|
190
|
+
expect(SnmpAuthProtocolUtil.isUnrecognized(stored)).toBe(false);
|
|
191
|
+
expect(SnmpPrivProtocolUtil.isUnrecognized(stored)).toBe(false);
|
|
192
|
+
},
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
test("a recognized value is not unrecognized", () => {
|
|
196
|
+
expect(SnmpSecurityLevelUtil.isUnrecognized("AuthPriv")).toBe(false);
|
|
197
|
+
expect(SnmpAuthProtocolUtil.isUnrecognized("SHA-256")).toBe(false);
|
|
198
|
+
expect(SnmpPrivProtocolUtil.isUnrecognized("AES-256")).toBe(false);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test("a value that matches nothing is unrecognized", () => {
|
|
202
|
+
expect(SnmpSecurityLevelUtil.isUnrecognized("nonsense")).toBe(true);
|
|
203
|
+
expect(SnmpAuthProtocolUtil.isUnrecognized("sha3")).toBe(true);
|
|
204
|
+
expect(SnmpPrivProtocolUtil.isUnrecognized("aes192")).toBe(true);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
describe("every enum member survives a round trip", () => {
|
|
209
|
+
/*
|
|
210
|
+
* Exhaustive over the enums rather than a fixed list, so adding a member
|
|
211
|
+
* without teaching parse() about it fails here instead of silently becoming
|
|
212
|
+
* unrecognized in production.
|
|
213
|
+
*/
|
|
214
|
+
test("SnmpSecurityLevel", () => {
|
|
215
|
+
for (const member of Object.values(SnmpSecurityLevel)) {
|
|
216
|
+
expect(SnmpSecurityLevelUtil.parse(member)).toBe(member);
|
|
217
|
+
expect(SnmpSecurityLevelUtil.isUnrecognized(member)).toBe(false);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
test("SnmpAuthProtocol", () => {
|
|
222
|
+
for (const member of Object.values(SnmpAuthProtocol)) {
|
|
223
|
+
expect(SnmpAuthProtocolUtil.parse(member)).toBe(member);
|
|
224
|
+
expect(SnmpAuthProtocolUtil.isUnrecognized(member)).toBe(false);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test("SnmpPrivProtocol", () => {
|
|
229
|
+
for (const member of Object.values(SnmpPrivProtocol)) {
|
|
230
|
+
expect(SnmpPrivProtocolUtil.parse(member)).toBe(member);
|
|
231
|
+
expect(SnmpPrivProtocolUtil.isUnrecognized(member)).toBe(false);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Every enum KEY must parse too - that is the spelling hand-written rows use.
|
|
236
|
+
test("every enum key spelling also parses", () => {
|
|
237
|
+
for (const key of Object.keys(SnmpSecurityLevel)) {
|
|
238
|
+
expect(SnmpSecurityLevelUtil.parse(key)).toBeDefined();
|
|
239
|
+
}
|
|
240
|
+
for (const key of Object.keys(SnmpAuthProtocol)) {
|
|
241
|
+
expect(SnmpAuthProtocolUtil.parse(key)).toBeDefined();
|
|
242
|
+
}
|
|
243
|
+
for (const key of Object.keys(SnmpPrivProtocol)) {
|
|
244
|
+
expect(SnmpPrivProtocolUtil.parse(key)).toBeDefined();
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
});
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { describe, expect, test } from "@jest/globals";
|
|
2
|
+
import SnmpVendorTemplateUtil, {
|
|
3
|
+
SnmpVendorTemplate,
|
|
4
|
+
SnmpVendorTemplates,
|
|
5
|
+
} from "../../../Types/Monitor/SnmpMonitor/SnmpVendorTemplate";
|
|
6
|
+
import SnmpOid from "../../../Types/Monitor/SnmpMonitor/SnmpOid";
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* SnmpVendorTemplateUtil is the device-fingerprinting brain for Network
|
|
10
|
+
* Device monitors: it parses sysObjectID into an IANA enterprise number,
|
|
11
|
+
* derives a vendor display name from it, routes to a vendor OID template,
|
|
12
|
+
* and merges template OIDs into a monitor without duplicating rows. These
|
|
13
|
+
* tests pin each of those behaviors against real-world sysObjectID values.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// Real sysObjectID values as devices actually report them.
|
|
17
|
+
const CISCO_SYS_OBJECT_ID: string = "1.3.6.1.4.1.9.1.1208"; // Catalyst 2960X
|
|
18
|
+
const MIKROTIK_SYS_OBJECT_ID: string = "1.3.6.1.4.1.14988.1";
|
|
19
|
+
const UBIQUITI_SYS_OBJECT_ID: string = "1.3.6.1.4.1.41112.1.4";
|
|
20
|
+
const JUNIPER_SYS_OBJECT_ID: string = "1.3.6.1.4.1.2636.1.1.1.2.29"; // EX2200
|
|
21
|
+
|
|
22
|
+
describe("SnmpVendorTemplateUtil.getEnterpriseNumber", () => {
|
|
23
|
+
test("extracts the enterprise number from a Cisco sysObjectID", () => {
|
|
24
|
+
expect(
|
|
25
|
+
SnmpVendorTemplateUtil.getEnterpriseNumber(CISCO_SYS_OBJECT_ID),
|
|
26
|
+
).toBe(9);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("accepts the leading-dot form some agents report", () => {
|
|
30
|
+
expect(
|
|
31
|
+
SnmpVendorTemplateUtil.getEnterpriseNumber(`.${CISCO_SYS_OBJECT_ID}`),
|
|
32
|
+
).toBe(9);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("tolerates surrounding whitespace", () => {
|
|
36
|
+
expect(
|
|
37
|
+
SnmpVendorTemplateUtil.getEnterpriseNumber(
|
|
38
|
+
` ${MIKROTIK_SYS_OBJECT_ID} `,
|
|
39
|
+
),
|
|
40
|
+
).toBe(14988);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("parses a bare enterprise arc with no product suffix", () => {
|
|
44
|
+
expect(
|
|
45
|
+
SnmpVendorTemplateUtil.getEnterpriseNumber("1.3.6.1.4.1.41112"),
|
|
46
|
+
).toBe(41112);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("returns undefined for a mib-2 OID outside the enterprises arc", () => {
|
|
50
|
+
// Some appliances report sysObjectID values under 1.3.6.1.2.1 (mib-2).
|
|
51
|
+
expect(
|
|
52
|
+
SnmpVendorTemplateUtil.getEnterpriseNumber("1.3.6.1.2.1.1"),
|
|
53
|
+
).toBeUndefined();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("returns undefined for garbage that is not an OID", () => {
|
|
57
|
+
expect(
|
|
58
|
+
SnmpVendorTemplateUtil.getEnterpriseNumber("not-an-oid"),
|
|
59
|
+
).toBeUndefined();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("returns undefined for the enterprises prefix with nothing after it", () => {
|
|
63
|
+
expect(
|
|
64
|
+
SnmpVendorTemplateUtil.getEnterpriseNumber("1.3.6.1.4.1."),
|
|
65
|
+
).toBeUndefined();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("returns undefined for an empty string", () => {
|
|
69
|
+
expect(SnmpVendorTemplateUtil.getEnterpriseNumber("")).toBeUndefined();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("returns undefined for undefined", () => {
|
|
73
|
+
expect(
|
|
74
|
+
SnmpVendorTemplateUtil.getEnterpriseNumber(undefined),
|
|
75
|
+
).toBeUndefined();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("SnmpVendorTemplateUtil.getVendorNameBySysObjectId", () => {
|
|
80
|
+
test.each([
|
|
81
|
+
[CISCO_SYS_OBJECT_ID, "Cisco"],
|
|
82
|
+
[MIKROTIK_SYS_OBJECT_ID, "MikroTik"],
|
|
83
|
+
[UBIQUITI_SYS_OBJECT_ID, "Ubiquiti"],
|
|
84
|
+
[JUNIPER_SYS_OBJECT_ID, "Juniper"],
|
|
85
|
+
])("%s resolves to vendor %s", (sysObjectId: string, vendor: string) => {
|
|
86
|
+
expect(SnmpVendorTemplateUtil.getVendorNameBySysObjectId(sysObjectId)).toBe(
|
|
87
|
+
vendor,
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("an enterprise number outside the map leaves the vendor blank", () => {
|
|
92
|
+
expect(
|
|
93
|
+
SnmpVendorTemplateUtil.getVendorNameBySysObjectId(
|
|
94
|
+
"1.3.6.1.4.1.424242.1.1",
|
|
95
|
+
),
|
|
96
|
+
).toBeUndefined();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("a non-enterprise OID leaves the vendor blank", () => {
|
|
100
|
+
expect(
|
|
101
|
+
SnmpVendorTemplateUtil.getVendorNameBySysObjectId("1.3.6.1.2.1.1"),
|
|
102
|
+
).toBeUndefined();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("undefined input leaves the vendor blank", () => {
|
|
106
|
+
expect(
|
|
107
|
+
SnmpVendorTemplateUtil.getVendorNameBySysObjectId(undefined),
|
|
108
|
+
).toBeUndefined();
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe("SnmpVendorTemplateUtil.matchBySysObjectId", () => {
|
|
113
|
+
test("a Cisco device is routed to the cisco-ios template", () => {
|
|
114
|
+
const template: SnmpVendorTemplate | undefined =
|
|
115
|
+
SnmpVendorTemplateUtil.matchBySysObjectId(CISCO_SYS_OBJECT_ID);
|
|
116
|
+
|
|
117
|
+
expect(template?.id).toBe("cisco-ios");
|
|
118
|
+
expect(template).toBe(SnmpVendorTemplateUtil.getById("cisco-ios"));
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("a MikroTik device is routed to the mikrotik-routeros template", () => {
|
|
122
|
+
expect(
|
|
123
|
+
SnmpVendorTemplateUtil.matchBySysObjectId(MIKROTIK_SYS_OBJECT_ID)?.id,
|
|
124
|
+
).toBe("mikrotik-routeros");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("a Ubiquiti device is routed to the ubiquiti-edgeos template", () => {
|
|
128
|
+
expect(
|
|
129
|
+
SnmpVendorTemplateUtil.matchBySysObjectId(UBIQUITI_SYS_OBJECT_ID)?.id,
|
|
130
|
+
).toBe("ubiquiti-edgeos");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
* Juniper has a vendor name in the enterprise map but no vendor-specific
|
|
135
|
+
* template — the match must come back empty so callers fall back to the
|
|
136
|
+
* generic Host Resources template rather than mislabeling the device.
|
|
137
|
+
*/
|
|
138
|
+
test("a Juniper device has a vendor name but no template", () => {
|
|
139
|
+
expect(
|
|
140
|
+
SnmpVendorTemplateUtil.getVendorNameBySysObjectId(JUNIPER_SYS_OBJECT_ID),
|
|
141
|
+
).toBe("Juniper");
|
|
142
|
+
expect(
|
|
143
|
+
SnmpVendorTemplateUtil.matchBySysObjectId(JUNIPER_SYS_OBJECT_ID),
|
|
144
|
+
).toBeUndefined();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("an unknown enterprise matches no template", () => {
|
|
148
|
+
expect(
|
|
149
|
+
SnmpVendorTemplateUtil.matchBySysObjectId("1.3.6.1.4.1.424242.1"),
|
|
150
|
+
).toBeUndefined();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test("undefined input matches no template", () => {
|
|
154
|
+
expect(
|
|
155
|
+
SnmpVendorTemplateUtil.matchBySysObjectId(undefined),
|
|
156
|
+
).toBeUndefined();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe("SnmpVendorTemplateUtil.getAll / getById", () => {
|
|
161
|
+
test("every shipped template is retrievable by its id", () => {
|
|
162
|
+
for (const template of SnmpVendorTemplates) {
|
|
163
|
+
expect(SnmpVendorTemplateUtil.getById(template.id)).toBe(template);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("an unknown template id returns undefined", () => {
|
|
168
|
+
expect(SnmpVendorTemplateUtil.getById("no-such-template")).toBeUndefined();
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
describe("SnmpVendorTemplateUtil.mergeOids", () => {
|
|
173
|
+
function oidValues(oids: Array<SnmpOid>): Array<string> {
|
|
174
|
+
return oids.map((oid: SnmpOid) => {
|
|
175
|
+
return oid.oid;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
test("merging into an empty list yields the template's OIDs", () => {
|
|
180
|
+
const merged: Array<SnmpOid> = SnmpVendorTemplateUtil.mergeOids(
|
|
181
|
+
[],
|
|
182
|
+
"cisco-ios",
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
expect(merged).toEqual(SnmpVendorTemplateUtil.getById("cisco-ios")!.oids);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test("applying the same template twice never duplicates rows", () => {
|
|
189
|
+
const once: Array<SnmpOid> = SnmpVendorTemplateUtil.mergeOids(
|
|
190
|
+
[],
|
|
191
|
+
"cisco-ios",
|
|
192
|
+
);
|
|
193
|
+
const twice: Array<SnmpOid> = SnmpVendorTemplateUtil.mergeOids(
|
|
194
|
+
once,
|
|
195
|
+
"cisco-ios",
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
expect(twice).toEqual(once);
|
|
199
|
+
expect(new Set(oidValues(twice)).size).toBe(twice.length);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
/*
|
|
203
|
+
* MikroTik and Ubiquiti both start with hrProcessorLoad
|
|
204
|
+
* (1.3.6.1.2.1.25.3.3.1.2.1) — applying both templates must produce that
|
|
205
|
+
* OID exactly once.
|
|
206
|
+
*/
|
|
207
|
+
test("overlapping templates share OIDs without duplicating them", () => {
|
|
208
|
+
const mikrotik: Array<SnmpOid> = SnmpVendorTemplateUtil.mergeOids(
|
|
209
|
+
[],
|
|
210
|
+
"mikrotik-routeros",
|
|
211
|
+
);
|
|
212
|
+
const both: Array<SnmpOid> = SnmpVendorTemplateUtil.mergeOids(
|
|
213
|
+
mikrotik,
|
|
214
|
+
"ubiquiti-edgeos",
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
const cpuLoadRows: Array<SnmpOid> = both.filter((oid: SnmpOid) => {
|
|
218
|
+
return oid.oid === "1.3.6.1.2.1.25.3.3.1.2.1";
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
expect(cpuLoadRows).toHaveLength(1);
|
|
222
|
+
expect(new Set(oidValues(both)).size).toBe(both.length);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
test("a user's existing row wins over the template's copy of the same OID", () => {
|
|
226
|
+
const custom: SnmpOid = {
|
|
227
|
+
oid: "1.3.6.1.4.1.9.9.109.1.1.1.1.8.1",
|
|
228
|
+
name: "My Custom CPU Name",
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const merged: Array<SnmpOid> = SnmpVendorTemplateUtil.mergeOids(
|
|
232
|
+
[custom],
|
|
233
|
+
"cisco-ios",
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
const cpuRows: Array<SnmpOid> = merged.filter((oid: SnmpOid) => {
|
|
237
|
+
return oid.oid === custom.oid;
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
expect(cpuRows).toHaveLength(1);
|
|
241
|
+
expect(cpuRows[0]?.name).toBe("My Custom CPU Name");
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test("an unknown template id returns the existing list unchanged", () => {
|
|
245
|
+
const existing: Array<SnmpOid> = [
|
|
246
|
+
{ oid: "1.3.6.1.2.1.1.1.0", name: "sysDescr" },
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
expect(
|
|
250
|
+
SnmpVendorTemplateUtil.mergeOids(existing, "no-such-template"),
|
|
251
|
+
).toEqual(existing);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test("merging does not mutate the caller's array", () => {
|
|
255
|
+
const existing: Array<SnmpOid> = [
|
|
256
|
+
{ oid: "1.3.6.1.2.1.1.1.0", name: "sysDescr" },
|
|
257
|
+
];
|
|
258
|
+
|
|
259
|
+
SnmpVendorTemplateUtil.mergeOids(existing, "cisco-ios");
|
|
260
|
+
|
|
261
|
+
expect(existing).toHaveLength(1);
|
|
262
|
+
});
|
|
263
|
+
});
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import BasicForm from "../../../UI/Components/Forms/BasicForm";
|
|
2
|
+
import Fields from "../../../UI/Components/Forms/Types/Fields";
|
|
3
|
+
import FormFieldSchemaType from "../../../UI/Components/Forms/Types/FormFieldSchemaType";
|
|
4
|
+
import FormValues from "../../../UI/Components/Forms/Types/FormValues";
|
|
5
|
+
import { DropdownOption } from "../../../UI/Components/Dropdown/Dropdown";
|
|
6
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
7
|
+
import { render, screen } from "@testing-library/react";
|
|
8
|
+
import userEvent from "@testing-library/user-event";
|
|
9
|
+
import * as React from "react";
|
|
10
|
+
import { describe, expect, test } from "@jest/globals";
|
|
11
|
+
import getJestMockFunction, { MockFunction } from "../../MockType";
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* BasicForm's initial-values effect canonicalizes each Dropdown field's stored
|
|
15
|
+
* value onto the matching option. It used to finish with
|
|
16
|
+
*
|
|
17
|
+
* values[fieldName] = dropdownOption?.value || null;
|
|
18
|
+
*
|
|
19
|
+
* which silently replaced any value that matched no option with null. That is
|
|
20
|
+
* data loss, not cosmetics: ModelForm submits every selected field, so an
|
|
21
|
+
* untouched field whose value was wiped here is PUT back as null and clears
|
|
22
|
+
* the column.
|
|
23
|
+
*
|
|
24
|
+
* Options legitimately fail to contain a valid stored value — a
|
|
25
|
+
* permission-scoped or truncated entity list, an options fetch that failed, or
|
|
26
|
+
* a free-text column holding a spelling the options don't list verbatim
|
|
27
|
+
* (NetworkDevice.snmpVersion stores either "V3" or the raw enum "3", and the
|
|
28
|
+
* SNMP form's showIf tolerates both via SnmpVersionUtil — but only if the
|
|
29
|
+
* value survives long enough to be read).
|
|
30
|
+
*
|
|
31
|
+
* These tests drive the real component and assert on the values it actually
|
|
32
|
+
* submits, because the normalization lives in a useEffect and re-implementing
|
|
33
|
+
* it in a test would pin nothing.
|
|
34
|
+
*
|
|
35
|
+
* Note: jest-dom matchers (toBeInTheDocument etc.) fail typecheck repo-wide,
|
|
36
|
+
* so assertions here stay on submitted values and plain DOM text.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
describe("BasicForm dropdown initial-value normalization", () => {
|
|
40
|
+
const OPTIONS: Array<DropdownOption> = [
|
|
41
|
+
{ label: "V1", value: "V1" },
|
|
42
|
+
{ label: "V2c", value: "V2c" },
|
|
43
|
+
{ label: "V3", value: "V3" },
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
type BuildFieldsFunction = (
|
|
47
|
+
options: Array<DropdownOption>,
|
|
48
|
+
) => Fields<FormValues<any>>;
|
|
49
|
+
|
|
50
|
+
const buildFields: BuildFieldsFunction = (
|
|
51
|
+
options: Array<DropdownOption>,
|
|
52
|
+
): Fields<FormValues<any>> => {
|
|
53
|
+
return [
|
|
54
|
+
{
|
|
55
|
+
field: { snmpVersion: true },
|
|
56
|
+
title: "SNMP Version",
|
|
57
|
+
fieldType: FormFieldSchemaType.Dropdown,
|
|
58
|
+
dropdownOptions: options,
|
|
59
|
+
required: false,
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
type SubmitFormFunction = (
|
|
65
|
+
initialValues: FormValues<any>,
|
|
66
|
+
fields: Fields<FormValues<any>>,
|
|
67
|
+
) => Promise<FormValues<any>>;
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
* Renders the form, clicks Save, and hands back the values BasicForm
|
|
71
|
+
* submitted — i.e. what would be written to the database.
|
|
72
|
+
*/
|
|
73
|
+
const submitForm: SubmitFormFunction = async (
|
|
74
|
+
initialValues: FormValues<any>,
|
|
75
|
+
fields: Fields<FormValues<any>>,
|
|
76
|
+
): Promise<FormValues<any>> => {
|
|
77
|
+
const onSubmit: MockFunction = getJestMockFunction();
|
|
78
|
+
|
|
79
|
+
render(
|
|
80
|
+
<BasicForm
|
|
81
|
+
fields={fields}
|
|
82
|
+
id="dropdown-normalization"
|
|
83
|
+
initialValues={initialValues}
|
|
84
|
+
onSubmit={onSubmit}
|
|
85
|
+
submitButtonText="Save"
|
|
86
|
+
/>,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
await userEvent.setup().click(screen.getByTestId("Save"));
|
|
90
|
+
|
|
91
|
+
return onSubmit.mock.calls[0]?.[0] as FormValues<any>;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
test("keeps a stored value that matches no option instead of nulling it", async () => {
|
|
95
|
+
/*
|
|
96
|
+
* The reported case: a device whose snmpVersion column holds the raw enum
|
|
97
|
+
* spelling "3" while the dropdown lists "V1"/"V2c"/"V3".
|
|
98
|
+
*/
|
|
99
|
+
const submitted: FormValues<any> = await submitForm(
|
|
100
|
+
{ snmpVersion: "3" } as FormValues<any>,
|
|
101
|
+
buildFields(OPTIONS),
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
expect(submitted).toEqual({ snmpVersion: "3" });
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("keeps stored values when the options failed to load", async () => {
|
|
108
|
+
/*
|
|
109
|
+
* ModelForm sets dropdownOptions to [] when an entity list comes back
|
|
110
|
+
* empty or its fetch throws. Nulling on no-match wiped every dropdown on
|
|
111
|
+
* such a form.
|
|
112
|
+
*/
|
|
113
|
+
const submitted: FormValues<any> = await submitForm(
|
|
114
|
+
{ snmpVersion: "V3" } as FormValues<any>,
|
|
115
|
+
buildFields([]),
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
expect(submitted).toEqual({ snmpVersion: "V3" });
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("still canonicalizes a value that does match an option", async () => {
|
|
122
|
+
const submitted: FormValues<any> = await submitForm(
|
|
123
|
+
{ snmpVersion: "V3" } as FormValues<any>,
|
|
124
|
+
buildFields(OPTIONS),
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
expect(submitted).toEqual({ snmpVersion: "V3" });
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("converts a matching ObjectID initial value to its string form", async () => {
|
|
131
|
+
const id: ObjectID = new ObjectID("3f1b6b0e-0000-4000-8000-000000000001");
|
|
132
|
+
|
|
133
|
+
const submitted: FormValues<any> = await submitForm(
|
|
134
|
+
{ snmpVersion: id } as unknown as FormValues<any>,
|
|
135
|
+
buildFields([{ label: "Probe A", value: id.toString() }]),
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
expect(submitted).toEqual({ snmpVersion: id.toString() });
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("preserves an unmatched ObjectID as a string, not as an ObjectID", async () => {
|
|
142
|
+
/*
|
|
143
|
+
* An entity dropdown whose referenced row is missing from the (possibly
|
|
144
|
+
* permission-scoped) option list must still submit the canonical string
|
|
145
|
+
* the API expects — preserving the raw ObjectID instance would send an
|
|
146
|
+
* object.
|
|
147
|
+
*/
|
|
148
|
+
const id: ObjectID = new ObjectID("3f1b6b0e-0000-4000-8000-000000000002");
|
|
149
|
+
|
|
150
|
+
const submitted: FormValues<any> = await submitForm(
|
|
151
|
+
{ snmpVersion: id } as unknown as FormValues<any>,
|
|
152
|
+
buildFields([{ label: "Someone else", value: "a-different-id" }]),
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
expect(submitted).toEqual({ snmpVersion: id.toString() });
|
|
156
|
+
expect(typeof submitted["snmpVersion"]).toBe("string");
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test("leaves an absent value alone", async () => {
|
|
160
|
+
const submitted: FormValues<any> = await submitForm(
|
|
161
|
+
{} as FormValues<any>,
|
|
162
|
+
buildFields(OPTIONS),
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
expect(submitted["snmpVersion"]).toBeUndefined();
|
|
166
|
+
});
|
|
167
|
+
});
|