@oneuptime/common 11.5.9 → 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.
Files changed (376) hide show
  1. package/Models/AnalyticsModels/Index.ts +13 -0
  2. package/Models/AnalyticsModels/MetricItemAggMV1mByContainer.ts +178 -0
  3. package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +179 -0
  4. package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +179 -0
  5. package/Models/AnalyticsModels/NetworkFlow.ts +397 -0
  6. package/Models/DatabaseModels/EnterpriseLicenseInstance.ts +18 -0
  7. package/Models/DatabaseModels/GlobalConfig.ts +36 -0
  8. package/Models/DatabaseModels/Index.ts +2 -0
  9. package/Models/DatabaseModels/MarketingConversion.ts +198 -0
  10. package/Models/DatabaseModels/MetricSavedView.ts +34 -0
  11. package/Models/DatabaseModels/MetricType.ts +74 -0
  12. package/Models/DatabaseModels/NetworkDevice.ts +332 -0
  13. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +113 -0
  14. package/Models/DatabaseModels/NetworkInterface.ts +58 -0
  15. package/Models/DatabaseModels/Project.ts +37 -0
  16. package/Models/DatabaseModels/User.ts +37 -0
  17. package/Server/API/BaseAnalyticsAPI.ts +23 -0
  18. package/Server/API/EnterpriseLicenseAPI.ts +14 -0
  19. package/Server/EnvironmentConfig.ts +84 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.ts +38 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.ts +28 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.ts +108 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.ts +31 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.ts +29 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.ts +35 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  27. package/Server/Services/AnalyticsDatabaseService.ts +70 -1
  28. package/Server/Services/IncidentService.ts +13 -0
  29. package/Server/Services/Index.ts +10 -0
  30. package/Server/Services/MarketingConversionService.ts +10 -0
  31. package/Server/Services/MetricItemAggMV1mByContainerService.ts +31 -0
  32. package/Server/Services/MetricItemAggMV1mByK8sClusterService.ts +31 -0
  33. package/Server/Services/MetricItemAggMV1mByServiceService.ts +31 -0
  34. package/Server/Services/MetricService.ts +970 -122
  35. package/Server/Services/MonitorService.ts +14 -0
  36. package/Server/Services/NetworkDeviceOwnerTeamService.ts +42 -0
  37. package/Server/Services/NetworkDeviceOwnerUserService.ts +106 -0
  38. package/Server/Services/NetworkFlowService.ts +11 -0
  39. package/Server/Services/OnCallDutyPolicyService.ts +11 -1
  40. package/Server/Services/ProjectService.ts +136 -0
  41. package/Server/Services/SpanService.ts +13 -9
  42. package/Server/Services/StatusPageService.ts +10 -0
  43. package/Server/Services/TeamMemberService.ts +11 -0
  44. package/Server/Services/UserService.ts +59 -0
  45. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +37 -7
  46. package/Server/Utils/Attribution.ts +99 -0
  47. package/Server/Utils/Marketing/ConversionUploadProvider.ts +103 -0
  48. package/Server/Utils/Marketing/ConversionUploadProviders.ts +22 -0
  49. package/Server/Utils/Marketing/Providers/GoogleAds.ts +270 -0
  50. package/Server/Utils/Marketing/Providers/LinkedIn.ts +147 -0
  51. package/Server/Utils/Marketing/Providers/Meta.ts +148 -0
  52. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +196 -0
  53. package/Server/Utils/Marketing/Providers/Reddit.ts +178 -0
  54. package/Server/Utils/Monitor/MonitorAlert.ts +71 -7
  55. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +31 -19
  56. package/Server/Utils/Monitor/MonitorIncident.ts +71 -7
  57. package/Server/Utils/Monitor/MonitorMetricUtil.ts +57 -0
  58. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +94 -0
  59. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +15 -0
  60. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +125 -14
  61. package/Server/Utils/ProductAnalytics.ts +133 -0
  62. package/Server/Utils/Telemetry/Telemetry.ts +39 -0
  63. package/Server/Utils/Telemetry/TelemetryEntity.ts +21 -0
  64. package/Tests/Server/API/BaseAnalyticsAPI.test.ts +72 -0
  65. package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +9 -1
  66. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +21 -2
  67. package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +173 -0
  68. package/Tests/Server/Services/MetricServiceAggregate.test.ts +1391 -0
  69. package/Tests/Server/Services/NetworkDeviceOwnerServices.test.ts +260 -0
  70. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilNetworkDevice.test.ts +389 -0
  71. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +764 -0
  72. package/Tests/Types/BaseDatabase/AggregationIntervalUtil.test.ts +111 -2
  73. package/Tests/Types/Database/EndsWith.test.ts +64 -0
  74. package/Tests/Types/Database/GreaterThan.test.ts +62 -0
  75. package/Tests/Types/Database/GreaterThanOrEqual.test.ts +65 -0
  76. package/Tests/Types/Database/GreaterThanOrNull.test.ts +63 -0
  77. package/Tests/Types/Database/Includes.test.ts +65 -0
  78. package/Tests/Types/Database/IncludesAll.test.ts +65 -0
  79. package/Tests/Types/Database/IncludesNone.test.ts +65 -0
  80. package/Tests/Types/Database/IsNull.test.ts +44 -0
  81. package/Tests/Types/Database/LessThan.test.ts +62 -0
  82. package/Tests/Types/Database/LessThanOrEqual.test.ts +62 -0
  83. package/Tests/Types/Database/LessThanOrNull.test.ts +62 -0
  84. package/Tests/Types/Database/MultiSearch.test.ts +81 -0
  85. package/Tests/Types/Database/NotContains.test.ts +64 -0
  86. package/Tests/Types/Database/NotNull.test.ts +44 -0
  87. package/Tests/Types/Database/StartsWith.test.ts +64 -0
  88. package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +83 -1
  89. package/Tests/Types/Monitor/SnmpV3EnumParsing.test.ts +247 -0
  90. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +263 -0
  91. package/Tests/UI/Components/XAxis.test.ts +5 -3
  92. package/Tests/Utils/EnterpriseLicenseUsage.test.ts +76 -0
  93. package/Tests/Utils/Metrics/MetricExplorerUrl.test.ts +622 -0
  94. package/Tests/Utils/Metrics/MetricFormulaEvaluator.test.ts +474 -0
  95. package/Tests/Utils/Telemetry/HeartbeatAvailability.test.ts +52 -4
  96. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +11 -0
  97. package/Types/BaseDatabase/AggregateBy.ts +31 -2
  98. package/Types/BaseDatabase/AggregatedResult.ts +22 -0
  99. package/Types/BaseDatabase/AggregationInterval.ts +11 -0
  100. package/Types/BaseDatabase/AggregationIntervalUtil.ts +30 -5
  101. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +16 -0
  102. package/Types/Email/EmailTemplateType.ts +3 -0
  103. package/Types/Marketing/MarketingConversion.ts +11 -0
  104. package/Types/Metrics/MetricQueryConfigData.ts +21 -0
  105. package/Types/Metrics/MetricQueryData.ts +8 -0
  106. package/Types/Metrics/MetricViewData.ts +8 -0
  107. package/Types/Monitor/MonitorMetricType.ts +8 -0
  108. package/Types/Monitor/MonitorStep.ts +9 -0
  109. package/Types/Monitor/MonitorStepSqlMonitor.ts +12 -0
  110. package/Types/Monitor/MonitorType.ts +2 -1
  111. package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +17 -12
  112. package/Types/Monitor/SnmpMonitor/CdpNeighbor.ts +13 -0
  113. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +37 -3
  114. package/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.ts +46 -0
  115. package/Types/Monitor/SnmpMonitor/SnmpEntityInfo.ts +15 -0
  116. package/Types/Monitor/SnmpMonitor/SnmpInterface.ts +8 -0
  117. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +17 -8
  118. package/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.ts +53 -0
  119. package/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.ts +43 -0
  120. package/Types/Monitor/SnmpMonitor/SnmpSystemInfo.ts +16 -0
  121. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +119 -3
  122. package/Types/NetFlow/NetworkFlowRecord.ts +25 -0
  123. package/Types/Syslog/SyslogMessage.ts +18 -0
  124. package/Types/Telemetry/TelemetrySavedViewState.ts +9 -0
  125. package/Types/Telemetry/TelemetrySavedViewType.ts +12 -0
  126. package/UI/Components/Charts/Area/AreaChart.tsx +51 -0
  127. package/UI/Components/Charts/Bar/BarChart.tsx +51 -1
  128. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +97 -26
  129. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +328 -1
  130. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +115 -0
  131. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +328 -1
  132. package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +7 -0
  133. package/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.ts +15 -0
  134. package/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.ts +13 -0
  135. package/UI/Components/Charts/Line/LineChart.tsx +51 -0
  136. package/UI/Components/Charts/Types/ReferenceRegionProps.ts +12 -0
  137. package/UI/Components/Charts/Types/TimeReferenceLineProps.ts +12 -0
  138. package/UI/Components/Charts/Types/XAxis/XAxisPrecision.ts +1 -0
  139. package/UI/Components/Charts/Utils/DataPoint.ts +0 -0
  140. package/UI/Components/Charts/Utils/TimeAnnotation.ts +169 -0
  141. package/UI/Components/Charts/Utils/XAxis.ts +28 -4
  142. package/UI/Components/Icon/Icon.tsx +33 -13
  143. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +9 -0
  144. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +67 -0
  145. package/UI/Components/Page/ModelPage.tsx +6 -1
  146. package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +33 -4
  147. package/UI/Styles/Theme.css +10 -0
  148. package/UI/Utils/User.ts +41 -2
  149. package/Utils/Analytics.ts +8 -6
  150. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +74 -0
  151. package/Utils/Metrics/MetricExplorerUrl.ts +771 -0
  152. package/Utils/Metrics/MetricFormulaEvaluator.ts +410 -46
  153. package/Utils/Monitor/NetworkTopologyUtil.ts +261 -49
  154. package/Utils/ValueFormatter.ts +22 -1
  155. package/build/dist/Models/AnalyticsModels/Index.js +13 -0
  156. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  157. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js +159 -0
  158. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js.map +1 -0
  159. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +158 -0
  160. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js.map +1 -0
  161. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +160 -0
  162. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js.map +1 -0
  163. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +351 -0
  164. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -0
  165. package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js +19 -0
  166. package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js.map +1 -1
  167. package/build/dist/Models/DatabaseModels/GlobalConfig.js +38 -0
  168. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  169. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  170. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  171. package/build/dist/Models/DatabaseModels/MarketingConversion.js +219 -0
  172. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -0
  173. package/build/dist/Models/DatabaseModels/MetricSavedView.js +35 -0
  174. package/build/dist/Models/DatabaseModels/MetricSavedView.js.map +1 -1
  175. package/build/dist/Models/DatabaseModels/MetricType.js +76 -0
  176. package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
  177. package/build/dist/Models/DatabaseModels/NetworkDevice.js +341 -0
  178. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  179. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +116 -0
  180. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  181. package/build/dist/Models/DatabaseModels/NetworkInterface.js +60 -0
  182. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
  183. package/build/dist/Models/DatabaseModels/Project.js +38 -0
  184. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  185. package/build/dist/Models/DatabaseModels/User.js +38 -0
  186. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  187. package/build/dist/Server/API/BaseAnalyticsAPI.js +19 -0
  188. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  189. package/build/dist/Server/API/EnterpriseLicenseAPI.js +8 -0
  190. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
  191. package/build/dist/Server/EnvironmentConfig.js +51 -0
  192. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  193. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js +27 -0
  194. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js.map +1 -0
  195. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js +21 -0
  196. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js.map +1 -0
  197. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js +47 -0
  198. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js.map +1 -0
  199. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js +16 -0
  200. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js.map +1 -0
  201. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js +18 -0
  202. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js.map +1 -0
  203. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js +20 -0
  204. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js.map +1 -0
  205. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  206. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  207. package/build/dist/Server/Services/AnalyticsDatabaseService.js +58 -4
  208. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  209. package/build/dist/Server/Services/IncidentService.js +12 -0
  210. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  211. package/build/dist/Server/Services/Index.js +10 -0
  212. package/build/dist/Server/Services/Index.js.map +1 -1
  213. package/build/dist/Server/Services/MarketingConversionService.js +9 -0
  214. package/build/dist/Server/Services/MarketingConversionService.js.map +1 -0
  215. package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js +29 -0
  216. package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js.map +1 -0
  217. package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js +29 -0
  218. package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js.map +1 -0
  219. package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js +29 -0
  220. package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js.map +1 -0
  221. package/build/dist/Server/Services/MetricService.js +761 -125
  222. package/build/dist/Server/Services/MetricService.js.map +1 -1
  223. package/build/dist/Server/Services/MonitorService.js +18 -5
  224. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  225. package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js +44 -0
  226. package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js.map +1 -1
  227. package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js +88 -0
  228. package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js.map +1 -1
  229. package/build/dist/Server/Services/NetworkFlowService.js +9 -0
  230. package/build/dist/Server/Services/NetworkFlowService.js.map +1 -0
  231. package/build/dist/Server/Services/OnCallDutyPolicyService.js +15 -6
  232. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  233. package/build/dist/Server/Services/ProjectService.js +107 -6
  234. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  235. package/build/dist/Server/Services/SpanService.js +8 -6
  236. package/build/dist/Server/Services/SpanService.js.map +1 -1
  237. package/build/dist/Server/Services/StatusPageService.js +10 -0
  238. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  239. package/build/dist/Server/Services/TeamMemberService.js +11 -0
  240. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  241. package/build/dist/Server/Services/UserService.js +52 -0
  242. package/build/dist/Server/Services/UserService.js.map +1 -1
  243. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +33 -7
  244. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  245. package/build/dist/Server/Utils/Attribution.js +74 -0
  246. package/build/dist/Server/Utils/Attribution.js.map +1 -0
  247. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +40 -0
  248. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -0
  249. package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +20 -0
  250. package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +1 -0
  251. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +177 -0
  252. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -0
  253. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +113 -0
  254. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -0
  255. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +109 -0
  256. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -0
  257. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +130 -0
  258. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -0
  259. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +126 -0
  260. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -0
  261. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +53 -9
  262. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  263. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -10
  264. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  265. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +54 -11
  266. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  267. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +43 -3
  268. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  269. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +68 -0
  270. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  271. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +15 -0
  272. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  273. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +100 -15
  274. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  275. package/build/dist/Server/Utils/ProductAnalytics.js +111 -0
  276. package/build/dist/Server/Utils/ProductAnalytics.js.map +1 -0
  277. package/build/dist/Server/Utils/Telemetry/Telemetry.js +32 -5
  278. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  279. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -0
  280. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  281. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +11 -0
  282. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  283. package/build/dist/Types/BaseDatabase/AggregationInterval.js +11 -0
  284. package/build/dist/Types/BaseDatabase/AggregationInterval.js.map +1 -1
  285. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +33 -5
  286. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
  287. package/build/dist/Types/Email/EmailTemplateType.js +2 -0
  288. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  289. package/build/dist/Types/Marketing/MarketingConversion.js +13 -0
  290. package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -0
  291. package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
  292. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  293. package/build/dist/Types/Monitor/MonitorStep.js +6 -0
  294. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  295. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +3 -0
  296. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
  297. package/build/dist/Types/Monitor/MonitorType.js +2 -1
  298. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  299. package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js +2 -0
  300. package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js.map +1 -0
  301. package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js +41 -0
  302. package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js.map +1 -1
  303. package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js +2 -0
  304. package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js.map +1 -0
  305. package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js +48 -0
  306. package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js.map +1 -1
  307. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js +38 -0
  308. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js.map +1 -1
  309. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js +2 -0
  310. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js.map +1 -0
  311. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +96 -3
  312. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  313. package/build/dist/Types/NetFlow/NetworkFlowRecord.js +2 -0
  314. package/build/dist/Types/NetFlow/NetworkFlowRecord.js.map +1 -0
  315. package/build/dist/Types/Syslog/SyslogMessage.js +2 -0
  316. package/build/dist/Types/Syslog/SyslogMessage.js.map +1 -0
  317. package/build/dist/Types/Telemetry/TelemetrySavedViewState.js +0 -7
  318. package/build/dist/Types/Telemetry/TelemetrySavedViewState.js.map +1 -1
  319. package/build/dist/Types/Telemetry/TelemetrySavedViewType.js +13 -0
  320. package/build/dist/Types/Telemetry/TelemetrySavedViewType.js.map +1 -0
  321. package/build/dist/UI/Components/Charts/Area/AreaChart.js +25 -1
  322. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  323. package/build/dist/UI/Components/Charts/Bar/BarChart.js +26 -2
  324. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  325. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +36 -12
  326. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  327. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +208 -6
  328. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  329. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +52 -3
  330. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  331. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +208 -6
  332. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  333. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +6 -1
  334. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -1
  335. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js +2 -0
  336. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js.map +1 -0
  337. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js +2 -0
  338. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js.map +1 -0
  339. package/build/dist/UI/Components/Charts/Line/LineChart.js +25 -1
  340. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  341. package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js +2 -0
  342. package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js.map +1 -0
  343. package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js +2 -0
  344. package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js.map +1 -0
  345. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js +1 -0
  346. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js.map +1 -1
  347. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +0 -0
  348. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  349. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +121 -0
  350. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -0
  351. package/build/dist/UI/Components/Charts/Utils/XAxis.js +27 -4
  352. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  353. package/build/dist/UI/Components/Icon/Icon.js +15 -8
  354. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  355. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  356. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +58 -0
  357. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  358. package/build/dist/UI/Components/Page/ModelPage.js +7 -1
  359. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  360. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +10 -4
  361. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
  362. package/build/dist/UI/Utils/User.js +35 -2
  363. package/build/dist/UI/Utils/User.js.map +1 -1
  364. package/build/dist/Utils/Analytics.js +8 -5
  365. package/build/dist/Utils/Analytics.js.map +1 -1
  366. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +57 -0
  367. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  368. package/build/dist/Utils/Metrics/MetricExplorerUrl.js +418 -0
  369. package/build/dist/Utils/Metrics/MetricExplorerUrl.js.map +1 -0
  370. package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js +296 -37
  371. package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js.map +1 -1
  372. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +176 -40
  373. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  374. package/build/dist/Utils/ValueFormatter.js +20 -1
  375. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  376. package/package.json +2 -2
@@ -0,0 +1,260 @@
1
+ import { afterEach, describe, expect, test } from "@jest/globals";
2
+ import NetworkDeviceOwnerUserService, {
3
+ NetworkDeviceOwners,
4
+ } from "../../../Server/Services/NetworkDeviceOwnerUserService";
5
+ import NetworkDeviceOwnerTeamService from "../../../Server/Services/NetworkDeviceOwnerTeamService";
6
+ import NetworkDeviceOwnerUser from "../../../Models/DatabaseModels/NetworkDeviceOwnerUser";
7
+ import NetworkDeviceOwnerTeam from "../../../Models/DatabaseModels/NetworkDeviceOwnerTeam";
8
+ import Monitor from "../../../Models/DatabaseModels/Monitor";
9
+ import MonitorStep from "../../../Types/Monitor/MonitorStep";
10
+ import MonitorSteps from "../../../Types/Monitor/MonitorSteps";
11
+ import ObjectID from "../../../Types/ObjectID";
12
+
13
+ /*
14
+ * getDeviceOwnersForMonitor fans a NetworkDevice's owner users/teams into
15
+ * monitor-created incidents/alerts and the owner-added notification job. The
16
+ * device id lives buried in monitor step config, so these tests pin the step
17
+ * selection rules (prefer the step that produced the probe response, fall
18
+ * back to the first device-referencing step), the no-device fast path that
19
+ * must not touch the database, and the shape/filtering of the returned id
20
+ * arrays. Database access is mocked at the findBy level.
21
+ */
22
+
23
+ const DEVICE_A: string = "8f2c1f0e-0000-4000-8000-0000000000aa";
24
+ const DEVICE_B: string = "8f2c1f0e-0000-4000-8000-0000000000bb";
25
+
26
+ function buildStep(networkDeviceId?: string): MonitorStep {
27
+ const step: MonitorStep = new MonitorStep();
28
+
29
+ if (networkDeviceId) {
30
+ step.data = {
31
+ ...step.data,
32
+ networkDeviceMonitor: {
33
+ networkDeviceId: networkDeviceId,
34
+ },
35
+ } as MonitorStep["data"];
36
+ }
37
+
38
+ return step;
39
+ }
40
+
41
+ function buildMonitor(steps: Array<MonitorStep>): Monitor {
42
+ const monitorSteps: MonitorSteps = new MonitorSteps();
43
+ monitorSteps.data = {
44
+ monitorStepsInstanceArray: steps,
45
+ defaultMonitorStatusId: undefined,
46
+ };
47
+
48
+ const monitor: Monitor = new Monitor();
49
+ monitor.monitorSteps = monitorSteps;
50
+
51
+ return monitor;
52
+ }
53
+
54
+ function ownerUserRow(userId?: ObjectID): NetworkDeviceOwnerUser {
55
+ const row: NetworkDeviceOwnerUser = new NetworkDeviceOwnerUser();
56
+ if (userId) {
57
+ row.userId = userId;
58
+ }
59
+ return row;
60
+ }
61
+
62
+ function ownerTeamRow(teamId?: ObjectID): NetworkDeviceOwnerTeam {
63
+ const row: NetworkDeviceOwnerTeam = new NetworkDeviceOwnerTeam();
64
+ if (teamId) {
65
+ row.teamId = teamId;
66
+ }
67
+ return row;
68
+ }
69
+
70
+ function mockOwnerRows(options?: {
71
+ users?: Array<NetworkDeviceOwnerUser> | undefined;
72
+ teams?: Array<NetworkDeviceOwnerTeam> | undefined;
73
+ }): {
74
+ userFindBy: jest.SpyInstance;
75
+ teamFindBy: jest.SpyInstance;
76
+ } {
77
+ const userFindBy: jest.SpyInstance = jest
78
+ .spyOn(NetworkDeviceOwnerUserService, "findBy")
79
+ .mockResolvedValue(options?.users || []);
80
+ const teamFindBy: jest.SpyInstance = jest
81
+ .spyOn(NetworkDeviceOwnerTeamService, "findBy")
82
+ .mockResolvedValue(options?.teams || []);
83
+
84
+ return { userFindBy: userFindBy, teamFindBy: teamFindBy };
85
+ }
86
+
87
+ function queriedDeviceId(spy: jest.SpyInstance): string | undefined {
88
+ return spy.mock.calls[0]?.[0]?.query?.networkDeviceId?.toString();
89
+ }
90
+
91
+ afterEach(() => {
92
+ jest.restoreAllMocks();
93
+ });
94
+
95
+ describe("NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor — no-device fast path", () => {
96
+ test("a monitor with no steps returns empty owners without touching the database", async () => {
97
+ const { userFindBy, teamFindBy } = mockOwnerRows();
98
+
99
+ const owners: NetworkDeviceOwners =
100
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
101
+ monitor: buildMonitor([]),
102
+ });
103
+
104
+ expect(owners).toEqual({ ownerUserIds: [], ownerTeamIds: [] });
105
+ expect(userFindBy).not.toHaveBeenCalled();
106
+ expect(teamFindBy).not.toHaveBeenCalled();
107
+ });
108
+
109
+ test("a monitor with no monitorSteps object at all behaves the same", async () => {
110
+ const { userFindBy, teamFindBy } = mockOwnerRows();
111
+
112
+ const owners: NetworkDeviceOwners =
113
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
114
+ monitor: new Monitor(),
115
+ });
116
+
117
+ expect(owners).toEqual({ ownerUserIds: [], ownerTeamIds: [] });
118
+ expect(userFindBy).not.toHaveBeenCalled();
119
+ expect(teamFindBy).not.toHaveBeenCalled();
120
+ });
121
+
122
+ test("steps that reference no device return empty owners without queries", async () => {
123
+ const { userFindBy, teamFindBy } = mockOwnerRows();
124
+
125
+ const owners: NetworkDeviceOwners =
126
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
127
+ monitor: buildMonitor([buildStep(), buildStep()]),
128
+ });
129
+
130
+ expect(owners).toEqual({ ownerUserIds: [], ownerTeamIds: [] });
131
+ expect(userFindBy).not.toHaveBeenCalled();
132
+ expect(teamFindBy).not.toHaveBeenCalled();
133
+ });
134
+ });
135
+
136
+ describe("NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor — step selection", () => {
137
+ test("the step that produced the probe response is preferred", async () => {
138
+ const stepA: MonitorStep = buildStep(DEVICE_A);
139
+ const stepB: MonitorStep = buildStep(DEVICE_B);
140
+ const { userFindBy, teamFindBy } = mockOwnerRows();
141
+
142
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
143
+ monitor: buildMonitor([stepA, stepB]),
144
+ monitorStepId: stepB.id.toString(),
145
+ });
146
+
147
+ expect(queriedDeviceId(userFindBy)).toBe(DEVICE_B);
148
+ expect(queriedDeviceId(teamFindBy)).toBe(DEVICE_B);
149
+ });
150
+
151
+ test("a monitorStepId matching no step falls back to the first device-referencing step", async () => {
152
+ const stepA: MonitorStep = buildStep(DEVICE_A);
153
+ const stepB: MonitorStep = buildStep(DEVICE_B);
154
+ const { userFindBy } = mockOwnerRows();
155
+
156
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
157
+ monitor: buildMonitor([stepA, stepB]),
158
+ monitorStepId: ObjectID.generate().toString(),
159
+ });
160
+
161
+ expect(queriedDeviceId(userFindBy)).toBe(DEVICE_A);
162
+ });
163
+
164
+ test("a matching step without device config falls back to the device-referencing step", async () => {
165
+ const stepWithoutDevice: MonitorStep = buildStep();
166
+ const stepWithDevice: MonitorStep = buildStep(DEVICE_B);
167
+ const { userFindBy } = mockOwnerRows();
168
+
169
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
170
+ monitor: buildMonitor([stepWithoutDevice, stepWithDevice]),
171
+ monitorStepId: stepWithoutDevice.id.toString(),
172
+ });
173
+
174
+ expect(queriedDeviceId(userFindBy)).toBe(DEVICE_B);
175
+ });
176
+
177
+ test("callers without a step id pick up owners from the first device-referencing step", async () => {
178
+ const stepWithoutDevice: MonitorStep = buildStep();
179
+ const stepWithDevice: MonitorStep = buildStep(DEVICE_A);
180
+ const { userFindBy } = mockOwnerRows();
181
+
182
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
183
+ monitor: buildMonitor([stepWithoutDevice, stepWithDevice]),
184
+ });
185
+
186
+ expect(queriedDeviceId(userFindBy)).toBe(DEVICE_A);
187
+ });
188
+ });
189
+
190
+ describe("NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor — returned owners", () => {
191
+ test("owner user and team ids come back from the mocked rows", async () => {
192
+ const userId1: ObjectID = ObjectID.generate();
193
+ const userId2: ObjectID = ObjectID.generate();
194
+ const teamId: ObjectID = ObjectID.generate();
195
+
196
+ mockOwnerRows({
197
+ users: [ownerUserRow(userId1), ownerUserRow(userId2)],
198
+ teams: [ownerTeamRow(teamId)],
199
+ });
200
+
201
+ const owners: NetworkDeviceOwners =
202
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
203
+ monitor: buildMonitor([buildStep(DEVICE_A)]),
204
+ });
205
+
206
+ expect(owners.ownerUserIds.map(String)).toEqual([
207
+ userId1.toString(),
208
+ userId2.toString(),
209
+ ]);
210
+ expect(owners.ownerTeamIds.map(String)).toEqual([teamId.toString()]);
211
+ });
212
+
213
+ test("rows missing their user/team id are filtered out of the result", async () => {
214
+ const userId: ObjectID = ObjectID.generate();
215
+ const teamId: ObjectID = ObjectID.generate();
216
+
217
+ mockOwnerRows({
218
+ users: [ownerUserRow(), ownerUserRow(userId)],
219
+ teams: [ownerTeamRow(teamId), ownerTeamRow()],
220
+ });
221
+
222
+ const owners: NetworkDeviceOwners =
223
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
224
+ monitor: buildMonitor([buildStep(DEVICE_A)]),
225
+ });
226
+
227
+ expect(owners.ownerUserIds.map(String)).toEqual([userId.toString()]);
228
+ expect(owners.ownerTeamIds.map(String)).toEqual([teamId.toString()]);
229
+ });
230
+
231
+ test("a device with no owners at all yields empty arrays (not undefined)", async () => {
232
+ const { userFindBy, teamFindBy } = mockOwnerRows();
233
+
234
+ const owners: NetworkDeviceOwners =
235
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
236
+ monitor: buildMonitor([buildStep(DEVICE_A)]),
237
+ monitorStepId: undefined,
238
+ });
239
+
240
+ expect(owners.ownerUserIds).toEqual([]);
241
+ expect(owners.ownerTeamIds).toEqual([]);
242
+ // The device IS referenced, so both ownership tables are consulted once.
243
+ expect(userFindBy).toHaveBeenCalledTimes(1);
244
+ expect(teamFindBy).toHaveBeenCalledTimes(1);
245
+ });
246
+
247
+ test("both queries are scoped to the referenced device id", async () => {
248
+ const { userFindBy, teamFindBy } = mockOwnerRows();
249
+
250
+ await NetworkDeviceOwnerUserService.getDeviceOwnersForMonitor({
251
+ monitor: buildMonitor([buildStep(DEVICE_A)]),
252
+ });
253
+
254
+ expect(queriedDeviceId(userFindBy)).toBe(DEVICE_A);
255
+ expect(queriedDeviceId(teamFindBy)).toBe(DEVICE_A);
256
+ expect(
257
+ userFindBy.mock.calls[0]?.[0]?.query?.networkDeviceId,
258
+ ).toBeInstanceOf(ObjectID);
259
+ });
260
+ });
@@ -0,0 +1,389 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import MonitorTemplateUtil from "../../../../Server/Utils/Monitor/MonitorTemplateUtil";
3
+ import MonitorType from "../../../../Types/Monitor/MonitorType";
4
+ import ObjectID from "../../../../Types/ObjectID";
5
+ import ProbeMonitorResponse from "../../../../Types/Probe/ProbeMonitorResponse";
6
+ import SnmpMonitorResponse from "../../../../Types/Monitor/SnmpMonitor/SnmpMonitorResponse";
7
+ import SnmpInterface from "../../../../Types/Monitor/SnmpMonitor/SnmpInterface";
8
+ import SnmpTrap from "../../../../Types/Monitor/SnmpMonitor/SnmpTrap";
9
+ import SnmpDataType from "../../../../Types/Monitor/SnmpMonitor/SnmpDataType";
10
+ import { JSONObject } from "../../../../Types/JSON";
11
+
12
+ /*
13
+ * The MonitorType.NetworkDevice branch of buildTemplateStorageMap defines the
14
+ * template-variable surface incident/alert titles can reference for SNMP
15
+ * monitors ("{{downInterfaces.0.name}} on {{sysName}} is down"). These tests
16
+ * pin that surface: the admin-up convention behind the interface counts,
17
+ * the {name, alias, interfaceIndex} shape of downInterfaces, empty-string
18
+ * defaulting of the system-group identity fields (and the guard protecting a
19
+ * user's custom OID named sysName), and the trap payload appearing only on
20
+ * trap-triggered checks.
21
+ */
22
+
23
+ function buildResponse(options?: {
24
+ snmp?: Partial<SnmpMonitorResponse> | undefined;
25
+ trap?: SnmpTrap | undefined;
26
+ }): ProbeMonitorResponse {
27
+ const snmpResponse: SnmpMonitorResponse = {
28
+ isOnline: true,
29
+ responseTimeInMs: 25,
30
+ failureCause: "",
31
+ oidResponses: [],
32
+ ...options?.snmp,
33
+ };
34
+
35
+ const response: ProbeMonitorResponse = {
36
+ projectId: ObjectID.generate(),
37
+ monitorStepId: ObjectID.generate(),
38
+ monitorId: ObjectID.generate(),
39
+ probeId: ObjectID.generate(),
40
+ failureCause: "",
41
+ monitoredAt: new Date("2026-07-16T12:00:00.000Z"),
42
+ isOnline: true,
43
+ snmpResponse: snmpResponse,
44
+ } as ProbeMonitorResponse;
45
+
46
+ if (options?.trap) {
47
+ response.snmpTrapResponse = options.trap;
48
+ }
49
+
50
+ return response;
51
+ }
52
+
53
+ function buildMap(response: ProbeMonitorResponse): JSONObject {
54
+ return MonitorTemplateUtil.buildTemplateStorageMap({
55
+ monitorType: MonitorType.NetworkDevice,
56
+ dataToProcess: response,
57
+ });
58
+ }
59
+
60
+ function iface(overrides: Partial<SnmpInterface>): SnmpInterface {
61
+ return {
62
+ interfaceIndex: 1,
63
+ name: "GigabitEthernet0/1",
64
+ isOperationallyUp: true,
65
+ isAdministrativelyUp: true,
66
+ ...overrides,
67
+ };
68
+ }
69
+
70
+ describe("MonitorTemplateUtil.buildTemplateStorageMap — NetworkDevice base fields", () => {
71
+ test("online status, timing and failure fields come from the SNMP response", () => {
72
+ const map: JSONObject = buildMap(
73
+ buildResponse({
74
+ snmp: {
75
+ responseTimeInMs: 42,
76
+ failureCause: "timed out",
77
+ isTimeout: true,
78
+ },
79
+ }),
80
+ );
81
+
82
+ expect(map["isOnline"]).toBe(true);
83
+ expect(map["responseTimeInMs"]).toBe(42);
84
+ expect(map["failureCause"]).toBe("timed out");
85
+ expect(map["isTimeout"]).toBe(true);
86
+ });
87
+
88
+ test("OID responses are exposed both as a list and by name", () => {
89
+ const map: JSONObject = buildMap(
90
+ buildResponse({
91
+ snmp: {
92
+ oidResponses: [
93
+ {
94
+ oid: "1.3.6.1.4.1.9.9.109.1.1.1.1.8.1",
95
+ name: "cpuLoad",
96
+ value: 37,
97
+ type: SnmpDataType.Integer,
98
+ },
99
+ ],
100
+ },
101
+ }),
102
+ );
103
+
104
+ expect(map["oidResponses"]).toEqual([
105
+ {
106
+ oid: "1.3.6.1.4.1.9.9.109.1.1.1.1.8.1",
107
+ name: "cpuLoad",
108
+ value: 37,
109
+ type: SnmpDataType.Integer,
110
+ },
111
+ ]);
112
+ expect(map["cpuLoad"]).toBe(37);
113
+ });
114
+ });
115
+
116
+ describe("MonitorTemplateUtil.buildTemplateStorageMap — interface walk variables", () => {
117
+ test("downInterfaces contains only admin-up interfaces that are oper-down", () => {
118
+ const map: JSONObject = buildMap(
119
+ buildResponse({
120
+ snmp: {
121
+ interfaces: [
122
+ iface({ interfaceIndex: 1, name: "Gi0/1" }),
123
+ iface({
124
+ interfaceIndex: 2,
125
+ name: "Gi0/2",
126
+ alias: "uplink-to-core",
127
+ isOperationallyUp: false,
128
+ }),
129
+ /*
130
+ * Administratively disabled: intentionally down, must never be
131
+ * reported as a failure in templates.
132
+ */
133
+ iface({
134
+ interfaceIndex: 3,
135
+ name: "Gi0/3",
136
+ isAdministrativelyUp: false,
137
+ isOperationallyUp: false,
138
+ }),
139
+ ],
140
+ },
141
+ }),
142
+ );
143
+
144
+ expect(map["downInterfaces"]).toEqual([
145
+ {
146
+ name: "Gi0/2",
147
+ alias: "uplink-to-core",
148
+ interfaceIndex: 2,
149
+ },
150
+ ]);
151
+ });
152
+
153
+ test("a down interface with no alias renders alias as an empty string", () => {
154
+ const map: JSONObject = buildMap(
155
+ buildResponse({
156
+ snmp: {
157
+ interfaces: [
158
+ iface({
159
+ interfaceIndex: 4,
160
+ name: "Gi0/4",
161
+ isOperationallyUp: false,
162
+ }),
163
+ ],
164
+ },
165
+ }),
166
+ );
167
+
168
+ expect(map["downInterfaces"]).toEqual([
169
+ { name: "Gi0/4", alias: "", interfaceIndex: 4 },
170
+ ]);
171
+ });
172
+
173
+ test("counts follow the admin-up convention (admin-down is neither up nor down)", () => {
174
+ const map: JSONObject = buildMap(
175
+ buildResponse({
176
+ snmp: {
177
+ interfaces: [
178
+ iface({ interfaceIndex: 1 }), // admin-up, oper-up
179
+ iface({ interfaceIndex: 2, isOperationallyUp: false }), // admin-up, oper-down
180
+ iface({
181
+ interfaceIndex: 3,
182
+ isAdministrativelyUp: false,
183
+ isOperationallyUp: false,
184
+ }), // admin-down
185
+ iface({ interfaceIndex: 4 }), // admin-up, oper-up
186
+ ],
187
+ },
188
+ }),
189
+ );
190
+
191
+ expect(map["interfacesTotal"]).toBe(4);
192
+ expect(map["interfacesUp"]).toBe(2);
193
+ expect(map["interfacesDown"]).toBe(1);
194
+ // Sanity: the admin-down interface is excluded from both up and down.
195
+ expect(
196
+ (map["interfacesUp"] as number) + (map["interfacesDown"] as number),
197
+ ).toBeLessThan(map["interfacesTotal"] as number);
198
+ });
199
+
200
+ test("all interfaces healthy yields an empty downInterfaces list", () => {
201
+ const map: JSONObject = buildMap(
202
+ buildResponse({
203
+ snmp: {
204
+ interfaces: [
205
+ iface({ interfaceIndex: 1 }),
206
+ iface({ interfaceIndex: 2 }),
207
+ ],
208
+ },
209
+ }),
210
+ );
211
+
212
+ expect(map["interfacesDown"]).toBe(0);
213
+ expect(map["downInterfaces"]).toEqual([]);
214
+ });
215
+
216
+ test("a check without an interface walk exposes no interface variables", () => {
217
+ const map: JSONObject = buildMap(buildResponse());
218
+
219
+ expect(map).not.toHaveProperty("interfacesTotal");
220
+ expect(map).not.toHaveProperty("interfacesUp");
221
+ expect(map).not.toHaveProperty("interfacesDown");
222
+ expect(map).not.toHaveProperty("downInterfaces");
223
+ });
224
+
225
+ test("an empty interface walk exposes no interface variables either", () => {
226
+ const map: JSONObject = buildMap(
227
+ buildResponse({ snmp: { interfaces: [] } }),
228
+ );
229
+
230
+ expect(map).not.toHaveProperty("interfacesTotal");
231
+ expect(map).not.toHaveProperty("downInterfaces");
232
+ });
233
+
234
+ test("interfaceWalkFailure passes through when the walk failed", () => {
235
+ const map: JSONObject = buildMap(
236
+ buildResponse({
237
+ snmp: { interfaceWalkFailure: "ifTable walk timed out" },
238
+ }),
239
+ );
240
+
241
+ expect(map["interfaceWalkFailure"]).toBe("ifTable walk timed out");
242
+ });
243
+
244
+ test("interfaceWalkFailure is absent when the walk succeeded", () => {
245
+ const map: JSONObject = buildMap(buildResponse());
246
+
247
+ expect(map).not.toHaveProperty("interfaceWalkFailure");
248
+ });
249
+ });
250
+
251
+ describe("MonitorTemplateUtil.buildTemplateStorageMap — system identity variables", () => {
252
+ test("sysName/sysDescr/sysObjectId/sysLocation come from the system group", () => {
253
+ const map: JSONObject = buildMap(
254
+ buildResponse({
255
+ snmp: {
256
+ systemInfo: {
257
+ sysName: "core-sw-01",
258
+ sysDescr: "Cisco IOS Software",
259
+ sysObjectId: "1.3.6.1.4.1.9.1.1208",
260
+ sysLocation: "rack 12",
261
+ },
262
+ },
263
+ }),
264
+ );
265
+
266
+ expect(map["sysName"]).toBe("core-sw-01");
267
+ expect(map["sysDescr"]).toBe("Cisco IOS Software");
268
+ expect(map["sysObjectId"]).toBe("1.3.6.1.4.1.9.1.1208");
269
+ expect(map["sysLocation"]).toBe("rack 12");
270
+ });
271
+
272
+ /*
273
+ * Missing fields default to "" so a template renders blank instead of a
274
+ * raw {{sysLocation}} placeholder.
275
+ */
276
+ test("fields the device did not report default to empty strings", () => {
277
+ const map: JSONObject = buildMap(
278
+ buildResponse({
279
+ snmp: {
280
+ systemInfo: { sysName: "core-sw-01" },
281
+ },
282
+ }),
283
+ );
284
+
285
+ expect(map["sysName"]).toBe("core-sw-01");
286
+ expect(map["sysDescr"]).toBe("");
287
+ expect(map["sysObjectId"]).toBe("");
288
+ expect(map["sysLocation"]).toBe("");
289
+ });
290
+
291
+ test("no systemInfo at all leaves the identity variables off the map", () => {
292
+ const map: JSONObject = buildMap(buildResponse());
293
+
294
+ expect(map).not.toHaveProperty("sysName");
295
+ expect(map).not.toHaveProperty("sysDescr");
296
+ });
297
+
298
+ /*
299
+ * A user may already expose a custom OID named "sysName". When the walked
300
+ * system group has no sysName of its own, the empty-string defaulting must
301
+ * not clobber the user's value.
302
+ */
303
+ test("an unreported field never clobbers a custom OID of the same name", () => {
304
+ const map: JSONObject = buildMap(
305
+ buildResponse({
306
+ snmp: {
307
+ oidResponses: [
308
+ {
309
+ oid: "1.3.6.1.2.1.1.5.0",
310
+ name: "sysName",
311
+ value: "name-from-custom-oid",
312
+ type: SnmpDataType.OctetString,
313
+ },
314
+ ],
315
+ systemInfo: { sysLocation: "rack 12" },
316
+ },
317
+ }),
318
+ );
319
+
320
+ expect(map["sysName"]).toBe("name-from-custom-oid");
321
+ expect(map["sysLocation"]).toBe("rack 12");
322
+ });
323
+
324
+ test("a value the walk did collect takes precedence over the custom OID", () => {
325
+ const map: JSONObject = buildMap(
326
+ buildResponse({
327
+ snmp: {
328
+ oidResponses: [
329
+ {
330
+ oid: "1.3.6.1.2.1.1.5.0",
331
+ name: "sysName",
332
+ value: "name-from-custom-oid",
333
+ type: SnmpDataType.OctetString,
334
+ },
335
+ ],
336
+ systemInfo: { sysName: "name-from-system-group" },
337
+ },
338
+ }),
339
+ );
340
+
341
+ expect(map["sysName"]).toBe("name-from-system-group");
342
+ });
343
+ });
344
+
345
+ describe("MonitorTemplateUtil.buildTemplateStorageMap — trap payload", () => {
346
+ const trap: SnmpTrap = {
347
+ sourceIpAddress: "10.0.0.7",
348
+ trapOid: "1.3.6.1.6.3.1.1.5.3", // linkDown
349
+ snmpVersion: "2c",
350
+ receivedAt: new Date("2026-07-16T11:59:00.000Z"),
351
+ varbinds: [
352
+ { oid: "1.3.6.1.2.1.2.2.1.1.2", value: "2" },
353
+ { oid: "1.3.6.1.2.1.2.2.1.7.2", value: "1" },
354
+ ],
355
+ };
356
+
357
+ test("trap variables are present on a trap-triggered check", () => {
358
+ const map: JSONObject = buildMap(buildResponse({ trap: trap }));
359
+
360
+ expect(map["trapOid"]).toBe("1.3.6.1.6.3.1.1.5.3");
361
+ expect(map["trapSourceIp"]).toBe("10.0.0.7");
362
+ expect(map["trapVarbinds"]).toEqual([
363
+ { oid: "1.3.6.1.2.1.2.2.1.1.2", value: "2" },
364
+ { oid: "1.3.6.1.2.1.2.2.1.7.2", value: "1" },
365
+ ]);
366
+ });
367
+
368
+ test("trap variables are absent on a scheduled poll", () => {
369
+ const map: JSONObject = buildMap(buildResponse());
370
+
371
+ expect(map).not.toHaveProperty("trapOid");
372
+ expect(map).not.toHaveProperty("trapSourceIp");
373
+ expect(map).not.toHaveProperty("trapVarbinds");
374
+ });
375
+
376
+ test("a trap-triggered check keeps its poll variables alongside the trap payload", () => {
377
+ const map: JSONObject = buildMap(
378
+ buildResponse({
379
+ snmp: {
380
+ systemInfo: { sysName: "core-sw-01" },
381
+ },
382
+ trap: trap,
383
+ }),
384
+ );
385
+
386
+ expect(map["sysName"]).toBe("core-sw-01");
387
+ expect(map["trapOid"]).toBe("1.3.6.1.6.3.1.1.5.3");
388
+ });
389
+ });