@oneuptime/common 14.0.3 → 14.0.6

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 (663) 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/MetricService.ts +1 -1
  37. package/Server/Services/OpenTelemetryIngestService.ts +19 -0
  38. package/Server/Services/PodmanResourceService.ts +43 -2
  39. package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +107 -23
  40. package/Server/Services/ServiceService.ts +1 -1
  41. package/Server/Services/TelemetryUsageBillingService.ts +29 -2
  42. package/Server/Services/UserProjectSsoConsentService.ts +74 -0
  43. package/Server/Services/UserService.ts +14 -1
  44. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +18 -0
  45. package/Server/Types/Database/QueryHelper.ts +84 -2
  46. package/Server/Utils/AI/Toolbox/MetricTools.ts +13 -2
  47. package/Server/Utils/AI/Toolbox/ResourceTools.ts +81 -2
  48. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +1 -1
  49. package/Server/Utils/Database/AffectedResourceRelations.ts +6 -0
  50. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +33 -0
  51. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +192 -9
  52. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  53. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +2264 -755
  54. package/Server/Utils/Monitor/MonitorIncident.ts +28 -1
  55. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +268 -6
  56. package/Server/Utils/Monitor/MonitorResource.ts +47 -11
  57. package/Server/Utils/Monitor/MonitorResourceContext.ts +1 -0
  58. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +239 -21
  59. package/Server/Utils/Monitor/PerSeriesResolutionRootCause.ts +43 -0
  60. package/Server/Utils/Monitor/SeriesResourceLabels.ts +291 -0
  61. package/Server/Utils/Monitor/SeriesResourceLinker.ts +111 -12
  62. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  63. package/Server/Utils/StartServer.ts +26 -6
  64. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  65. package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +688 -0
  66. package/Server/Utils/Telemetry/EntityRegistry.ts +5 -1
  67. package/Server/Utils/Telemetry/LogExceptionExtractor.ts +18 -1
  68. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +175 -12
  69. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +12 -0
  70. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +606 -36
  71. package/Server/Utils/Telemetry/Telemetry.ts +16 -0
  72. package/Server/Utils/Telemetry/TelemetryEntity.ts +22 -22
  73. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +16 -10
  74. package/Tests/App/Accounts/SignedInRedirect.test.tsx +241 -0
  75. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +221 -4
  76. package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +42 -0
  77. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +100 -0
  78. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +86 -0
  79. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +2 -0
  80. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +19 -0
  81. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +14 -0
  82. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +26 -1
  83. package/Tests/App/Dashboard/DashboardAppSsoError.test.tsx +501 -0
  84. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +64 -1
  85. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +178 -18
  86. package/Tests/App/Dashboard/DashboardMasterPageSsoRedirect.test.tsx +444 -0
  87. package/Tests/App/Dashboard/DashboardNavBarForeignHiddenRule.test.tsx +573 -0
  88. package/Tests/App/Dashboard/DatabaseChartAxes.test.tsx +431 -0
  89. package/Tests/App/Dashboard/DatabaseContainerDetailBadge.test.tsx +249 -0
  90. package/Tests/App/Dashboard/DatabaseDashboardE2EFixes.test.ts +681 -0
  91. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +1801 -0
  92. package/Tests/App/Dashboard/DatabaseFleetSummaryRefresh.test.tsx +280 -0
  93. package/Tests/App/Dashboard/DatabaseFormHelpers.test.tsx +321 -0
  94. package/Tests/App/Dashboard/DatabaseMetricMonitorLink.test.tsx +795 -0
  95. package/Tests/App/Dashboard/DatabaseOverviewHeader.test.tsx +580 -0
  96. package/Tests/App/Dashboard/DatabaseRecommendationsEngineMetrics.test.ts +270 -0
  97. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +1486 -0
  98. package/Tests/App/Dashboard/DatabaseServerEngineMetricsFilter.test.ts +223 -0
  99. package/Tests/App/Dashboard/DatabaseServerPresentation.test.ts +435 -0
  100. package/Tests/App/Dashboard/DatabaseServerSummary.test.ts +186 -0
  101. package/Tests/App/Dashboard/DatabaseServerTelemetryQueries.test.ts +1553 -0
  102. package/Tests/App/Dashboard/DatabaseTableTruncation.test.tsx +326 -0
  103. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +512 -0
  104. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +774 -0
  105. package/Tests/App/Dashboard/DatabaseViewLayout.test.tsx +233 -0
  106. package/Tests/App/Dashboard/DatabaseWorkloadBadge.test.tsx +972 -0
  107. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +5 -0
  108. package/Tests/App/Dashboard/DiscoveryReviewUnnamedHostHint.test.tsx +1061 -0
  109. package/Tests/App/Dashboard/EventOverlayScope.test.ts +147 -0
  110. package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +1 -0
  111. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +1 -0
  112. package/Tests/App/Dashboard/MetricsViewerDrillDown.test.tsx +310 -0
  113. package/Tests/App/Dashboard/MetricsViewerEntityScopedRows.test.tsx +495 -0
  114. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +132 -1
  115. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +5 -0
  116. package/Tests/App/Dashboard/NetworkTopologyExplorerSearch.test.tsx +1267 -0
  117. package/Tests/App/Dashboard/ProductOrientation.test.tsx +4 -3
  118. package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +349 -0
  119. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +62 -0
  120. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  121. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +14 -0
  122. package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +4 -1
  123. package/Tests/App/Dashboard/RumOverviewPage.test.tsx +127 -0
  124. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +2 -0
  125. package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +1085 -0
  126. package/Tests/App/Dashboard/SiteSearchBox.test.tsx +2110 -0
  127. package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +168 -8
  128. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +10 -0
  129. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +2 -1
  130. package/Tests/App/StatusPage/StatusPageHeaderForeignHiddenRule.test.tsx +284 -0
  131. package/Tests/ClassStrings.ts +178 -0
  132. package/Tests/Fixtures/MobilePasskeyUser.json +1 -2
  133. package/Tests/ForeignHiddenRuleGuard.ts +2152 -0
  134. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +2250 -0
  135. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +24 -5
  136. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  137. package/Tests/RenderedMarkup.ts +518 -0
  138. package/Tests/ResponsiveVisibility.test.ts +490 -4
  139. package/Tests/ResponsiveVisibility.ts +505 -52
  140. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  141. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +541 -0
  142. package/Tests/Server/Infrastructure/Postgres/AddUserProjectSsoConsentMigration.test.ts +234 -0
  143. package/Tests/Server/Services/ContainerSnapshotUpsertPostgres.test.ts +319 -0
  144. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +13 -0
  145. package/Tests/Server/Services/DatabaseServerEndpointService.test.ts +2033 -0
  146. package/Tests/Server/Services/DatabaseServerFeedAndOwnerServices.test.ts +529 -0
  147. package/Tests/Server/Services/DatabaseServerLifecycle.test.ts +3302 -0
  148. package/Tests/Server/Services/DatabaseServerRegistries.test.ts +603 -0
  149. package/Tests/Server/Services/DatabaseServerRuleEngines.test.ts +754 -0
  150. package/Tests/Server/Services/DatabaseServerService.test.ts +3558 -0
  151. package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +2045 -0
  152. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedPostgres.test.ts +362 -0
  153. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedReply.test.ts +210 -0
  154. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +18 -0
  155. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +2 -0
  156. package/Tests/Server/Services/IncomingCallPolicyEscalationRuleTarget.test.ts +225 -0
  157. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +280 -2
  158. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +8 -2
  159. package/Tests/Server/Services/IoTDeviceLatestMetricsPostgres.test.ts +689 -0
  160. package/Tests/Server/Services/IoTDeviceService.test.ts +379 -0
  161. package/Tests/Server/Services/LatestMetricsValuesShape.test.ts +360 -0
  162. package/Tests/Server/Services/LlmModelPriceService.test.ts +402 -0
  163. package/Tests/Server/Services/MetricServiceAggregate.test.ts +12 -0
  164. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
  165. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +61 -9
  166. package/Tests/Server/Services/ReminderRuleLookupPostgres.test.ts +2250 -0
  167. package/Tests/Server/Services/ReminderRuleRefreshOpenSubjectsPaging.test.ts +653 -0
  168. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +68 -20
  169. package/Tests/Server/Services/SavedViewDefaults.test.ts +325 -0
  170. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  171. package/Tests/Server/Services/StatusPageCertificateService.test.ts +169 -0
  172. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +191 -0
  173. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +9 -0
  174. package/Tests/Server/Services/UserProjectSsoConsentPostgres.test.ts +153 -0
  175. package/Tests/Server/Services/UserProjectSsoConsentService.test.ts +192 -0
  176. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +71 -0
  177. package/Tests/Server/Services/UserSignupIdTakeoverPostgres.test.ts +238 -0
  178. package/Tests/Server/Services/WorkspaceNotificationSummaryHelpers.test.ts +592 -0
  179. package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +3 -0
  180. package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +1 -0
  181. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +11 -0
  182. package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +8 -0
  183. package/Tests/Server/Types/Database/QueryHelperBooleanForCriteriaBackedRule.test.ts +1094 -0
  184. package/Tests/Server/Types/Database/QueryHelperSearchAllWords.test.ts +651 -0
  185. package/Tests/Server/Utils/AI/AlertWriteTools.test.ts +256 -0
  186. package/Tests/Server/Utils/AI/IncidentWriteTools.test.ts +482 -0
  187. package/Tests/Server/Utils/AI/ResourceTools.test.ts +134 -0
  188. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteria.test.ts +54 -0
  189. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +41 -0
  190. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +279 -9
  191. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaDisplayContext.test.ts +933 -0
  192. package/Tests/Server/Utils/Monitor/DatabaseMaintenanceSuppression.test.ts +582 -0
  193. package/Tests/Server/Utils/Monitor/DatabaseServerMonitorLinking.test.ts +753 -0
  194. package/Tests/Server/Utils/Monitor/MetricDecimalThreshold.test.ts +417 -0
  195. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +1 -0
  196. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +1 -0
  197. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +119 -0
  198. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +60 -25
  199. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorAffectedResourceEdgeCases.test.ts +1815 -0
  200. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesAffectedResources.test.ts +1447 -0
  201. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesRatioEmail.test.ts +352 -0
  202. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformMetricUnits.test.ts +717 -0
  203. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformRawScan.test.ts +2125 -0
  204. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformSeriesAffectedResources.test.ts +1288 -0
  205. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
  206. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +1 -0
  207. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +1 -0
  208. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +88 -0
  209. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +205 -0
  210. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +62 -0
  211. package/Tests/Server/Utils/Monitor/MonitorResourceDatabaseMaintenance.test.ts +803 -0
  212. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +133 -3
  213. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
  214. package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +472 -1
  215. package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
  216. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +236 -2
  217. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +70 -0
  218. package/Tests/Server/Utils/StartServerProtobufContentType.test.ts +54 -0
  219. package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +1895 -0
  220. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +7 -0
  221. package/Tests/Server/Utils/Telemetry/LogExceptionExtractorSeverityGate.test.ts +90 -0
  222. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +570 -0
  223. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +97 -2
  224. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +1337 -0
  225. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +295 -0
  226. package/Tests/Types/AI/AIResourceContext.test.ts +30 -0
  227. package/Tests/Types/BaseDatabase/AggregationType.test.ts +5 -1
  228. package/Tests/Types/Dashboard/KubernetesDashboardTemplate.test.ts +184 -0
  229. package/Tests/Types/Dashboard/KubernetesDashboardTemplates.test.ts +107 -0
  230. package/Tests/Types/DatabaseServer/DatabaseContainerClassifier.test.ts +3644 -0
  231. package/Tests/Types/DatabaseServer/DatabaseContainerCommand.test.ts +340 -0
  232. package/Tests/Types/DatabaseServer/DatabaseContainerCommandCorpus.ts +826 -0
  233. package/Tests/Types/DatabaseServer/DatabaseContainerCommandPostgres.test.ts +150 -0
  234. package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +2657 -0
  235. package/Tests/Types/DatabaseServer/DatabaseServerDiscoverySource.test.ts +64 -0
  236. package/Tests/Types/DatabaseServer/DatabaseServerEntityKeys.test.ts +952 -0
  237. package/Tests/Types/DatabaseServer/DatabaseServerMetricCatalog.test.ts +1161 -0
  238. package/Tests/Types/DatabaseServer/DatabaseSystem.test.ts +1514 -0
  239. package/Tests/Types/DatabaseServer/DatabaseTelemetryResolver.test.ts +1558 -0
  240. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +255 -6
  241. package/Tests/Types/Monitor/DatabaseAlertTemplates.test.ts +2254 -0
  242. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +292 -0
  243. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +272 -0
  244. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +253 -9
  245. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +13 -5
  246. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +4 -2
  247. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +111 -2
  248. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +61 -0
  249. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +114 -0
  250. package/Tests/Types/Monitor/Utils/KubernetesAgentEmittedMetrics.ts +202 -0
  251. package/Tests/Types/NetworkDevice/DiscoveredHostNamingStatus.test.ts +401 -0
  252. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +4 -1
  253. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +24 -2
  254. package/Tests/UI/Components/Card.test.tsx +93 -2
  255. package/Tests/UI/Components/FeedOptions.test.ts +6 -0
  256. package/Tests/UI/Components/FeedOptionsButton.test.tsx +8 -1
  257. package/Tests/UI/Components/ForeignHiddenRuleResilience.test.tsx +1147 -0
  258. package/Tests/UI/Components/HeaderRightRail.test.tsx +41 -1
  259. package/Tests/UI/Components/LogsEntityNames.test.ts +16 -1
  260. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +7 -3
  261. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +2 -1
  262. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  263. package/Tests/UI/Components/SrOnlyForeignRule.test.tsx +994 -0
  264. package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +34 -1
  265. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +4 -1
  266. package/Tests/UI/ForeignHiddenRuleGuard.test.ts +1951 -0
  267. package/Tests/UI/Rum/ChunkLoader.test.ts +76 -0
  268. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +19 -1
  269. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +53 -0
  270. package/Tests/UI/Rum/ReplaySignals.test.ts +54 -0
  271. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +19 -1
  272. package/Tests/UI/TailwindPlayCdnForeignHiddenRule.test.ts +1005 -0
  273. package/Tests/UI/ThemeGroupHoverReveal.test.ts +847 -0
  274. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +70 -0
  275. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +21 -0
  276. package/Tests/UI/Utils/ModelAPISsoRedirect.test.ts +127 -0
  277. package/Tests/UI/Utils/Navigation.test.ts +102 -0
  278. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +23 -0
  279. package/Tests/Utils/Dashboard/KubernetesClusterCpuTileRepair.test.ts +370 -0
  280. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  281. package/Tests/Utils/MetricUnitUtil.test.ts +227 -2
  282. package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +288 -2
  283. package/Tests/Utils/Monitor/PlatformResourceIdentityAndUnits.test.ts +1559 -0
  284. package/Tests/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.test.ts +2546 -0
  285. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +315 -0
  286. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +336 -1
  287. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +244 -0
  288. package/Tests/Utils/Rules/MonitorTypeRuleCriteria.test.ts +181 -0
  289. package/Tests/Utils/ValueFormatter.test.ts +50 -0
  290. package/Tests/tsconfig.json +16 -0
  291. package/Types/AI/AIResourceContext.ts +7 -0
  292. package/Types/BaseDatabase/AggregationType.ts +7 -0
  293. package/Types/Dashboard/DashboardTemplates.ts +22 -8
  294. package/Types/DatabaseServer/DatabaseConnectionSpan.ts +77 -0
  295. package/Types/DatabaseServer/DatabaseContainerClassifier.ts +2068 -0
  296. package/Types/DatabaseServer/DatabaseContainerCommand.ts +801 -0
  297. package/Types/DatabaseServer/DatabaseEndpoint.ts +1943 -0
  298. package/Types/DatabaseServer/DatabaseServerDiscoverySource.ts +68 -0
  299. package/Types/DatabaseServer/DatabaseServerMetricCatalog.ts +966 -0
  300. package/Types/DatabaseServer/DatabaseSystem.ts +2124 -0
  301. package/Types/DatabaseServer/DatabaseTelemetryResolver.ts +555 -0
  302. package/Types/Email/EmailTemplateType.ts +1 -0
  303. package/Types/Monitor/CephAlertTemplates.ts +18 -0
  304. package/Types/Monitor/DatabaseAlertTemplates.ts +2020 -0
  305. package/Types/Monitor/KubernetesAlertTemplates.ts +64 -24
  306. package/Types/Monitor/KubernetesMetricCatalog.ts +118 -19
  307. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +14 -0
  308. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +93 -10
  309. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +109 -8
  310. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +36 -7
  311. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +43 -2
  312. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +41 -6
  313. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +26 -0
  314. package/Types/NetworkDevice/DiscoveredHostNamingStatus.ts +147 -0
  315. package/Types/Permission.ts +267 -0
  316. package/Types/Probe/ProbeApiIngestResponse.ts +8 -0
  317. package/Types/Rules/RuleCriteriaFieldRegistry.ts +10 -0
  318. package/Types/Rules/RuleRun.ts +12 -0
  319. package/Types/Rum/SessionReplayCustomEvents.ts +29 -3
  320. package/Types/Rum/WebVitals.ts +13 -0
  321. package/Types/Telemetry/EntityType.ts +23 -0
  322. package/Types/Telemetry/ResourceFacetCatalog.ts +14 -0
  323. package/Types/Telemetry/ServiceType.ts +8 -0
  324. package/UI/Components/Banner/Banner.tsx +1 -1
  325. package/UI/Components/Card/Card.tsx +1 -1
  326. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +2 -2
  327. package/UI/Components/Charts/Line/LineChart.tsx +7 -0
  328. package/UI/Components/CommandPalette/CommandPalette.tsx +1 -1
  329. package/UI/Components/Date/StartAndEndDate.tsx +5 -5
  330. package/UI/Components/Diagram/HorizontalStepChain.tsx +1 -1
  331. package/UI/Components/Feed/FeedOptionsButton.tsx +1 -1
  332. package/UI/Components/Forms/BasicForm.tsx +1 -1
  333. package/UI/Components/Header/Header.tsx +1 -1
  334. package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -1
  335. package/UI/Components/HeaderAlert/HeaderAlert.tsx +1 -1
  336. package/UI/Components/Input/Input.tsx +11 -0
  337. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +1 -1
  338. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +1 -1
  339. package/UI/Components/Modal/ModalFooter.tsx +1 -1
  340. package/UI/Components/ModelDetail/CardModelDetail.tsx +2 -2
  341. package/UI/Components/ModelTable/BaseModelTable.tsx +4 -4
  342. package/UI/Components/Navbar/NavBar.tsx +9 -2
  343. package/UI/Components/Navbar/NavBarMenuModal.tsx +2 -2
  344. package/UI/Components/Page/Page.tsx +1 -1
  345. package/UI/Components/Pagination/Pagination.tsx +3 -3
  346. package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +1 -1
  347. package/UI/Components/SideMenu/SideMenu.tsx +4 -1
  348. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +4 -2
  349. package/UI/Components/StatusPage/ResourceList.tsx +6 -6
  350. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +1 -1
  351. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +1 -1
  352. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +1 -1
  353. package/UI/Components/Workflow/ComponentsModal.tsx +2 -2
  354. package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
  355. package/UI/Styles/Theme.css +8 -1
  356. package/UI/Utils/Navigation.ts +89 -42
  357. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +7 -0
  358. package/UI/Utils/TelemetryService.ts +4 -3
  359. package/Utils/Dashboard/KubernetesClusterCpuTileRepair.ts +147 -0
  360. package/Utils/LabelRuleImportExport.ts +2 -0
  361. package/Utils/MetricUnitUtil.ts +103 -11
  362. package/Utils/Monitor/MetricValueFormatter.ts +66 -13
  363. package/Utils/Monitor/PlatformMetricUnitUtil.ts +215 -0
  364. package/Utils/Monitor/PlatformResourceIdentity.ts +514 -0
  365. package/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.ts +425 -0
  366. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +32 -0
  367. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +73 -0
  368. package/Utils/Telemetry/DatabaseServerEntityKeys.ts +275 -0
  369. package/Utils/Telemetry/EntityKey.ts +176 -0
  370. package/Utils/ValueFormatter.ts +16 -0
  371. package/build/dist/Models/DatabaseModels/Alert.js +54 -0
  372. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  373. package/build/dist/Models/DatabaseModels/DatabaseServer.js +1683 -0
  374. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -0
  375. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +559 -0
  376. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -0
  377. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js +648 -0
  378. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js.map +1 -0
  379. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js +522 -0
  380. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js.map +1 -0
  381. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js +603 -0
  382. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js.map +1 -0
  383. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js +506 -0
  384. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js.map +1 -0
  385. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js +505 -0
  386. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js.map +1 -0
  387. package/build/dist/Models/DatabaseModels/Incident.js +54 -0
  388. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  389. package/build/dist/Models/DatabaseModels/Index.js +16 -0
  390. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  391. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  392. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
  393. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  394. package/build/dist/Models/DatabaseModels/TelemetryException.js +2 -0
  395. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  396. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js +162 -0
  397. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js.map +1 -0
  398. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js +240 -0
  399. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js.map +1 -0
  400. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js +26 -0
  401. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js.map +1 -0
  402. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  403. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  404. package/build/dist/Server/Middleware/MultipartFormData.js +1 -1
  405. package/build/dist/Server/Middleware/TelemetryIngest.js +15 -8
  406. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  407. package/build/dist/Server/Services/AlertReminderRuleService.js +72 -23
  408. package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
  409. package/build/dist/Server/Services/DatabaseServerEndpointService.js +694 -0
  410. package/build/dist/Server/Services/DatabaseServerEndpointService.js.map +1 -0
  411. package/build/dist/Server/Services/DatabaseServerFeedService.js +110 -0
  412. package/build/dist/Server/Services/DatabaseServerFeedService.js.map +1 -0
  413. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js +272 -0
  414. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js.map +1 -0
  415. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js +13 -0
  416. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js.map +1 -0
  417. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js +340 -0
  418. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js.map +1 -0
  419. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js +13 -0
  420. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js.map +1 -0
  421. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js +160 -0
  422. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js.map +1 -0
  423. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js +153 -0
  424. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js.map +1 -0
  425. package/build/dist/Server/Services/DatabaseServerService.js +3272 -0
  426. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -0
  427. package/build/dist/Server/Services/DatabaseService.js +8 -4
  428. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  429. package/build/dist/Server/Services/DockerResourceService.js +30 -3
  430. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  431. package/build/dist/Server/Services/IncidentReminderRuleService.js +73 -23
  432. package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
  433. package/build/dist/Server/Services/Index.js +16 -0
  434. package/build/dist/Server/Services/Index.js.map +1 -1
  435. package/build/dist/Server/Services/InventoryItemService.js +88 -5
  436. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  437. package/build/dist/Server/Services/IoTDeviceService.js +111 -24
  438. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  439. package/build/dist/Server/Services/MetricService.js +1 -1
  440. package/build/dist/Server/Services/OpenTelemetryIngestService.js +24 -9
  441. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  442. package/build/dist/Server/Services/PodmanResourceService.js +30 -3
  443. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  444. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +75 -23
  445. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
  446. package/build/dist/Server/Services/ServiceService.js +1 -1
  447. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  448. package/build/dist/Server/Services/TelemetryUsageBillingService.js +23 -2
  449. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  450. package/build/dist/Server/Services/UserProjectSsoConsentService.js +79 -0
  451. package/build/dist/Server/Services/UserProjectSsoConsentService.js.map +1 -0
  452. package/build/dist/Server/Services/UserService.js +13 -1
  453. package/build/dist/Server/Services/UserService.js.map +1 -1
  454. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +18 -0
  455. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  456. package/build/dist/Server/Types/Database/QueryHelper.js +73 -2
  457. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  458. package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js +13 -2
  459. package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js.map +1 -1
  460. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +58 -1
  461. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  462. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +1 -1
  463. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +6 -0
  464. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -1
  465. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +31 -0
  466. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  467. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +135 -14
  468. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  469. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -6
  470. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  471. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1489 -524
  472. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  473. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  474. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  475. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +196 -6
  476. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  477. package/build/dist/Server/Utils/Monitor/MonitorResource.js +36 -9
  478. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  479. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +1 -0
  480. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
  481. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +175 -17
  482. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  483. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js +29 -0
  484. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js.map +1 -0
  485. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +211 -0
  486. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  487. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +82 -10
  488. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  489. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  490. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  491. package/build/dist/Server/Utils/StartServer.js +20 -4
  492. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  493. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  494. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  495. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +442 -0
  496. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -0
  497. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -1
  498. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  499. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +15 -1
  500. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
  501. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +121 -5
  502. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  503. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +12 -0
  504. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  505. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +438 -36
  506. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
  507. package/build/dist/Server/Utils/Telemetry/Telemetry.js +12 -0
  508. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  509. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -18
  510. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  511. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +16 -10
  512. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -1
  513. package/build/dist/Types/AI/AIResourceContext.js +7 -0
  514. package/build/dist/Types/AI/AIResourceContext.js.map +1 -1
  515. package/build/dist/Types/BaseDatabase/AggregationType.js +7 -0
  516. package/build/dist/Types/BaseDatabase/AggregationType.js.map +1 -1
  517. package/build/dist/Types/Dashboard/DashboardTemplates.js +22 -8
  518. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  519. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js +71 -0
  520. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js.map +1 -0
  521. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js +1462 -0
  522. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js.map +1 -0
  523. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js +691 -0
  524. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js.map +1 -0
  525. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +1407 -0
  526. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -0
  527. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js +60 -0
  528. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js.map +1 -0
  529. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js +804 -0
  530. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js.map +1 -0
  531. package/build/dist/Types/DatabaseServer/DatabaseSystem.js +1860 -0
  532. package/build/dist/Types/DatabaseServer/DatabaseSystem.js.map +1 -0
  533. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js +406 -0
  534. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js.map +1 -0
  535. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  536. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  537. package/build/dist/Types/Monitor/CephAlertTemplates.js +18 -0
  538. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  539. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js +1518 -0
  540. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js.map +1 -0
  541. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +57 -24
  542. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  543. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +104 -18
  544. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  545. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +80 -3
  546. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  547. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +10 -3
  548. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  549. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +29 -0
  550. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  551. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +21 -6
  552. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -1
  553. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +25 -0
  554. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  555. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js +136 -0
  556. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js.map +1 -0
  557. package/build/dist/Types/Permission.js +234 -0
  558. package/build/dist/Types/Permission.js.map +1 -1
  559. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +10 -0
  560. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  561. package/build/dist/Types/Rules/RuleRun.js +4 -0
  562. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  563. package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -1
  564. package/build/dist/Types/Rum/WebVitals.js +12 -0
  565. package/build/dist/Types/Rum/WebVitals.js.map +1 -1
  566. package/build/dist/Types/Telemetry/EntityType.js +23 -0
  567. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  568. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +14 -0
  569. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -1
  570. package/build/dist/Types/Telemetry/ServiceType.js +8 -0
  571. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  572. package/build/dist/UI/Components/Banner/Banner.js +1 -1
  573. package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
  574. package/build/dist/UI/Components/Card/Card.js +1 -1
  575. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  576. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
  577. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  578. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  579. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  580. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +1 -1
  581. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  582. package/build/dist/UI/Components/Date/StartAndEndDate.js +5 -5
  583. package/build/dist/UI/Components/Date/StartAndEndDate.js.map +1 -1
  584. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +1 -1
  585. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -1
  586. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +1 -1
  587. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -1
  588. package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
  589. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  590. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
  591. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  592. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +1 -1
  593. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  594. package/build/dist/UI/Components/Input/Input.js +1 -1
  595. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  596. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +1 -1
  597. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  598. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  599. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  600. package/build/dist/UI/Components/Modal/ModalFooter.js +1 -1
  601. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  602. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
  603. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  604. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +4 -4
  605. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  606. package/build/dist/UI/Components/Navbar/NavBar.js +9 -2
  607. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  608. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
  609. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  610. package/build/dist/UI/Components/Page/Page.js +1 -1
  611. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  612. package/build/dist/UI/Components/Pagination/Pagination.js +3 -3
  613. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  614. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +1 -1
  615. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
  616. package/build/dist/UI/Components/SideMenu/SideMenu.js +4 -1
  617. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  618. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +3 -1
  619. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -1
  620. package/build/dist/UI/Components/StatusPage/ResourceList.js +6 -6
  621. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
  622. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  623. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  624. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +1 -1
  625. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  626. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +1 -1
  627. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
  628. package/build/dist/UI/Components/Workflow/ComponentsModal.js +2 -2
  629. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  630. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
  631. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  632. package/build/dist/UI/Utils/Navigation.js +66 -33
  633. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  634. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +7 -0
  635. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
  636. package/build/dist/UI/Utils/TelemetryService.js +3 -2
  637. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  638. package/build/dist/Utils/Dashboard/KubernetesClusterCpuTileRepair.js +110 -0
  639. package/build/dist/Utils/Dashboard/KubernetesClusterCpuTileRepair.js.map +1 -0
  640. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  641. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  642. package/build/dist/Utils/MetricUnitUtil.js +77 -13
  643. package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
  644. package/build/dist/Utils/Monitor/MetricValueFormatter.js +58 -13
  645. package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -1
  646. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js +161 -0
  647. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js.map +1 -0
  648. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js +323 -0
  649. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js.map +1 -0
  650. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js +270 -0
  651. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js.map +1 -0
  652. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +23 -0
  653. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  654. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +61 -0
  655. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -1
  656. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js +178 -0
  657. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js.map +1 -0
  658. package/build/dist/Utils/Telemetry/EntityKey.js +133 -0
  659. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  660. package/build/dist/Utils/ValueFormatter.js +15 -0
  661. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  662. package/package.json +1 -1
  663. package/tsconfig.tests.json +7 -5
@@ -0,0 +1,895 @@
1
+ import DatabaseService from "./DatabaseService";
2
+ import DatabaseServerFeedService from "./DatabaseServerFeedService";
3
+ import DatabaseServerService from "./DatabaseServerService";
4
+ import Model from "../../Models/DatabaseModels/DatabaseServerEndpoint";
5
+ import DatabaseServer from "../../Models/DatabaseModels/DatabaseServer";
6
+ import { DatabaseServerFeedEventType } from "../../Models/DatabaseModels/DatabaseServerFeed";
7
+ import CreateBy from "../Types/Database/CreateBy";
8
+ import DeleteBy from "../Types/Database/DeleteBy";
9
+ import { OnCreate, OnDelete } from "../Types/Database/Hooks";
10
+ import ModelPermission from "../Types/Database/Permissions/Index";
11
+ import Query from "../Types/Database/Query";
12
+ import RelationIdUtil from "../Utils/Database/RelationIdUtil";
13
+ import logger from "../Utils/Logger";
14
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
15
+ import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
16
+ import SortOrder from "../../Types/BaseDatabase/SortOrder";
17
+ import { Gray500, Red500 } from "../../Types/BrandColors";
18
+ import ColumnLength from "../../Types/Database/ColumnLength";
19
+ import LIMIT_MAX from "../../Types/Database/LimitMax";
20
+ import OneUptimeDate from "../../Types/Date";
21
+ import BadDataException from "../../Types/Exception/BadDataException";
22
+ import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
23
+ import ObjectID from "../../Types/ObjectID";
24
+ import {
25
+ DatabaseEndpoint,
26
+ ManualDatabaseEndpoint,
27
+ formatDatabaseEndpoint,
28
+ parseManualDatabaseEndpoint,
29
+ } from "../../Types/DatabaseServer/DatabaseEndpoint";
30
+
31
+ /*
32
+ * Who added an endpoint:
33
+ * - "auto": a telemetry path claimed it (the endpoint an application trace
34
+ * or a collector reported);
35
+ * - "workload": container discovery claimed it as a Service name of the
36
+ * Kubernetes workload the database runs as - released again once the
37
+ * workload stops producing it;
38
+ * - "user": a person added it (an alias from the database's Endpoints tab,
39
+ * or the address typed into the create form of a manually added
40
+ * database). Discovery never releases or moves a "user" endpoint.
41
+ */
42
+ export type DatabaseServerEndpointSource = "auto" | "workload" | "user";
43
+
44
+ /*
45
+ * The outcome of claimEndpoint. Discovery only ever needs to know whether the
46
+ * endpoint is now this row's, and - when it is not - that some other row
47
+ * already owns it, which is never tie-broken or taken over.
48
+ */
49
+ export type DatabaseServerEndpointClaimResult =
50
+ | "claimed"
51
+ | "already-owned-by-this"
52
+ | "owned-by-other";
53
+
54
+ export interface DatabaseServerEndpointOwner {
55
+ databaseServerId: ObjectID;
56
+ isPrimary: boolean;
57
+ // The endpoint row itself, when it was read (findOwnerByEndpoint reads it).
58
+ endpointId?: ObjectID | undefined;
59
+ source?: string | undefined;
60
+ lastMatchedAt?: Date | undefined;
61
+ }
62
+
63
+ /*
64
+ * "Last matched" is refreshed at most this often per endpoint: often enough
65
+ * that a stale alias stands out on the Endpoints tab, rarely enough that a
66
+ * busy endpoint costs one write an hour, not one per lookup.
67
+ */
68
+ export const ENDPOINT_MATCH_REFRESH_SECONDS: number = 60 * 60;
69
+
70
+ // What onBeforeDelete hands onDeleteSuccess: the endpoints the delete matched.
71
+ interface EndpointDeleteCarryForward {
72
+ endpointsToDelete: Array<Model>;
73
+ }
74
+
75
+ // What an alias looks like, for the refusal of an empty one.
76
+ const ENDPOINT_EXAMPLE: string =
77
+ "Enter the host name or IP address applications use to reach this database, with an optional port, for example orders-db.example.com:5432.";
78
+
79
+ /*
80
+ * The endpoints a database is reached at. Every endpoint belongs to at most
81
+ * one database per project: the (projectId, endpoint) unique index enforces
82
+ * it, and this service turns a collision into a message naming the database
83
+ * that already owns the endpoint instead of a raw constraint error.
84
+ *
85
+ * Endpoints are stored canonical (formatDatabaseEndpoint), because the
86
+ * telemetry entity key of a database is derived from the endpoint string -
87
+ * a person typing "Orders-DB.example.com" must land on the same key ingest
88
+ * computes for `server.address=orders-db.example.com`.
89
+ */
90
+ export class Service extends DatabaseService<Model> {
91
+ public constructor() {
92
+ super(Model);
93
+ }
94
+
95
+ /*
96
+ * A person adding an alias. Root writes (the discovery paths, through
97
+ * claimEndpoint) pass through untouched: they already hold a canonical
98
+ * endpoint and handle ownership themselves.
99
+ *
100
+ * Adding an endpoint is an EDIT of the database it is added to: it decides
101
+ * which traffic that database's pages show and - one owner per endpoint -
102
+ * that no other database can claim it. So the caller must be allowed to
103
+ * edit that very row, label and Owned scopes included. DatabaseService
104
+ * checks the create permission only after this hook, and never scopes a
105
+ * create to the parent row, so both happen here - the create permission
106
+ * FIRST, so a caller without it learns nothing about which databases exist
107
+ * or who owns an endpoint.
108
+ */
109
+ @CaptureSpan()
110
+ protected override async onBeforeCreate(
111
+ createBy: CreateBy<Model>,
112
+ ): Promise<OnCreate<Model>> {
113
+ if (createBy.props.isRoot) {
114
+ return { createBy: createBy, carryForward: null };
115
+ }
116
+
117
+ const data: Model = createBy.data;
118
+
119
+ ModelPermission.checkCreatePermissions(Model, data, createBy.props);
120
+
121
+ /*
122
+ * The tenant column is stamped from props.tenantId only after this hook,
123
+ * so read the request tenant first - it is the only project the caller
124
+ * was checked in.
125
+ */
126
+ const projectId: ObjectID | undefined =
127
+ createBy.props.tenantId || data.projectId || undefined;
128
+
129
+ if (!projectId) {
130
+ throw new BadDataException(
131
+ "Project ID is required to add a database endpoint.",
132
+ );
133
+ }
134
+
135
+ /*
136
+ * The reference arrives as the FK column or as a relation object, and
137
+ * TypeORM persists the relation object's id over the column's. Read both
138
+ * spellings, refuse a payload whose two spellings disagree, and leave the
139
+ * validated column as the only one that can reach the insert.
140
+ */
141
+ const databaseServerId: ObjectID | null = RelationIdUtil.readConsistent(
142
+ data as unknown as Record<string, unknown>,
143
+ ["databaseServerId", "databaseServer"],
144
+ "database",
145
+ );
146
+
147
+ data.setColumnValue("databaseServer", undefined);
148
+
149
+ if (!databaseServerId) {
150
+ throw new BadDataException(
151
+ "Select the database this endpoint belongs to.",
152
+ );
153
+ }
154
+
155
+ const databaseServer: DatabaseServer | null =
156
+ await this.findEditableDatabaseServer({
157
+ projectId: projectId,
158
+ databaseServerId: databaseServerId,
159
+ props: createBy.props,
160
+ });
161
+
162
+ /*
163
+ * One answer for "no such database in this project" and "a database you
164
+ * may not edit", so the refusal is not a way to probe for ids.
165
+ */
166
+ if (!databaseServer) {
167
+ throw new NotAuthorizedException(
168
+ "Database not found, or you do not have permission to edit it. Adding an endpoint to a database needs permission to edit that database.",
169
+ );
170
+ }
171
+
172
+ /*
173
+ * Canonicalize with the database's own context: its engine supplies the
174
+ * default port, and for a database discovered on Kubernetes its
175
+ * namespace expands a bare service name (and `<service>.<namespace>` to
176
+ * the Service's full name) and its cluster qualifies a cluster-local
177
+ * name - exactly what ingest does for the pods calling it. A value that
178
+ * cannot be used - `user@host`, a cluster qualifier on a public host, a
179
+ * loopback name, a port outside 1-65535 - is refused with a message
180
+ * saying what to change, never read as something else or quietly given
181
+ * the engine's default port.
182
+ */
183
+ const manual: ManualDatabaseEndpoint = parseManualDatabaseEndpoint(
184
+ data.endpoint,
185
+ {
186
+ system: databaseServer.dbSystem || "",
187
+ kubernetesClusterName:
188
+ databaseServer.kubernetesCluster?.clusterIdentifier,
189
+ kubernetesNamespace: databaseServer.kubernetesNamespace,
190
+ },
191
+ );
192
+
193
+ const endpoint: DatabaseEndpoint | null = manual.endpoint;
194
+
195
+ if (!endpoint) {
196
+ throw new BadDataException(
197
+ typeof data.endpoint !== "string" || !data.endpoint.trim()
198
+ ? `Endpoint is required. ${ENDPOINT_EXAMPLE}`
199
+ : manual.error || `This is not a valid endpoint. ${ENDPOINT_EXAMPLE}`,
200
+ );
201
+ }
202
+
203
+ const formatted: string = formatDatabaseEndpoint(endpoint);
204
+
205
+ if (formatted.length > ColumnLength.LongText) {
206
+ throw new BadDataException(
207
+ `This endpoint is too long. Endpoints can be at most ${ColumnLength.LongText} characters.`,
208
+ );
209
+ }
210
+
211
+ const owner: DatabaseServerEndpointOwner | null =
212
+ await this.findOwnerByEndpoint(projectId, formatted);
213
+
214
+ if (owner) {
215
+ if (owner.databaseServerId.toString() === databaseServerId.toString()) {
216
+ throw new BadDataException(
217
+ `${formatted} is already an endpoint of this database.`,
218
+ );
219
+ }
220
+
221
+ throw new BadDataException(
222
+ await getOwnedByOtherDatabaseMessage(formatted, owner, createBy.props),
223
+ );
224
+ }
225
+
226
+ data.databaseServerId = databaseServerId;
227
+ data.endpoint = formatted;
228
+ /*
229
+ * Forced, whatever the caller sent: a person only ever adds a removable
230
+ * alias. The primary endpoint is written by whichever path created the
231
+ * database, as root.
232
+ */
233
+ data.source = "user";
234
+ data.isPrimary = false;
235
+
236
+ return { createBy: createBy, carryForward: null };
237
+ }
238
+
239
+ /*
240
+ * A person removing endpoints. Removing one is an EDIT of the database it
241
+ * belongs to, exactly like adding one (onBeforeCreate): it decides which
242
+ * traffic that database's pages show, and frees the endpoint for another
243
+ * database to claim. DatabaseService scopes a delete to the project only -
244
+ * the endpoint has no labels of its own, and the parent's label and Owned
245
+ * scopes never reach a delete - so the caller must be allowed to edit
246
+ * every database the delete would touch, checked here: the delete
247
+ * permission FIRST (so a caller without it learns nothing), then the
248
+ * parents, and only then the primary guard, whose refusal names the
249
+ * endpoint.
250
+ *
251
+ * The primary endpoint is what the database was created from; discovery
252
+ * would claim it straight back, and a manually added database would lose
253
+ * the only endpoint its telemetry is keyed by. Aliases can be removed.
254
+ */
255
+ @CaptureSpan()
256
+ protected override async onBeforeDelete(
257
+ deleteBy: DeleteBy<Model>,
258
+ ): Promise<OnDelete<Model>> {
259
+ if (deleteBy.props.isRoot) {
260
+ return { deleteBy: deleteBy, carryForward: null };
261
+ }
262
+
263
+ // The project the caller was checked in, whatever project the query named.
264
+ const query: Query<Model> =
265
+ await ModelPermission.checkDeleteQueryPermission(
266
+ Model,
267
+ deleteBy.query,
268
+ deleteBy.props,
269
+ );
270
+
271
+ const matched: Array<Model> = await this.findBy({
272
+ query: query,
273
+ select: {
274
+ _id: true,
275
+ projectId: true,
276
+ databaseServerId: true,
277
+ endpoint: true,
278
+ isPrimary: true,
279
+ },
280
+ limit: LIMIT_MAX,
281
+ skip: 0,
282
+ props: {
283
+ isRoot: true,
284
+ },
285
+ });
286
+
287
+ const checked: Set<string> = new Set<string>();
288
+
289
+ for (const endpoint of matched) {
290
+ const databaseServerId: string | undefined =
291
+ endpoint.databaseServerId?.toString();
292
+ const projectId: ObjectID | undefined =
293
+ deleteBy.props.tenantId || endpoint.projectId || undefined;
294
+
295
+ if (!databaseServerId || !projectId || checked.has(databaseServerId)) {
296
+ continue;
297
+ }
298
+
299
+ const databaseServer: DatabaseServer | null =
300
+ await this.findEditableDatabaseServer({
301
+ projectId: projectId,
302
+ databaseServerId: new ObjectID(databaseServerId),
303
+ props: deleteBy.props,
304
+ });
305
+
306
+ // The same answer onBeforeCreate gives: no probing for ids.
307
+ if (!databaseServer) {
308
+ throw new NotAuthorizedException(
309
+ "Database not found, or you do not have permission to edit it. Removing an endpoint from a database needs permission to edit that database.",
310
+ );
311
+ }
312
+
313
+ checked.add(databaseServerId);
314
+ }
315
+
316
+ const primary: Model | undefined = matched.find((endpoint: Model) => {
317
+ return Boolean(endpoint.isPrimary);
318
+ });
319
+
320
+ if (primary) {
321
+ const endpoint: string = primary.endpoint || "The primary endpoint";
322
+
323
+ throw new BadDataException(
324
+ `${endpoint} is the primary endpoint of this database and cannot be removed. Add another endpoint as an alias instead, or delete the database.`,
325
+ );
326
+ }
327
+
328
+ // The rows are gone by onDeleteSuccess: its feed items are built from these.
329
+ const carryForward: EndpointDeleteCarryForward = {
330
+ endpointsToDelete: matched,
331
+ };
332
+
333
+ return { deleteBy: deleteBy, carryForward: carryForward };
334
+ }
335
+
336
+ /*
337
+ * A person added an alias: that is an edit of the database (it decides
338
+ * which traffic the database's pages show), so it goes on the database's
339
+ * Feed like any other edit, naming the endpoint and who added it. A
340
+ * discovery claim is root and never gets here.
341
+ */
342
+ @CaptureSpan()
343
+ protected override async onCreateSuccess(
344
+ onCreate: OnCreate<Model>,
345
+ createdItem: Model,
346
+ ): Promise<Model> {
347
+ if (onCreate.createBy.props.isRoot) {
348
+ return createdItem;
349
+ }
350
+
351
+ await this.writeEndpointFeedItem({
352
+ change: "added",
353
+ endpoint: createdItem,
354
+ projectId:
355
+ createdItem.projectId || onCreate.createBy.props.tenantId || undefined,
356
+ userId:
357
+ createdItem.createdByUserId ||
358
+ onCreate.createBy.props.userId ||
359
+ undefined,
360
+ });
361
+
362
+ return createdItem;
363
+ }
364
+
365
+ /*
366
+ * A person removed aliases: one feed item per endpoint actually removed,
367
+ * on its own database. Discovery's releases and moves are root writes and
368
+ * never get here.
369
+ */
370
+ @CaptureSpan()
371
+ protected override async onDeleteSuccess(
372
+ onDelete: OnDelete<Model>,
373
+ itemIdsBeforeDelete: Array<ObjectID>,
374
+ ): Promise<OnDelete<Model>> {
375
+ const carried: EndpointDeleteCarryForward | null =
376
+ (onDelete.carryForward as EndpointDeleteCarryForward | null) || null;
377
+
378
+ if (onDelete.deleteBy.props.isRoot || !carried) {
379
+ return onDelete;
380
+ }
381
+
382
+ const deletedIds: Set<string> = new Set<string>(
383
+ (itemIdsBeforeDelete || []).map((id: ObjectID): string => {
384
+ return id.toString();
385
+ }),
386
+ );
387
+
388
+ const userId: ObjectID | undefined =
389
+ onDelete.deleteBy.deletedByUser?.id ||
390
+ onDelete.deleteBy.props.userId ||
391
+ undefined;
392
+
393
+ for (const endpoint of carried.endpointsToDelete || []) {
394
+ if (!endpoint._id || !deletedIds.has(endpoint._id.toString())) {
395
+ continue;
396
+ }
397
+
398
+ await this.writeEndpointFeedItem({
399
+ change: "removed",
400
+ endpoint: endpoint,
401
+ projectId:
402
+ endpoint.projectId || onDelete.deleteBy.props.tenantId || undefined,
403
+ userId: userId,
404
+ });
405
+ }
406
+
407
+ return onDelete;
408
+ }
409
+
410
+ // One "endpoint added / removed" item on the database's Feed. Never throws.
411
+ private async writeEndpointFeedItem(data: {
412
+ change: "added" | "removed";
413
+ endpoint: Model;
414
+ projectId: ObjectID | undefined;
415
+ userId: ObjectID | undefined;
416
+ }): Promise<void> {
417
+ const databaseServerId: ObjectID | undefined =
418
+ data.endpoint.databaseServerId || undefined;
419
+ const endpoint: string = (data.endpoint.endpoint || "").trim();
420
+
421
+ if (!databaseServerId || !data.projectId || !endpoint) {
422
+ return;
423
+ }
424
+
425
+ try {
426
+ const link: string =
427
+ await DatabaseServerService.getDatabaseServerMarkdownLink(
428
+ data.projectId,
429
+ databaseServerId,
430
+ );
431
+ const added: boolean = data.change === "added";
432
+
433
+ await DatabaseServerFeedService.createDatabaseServerFeedItem({
434
+ databaseServerId: databaseServerId,
435
+ projectId: data.projectId,
436
+ databaseServerFeedEventType:
437
+ DatabaseServerFeedEventType.DatabaseServerUpdated,
438
+ displayColor: added ? Gray500 : Red500,
439
+ feedInfoInMarkdown: added
440
+ ? `🔗 Added the endpoint \`${endpoint}\` to ${link}.`
441
+ : `🔗 Removed the endpoint \`${endpoint}\` from ${link}.`,
442
+ moreInformationInMarkdown: added
443
+ ? `**Endpoint**: \`${endpoint}\`\n\nCalls applications make to this endpoint now count as this database's traffic, and no other database can claim it.`
444
+ : `**Endpoint**: \`${endpoint}\`\n\nCalls to this endpoint no longer count as this database's traffic, and another database may claim it.`,
445
+ userId: data.userId,
446
+ });
447
+ } catch (error) {
448
+ logger.warn(
449
+ `DatabaseServerEndpointService: could not write the feed item for endpoint ${endpoint} ${data.change}: ${
450
+ error instanceof Error ? error.message : String(error)
451
+ }`,
452
+ );
453
+ }
454
+ }
455
+
456
+ /**
457
+ * The database that owns this canonical (formatDatabaseEndpoint) endpoint
458
+ * in the project, or null when no database lists it.
459
+ */
460
+ @CaptureSpan()
461
+ public async findOwnerByEndpoint(
462
+ projectId: ObjectID,
463
+ formattedEndpoint: string,
464
+ ): Promise<DatabaseServerEndpointOwner | null> {
465
+ const endpoint: string = (formattedEndpoint || "").trim();
466
+
467
+ if (!endpoint) {
468
+ return null;
469
+ }
470
+
471
+ const row: Model | null = await this.findOneBy({
472
+ query: {
473
+ projectId: projectId,
474
+ endpoint: endpoint,
475
+ },
476
+ select: {
477
+ _id: true,
478
+ databaseServerId: true,
479
+ isPrimary: true,
480
+ source: true,
481
+ lastMatchedAt: true,
482
+ },
483
+ props: {
484
+ isRoot: true,
485
+ },
486
+ });
487
+
488
+ if (!row || !row.databaseServerId) {
489
+ return null;
490
+ }
491
+
492
+ return {
493
+ databaseServerId: new ObjectID(row.databaseServerId.toString()),
494
+ isPrimary: Boolean(row.isPrimary),
495
+ endpointId: row._id ? new ObjectID(row._id.toString()) : undefined,
496
+ source: row.source || undefined,
497
+ lastMatchedAt: row.lastMatchedAt || undefined,
498
+ };
499
+ }
500
+
501
+ /**
502
+ * Record that telemetry just matched this endpoint to its database: moves
503
+ * lastMatchedAt to now, at most once per ENDPOINT_MATCH_REFRESH_SECONDS
504
+ * (decided from the lastMatchedAt the owner lookup already read, so a
505
+ * fresh endpoint costs nothing). A "workload" endpoint is left alone: its
506
+ * lastMatchedAt says when the workload last produced it, which is what
507
+ * decides whether discovery may release it. Never throws.
508
+ */
509
+ @CaptureSpan()
510
+ public async markEndpointMatched(
511
+ owner: DatabaseServerEndpointOwner | null,
512
+ ): Promise<void> {
513
+ if (!owner || !owner.endpointId || owner.source === "workload") {
514
+ return;
515
+ }
516
+
517
+ const now: Date = OneUptimeDate.getCurrentDate();
518
+
519
+ if (
520
+ owner.lastMatchedAt &&
521
+ OneUptimeDate.isAfter(
522
+ owner.lastMatchedAt,
523
+ OneUptimeDate.addRemoveSeconds(now, -ENDPOINT_MATCH_REFRESH_SECONDS),
524
+ )
525
+ ) {
526
+ return;
527
+ }
528
+
529
+ try {
530
+ await this.updateColumnsByIdWithoutHooks({
531
+ id: owner.endpointId,
532
+ data: {
533
+ lastMatchedAt: now,
534
+ },
535
+ skipUpdateDateColumn: true,
536
+ });
537
+ owner.lastMatchedAt = now;
538
+ } catch (error) {
539
+ logger.warn(
540
+ `DatabaseServerEndpointService: could not record a match of endpoint ${owner.endpointId.toString()}: ${
541
+ error instanceof Error ? error.message : String(error)
542
+ }`,
543
+ );
544
+ }
545
+ }
546
+
547
+ /**
548
+ * Move lastMatchedAt to `now` on those of `endpoints` this database owns
549
+ * whose lastMatchedAt is empty or older than `staleBefore` - one
550
+ * statement, however many endpoints. The workload path calls it for the
551
+ * aliases a discovery run produced again.
552
+ */
553
+ @CaptureSpan()
554
+ public async refreshMatchedEndpoints(data: {
555
+ projectId: ObjectID;
556
+ databaseServerId: ObjectID;
557
+ endpoints: Array<string>;
558
+ now: Date;
559
+ staleBefore: Date;
560
+ }): Promise<void> {
561
+ if (data.endpoints.length === 0) {
562
+ return;
563
+ }
564
+
565
+ await this.getRepository().manager.query(
566
+ `UPDATE "DatabaseServerEndpoint"
567
+ SET "lastMatchedAt" = $1
568
+ WHERE "projectId" = $2
569
+ AND "databaseServerId" = $3
570
+ AND "endpoint" = ANY($4::text[])
571
+ AND ("lastMatchedAt" IS NULL OR "lastMatchedAt" < $5)
572
+ AND "deletedAt" IS NULL`,
573
+ [
574
+ data.now,
575
+ data.projectId.toString(),
576
+ data.databaseServerId.toString(),
577
+ data.endpoints,
578
+ data.staleBefore,
579
+ ],
580
+ );
581
+ }
582
+
583
+ /**
584
+ * Hand a discovered endpoint to another database: the workload that now
585
+ * serves it. A compare-and-set on the current owner, and never a "user"
586
+ * endpoint - those only a person moves. The endpoint becomes a "workload"
587
+ * endpoint of its new owner, matched now. True when it moved.
588
+ */
589
+ @CaptureSpan()
590
+ public async transferEndpoint(data: {
591
+ projectId: ObjectID;
592
+ endpointId: ObjectID;
593
+ fromDatabaseServerId: ObjectID;
594
+ toDatabaseServerId: ObjectID;
595
+ isPrimary: boolean;
596
+ now: Date;
597
+ }): Promise<boolean> {
598
+ /*
599
+ * Wrapped in a CTE so the statement is a SELECT: TypeORM answers a bare
600
+ * UPDATE with [rows, rowCount], which would read as "moved" every time.
601
+ */
602
+ const moved: unknown = await this.getRepository().manager.query(
603
+ `WITH "moved" AS (
604
+ UPDATE "DatabaseServerEndpoint"
605
+ SET "databaseServerId" = $1,
606
+ "source" = 'workload',
607
+ "isPrimary" = $2,
608
+ "lastMatchedAt" = $3,
609
+ "updatedAt" = CURRENT_TIMESTAMP
610
+ WHERE "_id" = $4
611
+ AND "projectId" = $5
612
+ AND "databaseServerId" = $6
613
+ AND COALESCE("source", '') <> 'user'
614
+ AND "deletedAt" IS NULL
615
+ RETURNING "_id"
616
+ )
617
+ SELECT "_id" FROM "moved"`,
618
+ [
619
+ data.toDatabaseServerId.toString(),
620
+ data.isPrimary,
621
+ data.now,
622
+ data.endpointId.toString(),
623
+ data.projectId.toString(),
624
+ data.fromDatabaseServerId.toString(),
625
+ ],
626
+ );
627
+
628
+ return Array.isArray(moved) && moved.length > 0;
629
+ }
630
+
631
+ /**
632
+ * Release the "workload" endpoints of one database that its workload no
633
+ * longer produces: not in `keepEndpoints` and not matched since
634
+ * `staleBefore` (so one partial discovery run releases nothing). Never the
635
+ * primary endpoint, never an "auto" or "user" one. Returns the endpoints
636
+ * released.
637
+ */
638
+ @CaptureSpan()
639
+ public async releaseUnproducedWorkloadEndpoints(data: {
640
+ projectId: ObjectID;
641
+ databaseServerId: ObjectID;
642
+ keepEndpoints: Array<string>;
643
+ staleBefore: Date;
644
+ }): Promise<Array<string>> {
645
+ // A CTE for the same reason as transferEndpoint: a SELECT's rows come back.
646
+ const released: unknown = await this.getRepository().manager.query(
647
+ `WITH "released" AS (
648
+ DELETE FROM "DatabaseServerEndpoint"
649
+ WHERE "projectId" = $1
650
+ AND "databaseServerId" = $2
651
+ AND "source" = 'workload'
652
+ AND "isPrimary" = false
653
+ AND NOT ("endpoint" = ANY($3::text[]))
654
+ AND ("lastMatchedAt" IS NULL OR "lastMatchedAt" < $4)
655
+ RETURNING "endpoint"
656
+ )
657
+ SELECT "endpoint" FROM "released"`,
658
+ [
659
+ data.projectId.toString(),
660
+ data.databaseServerId.toString(),
661
+ data.keepEndpoints,
662
+ data.staleBefore,
663
+ ],
664
+ );
665
+
666
+ if (!Array.isArray(released)) {
667
+ return [];
668
+ }
669
+
670
+ return released
671
+ .map((row: unknown): string => {
672
+ const endpoint: unknown = (row as { endpoint?: unknown })?.endpoint;
673
+ return typeof endpoint === "string" ? endpoint : "";
674
+ })
675
+ .filter((endpoint: string): boolean => {
676
+ return endpoint.length > 0;
677
+ });
678
+ }
679
+
680
+ // True when the database has a primary endpoint.
681
+ @CaptureSpan()
682
+ public async hasPrimaryEndpoint(data: {
683
+ projectId: ObjectID;
684
+ databaseServerId: ObjectID;
685
+ }): Promise<boolean> {
686
+ const primary: Model | null = await this.findOneBy({
687
+ query: {
688
+ projectId: data.projectId,
689
+ databaseServerId: data.databaseServerId,
690
+ isPrimary: true,
691
+ },
692
+ select: {
693
+ _id: true,
694
+ },
695
+ props: {
696
+ isRoot: true,
697
+ },
698
+ });
699
+
700
+ return Boolean(primary);
701
+ }
702
+
703
+ /**
704
+ * Make a canonical endpoint this database's, as root. Never takes an
705
+ * endpoint away from another database: that answers "owned-by-other" and
706
+ * the caller decides what to do (discovery logs and skips it).
707
+ *
708
+ * Two discovery writers can race to claim the same endpoint. The unique
709
+ * index lets exactly one insert through; the loser re-reads the owner and
710
+ * reports the winner rather than throwing.
711
+ */
712
+ @CaptureSpan()
713
+ public async claimEndpoint(data: {
714
+ projectId: ObjectID;
715
+ databaseServerId: ObjectID;
716
+ endpoint: string;
717
+ isPrimary: boolean;
718
+ source: DatabaseServerEndpointSource;
719
+ }): Promise<DatabaseServerEndpointClaimResult> {
720
+ const endpoint: string = (data.endpoint || "").trim();
721
+
722
+ if (!endpoint) {
723
+ throw new BadDataException("Endpoint is required to claim it.");
724
+ }
725
+
726
+ const existingOwner: DatabaseServerEndpointOwner | null =
727
+ await this.findOwnerByEndpoint(data.projectId, endpoint);
728
+
729
+ if (existingOwner) {
730
+ const result: DatabaseServerEndpointClaimResult = classifyOwner(
731
+ existingOwner,
732
+ data.databaseServerId,
733
+ );
734
+
735
+ // Re-reported by the database that owns it: that is a match.
736
+ if (result === "already-owned-by-this") {
737
+ await this.markEndpointMatched(existingOwner);
738
+ }
739
+
740
+ return result;
741
+ }
742
+
743
+ try {
744
+ const row: Model = new Model();
745
+ row.projectId = data.projectId;
746
+ row.databaseServerId = data.databaseServerId;
747
+ row.endpoint = endpoint;
748
+ row.isPrimary = data.isPrimary;
749
+ row.source = data.source;
750
+ row.lastMatchedAt = OneUptimeDate.getCurrentDate();
751
+
752
+ await this.create({
753
+ data: row,
754
+ props: {
755
+ isRoot: true,
756
+ },
757
+ });
758
+
759
+ return "claimed";
760
+ } catch (error) {
761
+ const racedOwner: DatabaseServerEndpointOwner | null =
762
+ await this.findOwnerByEndpoint(data.projectId, endpoint);
763
+
764
+ if (racedOwner) {
765
+ return classifyOwner(racedOwner, data.databaseServerId);
766
+ }
767
+
768
+ // Not a lost race (a foreign key, a dead connection): surface it.
769
+ throw error;
770
+ }
771
+ }
772
+
773
+ /**
774
+ * Every endpoint of one database, primary first then alphabetical - the
775
+ * input getDatabaseServerSignalEntityKeys turns into the database's
776
+ * telemetry key set.
777
+ */
778
+ @CaptureSpan()
779
+ public async listEndpoints(
780
+ databaseServerId: ObjectID,
781
+ ): Promise<Array<string>> {
782
+ const rows: Array<Model> = await this.findBy({
783
+ query: {
784
+ databaseServerId: databaseServerId,
785
+ },
786
+ select: {
787
+ _id: true,
788
+ endpoint: true,
789
+ isPrimary: true,
790
+ },
791
+ sort: {
792
+ isPrimary: SortOrder.Descending,
793
+ endpoint: SortOrder.Ascending,
794
+ },
795
+ limit: LIMIT_MAX,
796
+ skip: 0,
797
+ props: {
798
+ isRoot: true,
799
+ },
800
+ });
801
+
802
+ const endpoints: Array<string> = [];
803
+
804
+ for (const row of rows) {
805
+ if (row.endpoint && !endpoints.includes(row.endpoint)) {
806
+ endpoints.push(row.endpoint);
807
+ }
808
+ }
809
+
810
+ return endpoints;
811
+ }
812
+
813
+ /**
814
+ * The database a caller adds an endpoint to, read only if the caller may
815
+ * EDIT it: the update permission check scopes the lookup exactly the way
816
+ * an update of that row would be scoped (project, label-scoped and
817
+ * Owned-scoped grants, block permissions). Null when the row does not
818
+ * exist in the project or the caller may not edit it - deliberately the
819
+ * same answer.
820
+ */
821
+ @CaptureSpan()
822
+ public async findEditableDatabaseServer(data: {
823
+ projectId: ObjectID;
824
+ databaseServerId: ObjectID;
825
+ props: DatabaseCommonInteractionProps;
826
+ }): Promise<DatabaseServer | null> {
827
+ const editableQuery: Query<DatabaseServer> =
828
+ await ModelPermission.checkUpdateQueryPermissions(
829
+ DatabaseServer,
830
+ {
831
+ _id: data.databaseServerId.toString(),
832
+ projectId: data.projectId,
833
+ },
834
+ {},
835
+ data.props,
836
+ );
837
+
838
+ return await DatabaseServerService.findOneBy({
839
+ query: editableQuery,
840
+ select: {
841
+ _id: true,
842
+ dbSystem: true,
843
+ kubernetesNamespace: true,
844
+ kubernetesCluster: {
845
+ clusterIdentifier: true,
846
+ },
847
+ },
848
+ props: {
849
+ isRoot: true,
850
+ },
851
+ });
852
+ }
853
+ }
854
+
855
+ function classifyOwner(
856
+ owner: DatabaseServerEndpointOwner,
857
+ databaseServerId: ObjectID,
858
+ ): DatabaseServerEndpointClaimResult {
859
+ return owner.databaseServerId.toString() === databaseServerId.toString()
860
+ ? "already-owned-by-this"
861
+ : "owned-by-other";
862
+ }
863
+
864
+ /*
865
+ * "orders-db.example.com:5432 already belongs to the database "PostgreSQL
866
+ * orders-db.example.com:5432"" - naming the owner is the only way a person can
867
+ * find and fix the conflict. But only a database the caller can READ is
868
+ * named: with label- or Owned-scoped permissions the owner may be a row they
869
+ * are not allowed to see, and then it is just "another database". Without
870
+ * props (a root path) the name is read as root.
871
+ */
872
+ export async function getOwnedByOtherDatabaseMessage(
873
+ formattedEndpoint: string,
874
+ owner: DatabaseServerEndpointOwner,
875
+ props?: DatabaseCommonInteractionProps | undefined,
876
+ ): Promise<string> {
877
+ let ownerName: string = "";
878
+
879
+ try {
880
+ ownerName = await DatabaseServerService.getDatabaseServerNameIfReadable({
881
+ databaseServerId: owner.databaseServerId,
882
+ props: props,
883
+ });
884
+ } catch {
885
+ // The name only decorates the message; the refusal stands without it.
886
+ }
887
+
888
+ const ownerLabel: string = ownerName
889
+ ? `the database "${ownerName}"`
890
+ : "another database";
891
+
892
+ return `${formattedEndpoint} already belongs to ${ownerLabel}. An endpoint can belong to only one database in a project - remove it from that database first.`;
893
+ }
894
+
895
+ export default new Service();