@oneuptime/common 14.0.8 → 14.0.9

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 (639) hide show
  1. package/Models/DatabaseModels/Index.ts +2 -0
  2. package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
  3. package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
  4. package/Models/DatabaseModels/Project.ts +55 -5
  5. package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
  6. package/Models/DatabaseModels/RunnerJob.ts +75 -0
  7. package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
  8. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
  9. package/Server/API/AIChatAPI.ts +6 -3
  10. package/Server/API/AIInvestigationAPI.ts +17 -10
  11. package/Server/API/AutoRemediationAPI.ts +207 -25
  12. package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
  13. package/Server/API/MicrosoftTeamsAPI.ts +93 -14
  14. package/Server/API/ProxmoxResourceAPI.ts +244 -14
  15. package/Server/Infrastructure/GlobalCache.ts +32 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/TelemetryIngest.ts +41 -18
  21. package/Server/Services/AIService.ts +70 -1
  22. package/Server/Services/AlertService.ts +352 -11
  23. package/Server/Services/AlertSeverityService.ts +65 -15
  24. package/Server/Services/AutoRemediationRuleService.ts +1 -1
  25. package/Server/Services/IncidentService.ts +280 -104
  26. package/Server/Services/IncidentSeverityService.ts +66 -15
  27. package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
  28. package/Server/Services/KubernetesAiAgentService.ts +1634 -0
  29. package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
  30. package/Server/Services/KubernetesClusterService.ts +129 -21
  31. package/Server/Services/ProjectService.ts +32 -0
  32. package/Server/Services/ProxmoxResourceService.ts +322 -5
  33. package/Server/Services/RunnerJobService.ts +241 -104
  34. package/Server/Services/RunnerService.ts +1 -1
  35. package/Server/Services/ScheduledMaintenanceService.ts +737 -1
  36. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
  37. package/Server/Services/TeamComplianceSettingService.ts +1125 -9
  38. package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
  39. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
  40. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
  41. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
  42. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
  43. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
  44. package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
  45. package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
  46. package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
  47. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
  48. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
  49. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
  50. package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
  51. package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
  52. package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
  53. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
  54. package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
  55. package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
  56. package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
  57. package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
  58. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
  59. package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
  60. package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
  61. package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
  62. package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
  63. package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
  64. package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
  65. package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
  66. package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
  67. package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
  68. package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
  69. package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
  70. package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
  71. package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
  72. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
  73. package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
  74. package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
  75. package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
  76. package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
  77. package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
  78. package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
  79. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
  80. package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
  81. package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
  82. package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
  83. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
  84. package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
  85. package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
  86. package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
  87. package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
  88. package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
  89. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
  90. package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
  91. package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
  92. package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
  93. package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
  94. package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
  95. package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
  96. package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
  97. package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
  98. package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
  99. package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
  100. package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
  101. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
  102. package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
  103. package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
  104. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
  105. package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
  106. package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
  107. package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
  108. package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
  109. package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
  110. package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
  111. package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
  112. package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
  113. package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
  114. package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
  115. package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
  116. package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
  117. package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
  118. package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
  119. package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
  120. package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
  121. package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
  122. package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
  123. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
  124. package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
  125. package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
  126. package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
  127. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
  128. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
  129. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
  130. package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
  131. package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
  132. package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
  133. package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
  134. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
  135. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
  136. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
  137. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
  138. package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
  139. package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
  140. package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
  141. package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
  142. package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
  143. package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
  144. package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
  145. package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
  146. package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
  147. package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
  148. package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
  149. package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
  150. package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
  151. package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
  152. package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
  153. package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
  154. package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
  155. package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
  156. package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
  157. package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
  158. package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
  159. package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
  160. package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
  161. package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
  162. package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
  163. package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
  164. package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
  165. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
  166. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
  167. package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
  168. package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
  169. package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
  170. package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
  171. package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
  172. package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
  173. package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
  174. package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
  175. package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
  176. package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
  177. package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
  178. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
  179. package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
  180. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
  181. package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
  182. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
  183. package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
  184. package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
  185. package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
  186. package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
  187. package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
  188. package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
  189. package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
  190. package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
  191. package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
  192. package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
  193. package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
  194. package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
  195. package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
  196. package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
  197. package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
  198. package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
  199. package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
  200. package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
  201. package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
  202. package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
  203. package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
  204. package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
  205. package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
  206. package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
  207. package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
  208. package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
  209. package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
  210. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
  211. package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
  212. package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
  213. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
  214. package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
  215. package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
  216. package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
  217. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
  218. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
  219. package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
  220. package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
  221. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
  222. package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
  223. package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
  224. package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
  225. package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
  226. package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
  227. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
  228. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
  229. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
  230. package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
  231. package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
  232. package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
  233. package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
  234. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
  235. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
  236. package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
  237. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
  238. package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
  239. package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
  240. package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
  241. package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
  242. package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
  243. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
  244. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
  245. package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
  246. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
  247. package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
  248. package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
  249. package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
  250. package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
  251. package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
  252. package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
  253. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
  254. package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
  255. package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
  256. package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
  257. package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
  258. package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
  259. package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
  260. package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
  261. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
  262. package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
  263. package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
  264. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
  265. package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
  266. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
  267. package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
  268. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
  269. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
  270. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
  271. package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
  272. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
  273. package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
  274. package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
  275. package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
  276. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
  277. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
  278. package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
  279. package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
  280. package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
  281. package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
  282. package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
  283. package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
  284. package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
  285. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
  286. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
  287. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
  288. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
  289. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
  290. package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
  291. package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
  292. package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
  293. package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
  294. package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
  295. package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
  296. package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
  297. package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
  298. package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
  299. package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
  300. package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
  301. package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
  302. package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
  303. package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
  304. package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
  305. package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
  306. package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
  307. package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
  308. package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
  309. package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
  310. package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
  311. package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
  312. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
  313. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
  314. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
  315. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
  316. package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
  317. package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
  318. package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
  319. package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
  320. package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
  321. package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
  322. package/Tests/UI/Components/Input.test.tsx +80 -1
  323. package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
  324. package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
  325. package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
  326. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
  327. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
  328. package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
  329. package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
  330. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
  331. package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
  332. package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
  333. package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
  334. package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
  335. package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
  336. package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
  337. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
  338. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
  339. package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
  340. package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
  341. package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
  342. package/Tests/UI/Components/Toggle.test.tsx +66 -0
  343. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
  344. package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
  345. package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
  346. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
  347. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
  348. package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
  349. package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
  350. package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
  351. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
  352. package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
  353. package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
  354. package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
  355. package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
  356. package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
  357. package/Types/AI/AIRunType.ts +9 -4
  358. package/Types/AI/InvestigationNotStartedReason.ts +6 -0
  359. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
  360. package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
  361. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
  362. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
  363. package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
  364. package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
  365. package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
  366. package/Types/Team/ComplianceNotificationChannel.ts +22 -0
  367. package/Types/Team/ComplianceRule.ts +434 -0
  368. package/Types/Team/ComplianceRuleType.ts +21 -0
  369. package/Types/Team/TeamComplianceStatus.ts +81 -0
  370. package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
  371. package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
  372. package/UI/Components/ActionButton/RowActions.tsx +238 -0
  373. package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
  374. package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
  375. package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
  376. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
  377. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
  378. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
  379. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
  380. package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
  381. package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
  382. package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
  383. package/UI/Components/Charts/Line/LineChart.tsx +32 -2
  384. package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
  385. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
  386. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
  387. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
  388. package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
  389. package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
  390. package/UI/Components/Charts/Utils/XAxis.ts +75 -0
  391. package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
  392. package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
  393. package/UI/Components/Forms/Fields/FormField.tsx +10 -0
  394. package/UI/Components/Input/Input.tsx +90 -57
  395. package/UI/Components/List/ListRow.tsx +8 -74
  396. package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
  397. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
  398. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
  399. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
  400. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
  401. package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
  402. package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
  403. package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
  404. package/UI/Components/OrderedStatesList/Item.tsx +7 -72
  405. package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
  406. package/UI/Components/Table/TableBody.tsx +8 -2
  407. package/UI/Components/Table/TableRow.tsx +20 -140
  408. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
  409. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
  410. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
  411. package/UI/Components/TelemetryViewer/types.ts +2 -0
  412. package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
  413. package/UI/Components/Toggle/Toggle.tsx +26 -0
  414. package/UI/Components/Tooltip/Tooltip.tsx +8 -1
  415. package/UI/Styles/Theme.css +14 -2
  416. package/Utils/AiRemediation/CommandPolicy.ts +1 -1
  417. package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
  418. package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
  419. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  420. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  421. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
  422. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
  423. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
  424. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  425. package/build/dist/Models/DatabaseModels/Project.js +56 -5
  426. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  427. package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
  428. package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
  429. package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
  430. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  431. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
  432. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
  433. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  434. package/build/dist/Server/API/AIChatAPI.js +6 -1
  435. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  436. package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
  437. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  438. package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
  439. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  440. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
  441. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
  442. package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
  443. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  444. package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
  445. package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
  446. package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
  447. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  448. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
  449. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
  450. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
  451. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
  452. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
  453. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
  454. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  455. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  456. package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
  457. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  458. package/build/dist/Server/Services/AIService.js +59 -1
  459. package/build/dist/Server/Services/AIService.js.map +1 -1
  460. package/build/dist/Server/Services/AlertService.js +248 -13
  461. package/build/dist/Server/Services/AlertService.js.map +1 -1
  462. package/build/dist/Server/Services/AlertSeverityService.js +51 -15
  463. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
  464. package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
  465. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  466. package/build/dist/Server/Services/IncidentService.js +199 -72
  467. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  468. package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
  469. package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
  470. package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
  471. package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
  472. package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
  473. package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
  474. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
  475. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
  476. package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
  477. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  478. package/build/dist/Server/Services/ProjectService.js +22 -0
  479. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  480. package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
  481. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  482. package/build/dist/Server/Services/RunnerJobService.js +178 -92
  483. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  484. package/build/dist/Server/Services/RunnerService.js +1 -1
  485. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  486. package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
  487. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  488. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
  489. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  490. package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
  491. package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
  492. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
  493. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
  494. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
  495. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
  496. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
  497. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
  498. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
  499. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  500. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
  501. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  502. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
  503. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  504. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
  505. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
  506. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
  507. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
  508. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
  509. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
  510. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  511. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
  512. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  513. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
  514. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
  515. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
  516. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
  517. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
  518. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
  519. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
  520. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  521. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
  522. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  523. package/build/dist/Types/AI/AIRunType.js +9 -4
  524. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  525. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
  526. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  527. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
  528. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
  529. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
  530. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  531. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
  532. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
  533. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
  534. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
  535. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
  536. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  537. package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
  538. package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
  539. package/build/dist/Types/Team/ComplianceRule.js +304 -0
  540. package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
  541. package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
  542. package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
  543. package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
  544. package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
  545. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
  546. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  547. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
  548. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
  549. package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
  550. package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
  551. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
  552. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
  553. package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
  554. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  555. package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
  556. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
  558. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
  560. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
  562. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  563. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
  564. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  565. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
  566. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
  567. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
  568. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
  569. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
  570. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
  571. package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
  572. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  573. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
  574. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
  575. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
  576. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
  577. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
  578. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
  579. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
  580. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
  581. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
  582. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
  583. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
  584. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  585. package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
  586. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  587. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
  588. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
  589. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
  590. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  591. package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
  592. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  593. package/build/dist/UI/Components/Input/Input.js +69 -54
  594. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  595. package/build/dist/UI/Components/List/ListRow.js +4 -39
  596. package/build/dist/UI/Components/List/ListRow.js.map +1 -1
  597. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
  598. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  599. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
  600. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  601. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
  602. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  603. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
  604. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  605. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
  606. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  607. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
  608. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  609. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
  610. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  611. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
  612. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  613. package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
  614. package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
  615. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
  616. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
  617. package/build/dist/UI/Components/Table/TableBody.js +6 -2
  618. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  619. package/build/dist/UI/Components/Table/TableRow.js +12 -75
  620. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  621. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
  622. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  623. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
  624. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  625. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
  626. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  627. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
  628. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
  629. package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
  630. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  631. package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
  632. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  633. package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
  634. package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
  635. package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
  636. package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
  637. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
  638. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
  639. package/package.json +1 -1
@@ -0,0 +1,903 @@
1
+ import { JSONArray, JSONObject, JSONValue } from "../../../Types/JSON";
2
+
3
+ /*
4
+ * ------------------------------------------------------------------
5
+ * Proxmox VE native OpenTelemetry push — translate to the pve_* model
6
+ * ------------------------------------------------------------------
7
+ *
8
+ * Proxmox VE 9+ can push metrics itself (Datacenter → Metric Server →
9
+ * OpenTelemetry, PVE::Status::OpenTelemetry in pve-manager). Everything
10
+ * OneUptime builds for Proxmox — cluster discovery, the node / guest /
11
+ * storage inventory, the overview charts, the metric catalog and the
12
+ * alert templates — is written against the shape the Proxmox Agent
13
+ * ships (prometheus-pve-exporter series): `pve_*` names, resource
14
+ * identity in one `id` datapoint label (`node/pve1`, `qemu/100`,
15
+ * `lxc/101`, `storage/pve1/local`) plus the `pve.scope` / `pve.type` /
16
+ * `pve.id` attributes the agent's transform derives from it, and the
17
+ * cluster in the `proxmox.cluster.name` resource attribute.
18
+ *
19
+ * The native push differs in more than the prefix, which is why a
20
+ * per-cluster "series prefix" setting could not make it work:
21
+ *
22
+ * - names follow the PVE status hash keys: `proxmox_node_cpustat_cpu`,
23
+ * `proxmox_vm_maxmem`, `proxmox_storage_used`, …;
24
+ * - identity is spread over `node` / `vmid` / `type` / `storage`
25
+ * datapoint attributes, with no `id`;
26
+ * - there is no up/info series — a guest's run state only shows as a
27
+ * non-zero uptime;
28
+ * - the resource carries `service.name=proxmox-ve` and
29
+ * `proxmox.cluster` (not `proxmox.cluster.name`), so batches were
30
+ * routed to a phantom "proxmox-ve" Service and no cluster appeared
31
+ * unless the user added a resource attribute by hand.
32
+ *
33
+ * So each native-push resource block is rewritten in place, before
34
+ * anything reads it: the cluster identity is filled in from what PVE
35
+ * already sends, and the pve_* series the product reads are derived and
36
+ * appended next to the originals. The original proxmox_* series are left
37
+ * untouched — they stay available in Metrics Explorer, and anything a
38
+ * user already built on them keeps working.
39
+ *
40
+ * What the native push does not carry (HA state, start-on-boot, backup
41
+ * coverage, replication) cannot be derived and is not invented here.
42
+ * The one thing a node cannot say about itself — that it is down — is
43
+ * said for it by the nodes still alive: see
44
+ * appendProxmoxSiblingReportsInPlace below and ProxmoxNativeNodeLiveness.
45
+ */
46
+
47
+ // The service.name every PVE native push stamps on its resource.
48
+ export const PROXMOX_NATIVE_PUSH_SERVICE_NAME: string = "proxmox-ve";
49
+
50
+ /*
51
+ * `proxmox.cluster` value PVE falls back to when the node is not part of
52
+ * a cluster (PVE::Cluster::get_clinfo has no cluster name).
53
+ */
54
+ export const PROXMOX_NATIVE_PUSH_STANDALONE_CLUSTER: string = "single-node";
55
+
56
+ type NativeScope = "node" | "guest" | "storage";
57
+
58
+ /*
59
+ * Native series → canonical pve_* series. Counters are pushed with a
60
+ * `_total` suffix (PVE's _classify_metric_type); the bare spelling is
61
+ * accepted too so an older or future plugin revision still maps.
62
+ * pve-exporter reports the byte counters as gauges, so the derived
63
+ * series are gauges — that keeps the rate charts identical on both paths.
64
+ */
65
+ const NODE_SERIES: ReadonlyMap<string, string> = new Map<string, string>([
66
+ ["proxmox_node_uptime", "pve_uptime_seconds"],
67
+ // read_proc_stat: `cpu` is already a 0..1 ratio across all cores.
68
+ ["proxmox_node_cpustat_cpu", "pve_cpu_usage_ratio"],
69
+ ["proxmox_node_cpustat_cpus", "pve_cpu_usage_limit"],
70
+ ["proxmox_node_memory_memused", "pve_memory_usage_bytes"],
71
+ ["proxmox_node_memory_memtotal", "pve_memory_size_bytes"],
72
+ // blockstat is df('/') in bytes — the node's root filesystem.
73
+ ["proxmox_node_blockstat_used", "pve_disk_usage_bytes"],
74
+ ["proxmox_node_blockstat_total", "pve_disk_size_bytes"],
75
+ ]);
76
+
77
+ const GUEST_SERIES: ReadonlyMap<string, string> = new Map<string, string>([
78
+ ["proxmox_vm_uptime", "pve_uptime_seconds"],
79
+ // vmstatus: `cpu` is a 0..1 ratio of the guest's allocated vCPUs.
80
+ ["proxmox_vm_cpu", "pve_cpu_usage_ratio"],
81
+ ["proxmox_vm_cpus", "pve_cpu_usage_limit"],
82
+ ["proxmox_vm_mem", "pve_memory_usage_bytes"],
83
+ ["proxmox_vm_maxmem", "pve_memory_size_bytes"],
84
+ ["proxmox_vm_disk", "pve_disk_usage_bytes"],
85
+ ["proxmox_vm_maxdisk", "pve_disk_size_bytes"],
86
+ ["proxmox_vm_netin_total", "pve_network_receive_bytes"],
87
+ ["proxmox_vm_netin", "pve_network_receive_bytes"],
88
+ ["proxmox_vm_netout_total", "pve_network_transmit_bytes"],
89
+ ["proxmox_vm_netout", "pve_network_transmit_bytes"],
90
+ ["proxmox_vm_diskread_total", "pve_disk_read_bytes"],
91
+ ["proxmox_vm_diskread", "pve_disk_read_bytes"],
92
+ ["proxmox_vm_diskwrite_total", "pve_disk_write_bytes"],
93
+ ["proxmox_vm_diskwrite", "pve_disk_write_bytes"],
94
+ ]);
95
+
96
+ const STORAGE_SERIES: ReadonlyMap<string, string> = new Map<string, string>([
97
+ ["proxmox_storage_used", "pve_disk_usage_bytes"],
98
+ ["proxmox_storage_total", "pve_disk_size_bytes"],
99
+ /*
100
+ * pve-exporter reports a storage as up when PVE lists it available;
101
+ * the native push's `active` flag is the same signal.
102
+ */
103
+ ["proxmox_storage_active", "pve_up"],
104
+ ]);
105
+
106
+ function scopeOfNativeSeries(metricName: string): NativeScope | null {
107
+ if (NODE_SERIES.has(metricName)) {
108
+ return "node";
109
+ }
110
+ if (GUEST_SERIES.has(metricName)) {
111
+ return "guest";
112
+ }
113
+ if (STORAGE_SERIES.has(metricName)) {
114
+ return "storage";
115
+ }
116
+ return null;
117
+ }
118
+
119
+ function canonicalNameOf(metricName: string, scope: NativeScope): string {
120
+ const table: ReadonlyMap<string, string> =
121
+ scope === "node"
122
+ ? NODE_SERIES
123
+ : scope === "guest"
124
+ ? GUEST_SERIES
125
+ : STORAGE_SERIES;
126
+ return table.get(metricName) as string;
127
+ }
128
+
129
+ function readAttributeString(
130
+ attributes: JSONArray | undefined,
131
+ key: string,
132
+ ): string | null {
133
+ if (!Array.isArray(attributes)) {
134
+ return null;
135
+ }
136
+ for (const attribute of attributes) {
137
+ const attr: JSONObject | null =
138
+ attribute && typeof attribute === "object"
139
+ ? (attribute as JSONObject)
140
+ : null;
141
+ if (!attr || attr["key"] !== key) {
142
+ continue;
143
+ }
144
+ const value: JSONObject | undefined = attr["value"] as
145
+ | JSONObject
146
+ | undefined;
147
+ if (!value || typeof value !== "object") {
148
+ continue;
149
+ }
150
+ const raw: JSONValue =
151
+ value["stringValue"] ?? value["intValue"] ?? value["doubleValue"];
152
+ if (typeof raw === "string" && raw.trim()) {
153
+ return raw.trim();
154
+ }
155
+ if (typeof raw === "number" && Number.isFinite(raw)) {
156
+ return String(raw);
157
+ }
158
+ }
159
+ return null;
160
+ }
161
+
162
+ function stringAttribute(key: string, value: string): JSONObject {
163
+ return { key, value: { stringValue: value } };
164
+ }
165
+
166
+ function readNumber(datapoint: JSONObject): number | null {
167
+ const raw: JSONValue = datapoint["asDouble"] ?? datapoint["asInt"];
168
+ if (typeof raw === "number") {
169
+ return Number.isFinite(raw) ? raw : null;
170
+ }
171
+ if (typeof raw === "string" && raw.trim()) {
172
+ const parsed: number = Number(raw);
173
+ return Number.isFinite(parsed) ? parsed : null;
174
+ }
175
+ return null;
176
+ }
177
+
178
+ function metricDataPoints(metric: JSONObject): JSONArray {
179
+ const gauge: JSONObject | undefined = metric["gauge"] as
180
+ | JSONObject
181
+ | undefined;
182
+ const sum: JSONObject | undefined = metric["sum"] as JSONObject | undefined;
183
+ const points: JSONValue =
184
+ (gauge && gauge["dataPoints"]) || (sum && sum["dataPoints"]) || [];
185
+ return Array.isArray(points) ? (points as JSONArray) : [];
186
+ }
187
+
188
+ /*
189
+ * True for a resource block pushed by Proxmox VE itself. PVE always
190
+ * stamps both `proxmox.cluster` and `proxmox.node`; neither is set by the
191
+ * Proxmox Agent (which uses `proxmox.cluster.name`), so the pair tells
192
+ * the two paths apart before and after the rewrite below.
193
+ */
194
+ export function isProxmoxNativePushResource(
195
+ resourceAttributes: JSONArray | undefined,
196
+ ): boolean {
197
+ return Boolean(
198
+ readAttributeString(resourceAttributes, "proxmox.cluster") &&
199
+ readAttributeString(resourceAttributes, "proxmox.node"),
200
+ );
201
+ }
202
+
203
+ /*
204
+ * The cluster name a native push belongs to. An explicit
205
+ * `proxmox.cluster.name` (the old documented workaround, or a user's own
206
+ * choice) always wins, so existing clusters keep their identity. A
207
+ * standalone node reports the placeholder "single-node", which would
208
+ * merge every standalone host of a project into one cluster — the node
209
+ * name is used instead.
210
+ */
211
+ export function resolveProxmoxNativePushClusterName(
212
+ resourceAttributes: JSONArray | undefined,
213
+ ): string | null {
214
+ const explicit: string | null = readAttributeString(
215
+ resourceAttributes,
216
+ "proxmox.cluster.name",
217
+ );
218
+ if (explicit) {
219
+ return explicit;
220
+ }
221
+ const cluster: string | null = readAttributeString(
222
+ resourceAttributes,
223
+ "proxmox.cluster",
224
+ );
225
+ const node: string | null = readAttributeString(
226
+ resourceAttributes,
227
+ "proxmox.node",
228
+ );
229
+ if (cluster && cluster !== PROXMOX_NATIVE_PUSH_STANDALONE_CLUSTER) {
230
+ return cluster;
231
+ }
232
+ return node || cluster;
233
+ }
234
+
235
+ interface ResourceIdentity {
236
+ id: string;
237
+ scope: NativeScope;
238
+ type: string;
239
+ labels: Array<JSONObject>; // extra labels of the *_info series
240
+ infoMetricName: string;
241
+ }
242
+
243
+ function identityOf(data: {
244
+ scope: NativeScope;
245
+ datapointAttributes: JSONArray | undefined;
246
+ resourceNode: string | null;
247
+ }): ResourceIdentity | null {
248
+ const node: string | null =
249
+ readAttributeString(data.datapointAttributes, "node") || data.resourceNode;
250
+
251
+ if (data.scope === "node") {
252
+ if (!node) {
253
+ return null;
254
+ }
255
+ return {
256
+ id: `node/${node}`,
257
+ scope: "node",
258
+ type: "node",
259
+ labels: [stringAttribute("name", node)],
260
+ infoMetricName: "pve_node_info",
261
+ };
262
+ }
263
+
264
+ if (data.scope === "guest") {
265
+ const vmid: string | null = readAttributeString(
266
+ data.datapointAttributes,
267
+ "vmid",
268
+ );
269
+ const type: string | null = readAttributeString(
270
+ data.datapointAttributes,
271
+ "type",
272
+ );
273
+ if (!vmid || (type !== "qemu" && type !== "lxc")) {
274
+ return null;
275
+ }
276
+ const labels: Array<JSONObject> = [stringAttribute("type", type)];
277
+ const name: string | null = readAttributeString(
278
+ data.datapointAttributes,
279
+ "name",
280
+ );
281
+ if (name) {
282
+ labels.push(stringAttribute("name", name));
283
+ }
284
+ if (node) {
285
+ labels.push(stringAttribute("node", node));
286
+ }
287
+ return {
288
+ id: `${type}/${vmid}`,
289
+ scope: "guest",
290
+ type,
291
+ labels,
292
+ infoMetricName: "pve_guest_info",
293
+ };
294
+ }
295
+
296
+ const storage: string | null = readAttributeString(
297
+ data.datapointAttributes,
298
+ "storage",
299
+ );
300
+ if (!storage || !node) {
301
+ return null;
302
+ }
303
+ return {
304
+ id: `storage/${node}/${storage}`,
305
+ scope: "storage",
306
+ type: "storage",
307
+ labels: [
308
+ stringAttribute("node", node),
309
+ stringAttribute("storage", storage),
310
+ ],
311
+ infoMetricName: "pve_storage_info",
312
+ };
313
+ }
314
+
315
+ // The attributes the agent's transform/pve-identity processor stamps.
316
+ function identityAttributes(identity: ResourceIdentity): Array<JSONObject> {
317
+ return [
318
+ stringAttribute("id", identity.id),
319
+ stringAttribute("pve.scope", identity.scope),
320
+ stringAttribute("pve.type", identity.type),
321
+ stringAttribute(
322
+ "pve.id",
323
+ identity.id.substring(identity.id.indexOf("/") + 1),
324
+ ),
325
+ ];
326
+ }
327
+
328
+ function gaugePoint(data: {
329
+ value: number | JSONValue;
330
+ valueKey: "asInt" | "asDouble";
331
+ timeUnixNano: JSONValue;
332
+ attributes: Array<JSONObject>;
333
+ }): JSONObject {
334
+ const point: JSONObject = {
335
+ [data.valueKey]: data.value,
336
+ attributes: data.attributes,
337
+ };
338
+ if (data.timeUnixNano !== undefined && data.timeUnixNano !== null) {
339
+ point["timeUnixNano"] = data.timeUnixNano;
340
+ }
341
+ return point;
342
+ }
343
+
344
+ /*
345
+ * Accumulates the derived datapoints of one resource block, keyed by
346
+ * canonical metric name, plus one info/up series per resource seen.
347
+ */
348
+ class DerivedSeries {
349
+ private points: Map<string, Array<JSONObject>> = new Map();
350
+ private resourcesSeen: Set<string> = new Set();
351
+ // Timestamp of the first node seen — undefined when the block has none.
352
+ public nodeTimeUnixNano: JSONValue | undefined = undefined;
353
+
354
+ public add(metricName: string, point: JSONObject): void {
355
+ let list: Array<JSONObject> | undefined = this.points.get(metricName);
356
+ if (!list) {
357
+ list = [];
358
+ this.points.set(metricName, list);
359
+ }
360
+ list.push(point);
361
+ }
362
+
363
+ // First sighting of a resource in this block → emit its info series.
364
+ public markSeen(identity: ResourceIdentity, timeUnixNano: JSONValue): void {
365
+ const key: string = `${identity.scope}|${identity.id}`;
366
+ if (this.resourcesSeen.has(key)) {
367
+ return;
368
+ }
369
+ this.resourcesSeen.add(key);
370
+
371
+ this.add(
372
+ identity.infoMetricName,
373
+ gaugePoint({
374
+ value: "1",
375
+ valueKey: "asInt",
376
+ timeUnixNano,
377
+ attributes: [...identityAttributes(identity), ...identity.labels],
378
+ }),
379
+ );
380
+
381
+ /*
382
+ * A node that pushes is up — pve-exporter reports its own view the
383
+ * same way. A node that is down pushes nothing at all; its live
384
+ * siblings report it (appendProxmoxSiblingReportsInPlace).
385
+ */
386
+ if (identity.scope === "node") {
387
+ if (this.nodeTimeUnixNano === undefined) {
388
+ this.nodeTimeUnixNano = timeUnixNano ?? null;
389
+ }
390
+ this.add(
391
+ "pve_up",
392
+ gaugePoint({
393
+ value: "1",
394
+ valueKey: "asInt",
395
+ timeUnixNano,
396
+ attributes: identityAttributes(identity),
397
+ }),
398
+ );
399
+ }
400
+ }
401
+
402
+ public hasAny(): boolean {
403
+ return this.points.size > 0;
404
+ }
405
+
406
+ public toMetrics(): Array<JSONObject> {
407
+ const metrics: Array<JSONObject> = [];
408
+ for (const [name, dataPoints] of this.points) {
409
+ metrics.push({ name, gauge: { dataPoints } });
410
+ }
411
+ return metrics;
412
+ }
413
+ }
414
+
415
+ function blockAlreadyHasPveSeries(scopeMetrics: JSONArray): boolean {
416
+ for (const scopeMetric of scopeMetrics) {
417
+ const metrics: JSONValue = (scopeMetric as JSONObject)?.["metrics"];
418
+ if (!Array.isArray(metrics)) {
419
+ continue;
420
+ }
421
+ for (const metric of metrics) {
422
+ const name: JSONValue = (metric as JSONObject)?.["name"];
423
+ if (typeof name === "string" && name.startsWith("pve_")) {
424
+ return true;
425
+ }
426
+ }
427
+ }
428
+ return false;
429
+ }
430
+
431
+ function upsertResourceAttribute(
432
+ attributes: JSONArray,
433
+ key: string,
434
+ value: string,
435
+ ): void {
436
+ for (const attribute of attributes) {
437
+ const attr: JSONObject = attribute as JSONObject;
438
+ if (attr && attr["key"] === key) {
439
+ attr["value"] = { stringValue: value };
440
+ return;
441
+ }
442
+ }
443
+ attributes.push(stringAttribute(key, value));
444
+ }
445
+
446
+ /*
447
+ * Drop the `service.name=proxmox-ve` PVE stamps, so the batch routes to
448
+ * the discovered Proxmox cluster (per-cluster retention, no phantom
449
+ * Service) exactly like the agent — whose collector config deletes
450
+ * service.name for the same reason. A service.name the user set to
451
+ * something else through the metric server's resource attributes is a
452
+ * deliberate choice and is kept.
453
+ */
454
+ function removeNativeServiceName(attributes: JSONArray): void {
455
+ for (let i: number = attributes.length - 1; i >= 0; i--) {
456
+ const attr: JSONObject = attributes[i] as JSONObject;
457
+ if (
458
+ attr &&
459
+ attr["key"] === "service.name" &&
460
+ readAttributeString([attr], "service.name") ===
461
+ PROXMOX_NATIVE_PUSH_SERVICE_NAME
462
+ ) {
463
+ attributes.splice(i, 1);
464
+ }
465
+ }
466
+ }
467
+
468
+ /*
469
+ * `service.version` is PVE's version_text(): "<version>/<repoid>", e.g.
470
+ * "9.0.10/deb1ca707ec72a89". pve-exporter reports them as the `version`
471
+ * and `repoid` labels of pve_version_info.
472
+ */
473
+ function versionInfoLabels(resourceAttributes: JSONArray): Array<JSONObject> {
474
+ const text: string | null = readAttributeString(
475
+ resourceAttributes,
476
+ "service.version",
477
+ );
478
+ if (!text) {
479
+ return [];
480
+ }
481
+ const slash: number = text.indexOf("/");
482
+ const version: string = (slash >= 0 ? text.substring(0, slash) : text).trim();
483
+ const repoid: string = slash >= 0 ? text.substring(slash + 1).trim() : "";
484
+ if (!version) {
485
+ return [];
486
+ }
487
+ const labels: Array<JSONObject> = [stringAttribute("version", version)];
488
+ if (repoid) {
489
+ labels.push(stringAttribute("repoid", repoid));
490
+ }
491
+ return labels;
492
+ }
493
+
494
+ /*
495
+ * Derive the pve_* series of one scopeMetrics entry and append them to
496
+ * it. Returns what was derived, for the version-info decision.
497
+ */
498
+ function deriveScopeMetrics(data: {
499
+ scopeMetric: JSONObject;
500
+ resourceNode: string | null;
501
+ }): DerivedSeries {
502
+ const derived: DerivedSeries = new DerivedSeries();
503
+ const metrics: JSONValue = data.scopeMetric["metrics"];
504
+ if (!Array.isArray(metrics)) {
505
+ return derived;
506
+ }
507
+
508
+ for (const metricValue of metrics) {
509
+ const metric: JSONObject | null =
510
+ metricValue && typeof metricValue === "object"
511
+ ? (metricValue as JSONObject)
512
+ : null;
513
+ const metricName: JSONValue = metric?.["name"];
514
+ if (!metric || typeof metricName !== "string") {
515
+ continue;
516
+ }
517
+ const scope: NativeScope | null = scopeOfNativeSeries(metricName);
518
+ if (!scope) {
519
+ continue;
520
+ }
521
+ const canonicalName: string = canonicalNameOf(metricName, scope);
522
+
523
+ for (const datapointValue of metricDataPoints(metric)) {
524
+ const datapoint: JSONObject | null =
525
+ datapointValue && typeof datapointValue === "object"
526
+ ? (datapointValue as JSONObject)
527
+ : null;
528
+ if (!datapoint) {
529
+ continue;
530
+ }
531
+ const value: number | null = readNumber(datapoint);
532
+ if (value === null) {
533
+ continue;
534
+ }
535
+ const identity: ResourceIdentity | null = identityOf({
536
+ scope,
537
+ datapointAttributes: datapoint["attributes"] as JSONArray | undefined,
538
+ resourceNode: data.resourceNode,
539
+ });
540
+ if (!identity) {
541
+ continue;
542
+ }
543
+
544
+ const timeUnixNano: JSONValue = datapoint["timeUnixNano"];
545
+ derived.markSeen(identity, timeUnixNano);
546
+
547
+ const hasDouble: boolean =
548
+ datapoint["asDouble"] !== undefined && datapoint["asDouble"] !== null;
549
+ derived.add(
550
+ canonicalName,
551
+ gaugePoint({
552
+ value: hasDouble ? datapoint["asDouble"] : datapoint["asInt"],
553
+ valueKey: hasDouble ? "asDouble" : "asInt",
554
+ timeUnixNano,
555
+ attributes: identityAttributes(identity),
556
+ }),
557
+ );
558
+
559
+ /*
560
+ * PVE has no run-state series for guests; a running guest is the
561
+ * one with a non-zero uptime (vmstatus zeroes it when stopped).
562
+ * pve-exporter's pve_up is the same "status == running" signal.
563
+ */
564
+ if (identity.scope === "guest" && metricName === "proxmox_vm_uptime") {
565
+ derived.add(
566
+ "pve_up",
567
+ gaugePoint({
568
+ value: value > 0 ? "1" : "0",
569
+ valueKey: "asInt",
570
+ timeUnixNano,
571
+ attributes: identityAttributes(identity),
572
+ }),
573
+ );
574
+ }
575
+ }
576
+ }
577
+
578
+ return derived;
579
+ }
580
+
581
+ /*
582
+ * Rewrite every Proxmox VE native-push block of an OTLP metrics payload
583
+ * in place (see the header). Blocks from any other source — including
584
+ * the Proxmox Agent — are left exactly as they are. Idempotent: a block
585
+ * that already carries pve_* series (translated upstream, or already
586
+ * rewritten) only gets its cluster identity filled in.
587
+ */
588
+ export function normalizeProxmoxNativePushInPlace(
589
+ resourceEnvelopes: JSONArray,
590
+ ): void {
591
+ if (!Array.isArray(resourceEnvelopes)) {
592
+ return;
593
+ }
594
+
595
+ for (const envelopeValue of resourceEnvelopes) {
596
+ const envelope: JSONObject | null =
597
+ envelopeValue && typeof envelopeValue === "object"
598
+ ? (envelopeValue as JSONObject)
599
+ : null;
600
+ const resource: JSONObject | undefined = envelope?.["resource"] as
601
+ | JSONObject
602
+ | undefined;
603
+ const attributes: JSONValue = resource?.["attributes"];
604
+ if (!envelope || !Array.isArray(attributes)) {
605
+ continue;
606
+ }
607
+ const resourceAttributes: JSONArray = attributes as JSONArray;
608
+ if (!isProxmoxNativePushResource(resourceAttributes)) {
609
+ continue;
610
+ }
611
+
612
+ const clusterName: string | null =
613
+ resolveProxmoxNativePushClusterName(resourceAttributes);
614
+ if (clusterName) {
615
+ upsertResourceAttribute(
616
+ resourceAttributes,
617
+ "proxmox.cluster.name",
618
+ clusterName,
619
+ );
620
+ }
621
+ removeNativeServiceName(resourceAttributes);
622
+
623
+ const scopeMetricsValue: JSONValue = envelope["scopeMetrics"];
624
+ if (!Array.isArray(scopeMetricsValue)) {
625
+ continue;
626
+ }
627
+ const scopeMetrics: JSONArray = scopeMetricsValue as JSONArray;
628
+ if (blockAlreadyHasPveSeries(scopeMetrics)) {
629
+ continue;
630
+ }
631
+
632
+ const resourceNode: string | null = readAttributeString(
633
+ resourceAttributes,
634
+ "proxmox.node",
635
+ );
636
+
637
+ for (const scopeMetricValue of scopeMetrics) {
638
+ if (!scopeMetricValue || typeof scopeMetricValue !== "object") {
639
+ continue;
640
+ }
641
+ const scopeMetric: JSONObject = scopeMetricValue as JSONObject;
642
+ const derived: DerivedSeries = deriveScopeMetrics({
643
+ scopeMetric,
644
+ resourceNode,
645
+ });
646
+ if (!derived.hasAny()) {
647
+ continue;
648
+ }
649
+
650
+ /*
651
+ * One version series per node push (PVE flushes node, qemu, lxc
652
+ * and storage status as separate requests) — the node's own push
653
+ * is the one that carries it.
654
+ */
655
+ if (derived.nodeTimeUnixNano !== undefined) {
656
+ const labels: Array<JSONObject> = versionInfoLabels(resourceAttributes);
657
+ if (labels.length > 0) {
658
+ derived.add(
659
+ "pve_version_info",
660
+ gaugePoint({
661
+ value: "1",
662
+ valueKey: "asInt",
663
+ timeUnixNano: derived.nodeTimeUnixNano,
664
+ attributes: labels,
665
+ }),
666
+ );
667
+ }
668
+ }
669
+
670
+ (scopeMetric["metrics"] as JSONArray).push(...derived.toMetrics());
671
+ }
672
+ }
673
+ }
674
+
675
+ /*
676
+ * ------------------------------------------------------------------
677
+ * Reporting the nodes that have stopped reporting
678
+ * ------------------------------------------------------------------
679
+ *
680
+ * A native-push node that dies goes quiet — nothing ever says pve_up = 0
681
+ * for it. The nodes still alive speak for it: a live node's own status
682
+ * push carries, next to its own pve_up = 1, a pve_up = 0 for every
683
+ * sibling that has gone quiet (ProxmoxNativeNodeLiveness decides which).
684
+ * That is what pve-exporter does for the agent — one node's view reports
685
+ * the dead ones — so the unchanged Node Offline and Cluster Quorum at
686
+ * Risk monitors now fire on a native push too.
687
+ *
688
+ * The reports sit in their own scopeMetrics entry, named
689
+ * PROXMOX_SIBLING_REPORT_SCOPE_NAME, and every datapoint carries
690
+ * `oneuptime.proxmox.inferred = not-reporting`, so they can always be
691
+ * told apart from what a node said itself. The inventory fold skips
692
+ * them: a report must never refresh the silent node's "last seen".
693
+ *
694
+ * Quorum at Risk is Σ pve_up ÷ Σ pve_node_info over every row of a
695
+ * minute, so each node must weigh the same in the denominator. Every
696
+ * live node contributes one pve_node_info = 1 per push, and every live
697
+ * node reports (ProxmoxNativeNodeLiveness): with L live nodes and D
698
+ * silent ones, each report carries pve_node_info = D ÷ L in total (split
699
+ * across the silent nodes). A minute in which the live nodes land P
700
+ * pushes between them then sums to P in the numerator and P + P·D/L in
701
+ * the denominator — the ratio is L ÷ (L + D), as with the agent, however
702
+ * unevenly the pushes fall into the minute. The weights are multiples of
703
+ * 2^-16, so any sum of them is exact in floating point, whatever order
704
+ * ClickHouse adds them in, and rounded UP, so a cluster exactly half
705
+ * down never reads a hair above 50 %.
706
+ * ------------------------------------------------------------------
707
+ */
708
+
709
+ export const PROXMOX_SIBLING_REPORT_SCOPE_NAME: string =
710
+ "oneuptime.proxmox.sibling-report";
711
+
712
+ // Marks every reported datapoint as inferred, not measured.
713
+ export const PROXMOX_INFERRED_ATTRIBUTE: string = "oneuptime.proxmox.inferred";
714
+ export const PROXMOX_INFERRED_NOT_REPORTING: string = "not-reporting";
715
+
716
+ const WEIGHT_UNITS_PER_NODE: number = 65536; // 2^16
717
+
718
+ export function isProxmoxSiblingReportScope(
719
+ scopeMetric: JSONValue | undefined,
720
+ ): boolean {
721
+ const scope: JSONValue | undefined =
722
+ scopeMetric && typeof scopeMetric === "object"
723
+ ? (scopeMetric as JSONObject)["scope"]
724
+ : undefined;
725
+ return Boolean(
726
+ scope &&
727
+ typeof scope === "object" &&
728
+ (scope as JSONObject)["name"] === PROXMOX_SIBLING_REPORT_SCOPE_NAME,
729
+ );
730
+ }
731
+
732
+ /*
733
+ * The node a native-push block is the own status push of, and the
734
+ * timestamps of its own pve_up points — or null for anything else
735
+ * (guest / storage pushes, agent blocks, other telemetry). Reads the
736
+ * block after normalizeProxmoxNativePushInPlace.
737
+ */
738
+ export function readProxmoxNativeNodeStatus(
739
+ envelope: JSONValue | undefined,
740
+ ): { nodeName: string; timeUnixNanos: Array<JSONValue> } | null {
741
+ if (!envelope || typeof envelope !== "object") {
742
+ return null;
743
+ }
744
+ const resource: JSONObject | undefined = (envelope as JSONObject)[
745
+ "resource"
746
+ ] as JSONObject | undefined;
747
+ const attributes: JSONArray | undefined = resource?.["attributes"] as
748
+ | JSONArray
749
+ | undefined;
750
+ if (!isProxmoxNativePushResource(attributes)) {
751
+ return null;
752
+ }
753
+ const nodeName: string | null = readAttributeString(
754
+ attributes,
755
+ "proxmox.node",
756
+ );
757
+ const scopeMetrics: JSONValue = (envelope as JSONObject)["scopeMetrics"];
758
+ if (!nodeName || !Array.isArray(scopeMetrics)) {
759
+ return null;
760
+ }
761
+
762
+ const ownId: string = `node/${nodeName}`;
763
+ const timeUnixNanos: Array<JSONValue> = [];
764
+ for (const scopeMetric of scopeMetrics) {
765
+ if (isProxmoxSiblingReportScope(scopeMetric)) {
766
+ continue;
767
+ }
768
+ const metrics: JSONValue = (scopeMetric as JSONObject)?.["metrics"];
769
+ if (!Array.isArray(metrics)) {
770
+ continue;
771
+ }
772
+ for (const metric of metrics) {
773
+ if ((metric as JSONObject)?.["name"] !== "pve_up") {
774
+ continue;
775
+ }
776
+ for (const point of metricDataPoints(metric as JSONObject)) {
777
+ const datapoint: JSONObject | null =
778
+ point && typeof point === "object" ? (point as JSONObject) : null;
779
+ if (
780
+ datapoint &&
781
+ readAttributeString(
782
+ datapoint["attributes"] as JSONArray | undefined,
783
+ "id",
784
+ ) === ownId
785
+ ) {
786
+ timeUnixNanos.push(datapoint["timeUnixNano"] ?? null);
787
+ }
788
+ }
789
+ }
790
+ }
791
+
792
+ return timeUnixNanos.length > 0 ? { nodeName, timeUnixNanos } : null;
793
+ }
794
+
795
+ /*
796
+ * Each silent node's pve_node_info weight in one report: D ÷ L in total,
797
+ * rounded up to whole 2^-16 units, split as evenly as possible (the first
798
+ * nodes in the given order take the remainder). With L = D the weights
799
+ * add up to exactly 1. Rounding up can only ever lower the ratio by a
800
+ * negligible amount — too little to take a cluster with more live than
801
+ * silent nodes down to 50 %.
802
+ */
803
+ export function splitProxmoxSiblingInfoWeights(
804
+ silentNodes: Array<string>,
805
+ reporterCount: number,
806
+ ): Array<{ nodeName: string; weight: number }> {
807
+ if (silentNodes.length === 0 || reporterCount < 1) {
808
+ return [];
809
+ }
810
+ const totalUnits: number = Math.ceil(
811
+ (silentNodes.length * WEIGHT_UNITS_PER_NODE) / reporterCount,
812
+ );
813
+ const baseUnits: number = Math.floor(totalUnits / silentNodes.length);
814
+ const remainder: number = totalUnits - baseUnits * silentNodes.length;
815
+ return silentNodes.map((nodeName: string, index: number) => {
816
+ return {
817
+ nodeName,
818
+ weight: (baseUnits + (index < remainder ? 1 : 0)) / WEIGHT_UNITS_PER_NODE,
819
+ };
820
+ });
821
+ }
822
+
823
+ /*
824
+ * Append the "not reporting" reports to a node's own status push: per
825
+ * own pve_up point, pve_up = 0 and a pve_node_info weight for every
826
+ * silent sibling, at that point's timestamp, with the exact labels the
827
+ * sibling's own push would carry. Idempotent.
828
+ */
829
+ export function appendProxmoxSiblingReportsInPlace(
830
+ envelope: JSONObject,
831
+ report: {
832
+ silentNodes: Array<string>;
833
+ reporterCount: number;
834
+ timeUnixNanos: Array<JSONValue>;
835
+ },
836
+ ): void {
837
+ const scopeMetrics: JSONValue = envelope["scopeMetrics"];
838
+ if (
839
+ !Array.isArray(scopeMetrics) ||
840
+ report.silentNodes.length === 0 ||
841
+ report.timeUnixNanos.length === 0 ||
842
+ scopeMetrics.some((scopeMetric: JSONValue) => {
843
+ return isProxmoxSiblingReportScope(scopeMetric);
844
+ })
845
+ ) {
846
+ return;
847
+ }
848
+
849
+ const upPoints: Array<JSONObject> = [];
850
+ const infoPoints: Array<JSONObject> = [];
851
+ const inferred: JSONObject = stringAttribute(
852
+ PROXMOX_INFERRED_ATTRIBUTE,
853
+ PROXMOX_INFERRED_NOT_REPORTING,
854
+ );
855
+
856
+ for (const { nodeName, weight } of splitProxmoxSiblingInfoWeights(
857
+ report.silentNodes,
858
+ report.reporterCount,
859
+ )) {
860
+ const identity: ResourceIdentity | null = identityOf({
861
+ scope: "node",
862
+ datapointAttributes: [],
863
+ resourceNode: nodeName,
864
+ });
865
+ if (!identity) {
866
+ continue;
867
+ }
868
+ for (const timeUnixNano of report.timeUnixNanos) {
869
+ upPoints.push(
870
+ gaugePoint({
871
+ value: "0",
872
+ valueKey: "asInt",
873
+ timeUnixNano,
874
+ attributes: [...identityAttributes(identity), inferred],
875
+ }),
876
+ );
877
+ infoPoints.push(
878
+ gaugePoint({
879
+ value: weight,
880
+ valueKey: "asDouble",
881
+ timeUnixNano,
882
+ attributes: [
883
+ ...identityAttributes(identity),
884
+ ...identity.labels,
885
+ inferred,
886
+ ],
887
+ }),
888
+ );
889
+ }
890
+ }
891
+
892
+ if (upPoints.length === 0) {
893
+ return;
894
+ }
895
+
896
+ (scopeMetrics as JSONArray).push({
897
+ scope: { name: PROXMOX_SIBLING_REPORT_SCOPE_NAME, version: "1" },
898
+ metrics: [
899
+ { name: "pve_up", gauge: { dataPoints: upPoints } },
900
+ { name: "pve_node_info", gauge: { dataPoints: infoPoints } },
901
+ ],
902
+ });
903
+ }