@oneuptime/common 11.0.1 → 11.0.2

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 (341) hide show
  1. package/Models/DatabaseModels/Alert.ts +110 -0
  2. package/Models/DatabaseModels/CephCluster.ts +964 -0
  3. package/Models/DatabaseModels/CephClusterLabelRule.ts +514 -0
  4. package/Models/DatabaseModels/CephClusterOwnerRule.ts +596 -0
  5. package/Models/DatabaseModels/CephClusterOwnerTeam.ts +487 -0
  6. package/Models/DatabaseModels/CephClusterOwnerUser.ts +486 -0
  7. package/Models/DatabaseModels/CephResource.ts +809 -0
  8. package/Models/DatabaseModels/Host.ts +64 -0
  9. package/Models/DatabaseModels/Incident.ts +110 -0
  10. package/Models/DatabaseModels/Index.ts +24 -0
  11. package/Models/DatabaseModels/ProxmoxCluster.ts +943 -0
  12. package/Models/DatabaseModels/ProxmoxClusterLabelRule.ts +514 -0
  13. package/Models/DatabaseModels/ProxmoxClusterOwnerRule.ts +596 -0
  14. package/Models/DatabaseModels/ProxmoxClusterOwnerTeam.ts +487 -0
  15. package/Models/DatabaseModels/ProxmoxClusterOwnerUser.ts +486 -0
  16. package/Models/DatabaseModels/ProxmoxResource.ts +726 -0
  17. package/Models/DatabaseModels/ScheduledMaintenance.ts +110 -0
  18. package/Server/API/BillingInvoiceAPI.ts +47 -7
  19. package/Server/API/CephResourceAPI.ts +134 -0
  20. package/Server/API/DashboardAPI.ts +46 -0
  21. package/Server/API/ProjectAPI.ts +15 -0
  22. package/Server/API/ProxmoxResourceAPI.ts +132 -0
  23. package/Server/API/ResellerPlanAPI.ts +17 -0
  24. package/Server/Infrastructure/GlobalCache.ts +8 -2
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1781500000000-AddProxmoxAndCephClusterTables.ts +163 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1781600000000-AddProxmoxCephV2Columns.ts +211 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1781600000001-AddProxmoxCephActivityAndRules.ts +590 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1781700000000-AddProxmoxCephV3Columns.ts +64 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  30. package/Server/Infrastructure/Redis.ts +40 -12
  31. package/Server/Services/AnalyticsDatabaseService.ts +1 -1
  32. package/Server/Services/BillingService.ts +109 -21
  33. package/Server/Services/CephClusterLabelRuleEngineService.ts +200 -0
  34. package/Server/Services/CephClusterLabelRuleService.ts +14 -0
  35. package/Server/Services/CephClusterOwnerRuleEngineService.ts +218 -0
  36. package/Server/Services/CephClusterOwnerRuleService.ts +14 -0
  37. package/Server/Services/CephClusterOwnerTeamService.ts +10 -0
  38. package/Server/Services/CephClusterOwnerUserService.ts +10 -0
  39. package/Server/Services/CephClusterService.ts +401 -0
  40. package/Server/Services/CephResourceService.ts +383 -0
  41. package/Server/Services/CloudResourceService.ts +11 -3
  42. package/Server/Services/DockerHostService.ts +11 -3
  43. package/Server/Services/ExceptionAggregationService.ts +2 -0
  44. package/Server/Services/HostService.ts +11 -3
  45. package/Server/Services/Index.ts +24 -0
  46. package/Server/Services/KubernetesClusterService.ts +11 -3
  47. package/Server/Services/LogAggregationService.ts +2 -0
  48. package/Server/Services/MetricAggregationService.ts +2 -0
  49. package/Server/Services/OpenTelemetryIngestService.ts +36 -0
  50. package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +204 -0
  51. package/Server/Services/ProxmoxClusterLabelRuleService.ts +14 -0
  52. package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +222 -0
  53. package/Server/Services/ProxmoxClusterOwnerRuleService.ts +14 -0
  54. package/Server/Services/ProxmoxClusterOwnerTeamService.ts +10 -0
  55. package/Server/Services/ProxmoxClusterOwnerUserService.ts +10 -0
  56. package/Server/Services/ProxmoxClusterService.ts +382 -0
  57. package/Server/Services/ProxmoxResourceService.ts +404 -0
  58. package/Server/Services/RumApplicationService.ts +11 -3
  59. package/Server/Services/ServerlessFunctionService.ts +11 -3
  60. package/Server/Services/TelemetryUsageBillingService.ts +41 -3
  61. package/Server/Services/TraceAggregationService.ts +2 -0
  62. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +8 -23
  63. package/Server/Utils/Monitor/MonitorAlert.ts +45 -0
  64. package/Server/Utils/Monitor/MonitorClusterContext.ts +129 -0
  65. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +344 -4
  66. package/Server/Utils/Monitor/MonitorIncident.ts +130 -7
  67. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +39 -6
  68. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +3 -1
  69. package/Server/Utils/Monitor/SeriesResourceLabels.ts +33 -0
  70. package/Server/Utils/Profiling.ts +37 -2
  71. package/Server/Utils/Telemetry/EntityRegistry.ts +4 -0
  72. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +1096 -0
  73. package/Server/Utils/Telemetry/TelemetryEntity.ts +85 -0
  74. package/Server/Utils/Telemetry.ts +8 -19
  75. package/Tests/Server/API/BillingInvoiceAPI.test.ts +194 -0
  76. package/Tests/Server/API/ProjectAPI.test.ts +91 -0
  77. package/Tests/Server/API/ResellerPlanAPI.test.ts +207 -0
  78. package/Tests/Server/Infrastructure/GlobalCache.test.ts +100 -0
  79. package/Tests/Server/Services/BillingService.test.ts +323 -0
  80. package/Tests/Server/Services/CephResourceService.test.ts +264 -0
  81. package/Tests/Server/Services/ProxmoxResourceService.test.ts +326 -0
  82. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +322 -0
  83. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +13 -0
  84. package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +879 -0
  85. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +196 -0
  86. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +1231 -0
  87. package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +732 -0
  88. package/Tests/Utils/Telemetry/EntityRelationship.test.ts +49 -0
  89. package/Tests/Utils/Telemetry/HeartbeatAvailability.test.ts +423 -0
  90. package/Types/BaseDatabase/AggregationIntervalUtil.ts +74 -0
  91. package/Types/Dashboard/DashboardComponentType.ts +4 -0
  92. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +2 -0
  93. package/Types/Dashboard/DashboardComponents/DashboardCephOsdListComponent.ts +15 -0
  94. package/Types/Dashboard/DashboardComponents/DashboardCephPoolListComponent.ts +14 -0
  95. package/Types/Dashboard/DashboardComponents/DashboardProxmoxGuestListComponent.ts +17 -0
  96. package/Types/Dashboard/DashboardComponents/DashboardProxmoxNodeListComponent.ts +16 -0
  97. package/Types/Dashboard/DashboardTemplates.ts +446 -0
  98. package/Types/Icon/IconProp.ts +2 -0
  99. package/Types/Monitor/CephAlertTemplates.ts +1647 -0
  100. package/Types/Monitor/CephMetricCatalog.ts +409 -0
  101. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +44 -0
  102. package/Types/Monitor/MonitorStep.ts +64 -0
  103. package/Types/Monitor/MonitorStepCephMonitor.ts +57 -0
  104. package/Types/Monitor/MonitorStepProxmoxMonitor.ts +81 -0
  105. package/Types/Monitor/MonitorType.ts +29 -1
  106. package/Types/Monitor/ProxmoxAlertTemplates.ts +899 -0
  107. package/Types/Monitor/ProxmoxMetricCatalog.ts +382 -0
  108. package/Types/Permission.ts +464 -0
  109. package/Types/Telemetry/EntityType.ts +11 -0
  110. package/Types/Telemetry/ServiceType.ts +2 -0
  111. package/UI/Components/Icon/Icon.tsx +84 -0
  112. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +9 -5
  113. package/UI/Utils/Telemetry/Telemetry.ts +16 -21
  114. package/UI/Utils/TelemetryService.ts +7 -3
  115. package/Utils/Dashboard/Components/DashboardCephOsdListComponent.ts +63 -0
  116. package/Utils/Dashboard/Components/DashboardCephPoolListComponent.ts +32 -0
  117. package/Utils/Dashboard/Components/DashboardCephResourceListShared.ts +61 -0
  118. package/Utils/Dashboard/Components/DashboardProxmoxGuestListComponent.ts +69 -0
  119. package/Utils/Dashboard/Components/DashboardProxmoxNodeListComponent.ts +55 -0
  120. package/Utils/Dashboard/Components/DashboardProxmoxResourceListShared.ts +61 -0
  121. package/Utils/Dashboard/Components/Index.ts +28 -0
  122. package/Utils/Telemetry/EntityKey.ts +35 -0
  123. package/Utils/Telemetry/EntityRelationship.ts +6 -0
  124. package/Utils/Telemetry/HeartbeatAvailability.ts +262 -0
  125. package/build/dist/Models/DatabaseModels/Alert.js +108 -0
  126. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  127. package/build/dist/Models/DatabaseModels/CephCluster.js +992 -0
  128. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -0
  129. package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js +522 -0
  130. package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js.map +1 -0
  131. package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js +603 -0
  132. package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js.map +1 -0
  133. package/build/dist/Models/DatabaseModels/CephClusterOwnerTeam.js +503 -0
  134. package/build/dist/Models/DatabaseModels/CephClusterOwnerTeam.js.map +1 -0
  135. package/build/dist/Models/DatabaseModels/CephClusterOwnerUser.js +502 -0
  136. package/build/dist/Models/DatabaseModels/CephClusterOwnerUser.js.map +1 -0
  137. package/build/dist/Models/DatabaseModels/CephResource.js +846 -0
  138. package/build/dist/Models/DatabaseModels/CephResource.js.map +1 -0
  139. package/build/dist/Models/DatabaseModels/Host.js +63 -0
  140. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  141. package/build/dist/Models/DatabaseModels/Incident.js +108 -0
  142. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  143. package/build/dist/Models/DatabaseModels/Index.js +24 -0
  144. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  145. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +967 -0
  146. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -0
  147. package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js +522 -0
  148. package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js.map +1 -0
  149. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js +603 -0
  150. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js.map +1 -0
  151. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerTeam.js +503 -0
  152. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerTeam.js.map +1 -0
  153. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerUser.js +502 -0
  154. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerUser.js.map +1 -0
  155. package/build/dist/Models/DatabaseModels/ProxmoxResource.js +761 -0
  156. package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -0
  157. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +108 -0
  158. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  159. package/build/dist/Server/API/BillingInvoiceAPI.js +35 -5
  160. package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
  161. package/build/dist/Server/API/CephResourceAPI.js +98 -0
  162. package/build/dist/Server/API/CephResourceAPI.js.map +1 -0
  163. package/build/dist/Server/API/DashboardAPI.js +46 -0
  164. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  165. package/build/dist/Server/API/ProjectAPI.js +11 -0
  166. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  167. package/build/dist/Server/API/ProxmoxResourceAPI.js +95 -0
  168. package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -0
  169. package/build/dist/Server/API/ResellerPlanAPI.js +17 -3
  170. package/build/dist/Server/API/ResellerPlanAPI.js.map +1 -1
  171. package/build/dist/Server/Infrastructure/GlobalCache.js +7 -2
  172. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  173. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781500000000-AddProxmoxAndCephClusterTables.js +76 -0
  174. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781500000000-AddProxmoxAndCephClusterTables.js.map +1 -0
  175. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781600000000-AddProxmoxCephV2Columns.js +108 -0
  176. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781600000000-AddProxmoxCephV2Columns.js.map +1 -0
  177. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781600000001-AddProxmoxCephActivityAndRules.js +253 -0
  178. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781600000001-AddProxmoxCephActivityAndRules.js.map +1 -0
  179. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781700000000-AddProxmoxCephV3Columns.js +43 -0
  180. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781700000000-AddProxmoxCephV3Columns.js.map +1 -0
  181. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  182. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  183. package/build/dist/Server/Infrastructure/Redis.js +31 -8
  184. package/build/dist/Server/Infrastructure/Redis.js.map +1 -1
  185. package/build/dist/Server/Services/AnalyticsDatabaseService.js +1 -1
  186. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  187. package/build/dist/Server/Services/BillingService.js +85 -23
  188. package/build/dist/Server/Services/BillingService.js.map +1 -1
  189. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +166 -0
  190. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -0
  191. package/build/dist/Server/Services/CephClusterLabelRuleService.js +13 -0
  192. package/build/dist/Server/Services/CephClusterLabelRuleService.js.map +1 -0
  193. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +186 -0
  194. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -0
  195. package/build/dist/Server/Services/CephClusterOwnerRuleService.js +13 -0
  196. package/build/dist/Server/Services/CephClusterOwnerRuleService.js.map +1 -0
  197. package/build/dist/Server/Services/CephClusterOwnerTeamService.js +9 -0
  198. package/build/dist/Server/Services/CephClusterOwnerTeamService.js.map +1 -0
  199. package/build/dist/Server/Services/CephClusterOwnerUserService.js +9 -0
  200. package/build/dist/Server/Services/CephClusterOwnerUserService.js.map +1 -0
  201. package/build/dist/Server/Services/CephClusterService.js +353 -0
  202. package/build/dist/Server/Services/CephClusterService.js.map +1 -0
  203. package/build/dist/Server/Services/CephResourceService.js +257 -0
  204. package/build/dist/Server/Services/CephResourceService.js.map +1 -0
  205. package/build/dist/Server/Services/CloudResourceService.js +10 -2
  206. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  207. package/build/dist/Server/Services/DockerHostService.js +10 -2
  208. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  209. package/build/dist/Server/Services/ExceptionAggregationService.js +2 -0
  210. package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
  211. package/build/dist/Server/Services/HostService.js +10 -2
  212. package/build/dist/Server/Services/HostService.js.map +1 -1
  213. package/build/dist/Server/Services/Index.js +24 -0
  214. package/build/dist/Server/Services/Index.js.map +1 -1
  215. package/build/dist/Server/Services/KubernetesClusterService.js +10 -2
  216. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  217. package/build/dist/Server/Services/LogAggregationService.js +2 -0
  218. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  219. package/build/dist/Server/Services/MetricAggregationService.js +2 -0
  220. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  221. package/build/dist/Server/Services/OpenTelemetryIngestService.js +37 -7
  222. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  223. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +166 -0
  224. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -0
  225. package/build/dist/Server/Services/ProxmoxClusterLabelRuleService.js +13 -0
  226. package/build/dist/Server/Services/ProxmoxClusterLabelRuleService.js.map +1 -0
  227. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +186 -0
  228. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -0
  229. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleService.js +13 -0
  230. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleService.js.map +1 -0
  231. package/build/dist/Server/Services/ProxmoxClusterOwnerTeamService.js +9 -0
  232. package/build/dist/Server/Services/ProxmoxClusterOwnerTeamService.js.map +1 -0
  233. package/build/dist/Server/Services/ProxmoxClusterOwnerUserService.js +9 -0
  234. package/build/dist/Server/Services/ProxmoxClusterOwnerUserService.js.map +1 -0
  235. package/build/dist/Server/Services/ProxmoxClusterService.js +337 -0
  236. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -0
  237. package/build/dist/Server/Services/ProxmoxResourceService.js +285 -0
  238. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -0
  239. package/build/dist/Server/Services/RumApplicationService.js +10 -2
  240. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  241. package/build/dist/Server/Services/ServerlessFunctionService.js +10 -2
  242. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  243. package/build/dist/Server/Services/TelemetryUsageBillingService.js +30 -3
  244. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  245. package/build/dist/Server/Services/TraceAggregationService.js +2 -0
  246. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  247. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +8 -25
  248. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  249. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +36 -0
  250. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  251. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +90 -0
  252. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +1 -0
  253. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +228 -4
  254. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  255. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +103 -8
  256. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  257. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +23 -6
  258. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  259. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +3 -1
  260. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  261. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +23 -0
  262. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  263. package/build/dist/Server/Utils/Profiling.js +24 -3
  264. package/build/dist/Server/Utils/Profiling.js.map +1 -1
  265. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +4 -0
  266. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  267. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +854 -0
  268. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -0
  269. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +62 -0
  270. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  271. package/build/dist/Server/Utils/Telemetry.js +8 -10
  272. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  273. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +69 -0
  274. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -0
  275. package/build/dist/Types/Dashboard/DashboardComponentType.js +4 -0
  276. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  277. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +2 -0
  278. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  279. package/build/dist/Types/Dashboard/DashboardComponents/DashboardCephOsdListComponent.js +2 -0
  280. package/build/dist/Types/Dashboard/DashboardComponents/DashboardCephOsdListComponent.js.map +1 -0
  281. package/build/dist/Types/Dashboard/DashboardComponents/DashboardCephPoolListComponent.js +2 -0
  282. package/build/dist/Types/Dashboard/DashboardComponents/DashboardCephPoolListComponent.js.map +1 -0
  283. package/build/dist/Types/Dashboard/DashboardComponents/DashboardProxmoxGuestListComponent.js +2 -0
  284. package/build/dist/Types/Dashboard/DashboardComponents/DashboardProxmoxGuestListComponent.js.map +1 -0
  285. package/build/dist/Types/Dashboard/DashboardComponents/DashboardProxmoxNodeListComponent.js +2 -0
  286. package/build/dist/Types/Dashboard/DashboardComponents/DashboardProxmoxNodeListComponent.js.map +1 -0
  287. package/build/dist/Types/Dashboard/DashboardTemplates.js +394 -0
  288. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  289. package/build/dist/Types/Icon/IconProp.js +2 -0
  290. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  291. package/build/dist/Types/Monitor/CephAlertTemplates.js +1379 -0
  292. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -0
  293. package/build/dist/Types/Monitor/CephMetricCatalog.js +353 -0
  294. package/build/dist/Types/Monitor/CephMetricCatalog.js.map +1 -0
  295. package/build/dist/Types/Monitor/MonitorStep.js +46 -0
  296. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  297. package/build/dist/Types/Monitor/MonitorStepCephMonitor.js +34 -0
  298. package/build/dist/Types/Monitor/MonitorStepCephMonitor.js.map +1 -0
  299. package/build/dist/Types/Monitor/MonitorStepProxmoxMonitor.js +36 -0
  300. package/build/dist/Types/Monitor/MonitorStepProxmoxMonitor.js.map +1 -0
  301. package/build/dist/Types/Monitor/MonitorType.js +27 -1
  302. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  303. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +743 -0
  304. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -0
  305. package/build/dist/Types/Monitor/ProxmoxMetricCatalog.js +320 -0
  306. package/build/dist/Types/Monitor/ProxmoxMetricCatalog.js.map +1 -0
  307. package/build/dist/Types/Permission.js +408 -0
  308. package/build/dist/Types/Permission.js.map +1 -1
  309. package/build/dist/Types/Telemetry/EntityType.js +11 -0
  310. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  311. package/build/dist/Types/Telemetry/ServiceType.js +2 -0
  312. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  313. package/build/dist/UI/Components/Icon/Icon.js +33 -0
  314. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  315. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +5 -1
  316. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  317. package/build/dist/UI/Utils/Telemetry/Telemetry.js +11 -10
  318. package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
  319. package/build/dist/UI/Utils/TelemetryService.js +5 -2
  320. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  321. package/build/dist/Utils/Dashboard/Components/DashboardCephOsdListComponent.js +50 -0
  322. package/build/dist/Utils/Dashboard/Components/DashboardCephOsdListComponent.js.map +1 -0
  323. package/build/dist/Utils/Dashboard/Components/DashboardCephPoolListComponent.js +27 -0
  324. package/build/dist/Utils/Dashboard/Components/DashboardCephPoolListComponent.js.map +1 -0
  325. package/build/dist/Utils/Dashboard/Components/DashboardCephResourceListShared.js +46 -0
  326. package/build/dist/Utils/Dashboard/Components/DashboardCephResourceListShared.js.map +1 -0
  327. package/build/dist/Utils/Dashboard/Components/DashboardProxmoxGuestListComponent.js +55 -0
  328. package/build/dist/Utils/Dashboard/Components/DashboardProxmoxGuestListComponent.js.map +1 -0
  329. package/build/dist/Utils/Dashboard/Components/DashboardProxmoxNodeListComponent.js +42 -0
  330. package/build/dist/Utils/Dashboard/Components/DashboardProxmoxNodeListComponent.js.map +1 -0
  331. package/build/dist/Utils/Dashboard/Components/DashboardProxmoxResourceListShared.js +46 -0
  332. package/build/dist/Utils/Dashboard/Components/DashboardProxmoxResourceListShared.js.map +1 -0
  333. package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
  334. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  335. package/build/dist/Utils/Telemetry/EntityKey.js +27 -0
  336. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  337. package/build/dist/Utils/Telemetry/EntityRelationship.js +3 -0
  338. package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
  339. package/build/dist/Utils/Telemetry/HeartbeatAvailability.js +174 -0
  340. package/build/dist/Utils/Telemetry/HeartbeatAvailability.js.map +1 -0
  341. package/package.json +29 -21
@@ -0,0 +1,383 @@
1
+ import DatabaseService from "./DatabaseService";
2
+ import Model from "../../Models/DatabaseModels/CephResource";
3
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
4
+ import ObjectID from "../../Types/ObjectID";
5
+ import OneUptimeDate from "../../Types/Date";
6
+ import logger from "../Utils/Logger";
7
+
8
+ /*
9
+ * ------------------------------------------------------------------
10
+ * CephResourceService
11
+ *
12
+ * Writes and reads the Ceph inventory table populated by the
13
+ * telemetry ingest path. Callers are either:
14
+ * - OtelMetricsIngestService (bulkUpsert + bulkUpdateLatestMetrics,
15
+ * from the ceph_* snapshot scan in processMetricsAsync)
16
+ * - CleanupStaleResources worker (deleteStaleForCluster)
17
+ * - CephResourceAPI / the dashboard pages (reads via the inherited
18
+ * DatabaseService CRUD)
19
+ *
20
+ * Identity + status and the latest-metric mirror both arrive on the
21
+ * same ceph-mgr scrape, so both writes happen in the same flush.
22
+ *
23
+ * readOpsCounter / writeOpsCounter store the latest RAW cumulative
24
+ * ceph_pool_rd / ceph_pool_wr values — rates ("IOPS") are computed on
25
+ * read from ClickHouse, never from these columns.
26
+ *
27
+ * ------------------------------------------------------------------
28
+ */
29
+
30
+ export interface ParsedCephResource {
31
+ kind: string; // Osd | Pool | Mon | Mgr | Mds | Rgw
32
+ externalId: string; // ceph_daemon (osd.3, mon.a, ...) or pool_id
33
+ name: string | null; // pool name (Pool kind only)
34
+ hostname: string | null;
35
+ daemonVersion: string | null;
36
+ deviceClass: string | null;
37
+ isUp: boolean | null;
38
+ isIn: boolean | null;
39
+ inQuorum: boolean | null;
40
+ lastSeenAt: Date;
41
+ }
42
+
43
+ export interface CephResourceLatestMetric {
44
+ kind: string;
45
+ externalId: string;
46
+ statBytes: number | null;
47
+ statBytesUsed: number | null;
48
+ applyLatencyMs: number | null;
49
+ commitLatencyMs: number | null;
50
+ pgCount: number | null;
51
+ storedBytes: number | null;
52
+ maxAvailBytes: number | null;
53
+ objects: number | null;
54
+ readOpsCounter: number | null;
55
+ writeOpsCounter: number | null;
56
+ observedAt: Date;
57
+ }
58
+
59
+ export interface CephInventorySummary {
60
+ countsByKind: Record<string, number>;
61
+ osdUpCount: number;
62
+ osdInCount: number;
63
+ monInQuorumCount: number;
64
+ }
65
+
66
+ const UPSERT_BATCH_SIZE: number = 500;
67
+ const STALE_DELETE_WARN_THRESHOLD: number = 100;
68
+
69
+ /*
70
+ * Column order used by bulkUpsert() and its generated parameter tuples.
71
+ * Keep this and the INSERT column list in perfect sync.
72
+ */
73
+ const UPSERT_COLUMNS: Array<string> = [
74
+ "projectId",
75
+ "cephClusterId",
76
+ "kind",
77
+ "externalId",
78
+ "name",
79
+ "hostname",
80
+ "daemonVersion",
81
+ "deviceClass",
82
+ "isUp",
83
+ "isIn",
84
+ "inQuorum",
85
+ "lastSeenAt",
86
+ "version",
87
+ ];
88
+
89
+ export class Service extends DatabaseService<Model> {
90
+ public constructor() {
91
+ super(Model);
92
+ }
93
+
94
+ /**
95
+ * Upsert a batch of parsed resources for a single (project, cluster)
96
+ * pair. Uses ON CONFLICT on the UNIQUE (projectId, cephClusterId,
97
+ * kind, externalId) index with a dominance guard on lastSeenAt so
98
+ * out-of-order ingest never regresses a newer snapshot.
99
+ *
100
+ * Identity/status columns COALESCE against the existing row: a
101
+ * ceph-mgr batch is usually a complete scrape, but a batch that
102
+ * happens to lack a *_metadata series must not blank
103
+ * hostname/deviceClass/daemonVersion an earlier batch already filled.
104
+ */
105
+ @CaptureSpan()
106
+ public async bulkUpsert(data: {
107
+ projectId: ObjectID;
108
+ cephClusterId: ObjectID;
109
+ resources: Array<ParsedCephResource>;
110
+ }): Promise<void> {
111
+ if (data.resources.length === 0) {
112
+ return;
113
+ }
114
+
115
+ // Chunk to keep individual statement parameter counts reasonable.
116
+ for (let i: number = 0; i < data.resources.length; i += UPSERT_BATCH_SIZE) {
117
+ const chunk: Array<ParsedCephResource> = data.resources.slice(
118
+ i,
119
+ i + UPSERT_BATCH_SIZE,
120
+ );
121
+
122
+ const valueFragments: Array<string> = [];
123
+ const params: Array<unknown> = [];
124
+ let paramIndex: number = 1;
125
+
126
+ for (const r of chunk) {
127
+ const placeholders: Array<string> = [];
128
+ for (let c: number = 0; c < UPSERT_COLUMNS.length; c++) {
129
+ placeholders.push(`$${paramIndex++}`);
130
+ }
131
+ valueFragments.push(`(${placeholders.join(", ")})`);
132
+
133
+ params.push(
134
+ data.projectId.toString(),
135
+ data.cephClusterId.toString(),
136
+ r.kind,
137
+ r.externalId,
138
+ r.name,
139
+ r.hostname,
140
+ r.daemonVersion,
141
+ r.deviceClass,
142
+ r.isUp,
143
+ r.isIn,
144
+ r.inQuorum,
145
+ r.lastSeenAt,
146
+ 0, // version (BaseModel @VersionColumn)
147
+ );
148
+ }
149
+
150
+ const sql: string = `
151
+ INSERT INTO "CephResource" (
152
+ "projectId", "cephClusterId", "kind", "externalId",
153
+ "name", "hostname", "daemonVersion", "deviceClass",
154
+ "isUp", "isIn", "inQuorum",
155
+ "lastSeenAt", "version"
156
+ )
157
+ VALUES ${valueFragments.join(", ")}
158
+ ON CONFLICT ("projectId", "cephClusterId", "kind", "externalId")
159
+ DO UPDATE SET
160
+ "name" = COALESCE(EXCLUDED."name", "CephResource"."name"),
161
+ "hostname" = COALESCE(EXCLUDED."hostname", "CephResource"."hostname"),
162
+ "daemonVersion" = COALESCE(EXCLUDED."daemonVersion", "CephResource"."daemonVersion"),
163
+ "deviceClass" = COALESCE(EXCLUDED."deviceClass", "CephResource"."deviceClass"),
164
+ "isUp" = COALESCE(EXCLUDED."isUp", "CephResource"."isUp"),
165
+ "isIn" = COALESCE(EXCLUDED."isIn", "CephResource"."isIn"),
166
+ "inQuorum" = COALESCE(EXCLUDED."inQuorum", "CephResource"."inQuorum"),
167
+ "lastSeenAt" = EXCLUDED."lastSeenAt",
168
+ "updatedAt" = now()
169
+ WHERE EXCLUDED."lastSeenAt" >= "CephResource"."lastSeenAt"
170
+ `;
171
+
172
+ await this.getRepository().manager.query(sql, params);
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Update the latest-metric mirror columns for a batch of resources.
178
+ * Plain UPDATE: in practice the row always exists because bulkUpsert
179
+ * runs in the same flush; if it somehow doesn't, the write is
180
+ * silently skipped and the next flush catches up.
181
+ *
182
+ * Guarded by metricsUpdatedAt so out-of-order points don't regress a
183
+ * newer observation; COALESCE keeps the existing value when a batch
184
+ * lacks a series.
185
+ */
186
+ @CaptureSpan()
187
+ public async bulkUpdateLatestMetrics(data: {
188
+ projectId: ObjectID;
189
+ cephClusterId: ObjectID;
190
+ metrics: Array<CephResourceLatestMetric>;
191
+ }): Promise<void> {
192
+ if (data.metrics.length === 0) {
193
+ return;
194
+ }
195
+
196
+ for (let i: number = 0; i < data.metrics.length; i += UPSERT_BATCH_SIZE) {
197
+ const chunk: Array<CephResourceLatestMetric> = data.metrics.slice(
198
+ i,
199
+ i + UPSERT_BATCH_SIZE,
200
+ );
201
+
202
+ const valueFragments: Array<string> = [];
203
+ const params: Array<unknown> = [
204
+ data.projectId.toString(),
205
+ data.cephClusterId.toString(),
206
+ ];
207
+ let paramIndex: number = 3;
208
+
209
+ const bigintOrNull: (value: number | null) => string | null = (
210
+ value: number | null,
211
+ ) => {
212
+ return value !== null && value !== undefined
213
+ ? Math.trunc(value).toString()
214
+ : null;
215
+ };
216
+
217
+ for (const m of chunk) {
218
+ valueFragments.push(
219
+ `($${paramIndex++}, $${paramIndex++}, $${paramIndex++}::bigint, $${paramIndex++}::bigint, $${paramIndex++}::numeric, $${paramIndex++}::numeric, $${paramIndex++}::integer, $${paramIndex++}::bigint, $${paramIndex++}::bigint, $${paramIndex++}::bigint, $${paramIndex++}::bigint, $${paramIndex++}::bigint, $${paramIndex++}::timestamptz)`,
220
+ );
221
+ params.push(
222
+ m.kind,
223
+ m.externalId,
224
+ bigintOrNull(m.statBytes),
225
+ bigintOrNull(m.statBytesUsed),
226
+ m.applyLatencyMs !== null && m.applyLatencyMs !== undefined
227
+ ? m.applyLatencyMs
228
+ : null,
229
+ m.commitLatencyMs !== null && m.commitLatencyMs !== undefined
230
+ ? m.commitLatencyMs
231
+ : null,
232
+ m.pgCount !== null && m.pgCount !== undefined
233
+ ? Math.trunc(m.pgCount)
234
+ : null,
235
+ bigintOrNull(m.storedBytes),
236
+ bigintOrNull(m.maxAvailBytes),
237
+ bigintOrNull(m.objects),
238
+ bigintOrNull(m.readOpsCounter),
239
+ bigintOrNull(m.writeOpsCounter),
240
+ m.observedAt,
241
+ );
242
+ }
243
+
244
+ const sql: string = `
245
+ UPDATE "CephResource" AS c
246
+ SET
247
+ "statBytes" = COALESCE(v."statBytes", c."statBytes"),
248
+ "statBytesUsed" = COALESCE(v."statBytesUsed", c."statBytesUsed"),
249
+ "applyLatencyMs" = COALESCE(v."applyLatencyMs", c."applyLatencyMs"),
250
+ "commitLatencyMs" = COALESCE(v."commitLatencyMs", c."commitLatencyMs"),
251
+ "pgCount" = COALESCE(v."pgCount", c."pgCount"),
252
+ "storedBytes" = COALESCE(v."storedBytes", c."storedBytes"),
253
+ "maxAvailBytes" = COALESCE(v."maxAvailBytes", c."maxAvailBytes"),
254
+ "objects" = COALESCE(v."objects", c."objects"),
255
+ "readOpsCounter" = COALESCE(v."readOpsCounter", c."readOpsCounter"),
256
+ "writeOpsCounter" = COALESCE(v."writeOpsCounter", c."writeOpsCounter"),
257
+ "metricsUpdatedAt" = v."observedAt",
258
+ "updatedAt" = now()
259
+ FROM (VALUES ${valueFragments.join(", ")})
260
+ AS v("kind", "externalId", "statBytes", "statBytesUsed", "applyLatencyMs", "commitLatencyMs", "pgCount", "storedBytes", "maxAvailBytes", "objects", "readOpsCounter", "writeOpsCounter", "observedAt")
261
+ WHERE
262
+ c."projectId" = $1
263
+ AND c."cephClusterId" = $2
264
+ AND c."kind" = v."kind"
265
+ AND c."externalId" = v."externalId"
266
+ AND (c."metricsUpdatedAt" IS NULL OR v."observedAt" >= c."metricsUpdatedAt")
267
+ `;
268
+
269
+ await this.getRepository().manager.query(sql, params);
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Hard-delete all resources in a cluster whose last scrape is older
275
+ * than olderThan. Returns the number of deleted rows. Only called by
276
+ * the cleanup worker for clusters that are still connected — a
277
+ * disconnected cluster keeps its last-known inventory.
278
+ */
279
+ @CaptureSpan()
280
+ public async deleteStaleForCluster(data: {
281
+ cephClusterId: ObjectID;
282
+ olderThan: Date;
283
+ }): Promise<number> {
284
+ const result: Array<{ affected?: number }> | { affected?: number } =
285
+ await this.getRepository().manager.query(
286
+ `DELETE FROM "CephResource" WHERE "cephClusterId" = $1 AND "lastSeenAt" < $2`,
287
+ [data.cephClusterId.toString(), data.olderThan],
288
+ );
289
+
290
+ // Postgres driver returns [rows, affected] for DELETE — normalize.
291
+ let affected: number = 0;
292
+ if (Array.isArray(result) && result.length >= 2) {
293
+ const second: unknown = (result as Array<unknown>)[1];
294
+ if (typeof second === "number") {
295
+ affected = second;
296
+ }
297
+ }
298
+
299
+ if (affected > STALE_DELETE_WARN_THRESHOLD) {
300
+ logger.warn(
301
+ `CephResource cleanup deleted ${affected} stale rows for cluster ${data.cephClusterId.toString()} — larger than expected; investigate agent health.`,
302
+ );
303
+ }
304
+
305
+ return affected;
306
+ }
307
+
308
+ /**
309
+ * Compute the sidebar/overview summary in Postgres: counts per kind
310
+ * plus the up/in/quorum breakdowns, in a single round-trip.
311
+ */
312
+ @CaptureSpan()
313
+ public async getInventorySummary(data: {
314
+ projectId: ObjectID;
315
+ cephClusterId: ObjectID;
316
+ }): Promise<CephInventorySummary> {
317
+ const rows: Array<{
318
+ kind: string;
319
+ count: string;
320
+ upCount: string;
321
+ inCount: string;
322
+ quorumCount: string;
323
+ }> = await this.getRepository().manager.query(
324
+ `SELECT "kind",
325
+ COUNT(*)::text AS count,
326
+ COUNT(*) FILTER (WHERE "isUp" IS TRUE)::text AS "upCount",
327
+ COUNT(*) FILTER (WHERE "isIn" IS TRUE)::text AS "inCount",
328
+ COUNT(*) FILTER (WHERE "inQuorum" IS TRUE)::text AS "quorumCount"
329
+ FROM "CephResource"
330
+ WHERE "projectId" = $1 AND "cephClusterId" = $2 AND "deletedAt" IS NULL
331
+ GROUP BY "kind"`,
332
+ [data.projectId.toString(), data.cephClusterId.toString()],
333
+ );
334
+
335
+ const countsByKind: Record<string, number> = {};
336
+ let osdUpCount: number = 0;
337
+ let osdInCount: number = 0;
338
+ let monInQuorumCount: number = 0;
339
+ for (const row of rows) {
340
+ countsByKind[row.kind] = parseInt(row.count, 10) || 0;
341
+ if (row.kind === "Osd") {
342
+ osdUpCount = parseInt(row.upCount, 10) || 0;
343
+ osdInCount = parseInt(row.inCount, 10) || 0;
344
+ }
345
+ if (row.kind === "Mon") {
346
+ monInQuorumCount = parseInt(row.quorumCount, 10) || 0;
347
+ }
348
+ }
349
+
350
+ return {
351
+ countsByKind,
352
+ osdUpCount,
353
+ osdInCount,
354
+ monInQuorumCount,
355
+ };
356
+ }
357
+
358
+ /**
359
+ * Helper for the cleanup worker: snapshot-interval aware cutoff.
360
+ * 3× the 5-minute scrape interval by default. Tune via
361
+ * CEPH_INVENTORY_STALE_MINUTES (min 5).
362
+ */
363
+ public getStaleThresholdDate(nowOverride?: Date): Date {
364
+ const minutes: number = this.getStaleThresholdMinutes();
365
+ return OneUptimeDate.addRemoveMinutes(
366
+ nowOverride || OneUptimeDate.getCurrentDate(),
367
+ -minutes,
368
+ );
369
+ }
370
+
371
+ public getStaleThresholdMinutes(): number {
372
+ const raw: string | undefined = process.env["CEPH_INVENTORY_STALE_MINUTES"];
373
+ if (raw) {
374
+ const parsed: number = parseInt(raw, 10);
375
+ if (!isNaN(parsed) && parsed >= 5) {
376
+ return parsed;
377
+ }
378
+ }
379
+ return 15;
380
+ }
381
+ }
382
+
383
+ export default new Service();
@@ -294,15 +294,23 @@ export class Service extends DatabaseService<Model> {
294
294
 
295
295
  @CaptureSpan()
296
296
  public async markDisconnectedResources(): Promise<void> {
297
- const fiveMinutesAgo: Date = OneUptimeDate.addRemoveMinutes(
297
+ /*
298
+ * Threshold must stay well above the 5-minute OTel ingest
299
+ * maintenance fence (MAINTENANCE_FENCE_TTL_SECONDS in
300
+ * OtelIngestBaseService) — lastSeenAt is legitimately up to
301
+ * ~5 minutes stale during continuous telemetry, so a threshold
302
+ * equal to the fence TTL flaps healthy resources. 15 minutes
303
+ * gives 3x headroom.
304
+ */
305
+ const fifteenMinutesAgo: Date = OneUptimeDate.addRemoveMinutes(
298
306
  OneUptimeDate.getCurrentDate(),
299
- -5,
307
+ -15,
300
308
  );
301
309
 
302
310
  const connectedResources: Array<Model> = await this.findBy({
303
311
  query: {
304
312
  otelCollectorStatus: "connected",
305
- lastSeenAt: QueryHelper.lessThan(fiveMinutesAgo),
313
+ lastSeenAt: QueryHelper.lessThan(fifteenMinutesAgo),
306
314
  },
307
315
  select: {
308
316
  _id: true,
@@ -312,15 +312,23 @@ export class Service extends DatabaseService<Model> {
312
312
 
313
313
  @CaptureSpan()
314
314
  public async markDisconnectedHosts(): Promise<void> {
315
- const fiveMinutesAgo: Date = OneUptimeDate.addRemoveMinutes(
315
+ /*
316
+ * Threshold must stay well above the 5-minute OTel ingest
317
+ * maintenance fence (MAINTENANCE_FENCE_TTL_SECONDS in
318
+ * OtelIngestBaseService) — lastSeenAt is legitimately up to
319
+ * ~5 minutes stale during continuous telemetry, so a threshold
320
+ * equal to the fence TTL flaps healthy resources. 15 minutes
321
+ * gives 3x headroom.
322
+ */
323
+ const fifteenMinutesAgo: Date = OneUptimeDate.addRemoveMinutes(
316
324
  OneUptimeDate.getCurrentDate(),
317
- -5,
325
+ -15,
318
326
  );
319
327
 
320
328
  const connectedHosts: Array<Model> = await this.findBy({
321
329
  query: {
322
330
  otelCollectorStatus: "connected",
323
- lastSeenAt: QueryHelper.lessThan(fiveMinutesAgo),
331
+ lastSeenAt: QueryHelper.lessThan(fifteenMinutesAgo),
324
332
  },
325
333
  select: {
326
334
  _id: true,
@@ -73,6 +73,8 @@ export class ExceptionAggregationService {
73
73
  ["hostId", ServiceType.Host],
74
74
  ["dockerHostId", ServiceType.DockerHost],
75
75
  ["kubernetesClusterId", ServiceType.KubernetesCluster],
76
+ ["proxmoxClusterId", ServiceType.ProxmoxCluster],
77
+ ["cephClusterId", ServiceType.CephCluster],
76
78
  ["serverlessFunctionId", ServiceType.ServerlessFunction],
77
79
  ["cloudResourceId", ServiceType.CloudResource],
78
80
  ["rumApplicationId", ServiceType.RealUserMonitor],
@@ -441,15 +441,23 @@ export class Service extends DatabaseService<Model> {
441
441
 
442
442
  @CaptureSpan()
443
443
  public async markDisconnectedHosts(): Promise<void> {
444
- const fiveMinutesAgo: Date = OneUptimeDate.addRemoveMinutes(
444
+ /*
445
+ * Threshold must stay well above the 5-minute OTel ingest
446
+ * maintenance fence (MAINTENANCE_FENCE_TTL_SECONDS in
447
+ * OtelIngestBaseService) — lastSeenAt is legitimately up to
448
+ * ~5 minutes stale during continuous telemetry, so a threshold
449
+ * equal to the fence TTL flaps healthy resources. 15 minutes
450
+ * gives 3x headroom.
451
+ */
452
+ const fifteenMinutesAgo: Date = OneUptimeDate.addRemoveMinutes(
445
453
  OneUptimeDate.getCurrentDate(),
446
- -5,
454
+ -15,
447
455
  );
448
456
 
449
457
  const connectedHosts: Array<Model> = await this.findBy({
450
458
  query: {
451
459
  otelCollectorStatus: "connected",
452
- lastSeenAt: QueryHelper.lessThan(fiveMinutesAgo),
460
+ lastSeenAt: QueryHelper.lessThan(fifteenMinutesAgo),
453
461
  },
454
462
  select: {
455
463
  _id: true,
@@ -35,6 +35,18 @@ import IncidentStateTimelineService from "./IncidentStateTimelineService";
35
35
  import LabelService from "./LabelService";
36
36
  import KubernetesClusterService from "./KubernetesClusterService";
37
37
  import DockerHostService from "./DockerHostService";
38
+ import ProxmoxClusterService from "./ProxmoxClusterService";
39
+ import CephClusterService from "./CephClusterService";
40
+ import ProxmoxResourceService from "./ProxmoxResourceService";
41
+ import CephResourceService from "./CephResourceService";
42
+ import ProxmoxClusterLabelRuleService from "./ProxmoxClusterLabelRuleService";
43
+ import ProxmoxClusterOwnerRuleService from "./ProxmoxClusterOwnerRuleService";
44
+ import ProxmoxClusterOwnerTeamService from "./ProxmoxClusterOwnerTeamService";
45
+ import ProxmoxClusterOwnerUserService from "./ProxmoxClusterOwnerUserService";
46
+ import CephClusterLabelRuleService from "./CephClusterLabelRuleService";
47
+ import CephClusterOwnerRuleService from "./CephClusterOwnerRuleService";
48
+ import CephClusterOwnerTeamService from "./CephClusterOwnerTeamService";
49
+ import CephClusterOwnerUserService from "./CephClusterOwnerUserService";
38
50
  import LlmProviderService from "./LlmProviderService";
39
51
  import AuditLogService from "./AuditLogService";
40
52
  import LogService from "./LogService";
@@ -270,6 +282,18 @@ const services: Array<BaseService> = [
270
282
  LabelService,
271
283
  KubernetesClusterService,
272
284
  DockerHostService,
285
+ ProxmoxClusterService,
286
+ CephClusterService,
287
+ ProxmoxResourceService,
288
+ CephResourceService,
289
+ ProxmoxClusterLabelRuleService,
290
+ ProxmoxClusterOwnerRuleService,
291
+ ProxmoxClusterOwnerTeamService,
292
+ ProxmoxClusterOwnerUserService,
293
+ CephClusterLabelRuleService,
294
+ CephClusterOwnerRuleService,
295
+ CephClusterOwnerTeamService,
296
+ CephClusterOwnerUserService,
273
297
  LlmProviderService,
274
298
 
275
299
  MailService,
@@ -269,15 +269,23 @@ export class Service extends DatabaseService<Model> {
269
269
 
270
270
  @CaptureSpan()
271
271
  public async markDisconnectedClusters(): Promise<void> {
272
- const fiveMinutesAgo: Date = OneUptimeDate.addRemoveMinutes(
272
+ /*
273
+ * Threshold must stay well above the 5-minute OTel ingest
274
+ * maintenance fence (MAINTENANCE_FENCE_TTL_SECONDS in
275
+ * OtelIngestBaseService) — lastSeenAt is legitimately up to
276
+ * ~5 minutes stale during continuous telemetry, so a threshold
277
+ * equal to the fence TTL flaps healthy resources. 15 minutes
278
+ * gives 3x headroom.
279
+ */
280
+ const fifteenMinutesAgo: Date = OneUptimeDate.addRemoveMinutes(
273
281
  OneUptimeDate.getCurrentDate(),
274
- -5,
282
+ -15,
275
283
  );
276
284
 
277
285
  const connectedClusters: Array<Model> = await this.findBy({
278
286
  query: {
279
287
  otelCollectorStatus: "connected",
280
- lastSeenAt: QueryHelper.lessThan(fiveMinutesAgo),
288
+ lastSeenAt: QueryHelper.lessThan(fifteenMinutesAgo),
281
289
  },
282
290
  select: {
283
291
  _id: true,
@@ -110,6 +110,8 @@ export class LogAggregationService {
110
110
  ["hostId", ServiceType.Host],
111
111
  ["dockerHostId", ServiceType.DockerHost],
112
112
  ["kubernetesClusterId", ServiceType.KubernetesCluster],
113
+ ["proxmoxClusterId", ServiceType.ProxmoxCluster],
114
+ ["cephClusterId", ServiceType.CephCluster],
113
115
  ["serverlessFunctionId", ServiceType.ServerlessFunction],
114
116
  ["cloudResourceId", ServiceType.CloudResource],
115
117
  ["rumApplicationId", ServiceType.RealUserMonitor],
@@ -49,6 +49,8 @@ export class MetricAggregationService {
49
49
  ["hostId", ServiceType.Host],
50
50
  ["dockerHostId", ServiceType.DockerHost],
51
51
  ["kubernetesClusterId", ServiceType.KubernetesCluster],
52
+ ["proxmoxClusterId", ServiceType.ProxmoxCluster],
53
+ ["cephClusterId", ServiceType.CephCluster],
52
54
  ["serverlessFunctionId", ServiceType.ServerlessFunction],
53
55
  ["cloudResourceId", ServiceType.CloudResource],
54
56
  ["rumApplicationId", ServiceType.RealUserMonitor],
@@ -21,12 +21,16 @@ import ServiceType from "../../Types/Telemetry/ServiceType";
21
21
  import Host from "../../Models/DatabaseModels/Host";
22
22
  import DockerHost from "../../Models/DatabaseModels/DockerHost";
23
23
  import KubernetesCluster from "../../Models/DatabaseModels/KubernetesCluster";
24
+ import ProxmoxCluster from "../../Models/DatabaseModels/ProxmoxCluster";
25
+ import CephCluster from "../../Models/DatabaseModels/CephCluster";
24
26
  import ServerlessFunction from "../../Models/DatabaseModels/ServerlessFunction";
25
27
  import CloudResource from "../../Models/DatabaseModels/CloudResource";
26
28
  import RumApplication from "../../Models/DatabaseModels/RumApplication";
27
29
  import HostService from "./HostService";
28
30
  import DockerHostService from "./DockerHostService";
29
31
  import KubernetesClusterService from "./KubernetesClusterService";
32
+ import ProxmoxClusterService from "./ProxmoxClusterService";
33
+ import CephClusterService from "./CephClusterService";
30
34
  import ServerlessFunctionService from "./ServerlessFunctionService";
31
35
  import CloudResourceService from "./CloudResourceService";
32
36
  import RumApplicationService from "./RumApplicationService";
@@ -687,6 +691,38 @@ export default class OTelIngestService {
687
691
  telemetryRetentionConfig: cluster?.telemetryRetentionConfig ?? null,
688
692
  };
689
693
  }
694
+ if (primaryEntityType === ServiceType.ProxmoxCluster) {
695
+ const cluster: ProxmoxCluster | null =
696
+ await ProxmoxClusterService.findOneById({
697
+ id: resourceId,
698
+ select: {
699
+ retainTelemetryDataForDays: true,
700
+ telemetryRetentionConfig: true,
701
+ },
702
+ props: { isRoot: true },
703
+ });
704
+ return {
705
+ retainTelemetryDataForDays:
706
+ cluster?.retainTelemetryDataForDays ?? null,
707
+ telemetryRetentionConfig: cluster?.telemetryRetentionConfig ?? null,
708
+ };
709
+ }
710
+ if (primaryEntityType === ServiceType.CephCluster) {
711
+ const cluster: CephCluster | null =
712
+ await CephClusterService.findOneById({
713
+ id: resourceId,
714
+ select: {
715
+ retainTelemetryDataForDays: true,
716
+ telemetryRetentionConfig: true,
717
+ },
718
+ props: { isRoot: true },
719
+ });
720
+ return {
721
+ retainTelemetryDataForDays:
722
+ cluster?.retainTelemetryDataForDays ?? null,
723
+ telemetryRetentionConfig: cluster?.telemetryRetentionConfig ?? null,
724
+ };
725
+ }
690
726
  if (primaryEntityType === ServiceType.ServerlessFunction) {
691
727
  const serverlessFunction: ServerlessFunction | null =
692
728
  await ServerlessFunctionService.findOneById({