@oneuptime/common 14.0.3 → 14.0.5

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 (617) hide show
  1. package/Models/DatabaseModels/Alert.ts +55 -0
  2. package/Models/DatabaseModels/DatabaseServer.ts +1650 -0
  3. package/Models/DatabaseModels/DatabaseServerEndpoint.ts +540 -0
  4. package/Models/DatabaseModels/DatabaseServerFeed.ts +625 -0
  5. package/Models/DatabaseModels/DatabaseServerLabelRule.ts +514 -0
  6. package/Models/DatabaseModels/DatabaseServerOwnerRule.ts +596 -0
  7. package/Models/DatabaseModels/DatabaseServerOwnerTeam.ts +491 -0
  8. package/Models/DatabaseModels/DatabaseServerOwnerUser.ts +490 -0
  9. package/Models/DatabaseModels/Incident.ts +55 -0
  10. package/Models/DatabaseModels/Index.ts +16 -0
  11. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +26 -0
  12. package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
  13. package/Models/DatabaseModels/TelemetryException.ts +2 -0
  14. package/Models/DatabaseModels/UserProjectSsoConsent.ts +146 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.ts +673 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.ts +51 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  18. package/Server/Middleware/MultipartFormData.ts +1 -1
  19. package/Server/Middleware/TelemetryIngest.ts +15 -8
  20. package/Server/Services/AlertReminderRuleService.ts +100 -24
  21. package/Server/Services/DatabaseServerEndpointService.ts +895 -0
  22. package/Server/Services/DatabaseServerFeedService.ts +128 -0
  23. package/Server/Services/DatabaseServerLabelRuleEngineService.ts +340 -0
  24. package/Server/Services/DatabaseServerLabelRuleService.ts +14 -0
  25. package/Server/Services/DatabaseServerOwnerRuleEngineService.ts +425 -0
  26. package/Server/Services/DatabaseServerOwnerRuleService.ts +14 -0
  27. package/Server/Services/DatabaseServerOwnerTeamService.ts +180 -0
  28. package/Server/Services/DatabaseServerOwnerUserService.ts +173 -0
  29. package/Server/Services/DatabaseServerService.ts +4546 -0
  30. package/Server/Services/DatabaseService.ts +14 -8
  31. package/Server/Services/DockerResourceService.ts +43 -2
  32. package/Server/Services/IncidentReminderRuleService.ts +103 -23
  33. package/Server/Services/Index.ts +16 -0
  34. package/Server/Services/InventoryItemService.ts +113 -5
  35. package/Server/Services/IoTDeviceService.ts +145 -37
  36. package/Server/Services/OpenTelemetryIngestService.ts +19 -0
  37. package/Server/Services/PodmanResourceService.ts +43 -2
  38. package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +107 -23
  39. package/Server/Services/ServiceService.ts +1 -1
  40. package/Server/Services/TelemetryUsageBillingService.ts +29 -2
  41. package/Server/Services/UserProjectSsoConsentService.ts +74 -0
  42. package/Server/Services/UserService.ts +14 -1
  43. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +18 -0
  44. package/Server/Types/Database/QueryHelper.ts +30 -1
  45. package/Server/Utils/AI/Toolbox/ResourceTools.ts +69 -1
  46. package/Server/Utils/Database/AffectedResourceRelations.ts +6 -0
  47. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +188 -6
  48. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  49. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +2262 -755
  50. package/Server/Utils/Monitor/MonitorIncident.ts +28 -1
  51. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +268 -6
  52. package/Server/Utils/Monitor/MonitorResource.ts +47 -11
  53. package/Server/Utils/Monitor/MonitorResourceContext.ts +1 -0
  54. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +239 -21
  55. package/Server/Utils/Monitor/PerSeriesResolutionRootCause.ts +43 -0
  56. package/Server/Utils/Monitor/SeriesResourceLabels.ts +291 -0
  57. package/Server/Utils/Monitor/SeriesResourceLinker.ts +111 -12
  58. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  59. package/Server/Utils/StartServer.ts +26 -6
  60. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  61. package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +688 -0
  62. package/Server/Utils/Telemetry/EntityRegistry.ts +5 -1
  63. package/Server/Utils/Telemetry/LogExceptionExtractor.ts +18 -1
  64. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +175 -12
  65. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +12 -0
  66. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +606 -36
  67. package/Server/Utils/Telemetry/Telemetry.ts +16 -0
  68. package/Server/Utils/Telemetry/TelemetryEntity.ts +22 -22
  69. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +16 -10
  70. package/Tests/App/Accounts/SignedInRedirect.test.tsx +241 -0
  71. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +221 -4
  72. package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +42 -0
  73. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +100 -0
  74. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +86 -0
  75. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +2 -0
  76. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +19 -0
  77. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +14 -0
  78. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +26 -1
  79. package/Tests/App/Dashboard/DashboardAppSsoError.test.tsx +501 -0
  80. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +64 -1
  81. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +178 -18
  82. package/Tests/App/Dashboard/DashboardMasterPageSsoRedirect.test.tsx +444 -0
  83. package/Tests/App/Dashboard/DashboardNavBarForeignHiddenRule.test.tsx +573 -0
  84. package/Tests/App/Dashboard/DatabaseChartAxes.test.tsx +431 -0
  85. package/Tests/App/Dashboard/DatabaseContainerDetailBadge.test.tsx +249 -0
  86. package/Tests/App/Dashboard/DatabaseDashboardE2EFixes.test.ts +681 -0
  87. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +1801 -0
  88. package/Tests/App/Dashboard/DatabaseFleetSummaryRefresh.test.tsx +280 -0
  89. package/Tests/App/Dashboard/DatabaseFormHelpers.test.tsx +321 -0
  90. package/Tests/App/Dashboard/DatabaseMetricMonitorLink.test.tsx +795 -0
  91. package/Tests/App/Dashboard/DatabaseOverviewHeader.test.tsx +580 -0
  92. package/Tests/App/Dashboard/DatabaseRecommendationsEngineMetrics.test.ts +270 -0
  93. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +1486 -0
  94. package/Tests/App/Dashboard/DatabaseServerEngineMetricsFilter.test.ts +223 -0
  95. package/Tests/App/Dashboard/DatabaseServerPresentation.test.ts +435 -0
  96. package/Tests/App/Dashboard/DatabaseServerSummary.test.ts +186 -0
  97. package/Tests/App/Dashboard/DatabaseServerTelemetryQueries.test.ts +1553 -0
  98. package/Tests/App/Dashboard/DatabaseTableTruncation.test.tsx +326 -0
  99. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +512 -0
  100. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +774 -0
  101. package/Tests/App/Dashboard/DatabaseViewLayout.test.tsx +233 -0
  102. package/Tests/App/Dashboard/DatabaseWorkloadBadge.test.tsx +972 -0
  103. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +5 -0
  104. package/Tests/App/Dashboard/DiscoveryReviewUnnamedHostHint.test.tsx +1061 -0
  105. package/Tests/App/Dashboard/EventOverlayScope.test.ts +147 -0
  106. package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +1 -0
  107. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +1 -0
  108. package/Tests/App/Dashboard/MetricsViewerDrillDown.test.tsx +310 -0
  109. package/Tests/App/Dashboard/MetricsViewerEntityScopedRows.test.tsx +495 -0
  110. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +132 -1
  111. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +5 -0
  112. package/Tests/App/Dashboard/ProductOrientation.test.tsx +4 -3
  113. package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +349 -0
  114. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +62 -0
  115. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  116. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +14 -0
  117. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +2 -0
  118. package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +1085 -0
  119. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +10 -0
  120. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +2 -1
  121. package/Tests/App/StatusPage/StatusPageHeaderForeignHiddenRule.test.tsx +284 -0
  122. package/Tests/ClassStrings.ts +178 -0
  123. package/Tests/Fixtures/MobilePasskeyUser.json +1 -2
  124. package/Tests/ForeignHiddenRuleGuard.ts +2152 -0
  125. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +2250 -0
  126. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +24 -5
  127. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  128. package/Tests/RenderedMarkup.ts +518 -0
  129. package/Tests/ResponsiveVisibility.test.ts +490 -4
  130. package/Tests/ResponsiveVisibility.ts +505 -52
  131. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  132. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +541 -0
  133. package/Tests/Server/Infrastructure/Postgres/AddUserProjectSsoConsentMigration.test.ts +234 -0
  134. package/Tests/Server/Services/ContainerSnapshotUpsertPostgres.test.ts +319 -0
  135. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +13 -0
  136. package/Tests/Server/Services/DatabaseServerEndpointService.test.ts +2033 -0
  137. package/Tests/Server/Services/DatabaseServerFeedAndOwnerServices.test.ts +529 -0
  138. package/Tests/Server/Services/DatabaseServerLifecycle.test.ts +3302 -0
  139. package/Tests/Server/Services/DatabaseServerRegistries.test.ts +603 -0
  140. package/Tests/Server/Services/DatabaseServerRuleEngines.test.ts +754 -0
  141. package/Tests/Server/Services/DatabaseServerService.test.ts +3558 -0
  142. package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +2045 -0
  143. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedPostgres.test.ts +362 -0
  144. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedReply.test.ts +210 -0
  145. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +18 -0
  146. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +2 -0
  147. package/Tests/Server/Services/IncomingCallPolicyEscalationRuleTarget.test.ts +225 -0
  148. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +280 -2
  149. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +8 -2
  150. package/Tests/Server/Services/IoTDeviceLatestMetricsPostgres.test.ts +689 -0
  151. package/Tests/Server/Services/IoTDeviceService.test.ts +379 -0
  152. package/Tests/Server/Services/LatestMetricsValuesShape.test.ts +360 -0
  153. package/Tests/Server/Services/LlmModelPriceService.test.ts +402 -0
  154. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
  155. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +61 -9
  156. package/Tests/Server/Services/ReminderRuleLookupPostgres.test.ts +2250 -0
  157. package/Tests/Server/Services/ReminderRuleRefreshOpenSubjectsPaging.test.ts +653 -0
  158. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +68 -20
  159. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  160. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +9 -0
  161. package/Tests/Server/Services/UserProjectSsoConsentPostgres.test.ts +153 -0
  162. package/Tests/Server/Services/UserProjectSsoConsentService.test.ts +192 -0
  163. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +71 -0
  164. package/Tests/Server/Services/UserSignupIdTakeoverPostgres.test.ts +238 -0
  165. package/Tests/Server/Services/WorkspaceNotificationSummaryHelpers.test.ts +592 -0
  166. package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +3 -0
  167. package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +1 -0
  168. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +11 -0
  169. package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +8 -0
  170. package/Tests/Server/Types/Database/QueryHelperBooleanForCriteriaBackedRule.test.ts +1094 -0
  171. package/Tests/Server/Utils/AI/ResourceTools.test.ts +134 -0
  172. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +41 -0
  173. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +279 -9
  174. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaDisplayContext.test.ts +933 -0
  175. package/Tests/Server/Utils/Monitor/DatabaseMaintenanceSuppression.test.ts +582 -0
  176. package/Tests/Server/Utils/Monitor/DatabaseServerMonitorLinking.test.ts +753 -0
  177. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +1 -0
  178. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +1 -0
  179. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +119 -0
  180. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +60 -25
  181. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorAffectedResourceEdgeCases.test.ts +1719 -0
  182. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesAffectedResources.test.ts +1447 -0
  183. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesRatioEmail.test.ts +352 -0
  184. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformMetricUnits.test.ts +717 -0
  185. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformRawScan.test.ts +2125 -0
  186. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformSeriesAffectedResources.test.ts +1288 -0
  187. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
  188. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +1 -0
  189. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +1 -0
  190. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +88 -0
  191. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +205 -0
  192. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +62 -0
  193. package/Tests/Server/Utils/Monitor/MonitorResourceDatabaseMaintenance.test.ts +803 -0
  194. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +133 -3
  195. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
  196. package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +472 -1
  197. package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
  198. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +236 -2
  199. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +70 -0
  200. package/Tests/Server/Utils/StartServerProtobufContentType.test.ts +54 -0
  201. package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +1895 -0
  202. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +7 -0
  203. package/Tests/Server/Utils/Telemetry/LogExceptionExtractorSeverityGate.test.ts +90 -0
  204. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +570 -0
  205. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +97 -2
  206. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +1337 -0
  207. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +295 -0
  208. package/Tests/Types/AI/AIResourceContext.test.ts +30 -0
  209. package/Tests/Types/DatabaseServer/DatabaseContainerClassifier.test.ts +3644 -0
  210. package/Tests/Types/DatabaseServer/DatabaseContainerCommand.test.ts +340 -0
  211. package/Tests/Types/DatabaseServer/DatabaseContainerCommandCorpus.ts +826 -0
  212. package/Tests/Types/DatabaseServer/DatabaseContainerCommandPostgres.test.ts +150 -0
  213. package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +2657 -0
  214. package/Tests/Types/DatabaseServer/DatabaseServerDiscoverySource.test.ts +64 -0
  215. package/Tests/Types/DatabaseServer/DatabaseServerEntityKeys.test.ts +952 -0
  216. package/Tests/Types/DatabaseServer/DatabaseServerMetricCatalog.test.ts +1161 -0
  217. package/Tests/Types/DatabaseServer/DatabaseSystem.test.ts +1514 -0
  218. package/Tests/Types/DatabaseServer/DatabaseTelemetryResolver.test.ts +1558 -0
  219. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +255 -6
  220. package/Tests/Types/Monitor/DatabaseAlertTemplates.test.ts +2254 -0
  221. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +298 -0
  222. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +271 -0
  223. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +253 -9
  224. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +13 -5
  225. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +4 -2
  226. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +111 -2
  227. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +61 -0
  228. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +114 -0
  229. package/Tests/Types/Monitor/Utils/KubernetesAgentEmittedMetrics.ts +181 -0
  230. package/Tests/Types/NetworkDevice/DiscoveredHostNamingStatus.test.ts +401 -0
  231. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +4 -1
  232. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +24 -2
  233. package/Tests/UI/Components/Card.test.tsx +93 -2
  234. package/Tests/UI/Components/FeedOptions.test.ts +6 -0
  235. package/Tests/UI/Components/FeedOptionsButton.test.tsx +8 -1
  236. package/Tests/UI/Components/ForeignHiddenRuleResilience.test.tsx +1147 -0
  237. package/Tests/UI/Components/HeaderRightRail.test.tsx +41 -1
  238. package/Tests/UI/Components/LogsEntityNames.test.ts +16 -1
  239. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +7 -3
  240. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +2 -1
  241. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  242. package/Tests/UI/Components/SrOnlyForeignRule.test.tsx +994 -0
  243. package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +34 -1
  244. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +4 -1
  245. package/Tests/UI/ForeignHiddenRuleGuard.test.ts +1951 -0
  246. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +19 -1
  247. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +19 -1
  248. package/Tests/UI/TailwindPlayCdnForeignHiddenRule.test.ts +1005 -0
  249. package/Tests/UI/ThemeGroupHoverReveal.test.ts +847 -0
  250. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +70 -0
  251. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +21 -0
  252. package/Tests/UI/Utils/ModelAPISsoRedirect.test.ts +127 -0
  253. package/Tests/UI/Utils/Navigation.test.ts +102 -0
  254. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +23 -0
  255. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  256. package/Tests/Utils/MetricUnitUtil.test.ts +227 -2
  257. package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +288 -2
  258. package/Tests/Utils/Monitor/PlatformResourceIdentityAndUnits.test.ts +1559 -0
  259. package/Tests/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.test.ts +2546 -0
  260. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +315 -0
  261. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +336 -1
  262. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +244 -0
  263. package/Tests/Utils/ValueFormatter.test.ts +50 -0
  264. package/Tests/tsconfig.json +16 -0
  265. package/Types/AI/AIResourceContext.ts +7 -0
  266. package/Types/Dashboard/DashboardTemplates.ts +2 -1
  267. package/Types/DatabaseServer/DatabaseConnectionSpan.ts +77 -0
  268. package/Types/DatabaseServer/DatabaseContainerClassifier.ts +2068 -0
  269. package/Types/DatabaseServer/DatabaseContainerCommand.ts +801 -0
  270. package/Types/DatabaseServer/DatabaseEndpoint.ts +1943 -0
  271. package/Types/DatabaseServer/DatabaseServerDiscoverySource.ts +68 -0
  272. package/Types/DatabaseServer/DatabaseServerMetricCatalog.ts +966 -0
  273. package/Types/DatabaseServer/DatabaseSystem.ts +2124 -0
  274. package/Types/DatabaseServer/DatabaseTelemetryResolver.ts +555 -0
  275. package/Types/Email/EmailTemplateType.ts +1 -0
  276. package/Types/Monitor/CephAlertTemplates.ts +18 -0
  277. package/Types/Monitor/DatabaseAlertTemplates.ts +2020 -0
  278. package/Types/Monitor/KubernetesAlertTemplates.ts +64 -24
  279. package/Types/Monitor/KubernetesMetricCatalog.ts +118 -19
  280. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +14 -0
  281. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +93 -10
  282. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +109 -8
  283. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +36 -7
  284. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +43 -2
  285. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +41 -6
  286. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +26 -0
  287. package/Types/NetworkDevice/DiscoveredHostNamingStatus.ts +147 -0
  288. package/Types/Permission.ts +267 -0
  289. package/Types/Probe/ProbeApiIngestResponse.ts +8 -0
  290. package/Types/Rules/RuleCriteriaFieldRegistry.ts +10 -0
  291. package/Types/Rules/RuleRun.ts +12 -0
  292. package/Types/Telemetry/EntityType.ts +23 -0
  293. package/Types/Telemetry/ResourceFacetCatalog.ts +14 -0
  294. package/Types/Telemetry/ServiceType.ts +8 -0
  295. package/UI/Components/Banner/Banner.tsx +1 -1
  296. package/UI/Components/Card/Card.tsx +1 -1
  297. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +2 -2
  298. package/UI/Components/Charts/Line/LineChart.tsx +7 -0
  299. package/UI/Components/CommandPalette/CommandPalette.tsx +1 -1
  300. package/UI/Components/Date/StartAndEndDate.tsx +5 -5
  301. package/UI/Components/Diagram/HorizontalStepChain.tsx +1 -1
  302. package/UI/Components/Feed/FeedOptionsButton.tsx +1 -1
  303. package/UI/Components/Forms/BasicForm.tsx +1 -1
  304. package/UI/Components/Header/Header.tsx +1 -1
  305. package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -1
  306. package/UI/Components/HeaderAlert/HeaderAlert.tsx +1 -1
  307. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +1 -1
  308. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +1 -1
  309. package/UI/Components/Modal/ModalFooter.tsx +1 -1
  310. package/UI/Components/ModelDetail/CardModelDetail.tsx +2 -2
  311. package/UI/Components/ModelTable/BaseModelTable.tsx +4 -4
  312. package/UI/Components/Navbar/NavBar.tsx +9 -2
  313. package/UI/Components/Navbar/NavBarMenuModal.tsx +2 -2
  314. package/UI/Components/Page/Page.tsx +1 -1
  315. package/UI/Components/Pagination/Pagination.tsx +3 -3
  316. package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +1 -1
  317. package/UI/Components/SideMenu/SideMenu.tsx +4 -1
  318. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +4 -2
  319. package/UI/Components/StatusPage/ResourceList.tsx +6 -6
  320. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +1 -1
  321. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +1 -1
  322. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +1 -1
  323. package/UI/Components/Workflow/ComponentsModal.tsx +2 -2
  324. package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
  325. package/UI/Styles/Theme.css +8 -1
  326. package/UI/Utils/Navigation.ts +89 -42
  327. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +7 -0
  328. package/UI/Utils/TelemetryService.ts +4 -3
  329. package/Utils/LabelRuleImportExport.ts +2 -0
  330. package/Utils/MetricUnitUtil.ts +103 -11
  331. package/Utils/Monitor/MetricValueFormatter.ts +66 -13
  332. package/Utils/Monitor/PlatformMetricUnitUtil.ts +215 -0
  333. package/Utils/Monitor/PlatformResourceIdentity.ts +514 -0
  334. package/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.ts +425 -0
  335. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +32 -0
  336. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +73 -0
  337. package/Utils/Telemetry/DatabaseServerEntityKeys.ts +275 -0
  338. package/Utils/Telemetry/EntityKey.ts +176 -0
  339. package/Utils/ValueFormatter.ts +16 -0
  340. package/build/dist/Models/DatabaseModels/Alert.js +54 -0
  341. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  342. package/build/dist/Models/DatabaseModels/DatabaseServer.js +1683 -0
  343. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -0
  344. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +559 -0
  345. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -0
  346. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js +648 -0
  347. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js.map +1 -0
  348. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js +522 -0
  349. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js.map +1 -0
  350. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js +603 -0
  351. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js.map +1 -0
  352. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js +506 -0
  353. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js.map +1 -0
  354. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js +505 -0
  355. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js.map +1 -0
  356. package/build/dist/Models/DatabaseModels/Incident.js +54 -0
  357. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  358. package/build/dist/Models/DatabaseModels/Index.js +16 -0
  359. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  360. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
  362. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/TelemetryException.js +2 -0
  364. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js +162 -0
  366. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js.map +1 -0
  367. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js +240 -0
  368. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js.map +1 -0
  369. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js +26 -0
  370. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js.map +1 -0
  371. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  372. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  373. package/build/dist/Server/Middleware/MultipartFormData.js +1 -1
  374. package/build/dist/Server/Middleware/TelemetryIngest.js +15 -8
  375. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  376. package/build/dist/Server/Services/AlertReminderRuleService.js +72 -23
  377. package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
  378. package/build/dist/Server/Services/DatabaseServerEndpointService.js +694 -0
  379. package/build/dist/Server/Services/DatabaseServerEndpointService.js.map +1 -0
  380. package/build/dist/Server/Services/DatabaseServerFeedService.js +110 -0
  381. package/build/dist/Server/Services/DatabaseServerFeedService.js.map +1 -0
  382. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js +272 -0
  383. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js.map +1 -0
  384. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js +13 -0
  385. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js.map +1 -0
  386. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js +340 -0
  387. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js.map +1 -0
  388. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js +13 -0
  389. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js.map +1 -0
  390. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js +160 -0
  391. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js.map +1 -0
  392. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js +153 -0
  393. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js.map +1 -0
  394. package/build/dist/Server/Services/DatabaseServerService.js +3272 -0
  395. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -0
  396. package/build/dist/Server/Services/DatabaseService.js +8 -4
  397. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  398. package/build/dist/Server/Services/DockerResourceService.js +30 -3
  399. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  400. package/build/dist/Server/Services/IncidentReminderRuleService.js +73 -23
  401. package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
  402. package/build/dist/Server/Services/Index.js +16 -0
  403. package/build/dist/Server/Services/Index.js.map +1 -1
  404. package/build/dist/Server/Services/InventoryItemService.js +88 -5
  405. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  406. package/build/dist/Server/Services/IoTDeviceService.js +111 -24
  407. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  408. package/build/dist/Server/Services/OpenTelemetryIngestService.js +24 -9
  409. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  410. package/build/dist/Server/Services/PodmanResourceService.js +30 -3
  411. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  412. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +75 -23
  413. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
  414. package/build/dist/Server/Services/ServiceService.js +1 -1
  415. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  416. package/build/dist/Server/Services/TelemetryUsageBillingService.js +23 -2
  417. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  418. package/build/dist/Server/Services/UserProjectSsoConsentService.js +79 -0
  419. package/build/dist/Server/Services/UserProjectSsoConsentService.js.map +1 -0
  420. package/build/dist/Server/Services/UserService.js +13 -1
  421. package/build/dist/Server/Services/UserService.js.map +1 -1
  422. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +18 -0
  423. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  424. package/build/dist/Server/Types/Database/QueryHelper.js +26 -1
  425. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  426. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +46 -0
  427. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  428. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +6 -0
  429. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -1
  430. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +134 -13
  431. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  432. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -6
  433. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  434. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1489 -524
  435. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  436. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  437. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  438. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +196 -6
  439. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  440. package/build/dist/Server/Utils/Monitor/MonitorResource.js +36 -9
  441. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  442. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +1 -0
  443. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
  444. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +175 -17
  445. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  446. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js +29 -0
  447. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js.map +1 -0
  448. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +211 -0
  449. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  450. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +82 -10
  451. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  452. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  453. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  454. package/build/dist/Server/Utils/StartServer.js +20 -4
  455. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  456. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  457. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  458. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +442 -0
  459. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -0
  460. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -1
  461. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  462. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +15 -1
  463. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
  464. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +121 -5
  465. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  466. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +12 -0
  467. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  468. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +438 -36
  469. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
  470. package/build/dist/Server/Utils/Telemetry/Telemetry.js +12 -0
  471. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  472. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -18
  473. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  474. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +16 -10
  475. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -1
  476. package/build/dist/Types/AI/AIResourceContext.js +7 -0
  477. package/build/dist/Types/AI/AIResourceContext.js.map +1 -1
  478. package/build/dist/Types/Dashboard/DashboardTemplates.js +2 -1
  479. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  480. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js +71 -0
  481. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js.map +1 -0
  482. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js +1462 -0
  483. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js.map +1 -0
  484. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js +691 -0
  485. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js.map +1 -0
  486. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +1407 -0
  487. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -0
  488. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js +60 -0
  489. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js.map +1 -0
  490. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js +804 -0
  491. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js.map +1 -0
  492. package/build/dist/Types/DatabaseServer/DatabaseSystem.js +1860 -0
  493. package/build/dist/Types/DatabaseServer/DatabaseSystem.js.map +1 -0
  494. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js +406 -0
  495. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js.map +1 -0
  496. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  497. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  498. package/build/dist/Types/Monitor/CephAlertTemplates.js +18 -0
  499. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  500. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js +1518 -0
  501. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js.map +1 -0
  502. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +57 -24
  503. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  504. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +104 -18
  505. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  506. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +80 -3
  507. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  508. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +10 -3
  509. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  510. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +29 -0
  511. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  512. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +21 -6
  513. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -1
  514. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +25 -0
  515. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  516. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js +136 -0
  517. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js.map +1 -0
  518. package/build/dist/Types/Permission.js +234 -0
  519. package/build/dist/Types/Permission.js.map +1 -1
  520. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +10 -0
  521. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  522. package/build/dist/Types/Rules/RuleRun.js +4 -0
  523. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  524. package/build/dist/Types/Telemetry/EntityType.js +23 -0
  525. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  526. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +14 -0
  527. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -1
  528. package/build/dist/Types/Telemetry/ServiceType.js +8 -0
  529. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  530. package/build/dist/UI/Components/Banner/Banner.js +1 -1
  531. package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
  532. package/build/dist/UI/Components/Card/Card.js +1 -1
  533. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  534. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
  535. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  536. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  537. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  538. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +1 -1
  539. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  540. package/build/dist/UI/Components/Date/StartAndEndDate.js +5 -5
  541. package/build/dist/UI/Components/Date/StartAndEndDate.js.map +1 -1
  542. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +1 -1
  543. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -1
  544. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +1 -1
  545. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -1
  546. package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
  547. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  548. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
  549. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  550. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +1 -1
  551. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  552. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +1 -1
  553. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  554. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  555. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  556. package/build/dist/UI/Components/Modal/ModalFooter.js +1 -1
  557. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  558. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
  559. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  560. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +4 -4
  561. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  562. package/build/dist/UI/Components/Navbar/NavBar.js +9 -2
  563. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  564. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
  565. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  566. package/build/dist/UI/Components/Page/Page.js +1 -1
  567. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  568. package/build/dist/UI/Components/Pagination/Pagination.js +3 -3
  569. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  570. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +1 -1
  571. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
  572. package/build/dist/UI/Components/SideMenu/SideMenu.js +4 -1
  573. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  574. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +3 -1
  575. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -1
  576. package/build/dist/UI/Components/StatusPage/ResourceList.js +6 -6
  577. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
  578. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  579. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  580. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +1 -1
  581. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  582. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +1 -1
  583. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
  584. package/build/dist/UI/Components/Workflow/ComponentsModal.js +2 -2
  585. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  586. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
  587. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  588. package/build/dist/UI/Utils/Navigation.js +66 -33
  589. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  590. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +7 -0
  591. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
  592. package/build/dist/UI/Utils/TelemetryService.js +3 -2
  593. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  594. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  595. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  596. package/build/dist/Utils/MetricUnitUtil.js +77 -13
  597. package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
  598. package/build/dist/Utils/Monitor/MetricValueFormatter.js +58 -13
  599. package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -1
  600. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js +161 -0
  601. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js.map +1 -0
  602. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js +323 -0
  603. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js.map +1 -0
  604. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js +270 -0
  605. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js.map +1 -0
  606. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +23 -0
  607. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  608. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +61 -0
  609. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -1
  610. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js +178 -0
  611. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js.map +1 -0
  612. package/build/dist/Utils/Telemetry/EntityKey.js +133 -0
  613. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  614. package/build/dist/Utils/ValueFormatter.js +15 -0
  615. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  616. package/package.json +1 -1
  617. package/tsconfig.tests.json +7 -5
@@ -0,0 +1,952 @@
1
+ import {
2
+ DatabaseServerMemberKeys,
3
+ DEFAULT_MEMBER_KEY_MAX_AGE_DAYS,
4
+ DEFAULT_MEMBER_KEY_MAX_COUNT,
5
+ getDatabaseServerSignalEntityKeys,
6
+ MAX_DATABASE_SERVER_ENTITY_KEYS,
7
+ mergeDatabaseServerMemberKeys,
8
+ } from "../../../Utils/Telemetry/DatabaseServerEntityKeys";
9
+ import {
10
+ DATABASE_SERVER_ROW_IDENTITY_ATTRIBUTE,
11
+ keyForContainer,
12
+ keyForDatabaseEndpoint,
13
+ keyForDatabaseServerRow,
14
+ keyForKubernetesDeployment,
15
+ keyForKubernetesPod,
16
+ } from "../../../Utils/Telemetry/EntityKey";
17
+ import {
18
+ buildKubernetesDatabaseAliases,
19
+ canonicalizeDatabaseEndpoint,
20
+ DatabaseCallerContext,
21
+ DatabaseEndpoint,
22
+ } from "../../../Types/DatabaseServer/DatabaseEndpoint";
23
+ import { resolveDatabaseCallTarget } from "../../../Types/DatabaseServer/DatabaseTelemetryResolver";
24
+ import EntityType from "../../../Types/Telemetry/EntityType";
25
+ import { describe, expect, test } from "@jest/globals";
26
+ import { createHash } from "crypto";
27
+
28
+ const PROJECT: string = "5f2b7c1e-8d3a-4b6f-9c0d-1e2f3a4b5c6d";
29
+ const NOW: Date = new Date("2026-09-23T12:00:00.000Z");
30
+ const DAY: number = 24 * 60 * 60 * 1000;
31
+
32
+ /*
33
+ * Independent reimplementation of the documented preimage, so these tests
34
+ * break if the key construction ever silently changes (a read-side key that
35
+ * does not byte-match the ingest stamp finds nothing).
36
+ */
37
+ function expectedKey(
38
+ projectId: string,
39
+ entityType: EntityType,
40
+ identifyingAttributes: Record<string, string>,
41
+ ): string {
42
+ const escape: (token: string) => string = (token: string): string => {
43
+ return token.replace(/([\\|=])/g, "\\$1");
44
+ };
45
+ const parts: Array<string> = Object.keys(identifyingAttributes)
46
+ .sort()
47
+ .map((key: string): string => {
48
+ return `${escape(key)}=${escape(
49
+ identifyingAttributes[key]!.trim().toLowerCase(),
50
+ )}`;
51
+ });
52
+ return createHash("sha256")
53
+ .update(`${projectId}|${entityType}|${parts.join("|")}`)
54
+ .digest("hex")
55
+ .slice(0, 16);
56
+ }
57
+
58
+ function hexKey(seed: number): string {
59
+ return seed.toString(16).padStart(16, "0");
60
+ }
61
+
62
+ function isoDaysAgo(days: number): string {
63
+ return new Date(NOW.getTime() - days * DAY).toISOString();
64
+ }
65
+
66
+ describe("keyForDatabaseEndpoint", () => {
67
+ test("hashes server.address + server.port under the database.server type", () => {
68
+ expect(
69
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: 5432 }),
70
+ ).toBe(
71
+ expectedKey(PROJECT, EntityType.DatabaseServer, {
72
+ "server.address": "db.prod",
73
+ "server.port": "5432",
74
+ }),
75
+ );
76
+ expect(EntityType.DatabaseServer).toBe("database.server");
77
+ });
78
+
79
+ test("a cluster qualifier becomes k8s.cluster.name in the identity", () => {
80
+ expect(
81
+ keyForDatabaseEndpoint(PROJECT, {
82
+ host: "pg.shop.svc.cluster.local",
83
+ port: 5432,
84
+ kubernetesClusterName: "prod",
85
+ }),
86
+ ).toBe(
87
+ expectedKey(PROJECT, EntityType.DatabaseServer, {
88
+ "server.address": "pg.shop.svc.cluster.local",
89
+ "server.port": "5432",
90
+ "k8s.cluster.name": "prod",
91
+ }),
92
+ );
93
+ });
94
+
95
+ test("a null port leaves server.port out (it is not hashed as '')", () => {
96
+ expect(
97
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: null }),
98
+ ).toBe(
99
+ expectedKey(PROJECT, EntityType.DatabaseServer, {
100
+ "server.address": "db.prod",
101
+ }),
102
+ );
103
+ });
104
+
105
+ test("a blank cluster is no cluster", () => {
106
+ const unqualified: string = keyForDatabaseEndpoint(PROJECT, {
107
+ host: "10.0.0.5",
108
+ port: 5432,
109
+ });
110
+ for (const blank of ["", " ", null, undefined]) {
111
+ expect(
112
+ keyForDatabaseEndpoint(PROJECT, {
113
+ host: "10.0.0.5",
114
+ port: 5432,
115
+ kubernetesClusterName: blank,
116
+ }),
117
+ ).toBe(unqualified);
118
+ }
119
+ });
120
+
121
+ test("cluster-qualified ≠ unqualified; clusters ≠ each other", () => {
122
+ const unqualified: string = keyForDatabaseEndpoint(PROJECT, {
123
+ host: "10.0.0.5",
124
+ port: 5432,
125
+ });
126
+ const prod: string = keyForDatabaseEndpoint(PROJECT, {
127
+ host: "10.0.0.5",
128
+ port: 5432,
129
+ kubernetesClusterName: "prod",
130
+ });
131
+ const staging: string = keyForDatabaseEndpoint(PROJECT, {
132
+ host: "10.0.0.5",
133
+ port: 5432,
134
+ kubernetesClusterName: "staging",
135
+ });
136
+ expect(new Set([unqualified, prod, staging]).size).toBe(3);
137
+ });
138
+
139
+ test("different ports and projects are different keys", () => {
140
+ const base: string = keyForDatabaseEndpoint(PROJECT, {
141
+ host: "db.prod",
142
+ port: 5432,
143
+ });
144
+ expect(
145
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: 5433 }),
146
+ ).not.toBe(base);
147
+ expect(
148
+ keyForDatabaseEndpoint("another-project", {
149
+ host: "db.prod",
150
+ port: 5432,
151
+ }),
152
+ ).not.toBe(base);
153
+ });
154
+
155
+ test("casing and padding never fork the key", () => {
156
+ expect(
157
+ keyForDatabaseEndpoint(PROJECT, {
158
+ host: " DB.Prod ",
159
+ port: 5432,
160
+ kubernetesClusterName: " PROD ",
161
+ }),
162
+ ).toBe(
163
+ keyForDatabaseEndpoint(PROJECT, {
164
+ host: "db.prod",
165
+ port: 5432,
166
+ kubernetesClusterName: "prod",
167
+ }),
168
+ );
169
+ });
170
+
171
+ test("is a 16-char lowercase hex key", () => {
172
+ expect(
173
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: 5432 }),
174
+ ).toMatch(/^[0-9a-f]{16}$/);
175
+ });
176
+ });
177
+
178
+ describe("keys are engine-agnostic", () => {
179
+ const VM: DatabaseCallerContext = { hostName: "app-7", isEphemeral: false };
180
+
181
+ test("the same endpoint under postgresql and cockroachdb is ONE key", () => {
182
+ const asPostgres: DatabaseEndpoint | null = canonicalizeDatabaseEndpoint({
183
+ system: "postgresql",
184
+ address: "crdb.prod",
185
+ port: 26257,
186
+ caller: VM,
187
+ purpose: "client-call",
188
+ });
189
+ const asCockroach: DatabaseEndpoint | null = canonicalizeDatabaseEndpoint({
190
+ system: "cockroachdb",
191
+ address: "crdb.prod",
192
+ caller: VM,
193
+ purpose: "collector",
194
+ });
195
+ expect(asPostgres).toEqual(asCockroach);
196
+ expect(keyForDatabaseEndpoint(PROJECT, asPostgres!)).toBe(
197
+ keyForDatabaseEndpoint(PROJECT, asCockroach!),
198
+ );
199
+ });
200
+
201
+ test("OpenSearch reached by an Elasticsearch client joins its row", () => {
202
+ const span: ReturnType<typeof resolveDatabaseCallTarget> =
203
+ resolveDatabaseCallTarget({
204
+ getAttribute: (key: string): unknown => {
205
+ return (
206
+ {
207
+ "db.system.name": "elasticsearch",
208
+ "server.address": "search.prod",
209
+ } as Record<string, unknown>
210
+ )[key];
211
+ },
212
+ caller: VM,
213
+ });
214
+ expect(
215
+ getDatabaseServerSignalEntityKeys({
216
+ projectId: PROJECT,
217
+ endpoints: ["search.prod:9200"],
218
+ dbSystem: "opensearch",
219
+ memberEntityKeys: null,
220
+ }),
221
+ ).toContain(keyForDatabaseEndpoint(PROJECT, span!.endpoint));
222
+ });
223
+ });
224
+
225
+ describe("member key helpers (shape)", () => {
226
+ test("keyForKubernetesPod / keyForKubernetesDeployment / keyForContainer hash their semconv identity", () => {
227
+ expect(
228
+ keyForKubernetesPod(PROJECT, {
229
+ clusterName: "prod",
230
+ namespace: "shop",
231
+ podName: "pg-0",
232
+ }),
233
+ ).toBe(
234
+ expectedKey(PROJECT, EntityType.KubernetesPod, {
235
+ "k8s.cluster.name": "prod",
236
+ "k8s.namespace.name": "shop",
237
+ "k8s.pod.name": "pg-0",
238
+ }),
239
+ );
240
+ expect(
241
+ keyForKubernetesDeployment(PROJECT, {
242
+ clusterName: "prod",
243
+ namespace: "shop",
244
+ deploymentName: "cache",
245
+ }),
246
+ ).toBe(
247
+ expectedKey(PROJECT, EntityType.KubernetesDeployment, {
248
+ "k8s.cluster.name": "prod",
249
+ "k8s.namespace.name": "shop",
250
+ "k8s.deployment.name": "cache",
251
+ }),
252
+ );
253
+ expect(keyForContainer(PROJECT, "ABC123def456")).toBe(
254
+ expectedKey(PROJECT, EntityType.Container, {
255
+ "container.id": "abc123def456",
256
+ }),
257
+ );
258
+ });
259
+
260
+ test("blank cluster / namespace are left out, not hashed as ''", () => {
261
+ expect(
262
+ keyForKubernetesPod(PROJECT, {
263
+ clusterName: " ",
264
+ namespace: null,
265
+ podName: "pg-0",
266
+ }),
267
+ ).toBe(
268
+ expectedKey(PROJECT, EntityType.KubernetesPod, {
269
+ "k8s.pod.name": "pg-0",
270
+ }),
271
+ );
272
+ expect(
273
+ keyForKubernetesDeployment(PROJECT, { deploymentName: "cache" }),
274
+ ).toBe(
275
+ expectedKey(PROJECT, EntityType.KubernetesDeployment, {
276
+ "k8s.deployment.name": "cache",
277
+ }),
278
+ );
279
+ });
280
+
281
+ test("a pod and a deployment of the same name never collide", () => {
282
+ expect(
283
+ keyForKubernetesPod(PROJECT, { namespace: "a", podName: "x" }),
284
+ ).not.toBe(
285
+ keyForKubernetesDeployment(PROJECT, {
286
+ namespace: "a",
287
+ deploymentName: "x",
288
+ }),
289
+ );
290
+ });
291
+ });
292
+
293
+ describe("mergeDatabaseServerMemberKeys", () => {
294
+ const A: string = hexKey(0xa);
295
+ const B: string = hexKey(0xb);
296
+ const C: string = hexKey(0xc);
297
+
298
+ test("defaults are 30 days / 200 keys", () => {
299
+ expect(DEFAULT_MEMBER_KEY_MAX_AGE_DAYS).toBe(30);
300
+ expect(DEFAULT_MEMBER_KEY_MAX_COUNT).toBe(200);
301
+ });
302
+
303
+ test("seen keys are stamped now", () => {
304
+ expect(mergeDatabaseServerMemberKeys(null, [A, B], NOW)).toEqual({
305
+ [A]: NOW.toISOString(),
306
+ [B]: NOW.toISOString(),
307
+ });
308
+ });
309
+
310
+ test("after a rollout both the old and the new pod key are in scope", () => {
311
+ const beforeRollout: DatabaseServerMemberKeys =
312
+ mergeDatabaseServerMemberKeys({}, [A], new Date(NOW.getTime() - 2 * DAY));
313
+ const afterRollout: DatabaseServerMemberKeys =
314
+ mergeDatabaseServerMemberKeys(beforeRollout, [B], NOW);
315
+ expect(Object.keys(afterRollout).sort()).toEqual([A, B].sort());
316
+ expect(afterRollout[A]).toBe(isoDaysAgo(2));
317
+ expect(afterRollout[B]).toBe(NOW.toISOString());
318
+ });
319
+
320
+ test("a re-seen key moves to now", () => {
321
+ expect(
322
+ mergeDatabaseServerMemberKeys({ [A]: isoDaysAgo(5) }, [A], NOW),
323
+ ).toEqual({ [A]: NOW.toISOString() });
324
+ });
325
+
326
+ test("keys not seen for longer than the retention are dropped", () => {
327
+ expect(
328
+ mergeDatabaseServerMemberKeys(
329
+ { [A]: isoDaysAgo(29), [B]: isoDaysAgo(31), [C]: isoDaysAgo(30) },
330
+ [],
331
+ NOW,
332
+ ),
333
+ ).toEqual({ [A]: isoDaysAgo(29), [C]: isoDaysAgo(30) });
334
+ });
335
+
336
+ test("a custom retention is honoured", () => {
337
+ expect(
338
+ mergeDatabaseServerMemberKeys(
339
+ { [A]: isoDaysAgo(2), [B]: isoDaysAgo(8) },
340
+ [],
341
+ NOW,
342
+ { maxAgeDays: 7 },
343
+ ),
344
+ ).toEqual({ [A]: isoDaysAgo(2) });
345
+ });
346
+
347
+ test("the cap keeps the most recent, and keys seen now always survive", () => {
348
+ const existing: Record<string, string> = {};
349
+ for (let index: number = 1; index <= 10; index++) {
350
+ existing[hexKey(0x100 + index)] = isoDaysAgo(index);
351
+ }
352
+ const merged: DatabaseServerMemberKeys = mergeDatabaseServerMemberKeys(
353
+ existing,
354
+ [A],
355
+ NOW,
356
+ { max: 4 },
357
+ );
358
+ expect(Object.keys(merged)).toEqual([
359
+ A,
360
+ hexKey(0x101),
361
+ hexKey(0x102),
362
+ hexKey(0x103),
363
+ ]);
364
+ });
365
+
366
+ test("the default cap is 200", () => {
367
+ const existing: Record<string, string> = {};
368
+ for (let index: number = 0; index < 250; index++) {
369
+ existing[hexKey(0x1000 + index)] = new Date(
370
+ NOW.getTime() - index * 1000,
371
+ ).toISOString();
372
+ }
373
+ expect(
374
+ Object.keys(mergeDatabaseServerMemberKeys(existing, [], NOW)).length,
375
+ ).toBe(200);
376
+ });
377
+
378
+ test("ties in recency are broken by key, so the result is stable", () => {
379
+ const seen: Array<string> = [C, A, B];
380
+ const merged: DatabaseServerMemberKeys = mergeDatabaseServerMemberKeys(
381
+ {},
382
+ seen,
383
+ NOW,
384
+ { max: 2 },
385
+ );
386
+ expect(Object.keys(merged)).toEqual([A, B]);
387
+ expect(
388
+ mergeDatabaseServerMemberKeys({}, [...seen].reverse(), NOW, { max: 2 }),
389
+ ).toEqual(merged);
390
+ });
391
+
392
+ test("the result is ordered most recent first", () => {
393
+ const merged: DatabaseServerMemberKeys = mergeDatabaseServerMemberKeys(
394
+ { [A]: isoDaysAgo(3), [B]: isoDaysAgo(1) },
395
+ [C],
396
+ NOW,
397
+ );
398
+ expect(Object.keys(merged)).toEqual([C, B, A]);
399
+ });
400
+
401
+ test("malformed keys and timestamps are dropped, not thrown on", () => {
402
+ expect(
403
+ mergeDatabaseServerMemberKeys(
404
+ {
405
+ [A]: "not a date",
406
+ "not-a-key": NOW.toISOString(),
407
+ [B.toUpperCase()]: isoDaysAgo(1),
408
+ [C]: 12345,
409
+ },
410
+ [
411
+ "short",
412
+ "zzzzzzzzzzzzzzzz",
413
+ 42 as unknown as string,
414
+ ` ${A.toUpperCase()} `,
415
+ ],
416
+ NOW,
417
+ ),
418
+ ).toEqual({ [A]: NOW.toISOString(), [B]: isoDaysAgo(1) });
419
+ });
420
+
421
+ test("the { key, lastSeenAt } array form is accepted too", () => {
422
+ expect(
423
+ mergeDatabaseServerMemberKeys(
424
+ [
425
+ { key: A, lastSeenAt: isoDaysAgo(1) },
426
+ { key: A, lastSeenAt: isoDaysAgo(3) },
427
+ { key: B, lastSeenAt: isoDaysAgo(2) },
428
+ null,
429
+ "bare-string",
430
+ ],
431
+ [],
432
+ NOW,
433
+ ),
434
+ ).toEqual({ [A]: isoDaysAgo(1), [B]: isoDaysAgo(2) });
435
+ });
436
+
437
+ test("a timestamp in the future is clamped to now", () => {
438
+ expect(
439
+ mergeDatabaseServerMemberKeys(
440
+ { [A]: new Date(NOW.getTime() + 365 * DAY).toISOString() },
441
+ [],
442
+ NOW,
443
+ ),
444
+ ).toEqual({ [A]: NOW.toISOString() });
445
+ });
446
+
447
+ test("garbage existing values are an empty set", () => {
448
+ for (const existing of [null, undefined, "x", 42, true]) {
449
+ expect(mergeDatabaseServerMemberKeys(existing, [A], NOW)).toEqual({
450
+ [A]: NOW.toISOString(),
451
+ });
452
+ }
453
+ });
454
+
455
+ test("invalid options fall back to the defaults", () => {
456
+ expect(
457
+ mergeDatabaseServerMemberKeys({ [A]: isoDaysAgo(20) }, [], NOW, {
458
+ maxAgeDays: 0,
459
+ max: 0,
460
+ }),
461
+ ).toEqual({ [A]: isoDaysAgo(20) });
462
+ expect(
463
+ mergeDatabaseServerMemberKeys({ [A]: isoDaysAgo(20) }, [], NOW, {
464
+ maxAgeDays: Number.NaN,
465
+ max: -3,
466
+ }),
467
+ ).toEqual({ [A]: isoDaysAgo(20) });
468
+ });
469
+
470
+ test("an invalid `now` falls back to the current time instead of throwing", () => {
471
+ const merged: DatabaseServerMemberKeys = mergeDatabaseServerMemberKeys(
472
+ {},
473
+ [A],
474
+ new Date("nope"),
475
+ );
476
+ expect(Object.keys(merged)).toEqual([A]);
477
+ expect(Number.isFinite(Date.parse(merged[A]!))).toBe(true);
478
+ });
479
+
480
+ test("a non-array seenNow is ignored", () => {
481
+ expect(
482
+ mergeDatabaseServerMemberKeys(
483
+ { [A]: isoDaysAgo(1) },
484
+ null as unknown as Array<string>,
485
+ NOW,
486
+ ),
487
+ ).toEqual({ [A]: isoDaysAgo(1) });
488
+ });
489
+ });
490
+
491
+ describe("getDatabaseServerSignalEntityKeys", () => {
492
+ const M1: string = hexKey(0x1);
493
+ const M2: string = hexKey(0x2);
494
+
495
+ test("MAX_DATABASE_SERVER_ENTITY_KEYS is 200", () => {
496
+ expect(MAX_DATABASE_SERVER_ENTITY_KEYS).toBe(200);
497
+ });
498
+
499
+ test("one key per stored endpoint (strings or { endpoint } rows), then members", () => {
500
+ expect(
501
+ getDatabaseServerSignalEntityKeys({
502
+ projectId: PROJECT,
503
+ endpoints: [
504
+ "db.prod:5432",
505
+ { endpoint: "pg.shop.svc.cluster.local:5432@prod" },
506
+ ],
507
+ dbSystem: "postgresql",
508
+ memberEntityKeys: {
509
+ [M1]: isoDaysAgo(3),
510
+ [M2]: isoDaysAgo(1),
511
+ },
512
+ }),
513
+ ).toEqual([
514
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: 5432 }),
515
+ keyForDatabaseEndpoint(PROJECT, {
516
+ host: "pg.shop.svc.cluster.local",
517
+ port: 5432,
518
+ kubernetesClusterName: "prod",
519
+ }),
520
+ M2,
521
+ M1,
522
+ ]);
523
+ });
524
+
525
+ test("no twin derivation: a qualified alias yields ONLY the qualified key", () => {
526
+ const keys: Array<string> = getDatabaseServerSignalEntityKeys({
527
+ projectId: PROJECT,
528
+ endpoints: ["pg.shop.svc.cluster.local:5432@prod"],
529
+ dbSystem: "postgresql",
530
+ memberEntityKeys: null,
531
+ });
532
+ expect(keys).toEqual([
533
+ keyForDatabaseEndpoint(PROJECT, {
534
+ host: "pg.shop.svc.cluster.local",
535
+ port: 5432,
536
+ kubernetesClusterName: "prod",
537
+ }),
538
+ ]);
539
+ expect(keys).not.toContain(
540
+ keyForDatabaseEndpoint(PROJECT, {
541
+ host: "pg.shop.svc.cluster.local",
542
+ port: 5432,
543
+ }),
544
+ );
545
+ });
546
+
547
+ test("a port-less stored endpoint gets the engine default, like ingest", () => {
548
+ expect(
549
+ getDatabaseServerSignalEntityKeys({
550
+ projectId: PROJECT,
551
+ endpoints: ["db.prod"],
552
+ dbSystem: "postgres",
553
+ memberEntityKeys: null,
554
+ }),
555
+ ).toEqual([
556
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: 5432 }),
557
+ ]);
558
+ expect(
559
+ getDatabaseServerSignalEntityKeys({
560
+ projectId: PROJECT,
561
+ endpoints: ["db.prod"],
562
+ memberEntityKeys: null,
563
+ }),
564
+ ).toEqual([
565
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: null }),
566
+ ]);
567
+ });
568
+
569
+ test("unparseable endpoints are skipped; duplicates collapse", () => {
570
+ expect(
571
+ getDatabaseServerSignalEntityKeys({
572
+ projectId: PROJECT,
573
+ endpoints: [
574
+ "[REDACTED]",
575
+ "localhost:5432",
576
+ "",
577
+ { endpoint: undefined },
578
+ {},
579
+ "db.prod:5432",
580
+ "DB.PROD:5432",
581
+ null as unknown as string,
582
+ ],
583
+ dbSystem: "postgresql",
584
+ memberEntityKeys: null,
585
+ }),
586
+ ).toEqual([
587
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: 5432 }),
588
+ ]);
589
+ });
590
+
591
+ test("member keys: only 16-hex keys, any stored shape, most recent first", () => {
592
+ expect(
593
+ getDatabaseServerSignalEntityKeys({
594
+ projectId: PROJECT,
595
+ endpoints: [],
596
+ memberEntityKeys: {
597
+ [M1]: isoDaysAgo(2),
598
+ "not-a-key": isoDaysAgo(1),
599
+ [M2.toUpperCase()]: isoDaysAgo(1),
600
+ },
601
+ }),
602
+ ).toEqual([M2, M1]);
603
+ expect(
604
+ getDatabaseServerSignalEntityKeys({
605
+ projectId: PROJECT,
606
+ endpoints: null,
607
+ memberEntityKeys: [M1, "nope", { key: M2, lastSeenAt: isoDaysAgo(1) }],
608
+ }),
609
+ ).toEqual([M2, M1]);
610
+ });
611
+
612
+ test("capped at 200 with endpoint keys first", () => {
613
+ const members: Record<string, string> = {};
614
+ for (let index: number = 0; index < 300; index++) {
615
+ members[hexKey(0x5000 + index)] = isoDaysAgo(1);
616
+ }
617
+ const endpointKey: string = keyForDatabaseEndpoint(PROJECT, {
618
+ host: "db.prod",
619
+ port: 5432,
620
+ });
621
+ const keys: Array<string> = getDatabaseServerSignalEntityKeys({
622
+ projectId: PROJECT,
623
+ endpoints: ["db.prod:5432"],
624
+ dbSystem: "postgresql",
625
+ memberEntityKeys: members,
626
+ });
627
+ expect(keys.length).toBe(200);
628
+ expect(keys[0]).toBe(endpointKey);
629
+ expect(new Set(keys).size).toBe(200);
630
+ });
631
+
632
+ test("nothing to scope by → [] (callers must then refuse to query)", () => {
633
+ expect(
634
+ getDatabaseServerSignalEntityKeys({
635
+ projectId: PROJECT,
636
+ endpoints: null,
637
+ memberEntityKeys: null,
638
+ }),
639
+ ).toEqual([]);
640
+ expect(
641
+ getDatabaseServerSignalEntityKeys({
642
+ projectId: PROJECT,
643
+ endpoints: undefined,
644
+ memberEntityKeys: "garbage",
645
+ }),
646
+ ).toEqual([]);
647
+ expect(
648
+ getDatabaseServerSignalEntityKeys({
649
+ projectId: " ",
650
+ endpoints: ["db.prod:5432"],
651
+ memberEntityKeys: { [M1]: isoDaysAgo(1) },
652
+ }),
653
+ ).toEqual([]);
654
+ });
655
+
656
+ test("keys are project-scoped", () => {
657
+ const a: Array<string> = getDatabaseServerSignalEntityKeys({
658
+ projectId: PROJECT,
659
+ endpoints: ["db.prod:5432"],
660
+ memberEntityKeys: null,
661
+ });
662
+ const b: Array<string> = getDatabaseServerSignalEntityKeys({
663
+ projectId: "another-project",
664
+ endpoints: ["db.prod:5432"],
665
+ memberEntityKeys: null,
666
+ });
667
+ expect(a[0]).not.toBe(b[0]);
668
+ });
669
+
670
+ test("end to end: a Kubernetes app's span lands on the workload row's page", () => {
671
+ // Worker side: the row's aliases for a CNPG cluster in a 1-cluster project.
672
+ const aliases: Array<string> = buildKubernetesDatabaseAliases({
673
+ system: "postgresql",
674
+ namespace: "shop",
675
+ clusterName: "prod-eu",
676
+ serviceNames: ["pg-main-rw", "pg-main-ro"],
677
+ ports: [5432],
678
+ includeUnqualified: true,
679
+ });
680
+ const podKey: string = keyForKubernetesPod(PROJECT, {
681
+ clusterName: "prod-eu",
682
+ namespace: "shop",
683
+ podName: "pg-main-1",
684
+ });
685
+ const pageKeys: Array<string> = getDatabaseServerSignalEntityKeys({
686
+ projectId: PROJECT,
687
+ endpoints: aliases,
688
+ dbSystem: "postgresql",
689
+ memberEntityKeys: mergeDatabaseServerMemberKeys(null, [podKey], NOW),
690
+ });
691
+
692
+ // Ingest side: an app in the same namespace calls "pg-main-rw".
693
+ const inCluster: ReturnType<typeof resolveDatabaseCallTarget> =
694
+ resolveDatabaseCallTarget({
695
+ getAttribute: (key: string): unknown => {
696
+ return (
697
+ {
698
+ "db.system.name": "postgresql",
699
+ "server.address": "pg-main-rw",
700
+ } as Record<string, unknown>
701
+ )[key];
702
+ },
703
+ caller: {
704
+ kubernetesNamespace: "shop",
705
+ kubernetesClusterName: "prod-eu",
706
+ isEphemeral: true,
707
+ },
708
+ });
709
+ // A direct exporter without k8s attributes uses the FQDN.
710
+ const direct: ReturnType<typeof resolveDatabaseCallTarget> =
711
+ resolveDatabaseCallTarget({
712
+ getAttribute: (key: string): unknown => {
713
+ return (
714
+ {
715
+ "db.system.name": "postgresql",
716
+ "server.address": "pg-main-ro.shop.svc.cluster.local",
717
+ } as Record<string, unknown>
718
+ )[key];
719
+ },
720
+ caller: { isEphemeral: true },
721
+ });
722
+
723
+ expect(pageKeys).toContain(
724
+ keyForDatabaseEndpoint(PROJECT, inCluster!.endpoint),
725
+ );
726
+ expect(pageKeys).toContain(
727
+ keyForDatabaseEndpoint(PROJECT, direct!.endpoint),
728
+ );
729
+ expect(pageKeys).toContain(podKey);
730
+ });
731
+
732
+ test("end to end: another cluster's same-named Service does not land here", () => {
733
+ const pageKeys: Array<string> = getDatabaseServerSignalEntityKeys({
734
+ projectId: PROJECT,
735
+ endpoints: buildKubernetesDatabaseAliases({
736
+ system: "postgresql",
737
+ namespace: "shop",
738
+ clusterName: "prod-eu",
739
+ serviceNames: ["pg"],
740
+ ports: [],
741
+ includeUnqualified: false,
742
+ }),
743
+ dbSystem: "postgresql",
744
+ memberEntityKeys: null,
745
+ });
746
+ const fromStaging: ReturnType<typeof resolveDatabaseCallTarget> =
747
+ resolveDatabaseCallTarget({
748
+ getAttribute: (key: string): unknown => {
749
+ return (
750
+ {
751
+ "db.system.name": "postgresql",
752
+ "server.address": "pg",
753
+ } as Record<string, unknown>
754
+ )[key];
755
+ },
756
+ caller: {
757
+ kubernetesNamespace: "shop",
758
+ kubernetesClusterName: "staging",
759
+ isEphemeral: true,
760
+ },
761
+ });
762
+ expect(pageKeys).not.toContain(
763
+ keyForDatabaseEndpoint(PROJECT, fromStaging!.endpoint),
764
+ );
765
+ });
766
+
767
+ test("same input, same output", () => {
768
+ const input: Parameters<typeof getDatabaseServerSignalEntityKeys>[0] = {
769
+ projectId: PROJECT,
770
+ endpoints: ["a.prod:5432", "b.prod:5432"],
771
+ dbSystem: "postgresql",
772
+ memberEntityKeys: { [M1]: isoDaysAgo(1), [M2]: isoDaysAgo(1) },
773
+ };
774
+ expect(getDatabaseServerSignalEntityKeys(input)).toEqual(
775
+ getDatabaseServerSignalEntityKeys(input),
776
+ );
777
+ expect(getDatabaseServerSignalEntityKeys(input).slice(2)).toEqual([M1, M2]);
778
+ });
779
+ });
780
+
781
+ /*
782
+ * The ROW key. Telemetry linked to a database by
783
+ * `oneuptime.database.server.id` must reach that database's pages whatever
784
+ * address it reported — a cluster-local name without its cluster, a private
785
+ * IP, an address another row owns, or none at all. Endpoint keys cannot
786
+ * carry that; the row key, stamped by ingest and always part of the row's
787
+ * key set, does.
788
+ */
789
+ describe("keyForDatabaseServerRow", () => {
790
+ const ROW_ID: string = "66666666-6666-4666-8666-666666666666";
791
+
792
+ test("hashes oneuptime.database.server.id under the database.server type", () => {
793
+ expect(DATABASE_SERVER_ROW_IDENTITY_ATTRIBUTE).toBe(
794
+ "oneuptime.database.server.id",
795
+ );
796
+ expect(keyForDatabaseServerRow(PROJECT, ROW_ID)).toBe(
797
+ expectedKey(PROJECT, EntityType.DatabaseServer, {
798
+ "oneuptime.database.server.id": ROW_ID,
799
+ }),
800
+ );
801
+ });
802
+
803
+ test("an upper-case or padded id is the same row", () => {
804
+ expect(keyForDatabaseServerRow(PROJECT, ` ${ROW_ID.toUpperCase()} `)).toBe(
805
+ keyForDatabaseServerRow(PROJECT, ROW_ID),
806
+ );
807
+ });
808
+
809
+ test("never equals an endpoint key, another row's key or another project's", () => {
810
+ const rowKey: string = keyForDatabaseServerRow(PROJECT, ROW_ID);
811
+ expect(rowKey).not.toBe(
812
+ keyForDatabaseEndpoint(PROJECT, { host: ROW_ID, port: null }),
813
+ );
814
+ expect(rowKey).not.toBe(
815
+ keyForDatabaseServerRow(PROJECT, "77777777-7777-4777-8777-777777777777"),
816
+ );
817
+ expect(rowKey).not.toBe(keyForDatabaseServerRow("another-project", ROW_ID));
818
+ expect(rowKey).toMatch(/^[0-9a-f]{16}$/);
819
+ });
820
+ });
821
+
822
+ describe("getDatabaseServerSignalEntityKeys — the row key", () => {
823
+ const ROW_ID: string = "66666666-6666-4666-8666-666666666666";
824
+ const ROW_KEY: string = keyForDatabaseServerRow(PROJECT, ROW_ID);
825
+ const M1: string = hexKey(0x1);
826
+
827
+ test("comes first, before the endpoint and member keys", () => {
828
+ expect(
829
+ getDatabaseServerSignalEntityKeys({
830
+ projectId: PROJECT,
831
+ databaseServerId: ROW_ID,
832
+ endpoints: ["db.prod:5432"],
833
+ dbSystem: "postgresql",
834
+ memberEntityKeys: { [M1]: isoDaysAgo(1) },
835
+ }),
836
+ ).toEqual([
837
+ ROW_KEY,
838
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: 5432 }),
839
+ M1,
840
+ ]);
841
+ });
842
+
843
+ test("an ObjectID-like id (anything with a string form) keys like its string", () => {
844
+ expect(
845
+ getDatabaseServerSignalEntityKeys({
846
+ projectId: PROJECT,
847
+ databaseServerId: {
848
+ toString: (): string => {
849
+ return ROW_ID;
850
+ },
851
+ },
852
+ endpoints: null,
853
+ memberEntityKeys: null,
854
+ }),
855
+ ).toEqual([ROW_KEY]);
856
+ });
857
+
858
+ test("a row with no endpoint and no member is still scoped — by its row key", () => {
859
+ // memcached / elasticsearch linked by id alone report no address at all.
860
+ expect(
861
+ getDatabaseServerSignalEntityKeys({
862
+ projectId: PROJECT,
863
+ databaseServerId: ROW_ID,
864
+ endpoints: [],
865
+ dbSystem: "memcached",
866
+ memberEntityKeys: null,
867
+ }),
868
+ ).toEqual([ROW_KEY]);
869
+ });
870
+
871
+ test("a blank or missing id adds nothing (the member-only scope passes none)", () => {
872
+ for (const blank of ["", " ", null, undefined]) {
873
+ expect(
874
+ getDatabaseServerSignalEntityKeys({
875
+ projectId: PROJECT,
876
+ databaseServerId: blank,
877
+ endpoints: null,
878
+ memberEntityKeys: { [M1]: isoDaysAgo(1) },
879
+ }),
880
+ ).toEqual([M1]);
881
+ }
882
+ expect(
883
+ getDatabaseServerSignalEntityKeys({
884
+ projectId: PROJECT,
885
+ databaseServerId: {} as unknown as string,
886
+ endpoints: null,
887
+ memberEntityKeys: null,
888
+ }),
889
+ ).toEqual([]);
890
+ });
891
+
892
+ test("without a project there is still nothing, id or not", () => {
893
+ expect(
894
+ getDatabaseServerSignalEntityKeys({
895
+ projectId: "",
896
+ databaseServerId: ROW_ID,
897
+ endpoints: ["db.prod:5432"],
898
+ memberEntityKeys: null,
899
+ }),
900
+ ).toEqual([]);
901
+ });
902
+
903
+ test("never evicted by the 200-key cap, and the endpoints stay ahead of the members", () => {
904
+ const members: Record<string, string> = {};
905
+ for (let index: number = 0; index < 300; index++) {
906
+ members[hexKey(0x5000 + index)] = isoDaysAgo(1);
907
+ }
908
+ const keys: Array<string> = getDatabaseServerSignalEntityKeys({
909
+ projectId: PROJECT,
910
+ databaseServerId: ROW_ID,
911
+ endpoints: ["db.prod:5432"],
912
+ dbSystem: "postgresql",
913
+ memberEntityKeys: members,
914
+ });
915
+ expect(keys.length).toBe(MAX_DATABASE_SERVER_ENTITY_KEYS);
916
+ expect(keys[0]).toBe(ROW_KEY);
917
+ expect(keys[1]).toBe(
918
+ keyForDatabaseEndpoint(PROJECT, { host: "db.prod", port: 5432 }),
919
+ );
920
+ });
921
+
922
+ test("regression: a linked agent with the cluster-local address the Documentation tab prefills lands on a multi-cluster workload row's page", () => {
923
+ // The row the worker made in a TWO-cluster project: qualified aliases only.
924
+ const pageKeys: Array<string> = getDatabaseServerSignalEntityKeys({
925
+ projectId: PROJECT,
926
+ databaseServerId: ROW_ID,
927
+ endpoints: buildKubernetesDatabaseAliases({
928
+ system: "postgresql",
929
+ namespace: "prod",
930
+ clusterName: "cluster-a",
931
+ serviceNames: ["postgres"],
932
+ ports: [],
933
+ includeUnqualified: false,
934
+ }),
935
+ dbSystem: "postgresql",
936
+ memberEntityKeys: null,
937
+ });
938
+
939
+ /*
940
+ * The agent reports server.address=postgres.prod.svc.cluster.local with
941
+ * no k8s.cluster.name: a LOCAL endpoint whose key the row never owns.
942
+ */
943
+ const agentEndpointKey: string = keyForDatabaseEndpoint(PROJECT, {
944
+ host: "postgres.prod.svc.cluster.local",
945
+ port: 5432,
946
+ });
947
+ expect(pageKeys).not.toContain(agentEndpointKey);
948
+
949
+ // The row key ingest stamps for the linked id is what the page matches.
950
+ expect(pageKeys).toContain(keyForDatabaseServerRow(PROJECT, ROW_ID));
951
+ });
952
+ });