@oneuptime/common 12.0.5 → 12.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. package/Models/DatabaseModels/AIRun.ts +33 -0
  2. package/Models/DatabaseModels/DataSource.ts +744 -0
  3. package/Models/DatabaseModels/Index.ts +3 -0
  4. package/Models/DatabaseModels/ProjectCallSMSConfig.ts +10 -2
  5. package/Models/DatabaseModels/User.ts +2 -0
  6. package/Models/DatabaseModels/UserOnCallLog.ts +2 -0
  7. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +2 -0
  8. package/Models/DatabaseModels/UserSession.ts +2 -0
  9. package/Models/DatabaseModels/UserTotpAuth.ts +6 -4
  10. package/Models/DatabaseModels/UserWebAuthn.ts +5 -3
  11. package/Server/API/AIInsightAPI.ts +47 -4
  12. package/Server/API/AIInvestigationAPI.ts +25 -0
  13. package/Server/API/DashboardAPI.ts +176 -492
  14. package/Server/API/DataSourceAPI.ts +268 -0
  15. package/Server/API/StatusPageAPI.ts +11 -1
  16. package/Server/API/UserAPI.ts +119 -0
  17. package/Server/Infrastructure/ClickhouseConfig.ts +59 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.ts +39 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.ts +24 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.ts +76 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  22. package/Server/Infrastructure/Queue.ts +26 -0
  23. package/Server/Infrastructure/QueueWorker.ts +17 -0
  24. package/Server/Middleware/TelemetryIngest.ts +8 -3
  25. package/Server/Services/AIInsightService.ts +132 -12
  26. package/Server/Services/AIRunService.ts +34 -0
  27. package/Server/Services/AIService.ts +17 -2
  28. package/Server/Services/AlertService.ts +38 -32
  29. package/Server/Services/AnalyticsDatabaseService.ts +8 -4
  30. package/Server/Services/DataSourceService.ts +200 -0
  31. package/Server/Services/HostService.ts +92 -0
  32. package/Server/Services/IncidentService.ts +45 -0
  33. package/Server/Services/Index.ts +2 -0
  34. package/Server/Services/MonitorService.ts +49 -0
  35. package/Server/Services/MonitorStatusService.ts +166 -0
  36. package/Server/Services/OpenTelemetryIngestService.ts +255 -184
  37. package/Server/Services/RumSessionPinService.ts +7 -21
  38. package/Server/Services/StatusPageSubscriberService.ts +13 -0
  39. package/Server/Services/UserService.ts +280 -9
  40. package/Server/Static/Vendor/README.md +62 -0
  41. package/Server/Static/Vendor/fonts/InterVariable.woff2 +0 -0
  42. package/Server/Static/Vendor/highlight/highlight.min.js +1244 -0
  43. package/Server/Static/Vendor/highlight/languages/apache.min.js +15 -0
  44. package/Server/Static/Vendor/highlight/languages/bash.min.js +21 -0
  45. package/Server/Static/Vendor/highlight/languages/c.min.js +41 -0
  46. package/Server/Static/Vendor/highlight/languages/cpp.min.js +47 -0
  47. package/Server/Static/Vendor/highlight/languages/csharp.min.js +49 -0
  48. package/Server/Static/Vendor/highlight/languages/css.min.js +31 -0
  49. package/Server/Static/Vendor/highlight/languages/diff.min.js +9 -0
  50. package/Server/Static/Vendor/highlight/languages/dns.min.js +11 -0
  51. package/Server/Static/Vendor/highlight/languages/dockerfile.min.js +8 -0
  52. package/Server/Static/Vendor/highlight/languages/go.min.js +20 -0
  53. package/Server/Static/Vendor/highlight/languages/graphql.min.js +12 -0
  54. package/Server/Static/Vendor/highlight/languages/http.min.js +14 -0
  55. package/Server/Static/Vendor/highlight/languages/ini.min.js +15 -0
  56. package/Server/Static/Vendor/highlight/languages/java.min.js +38 -0
  57. package/Server/Static/Vendor/highlight/languages/javascript.min.js +81 -0
  58. package/Server/Static/Vendor/highlight/languages/json.min.js +8 -0
  59. package/Server/Static/Vendor/highlight/languages/kotlin.min.js +46 -0
  60. package/Server/Static/Vendor/highlight/languages/lua.min.js +15 -0
  61. package/Server/Static/Vendor/highlight/languages/makefile.min.js +14 -0
  62. package/Server/Static/Vendor/highlight/languages/nginx.min.js +21 -0
  63. package/Server/Static/Vendor/highlight/languages/perl.min.js +41 -0
  64. package/Server/Static/Vendor/highlight/languages/php.min.js +59 -0
  65. package/Server/Static/Vendor/highlight/languages/powershell.min.js +39 -0
  66. package/Server/Static/Vendor/highlight/languages/python.min.js +42 -0
  67. package/Server/Static/Vendor/highlight/languages/r.min.js +26 -0
  68. package/Server/Static/Vendor/highlight/languages/ruby.min.js +54 -0
  69. package/Server/Static/Vendor/highlight/languages/rust.min.js +27 -0
  70. package/Server/Static/Vendor/highlight/languages/scala.min.js +28 -0
  71. package/Server/Static/Vendor/highlight/languages/sql.min.js +21 -0
  72. package/Server/Static/Vendor/highlight/languages/swift.min.js +68 -0
  73. package/Server/Static/Vendor/highlight/languages/typescript.min.js +99 -0
  74. package/Server/Static/Vendor/highlight/languages/xml.min.js +29 -0
  75. package/Server/Static/Vendor/highlight/languages/yaml.min.js +28 -0
  76. package/Server/Static/Vendor/highlight/styles/github-dark.min.css +10 -0
  77. package/Server/Static/Vendor/highlight/styles/vs2015.min.css +1 -0
  78. package/Server/Static/Vendor/tailwind/tailwind-3.4.5.js +21028 -0
  79. package/Server/Types/Database/Permissions/BasePermission.ts +7 -0
  80. package/Server/Types/Database/Permissions/DeletePermission.ts +2 -0
  81. package/Server/Types/Database/Permissions/ReadPermission.ts +3 -0
  82. package/Server/Types/Database/Permissions/TenantPermission.ts +101 -16
  83. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +2 -2
  84. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +90 -11
  85. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +1 -0
  86. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +1 -0
  87. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.ts +125 -0
  88. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +25 -15
  89. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +256 -57
  90. package/Server/Utils/AI/SRE/Insights/InsightStore.ts +76 -18
  91. package/Server/Utils/AI/SRE/InvestigationTldr.ts +352 -0
  92. package/Server/Utils/AnalyticsDatabase/InsertDedupContext.ts +7 -2
  93. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +1793 -0
  94. package/Server/Utils/Dashboard/PublicDashboardViewConfig.ts +65 -0
  95. package/Server/Utils/DataSource/ConnectorRegistry.ts +53 -0
  96. package/Server/Utils/DataSource/Connectors/ClickHouseConnector.ts +338 -0
  97. package/Server/Utils/DataSource/Connectors/ElasticsearchConnector.ts +717 -0
  98. package/Server/Utils/DataSource/Connectors/LokiConnector.ts +606 -0
  99. package/Server/Utils/DataSource/Connectors/MySqlConnector.ts +307 -0
  100. package/Server/Utils/DataSource/Connectors/PostgresConnector.ts +260 -0
  101. package/Server/Utils/DataSource/Connectors/PrometheusConnector.ts +555 -0
  102. package/Server/Utils/DataSource/Connectors/RestApiConnector.ts +597 -0
  103. package/Server/Utils/DataSource/Connectors/SqlServerConnector.ts +318 -0
  104. package/Server/Utils/DataSource/EgressGuard.ts +446 -0
  105. package/Server/Utils/DataSource/HttpFetch.ts +221 -0
  106. package/Server/Utils/DataSource/SqlQueryGuard.ts +383 -0
  107. package/Server/Utils/DataSource/SqlResultShaper.ts +372 -0
  108. package/Server/Utils/DataSource/Types.ts +93 -0
  109. package/Server/Utils/Database/PostgresErrorTranslator.ts +172 -17
  110. package/Server/Utils/InProcessMemo.ts +141 -0
  111. package/Server/Utils/InstanceHealth/TelemetryIngestion.ts +628 -0
  112. package/Server/Utils/Monitor/MonitorMetricUtil.ts +58 -0
  113. package/Server/Utils/Monitor/MonitorResource.ts +14 -0
  114. package/Server/Utils/Response.ts +12 -1
  115. package/Server/Utils/SSRFProtection.ts +237 -0
  116. package/Server/Utils/StartServer.ts +8 -0
  117. package/Server/Utils/StatusPageSubscriberWebhook.ts +30 -0
  118. package/Server/Utils/Telemetry/CaptureSpan.ts +30 -18
  119. package/Server/Utils/Telemetry/IngestionTimestamp.ts +75 -0
  120. package/Server/Utils/Telemetry/ResourceHeartbeat.ts +99 -7
  121. package/Server/Utils/Telemetry/Telemetry.ts +112 -1
  122. package/Server/Utils/Telemetry.ts +104 -3
  123. package/Server/Utils/VendorAssets.ts +165 -0
  124. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +28 -5
  125. package/Server/Utils/Workspace/Slack/Slack.ts +5 -0
  126. package/Server/Views/Partials/Head.ejs +21 -7
  127. package/Tests/App/AdminDashboard/AdminProjectsIdFilter.test.tsx +207 -0
  128. package/Tests/App/AdminDashboard/AdminUsersIdFilter.test.tsx +216 -0
  129. package/Tests/App/Dashboard/AIInsightViewActions.test.tsx +422 -0
  130. package/Tests/App/Dashboard/AddWidgetModal.test.tsx +10 -3
  131. package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +387 -0
  132. package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +199 -0
  133. package/Tests/App/Dashboard/DataSourceChartSyntheticConfig.test.tsx +736 -0
  134. package/Tests/App/Dashboard/DataSourceQueryEditor.test.tsx +868 -0
  135. package/Tests/App/Dashboard/DataSourceWidgetCatalog.test.ts +440 -0
  136. package/Tests/App/Dashboard/DataSourceWidgetFetching.test.tsx +2109 -0
  137. package/Tests/App/Dashboard/DataSourceWidgetViews.test.tsx +726 -0
  138. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +447 -0
  139. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +514 -3
  140. package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +391 -0
  141. package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +326 -0
  142. package/Tests/App/Dashboard/SideMenuHarness.tsx +187 -0
  143. package/Tests/App/Dashboard/WidgetCatalog.test.ts +6 -1
  144. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +1858 -0
  145. package/Tests/Models/DatabaseModels/DataSourceModelSecrets.test.ts +70 -0
  146. package/Tests/Server/API/AIInvestigationAPI.test.ts +187 -0
  147. package/Tests/Server/API/DashboardPublicDataSourceStrip.test.ts +686 -0
  148. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +585 -823
  149. package/Tests/Server/API/DataSourceAPIRoutes.test.ts +486 -0
  150. package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +291 -0
  151. package/Tests/Server/API/UserAuthenticationAPI.test.ts +641 -0
  152. package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +441 -0
  153. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +140 -0
  154. package/Tests/Server/Services/AIInsightService.test.ts +266 -11
  155. package/Tests/Server/Services/AIRunAnalysisTldrPersistence.test.ts +160 -0
  156. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +4 -0
  157. package/Tests/Server/Services/AlertMetricResourceAttributes.test.ts +352 -0
  158. package/Tests/Server/Services/DataSourceServiceSettings.test.ts +244 -0
  159. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +397 -0
  160. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +41 -2
  161. package/Tests/Server/Services/IncidentMetricResourceAttributes.test.ts +408 -0
  162. package/Tests/Server/Services/MonitorStatusServiceDeleteReferenceCleanup.test.ts +351 -0
  163. package/Tests/Server/Services/MonitorStatusServiceValidation.test.ts +171 -0
  164. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +398 -0
  165. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +19 -0
  166. package/Tests/Server/Services/ProjectCallSMSConfigCredentialUniqueness.test.ts +305 -0
  167. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +36 -1
  168. package/Tests/Server/Services/RumSessionPinUniqueViolationRecovery.test.ts +163 -0
  169. package/Tests/Server/Services/UserAuthenticationService.test.ts +973 -0
  170. package/Tests/Server/Types/Database/ObjectIdColumnQuery.test.ts +262 -0
  171. package/Tests/Server/Types/Database/Permissions/TenantPermission.test.ts +358 -0
  172. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +2 -2
  173. package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +6 -1
  174. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +121 -4
  175. package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +361 -10
  176. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +292 -0
  177. package/Tests/Server/Utils/AI/InvestigationTldr.test.ts +623 -0
  178. package/Tests/Server/Utils/AI/InvestigationTldrWiring.test.ts +98 -0
  179. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +857 -0
  180. package/Tests/Server/Utils/Dashboard/PublicDashboardViewConfig.test.ts +480 -0
  181. package/Tests/Server/Utils/DataSource/ClickHouseConnector.test.ts +759 -0
  182. package/Tests/Server/Utils/DataSource/ConnectorRegistry.test.ts +37 -0
  183. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +645 -0
  184. package/Tests/Server/Utils/DataSource/ElasticsearchConnector.test.ts +1206 -0
  185. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +616 -0
  186. package/Tests/Server/Utils/DataSource/LokiConnector.test.ts +970 -0
  187. package/Tests/Server/Utils/DataSource/MySqlConnector.test.ts +935 -0
  188. package/Tests/Server/Utils/DataSource/PostgresConnector.test.ts +854 -0
  189. package/Tests/Server/Utils/DataSource/PrometheusConnector.test.ts +881 -0
  190. package/Tests/Server/Utils/DataSource/RestApiConnector.test.ts +1020 -0
  191. package/Tests/Server/Utils/DataSource/SqlQueryGuard.test.ts +425 -0
  192. package/Tests/Server/Utils/DataSource/SqlResultShaper.test.ts +555 -0
  193. package/Tests/Server/Utils/DataSource/SqlServerConnector.test.ts +934 -0
  194. package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +228 -7
  195. package/Tests/Server/Utils/InProcessMemo.test.ts +292 -0
  196. package/Tests/Server/Utils/InstanceHealth/TelemetryIngestion.test.ts +960 -0
  197. package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +103 -0
  198. package/Tests/Server/Utils/Monitor/MonitorMetricResourceAttributes.test.ts +336 -0
  199. package/Tests/Server/Utils/OfflineAssetHygiene.test.ts +521 -0
  200. package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +143 -0
  201. package/Tests/Server/Utils/SSRFProtection.test.ts +193 -0
  202. package/Tests/Server/Utils/StatusPageSubscriberWebhook.test.ts +101 -0
  203. package/Tests/Server/Utils/TailwindBuildCopy.test.ts +225 -0
  204. package/Tests/Server/Utils/Telemetry/ResourceHeartbeatL1Memo.test.ts +355 -0
  205. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriter.test.ts +128 -0
  206. package/Tests/Server/Utils/Telemetry/TelemetryUtilAttributeKeys.test.ts +381 -0
  207. package/Tests/Server/Utils/Telemetry.test.ts +87 -0
  208. package/Tests/Server/Utils/VendorAssetIntegrity.test.ts +343 -0
  209. package/Tests/Server/Utils/VendorAssets.test.ts +671 -0
  210. package/Tests/Server/Views/OfflineRender.test.ts +297 -0
  211. package/Tests/Types/Dashboard/DataSourceComponentTypes.test.ts +618 -0
  212. package/Tests/Types/DateClickhouseFormat.test.ts +192 -0
  213. package/Tests/Types/Password.test.ts +363 -0
  214. package/Tests/UI/Components/ConfirmModal.test.tsx +7 -0
  215. package/Tests/UI/Components/ErrorBoundary.test.tsx +53 -0
  216. package/Tests/UI/Components/Modal.test.tsx +281 -1
  217. package/Tests/UI/Components/ObjectIdFilterPipeline.test.tsx +396 -0
  218. package/Tests/UI/Components/StatusPage/ResourceGroupNavigator.test.tsx +1147 -0
  219. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +116 -1
  220. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  221. package/Tests/Utils/Analytics.test.ts +23 -0
  222. package/Tests/Utils/Dashboard/Components/DashboardDataSourceComponents.test.ts +640 -0
  223. package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +138 -0
  224. package/Tests/Utils/DataSource/DataSourceValueReducer.test.ts +526 -0
  225. package/Tests/Utils/Metrics/MetricResourceAttributeUtil.test.ts +691 -0
  226. package/Tests/Utils/StatusPage/GroupHierarchyView.test.ts +1452 -0
  227. package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +931 -0
  228. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +288 -0
  229. package/Tests/Utils/Telemetry/IngestionTimestamp.test.ts +170 -0
  230. package/Types/AI/AIInsightEvidence.ts +6 -0
  231. package/Types/Analytics/RevenueEvent.ts +31 -0
  232. package/Types/Dashboard/DashboardComponentType.ts +31 -0
  233. package/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.ts +27 -0
  234. package/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.ts +32 -0
  235. package/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.ts +30 -0
  236. package/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.ts +55 -0
  237. package/Types/DataSource/DataSourceLimits.ts +62 -0
  238. package/Types/DataSource/DataSourceQueryConfig.ts +41 -0
  239. package/Types/DataSource/DataSourceTableResult.ts +38 -0
  240. package/Types/DataSource/DataSourceType.ts +213 -0
  241. package/Types/Date.ts +43 -3
  242. package/Types/Password.ts +64 -0
  243. package/Types/Permission.ts +46 -0
  244. package/Types/UserAuthenticationStatus.ts +34 -0
  245. package/UI/Components/Button/Button.tsx +1 -1
  246. package/UI/Components/ErrorBoundary.tsx +459 -108
  247. package/UI/Components/Icon/Icon.tsx +10 -9
  248. package/UI/Components/Modal/ConfirmModal.tsx +6 -1
  249. package/UI/Components/Modal/Modal.tsx +267 -35
  250. package/UI/Components/Modal/ModalFooter.tsx +6 -1
  251. package/UI/Components/MoreMenu/MoreMenu.tsx +19 -4
  252. package/UI/Components/MoreMenu/MoreMenuItem.tsx +6 -1
  253. package/UI/Components/StatusPage/ResourceGrid.tsx +314 -0
  254. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +808 -0
  255. package/UI/Components/StatusPage/ResourceList.tsx +570 -0
  256. package/UI/Styles/Theme.css +18 -0
  257. package/UI/Utils/API/RequestOptions.ts +7 -0
  258. package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +1 -0
  259. package/UI/Utils/ModelAPI/ModelAPI.ts +1 -0
  260. package/UI/Utils/TestDataSource.ts +61 -0
  261. package/UI/esbuild-config.js +45 -0
  262. package/Utils/Analytics.ts +15 -0
  263. package/Utils/Dashboard/Components/DashboardDataSourceChartComponent.ts +88 -0
  264. package/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.ts +123 -0
  265. package/Utils/Dashboard/Components/DashboardDataSourceShared.ts +16 -0
  266. package/Utils/Dashboard/Components/DashboardDataSourceTableComponent.ts +72 -0
  267. package/Utils/Dashboard/Components/DashboardDataSourceValueComponent.ts +126 -0
  268. package/Utils/Dashboard/Components/Index.ts +28 -0
  269. package/Utils/DataSource/DataSourceQueryText.ts +94 -0
  270. package/Utils/DataSource/DataSourceValueReducer.ts +156 -0
  271. package/Utils/Metrics/MetricResourceAttributeUtil.ts +380 -0
  272. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +8 -6
  273. package/Utils/StatusPage/GroupHierarchyView.ts +931 -0
  274. package/Utils/StatusPage/ResourceExplorer.ts +853 -0
  275. package/build/dist/Models/DatabaseModels/AIRun.js +34 -0
  276. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  277. package/build/dist/Models/DatabaseModels/DataSource.js +774 -0
  278. package/build/dist/Models/DatabaseModels/DataSource.js.map +1 -0
  279. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  280. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +14 -4
  282. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/User.js +2 -0
  284. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -0
  286. package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +2 -0
  288. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/UserSession.js +2 -0
  290. package/build/dist/Models/DatabaseModels/UserSession.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/UserTotpAuth.js +6 -4
  292. package/build/dist/Models/DatabaseModels/UserTotpAuth.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/UserWebAuthn.js +5 -3
  294. package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
  295. package/build/dist/Server/API/AIInsightAPI.js +34 -4
  296. package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
  297. package/build/dist/Server/API/AIInvestigationAPI.js +23 -0
  298. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  299. package/build/dist/Server/API/DashboardAPI.js +119 -433
  300. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  301. package/build/dist/Server/API/DataSourceAPI.js +173 -0
  302. package/build/dist/Server/API/DataSourceAPI.js.map +1 -0
  303. package/build/dist/Server/API/StatusPageAPI.js +11 -1
  304. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  305. package/build/dist/Server/API/UserAPI.js +94 -2
  306. package/build/dist/Server/API/UserAPI.js.map +1 -1
  307. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +49 -0
  308. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  309. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js +20 -0
  310. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js.map +1 -0
  311. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js +19 -0
  312. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js.map +1 -0
  313. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js +64 -0
  314. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js.map +1 -0
  315. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  316. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  317. package/build/dist/Server/Infrastructure/Queue.js +27 -0
  318. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  319. package/build/dist/Server/Infrastructure/QueueWorker.js +13 -0
  320. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  321. package/build/dist/Server/Middleware/TelemetryIngest.js +8 -3
  322. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  323. package/build/dist/Server/Services/AIInsightService.js +110 -10
  324. package/build/dist/Server/Services/AIInsightService.js.map +1 -1
  325. package/build/dist/Server/Services/AIRunService.js +34 -0
  326. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  327. package/build/dist/Server/Services/AIService.js +16 -2
  328. package/build/dist/Server/Services/AIService.js.map +1 -1
  329. package/build/dist/Server/Services/AlertService.js +28 -35
  330. package/build/dist/Server/Services/AlertService.js.map +1 -1
  331. package/build/dist/Server/Services/AnalyticsDatabaseService.js +8 -4
  332. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  333. package/build/dist/Server/Services/DataSourceService.js +159 -0
  334. package/build/dist/Server/Services/DataSourceService.js.map +1 -0
  335. package/build/dist/Server/Services/HostService.js +74 -0
  336. package/build/dist/Server/Services/HostService.js.map +1 -1
  337. package/build/dist/Server/Services/IncidentService.js +35 -24
  338. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  339. package/build/dist/Server/Services/Index.js +2 -0
  340. package/build/dist/Server/Services/Index.js.map +1 -1
  341. package/build/dist/Server/Services/MonitorService.js +45 -0
  342. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  343. package/build/dist/Server/Services/MonitorStatusService.js +129 -0
  344. package/build/dist/Server/Services/MonitorStatusService.js.map +1 -1
  345. package/build/dist/Server/Services/OpenTelemetryIngestService.js +222 -159
  346. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  347. package/build/dist/Server/Services/RumSessionPinService.js +7 -15
  348. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  349. package/build/dist/Server/Services/StatusPageSubscriberService.js +10 -0
  350. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  351. package/build/dist/Server/Services/UserService.js +241 -10
  352. package/build/dist/Server/Services/UserService.js.map +1 -1
  353. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +6 -0
  354. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  355. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js +1 -0
  356. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js.map +1 -1
  357. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +2 -0
  358. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
  359. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +68 -12
  360. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  361. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +2 -2
  362. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  363. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +68 -8
  364. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  365. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +1 -0
  366. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  367. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +1 -0
  368. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  369. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js +97 -0
  370. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js.map +1 -0
  371. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +17 -15
  372. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  373. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +178 -54
  374. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  375. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +65 -16
  376. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -1
  377. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js +303 -0
  378. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js.map +1 -0
  379. package/build/dist/Server/Utils/AnalyticsDatabase/InsertDedupContext.js.map +1 -1
  380. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +1261 -0
  381. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -0
  382. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js +47 -0
  383. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js.map +1 -0
  384. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js +42 -0
  385. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js.map +1 -0
  386. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js +187 -0
  387. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js.map +1 -0
  388. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js +493 -0
  389. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js.map +1 -0
  390. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js +399 -0
  391. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js.map +1 -0
  392. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js +195 -0
  393. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js.map +1 -0
  394. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js +149 -0
  395. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js.map +1 -0
  396. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js +362 -0
  397. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js.map +1 -0
  398. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js +342 -0
  399. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js.map +1 -0
  400. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js +186 -0
  401. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js.map +1 -0
  402. package/build/dist/Server/Utils/DataSource/EgressGuard.js +305 -0
  403. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -0
  404. package/build/dist/Server/Utils/DataSource/HttpFetch.js +134 -0
  405. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -0
  406. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js +331 -0
  407. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js.map +1 -0
  408. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js +280 -0
  409. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js.map +1 -0
  410. package/build/dist/Server/Utils/DataSource/Types.js +2 -0
  411. package/build/dist/Server/Utils/DataSource/Types.js.map +1 -0
  412. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +103 -9
  413. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
  414. package/build/dist/Server/Utils/InProcessMemo.js +113 -0
  415. package/build/dist/Server/Utils/InProcessMemo.js.map +1 -0
  416. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js +406 -0
  417. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js.map +1 -0
  418. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +34 -0
  419. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  420. package/build/dist/Server/Utils/Monitor/MonitorResource.js +14 -0
  421. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  422. package/build/dist/Server/Utils/Response.js +9 -1
  423. package/build/dist/Server/Utils/Response.js.map +1 -1
  424. package/build/dist/Server/Utils/SSRFProtection.js +192 -0
  425. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -0
  426. package/build/dist/Server/Utils/StartServer.js +7 -0
  427. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  428. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +24 -0
  429. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -1
  430. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +25 -11
  431. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  432. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js +32 -0
  433. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js.map +1 -0
  434. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +92 -5
  435. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
  436. package/build/dist/Server/Utils/Telemetry/Telemetry.js +92 -6
  437. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  438. package/build/dist/Server/Utils/Telemetry.js +93 -6
  439. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  440. package/build/dist/Server/Utils/VendorAssets.js +121 -0
  441. package/build/dist/Server/Utils/VendorAssets.js.map +1 -0
  442. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -4
  443. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  444. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +5 -0
  445. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  446. package/build/dist/Types/Analytics/RevenueEvent.js +26 -0
  447. package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -0
  448. package/build/dist/Types/Dashboard/DashboardComponentType.js +27 -0
  449. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  450. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js +2 -0
  451. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js.map +1 -0
  452. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js +2 -0
  453. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js.map +1 -0
  454. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js +2 -0
  455. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js.map +1 -0
  456. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js +16 -0
  457. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js.map +1 -0
  458. package/build/dist/Types/DataSource/DataSourceLimits.js +47 -0
  459. package/build/dist/Types/DataSource/DataSourceLimits.js.map +1 -0
  460. package/build/dist/Types/DataSource/DataSourceQueryConfig.js +10 -0
  461. package/build/dist/Types/DataSource/DataSourceQueryConfig.js.map +1 -0
  462. package/build/dist/Types/DataSource/DataSourceTableResult.js +14 -0
  463. package/build/dist/Types/DataSource/DataSourceTableResult.js.map +1 -0
  464. package/build/dist/Types/DataSource/DataSourceType.js +183 -0
  465. package/build/dist/Types/DataSource/DataSourceType.js.map +1 -0
  466. package/build/dist/Types/Date.js +38 -3
  467. package/build/dist/Types/Date.js.map +1 -1
  468. package/build/dist/Types/Password.js +56 -0
  469. package/build/dist/Types/Password.js.map +1 -0
  470. package/build/dist/Types/Permission.js +42 -0
  471. package/build/dist/Types/Permission.js.map +1 -1
  472. package/build/dist/Types/UserAuthenticationStatus.js +2 -0
  473. package/build/dist/Types/UserAuthenticationStatus.js.map +1 -0
  474. package/build/dist/UI/Components/ErrorBoundary.js +388 -72
  475. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  476. package/build/dist/UI/Components/Icon/Icon.js +10 -4
  477. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  478. package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
  479. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  480. package/build/dist/UI/Components/Modal/Modal.js +178 -19
  481. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  482. package/build/dist/UI/Components/Modal/ModalFooter.js +3 -1
  483. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  484. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +9 -6
  485. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  486. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +7 -1
  487. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  488. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +119 -0
  489. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -0
  490. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +354 -0
  491. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -0
  492. package/build/dist/UI/Components/StatusPage/ResourceList.js +203 -0
  493. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -0
  494. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +1 -6
  495. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
  496. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +3 -8
  497. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  498. package/build/dist/UI/Utils/TestDataSource.js +39 -0
  499. package/build/dist/UI/Utils/TestDataSource.js.map +1 -0
  500. package/build/dist/Utils/Analytics.js +4 -0
  501. package/build/dist/Utils/Analytics.js.map +1 -1
  502. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js +79 -0
  503. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js.map +1 -0
  504. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js +111 -0
  505. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js.map +1 -0
  506. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js +15 -0
  507. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js.map +1 -0
  508. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js +62 -0
  509. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js.map +1 -0
  510. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js +112 -0
  511. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js.map +1 -0
  512. package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
  513. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  514. package/build/dist/Utils/DataSource/DataSourceQueryText.js +64 -0
  515. package/build/dist/Utils/DataSource/DataSourceQueryText.js.map +1 -0
  516. package/build/dist/Utils/DataSource/DataSourceValueReducer.js +124 -0
  517. package/build/dist/Utils/DataSource/DataSourceValueReducer.js.map +1 -0
  518. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js +281 -0
  519. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js.map +1 -0
  520. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +8 -6
  521. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
  522. package/build/dist/Utils/StatusPage/GroupHierarchyView.js +560 -0
  523. package/build/dist/Utils/StatusPage/GroupHierarchyView.js.map +1 -0
  524. package/build/dist/Utils/StatusPage/ResourceExplorer.js +519 -0
  525. package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -0
  526. package/jest.config.json +1 -0
  527. package/package.json +5 -1
  528. package/tsconfig.json +12 -10
@@ -0,0 +1,1793 @@
1
+ import InBetween from "../../../Types/BaseDatabase/InBetween";
2
+ import Includes from "../../../Types/BaseDatabase/Includes";
3
+ import Search from "../../../Types/BaseDatabase/Search";
4
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
5
+ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
6
+ import DashboardComponentType from "../../../Types/Dashboard/DashboardComponentType";
7
+ import DashboardVariable, {
8
+ DashboardVariableType,
9
+ } from "../../../Types/Dashboard/DashboardVariable";
10
+ import BadDataException from "../../../Types/Exception/BadDataException";
11
+ import { JSONObject, JSONValue } from "../../../Types/JSON";
12
+ import JSONFunctions from "../../../Types/JSONFunctions";
13
+ import {
14
+ LogFilter,
15
+ queryStringToFilter,
16
+ } from "../../../Types/Log/LogQueryToFilter";
17
+ import DashboardModelQueryInterpolation, {
18
+ AttributeToColumnMap,
19
+ } from "../../../Utils/Dashboard/ModelQueryVariableInterpolation";
20
+ import DashboardVariableInterpolation from "../../../Utils/Dashboard/VariableInterpolation";
21
+
22
+ export interface PublicDashboardResourceListPolicyResult {
23
+ resourceType: string;
24
+ query: JSONObject;
25
+ select: JSONObject;
26
+ sort: JSONObject;
27
+ limit: number;
28
+ }
29
+
30
+ export interface BuildPublicDashboardResourceListPolicyData {
31
+ widget: JSONObject;
32
+ dashboardViewConfig: unknown;
33
+ requestedVariables: unknown;
34
+ requestedQuery: unknown;
35
+ }
36
+
37
+ interface PolicyDraft {
38
+ resourceType: string;
39
+ query: Record<string, unknown>;
40
+ sort: JSONObject;
41
+ limit: number;
42
+ attributeToColumn?: AttributeToColumnMap | undefined;
43
+ interpolateAttributeMap?: boolean | undefined;
44
+ }
45
+
46
+ const DEFAULT_LIST_LIMIT: number = 25;
47
+ const DEFAULT_TELEMETRY_LIMIT: number = 50;
48
+ const DEFAULT_NETWORK_MAP_MAX_SITES: number = 250;
49
+
50
+ /*
51
+ * These bounds are deliberately much smaller than the request-body limit.
52
+ * Variable values can become IN-list parameters, so a public request must not
53
+ * be able to turn one dashboard refresh into an unbounded query compilation.
54
+ */
55
+ const MAX_REQUESTED_VARIABLES: number = 50;
56
+ const MAX_SELECTED_VALUES_PER_VARIABLE: number = 100;
57
+ const MAX_TOTAL_SELECTED_VALUES: number = 200;
58
+ const MAX_VARIABLE_ID_LENGTH: number = 256;
59
+ const MAX_VARIABLE_VALUE_LENGTH: number = 1024;
60
+
61
+ const HOST_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
62
+ "host.name": "name",
63
+ "host.id": "hostIdentifier",
64
+ "resource.host.name": "name",
65
+ "resource.host.id": "hostIdentifier",
66
+ };
67
+
68
+ const CONTAINER_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
69
+ "container.name": "name",
70
+ "container.image.name": "imageName",
71
+ };
72
+
73
+ const IMAGE_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
74
+ "container.image.name": "name",
75
+ };
76
+
77
+ const HOST_NAME_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
78
+ "host.name": "name",
79
+ };
80
+
81
+ const KUBERNETES_POD_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
82
+ "k8s.pod.name": "name",
83
+ "k8s.namespace.name": "namespaceKey",
84
+ "resource.k8s.pod.name": "name",
85
+ "resource.k8s.namespace.name": "namespaceKey",
86
+ };
87
+
88
+ const KUBERNETES_NODE_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
89
+ "k8s.node.name": "name",
90
+ "resource.k8s.node.name": "name",
91
+ };
92
+
93
+ const KUBERNETES_NAMESPACE_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
94
+ "k8s.namespace.name": "name",
95
+ "resource.k8s.namespace.name": "name",
96
+ };
97
+
98
+ const KUBERNETES_DEPLOYMENT_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
99
+ "k8s.deployment.name": "name",
100
+ "k8s.namespace.name": "namespaceKey",
101
+ "resource.k8s.deployment.name": "name",
102
+ "resource.k8s.namespace.name": "namespaceKey",
103
+ };
104
+
105
+ const KUBERNETES_STATEFUL_SET_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
106
+ "k8s.statefulset.name": "name",
107
+ "k8s.namespace.name": "namespaceKey",
108
+ "resource.k8s.statefulset.name": "name",
109
+ "resource.k8s.namespace.name": "namespaceKey",
110
+ };
111
+
112
+ const KUBERNETES_DAEMON_SET_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
113
+ "k8s.daemonset.name": "name",
114
+ "k8s.namespace.name": "namespaceKey",
115
+ "resource.k8s.daemonset.name": "name",
116
+ "resource.k8s.namespace.name": "namespaceKey",
117
+ };
118
+
119
+ const KUBERNETES_JOB_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
120
+ "k8s.job.name": "name",
121
+ "k8s.namespace.name": "namespaceKey",
122
+ "resource.k8s.job.name": "name",
123
+ "resource.k8s.namespace.name": "namespaceKey",
124
+ };
125
+
126
+ const KUBERNETES_CRON_JOB_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
127
+ "k8s.cronjob.name": "name",
128
+ "k8s.namespace.name": "namespaceKey",
129
+ "resource.k8s.cronjob.name": "name",
130
+ "resource.k8s.namespace.name": "namespaceKey",
131
+ };
132
+
133
+ const PROXMOX_NODE_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
134
+ "pve.id": "name",
135
+ };
136
+
137
+ const CEPH_OSD_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
138
+ ceph_daemon: "externalId",
139
+ };
140
+
141
+ const CEPH_POOL_ATTRIBUTE_TO_COLUMN: AttributeToColumnMap = {
142
+ pool_id: "externalId",
143
+ };
144
+
145
+ /*
146
+ * Produces the complete server-owned policy for one already-selected public
147
+ * dashboard widget. No caller-supplied project, kind, filter, sort, or limit is
148
+ * copied. The route adds the dashboard's projectId after this policy returns.
149
+ */
150
+ export default class PublicDashboardResourceListPolicy {
151
+ public static build(
152
+ data: BuildPublicDashboardResourceListPolicyData,
153
+ ): PublicDashboardResourceListPolicyResult {
154
+ const widget: Record<string, unknown> =
155
+ PublicDashboardResourceListPolicy.requireObject(
156
+ data.widget,
157
+ "Dashboard widget",
158
+ );
159
+ const argumentsObject: Record<string, unknown> =
160
+ PublicDashboardResourceListPolicy.requireObject(
161
+ widget["arguments"],
162
+ "Dashboard widget arguments",
163
+ );
164
+
165
+ const componentType: unknown = widget["componentType"];
166
+ if (typeof componentType !== "string" || componentType.length === 0) {
167
+ throw new BadDataException("Dashboard widget has no component type.");
168
+ }
169
+
170
+ const variables: Array<DashboardVariable> =
171
+ PublicDashboardResourceListPolicy.resolveDashboardVariableSelections({
172
+ dashboardViewConfig: data.dashboardViewConfig,
173
+ requestedVariables: data.requestedVariables,
174
+ });
175
+
176
+ const draft: PolicyDraft = PublicDashboardResourceListPolicy.buildDraft({
177
+ componentType: componentType as DashboardComponentType,
178
+ argumentsObject,
179
+ requestedQuery: data.requestedQuery,
180
+ });
181
+
182
+ let query: Record<string, unknown> = draft.query;
183
+
184
+ if (draft.attributeToColumn) {
185
+ query = DashboardModelQueryInterpolation.applyToQuery(
186
+ query,
187
+ variables,
188
+ draft.attributeToColumn,
189
+ );
190
+ }
191
+
192
+ if (draft.interpolateAttributeMap) {
193
+ const currentAttributes: unknown = query["attributes"];
194
+ const baseAttributes: Record<string, unknown> | undefined =
195
+ currentAttributes === undefined
196
+ ? undefined
197
+ : PublicDashboardResourceListPolicy.requireObject(
198
+ currentAttributes,
199
+ "Log attributes filter",
200
+ );
201
+ const interpolatedAttributes: Record<string, unknown> =
202
+ DashboardVariableInterpolation.applyToAttributes(
203
+ baseAttributes,
204
+ variables,
205
+ );
206
+
207
+ if (Object.keys(interpolatedAttributes).length > 0) {
208
+ query["attributes"] = interpolatedAttributes;
209
+ } else {
210
+ delete query["attributes"];
211
+ }
212
+ }
213
+
214
+ return {
215
+ resourceType: draft.resourceType,
216
+ query: query as JSONObject,
217
+ select: PublicDashboardResourceListPolicy.selectForComponent(
218
+ componentType as DashboardComponentType,
219
+ ),
220
+ sort: draft.sort,
221
+ limit: draft.limit,
222
+ };
223
+ }
224
+
225
+ /*
226
+ * Public list responses are projected to the fields consumed by the exact
227
+ * stored widget. Resource models shared by several widget kinds must never
228
+ * inherit a union of their siblings' fields.
229
+ */
230
+ private static selectForComponent(
231
+ componentType: DashboardComponentType,
232
+ ): JSONObject {
233
+ switch (componentType) {
234
+ case DashboardComponentType.IncidentList:
235
+ return {
236
+ _id: true,
237
+ title: true,
238
+ createdAt: true,
239
+ currentIncidentState: { name: true, color: true },
240
+ incidentSeverity: { name: true, color: true },
241
+ };
242
+ case DashboardComponentType.AlertList:
243
+ return {
244
+ _id: true,
245
+ title: true,
246
+ createdAt: true,
247
+ currentAlertState: { name: true, color: true },
248
+ alertSeverity: { name: true, color: true },
249
+ };
250
+ case DashboardComponentType.MonitorList:
251
+ return {
252
+ _id: true,
253
+ name: true,
254
+ monitorType: true,
255
+ currentMonitorStatus: { name: true, color: true },
256
+ };
257
+ case DashboardComponentType.NetworkMap:
258
+ return {
259
+ _id: true,
260
+ name: true,
261
+ networkSiteType: { name: true },
262
+ latitude: true,
263
+ longitude: true,
264
+ currentMonitorStatus: {
265
+ name: true,
266
+ color: true,
267
+ priority: true,
268
+ isOperationalState: true,
269
+ },
270
+ };
271
+ case DashboardComponentType.HostList:
272
+ return {
273
+ _id: true,
274
+ name: true,
275
+ otelCollectorStatus: true,
276
+ osType: true,
277
+ osVersion: true,
278
+ cpuCores: true,
279
+ totalMemoryBytes: true,
280
+ lastSeenAt: true,
281
+ };
282
+ case DashboardComponentType.KubernetesPodList:
283
+ return {
284
+ _id: true,
285
+ name: true,
286
+ namespaceKey: true,
287
+ phase: true,
288
+ kubernetesClusterId: true,
289
+ kubernetesCluster: { name: true },
290
+ };
291
+ case DashboardComponentType.KubernetesNodeList:
292
+ return {
293
+ _id: true,
294
+ name: true,
295
+ namespaceKey: true,
296
+ isReady: true,
297
+ hasMemoryPressure: true,
298
+ hasDiskPressure: true,
299
+ hasPidPressure: true,
300
+ kubernetesClusterId: true,
301
+ kubernetesCluster: { name: true },
302
+ };
303
+ case DashboardComponentType.KubernetesNamespaceList:
304
+ return {
305
+ _id: true,
306
+ name: true,
307
+ phase: true,
308
+ kubernetesClusterId: true,
309
+ kubernetesCluster: { name: true },
310
+ };
311
+ case DashboardComponentType.KubernetesDeploymentList:
312
+ case DashboardComponentType.KubernetesStatefulSetList:
313
+ case DashboardComponentType.KubernetesDaemonSetList:
314
+ case DashboardComponentType.KubernetesJobList:
315
+ case DashboardComponentType.KubernetesCronJobList:
316
+ return {
317
+ _id: true,
318
+ name: true,
319
+ namespaceKey: true,
320
+ isReady: true,
321
+ kubernetesClusterId: true,
322
+ kubernetesCluster: { name: true },
323
+ };
324
+ case DashboardComponentType.DockerHostList:
325
+ case DashboardComponentType.PodmanHostList:
326
+ return {
327
+ _id: true,
328
+ name: true,
329
+ otelCollectorStatus: true,
330
+ containersRunning: true,
331
+ containersStopped: true,
332
+ containersPaused: true,
333
+ osType: true,
334
+ osVersion: true,
335
+ };
336
+ case DashboardComponentType.DockerContainerList:
337
+ return {
338
+ _id: true,
339
+ name: true,
340
+ imageName: true,
341
+ state: true,
342
+ latestCpuPercent: true,
343
+ latestMemoryBytes: true,
344
+ dockerHostId: true,
345
+ dockerHost: { name: true },
346
+ };
347
+ case DashboardComponentType.DockerImageList:
348
+ return {
349
+ _id: true,
350
+ name: true,
351
+ containerId: true,
352
+ dockerHost: { name: true },
353
+ };
354
+ case DashboardComponentType.DockerNetworkList:
355
+ case DashboardComponentType.DockerVolumeList:
356
+ return {
357
+ _id: true,
358
+ name: true,
359
+ state: true,
360
+ dockerHost: { name: true },
361
+ };
362
+ case DashboardComponentType.PodmanContainerList:
363
+ return {
364
+ _id: true,
365
+ name: true,
366
+ imageName: true,
367
+ state: true,
368
+ latestCpuPercent: true,
369
+ latestMemoryBytes: true,
370
+ podmanHostId: true,
371
+ podmanHost: { name: true },
372
+ };
373
+ case DashboardComponentType.PodmanImageList:
374
+ return {
375
+ _id: true,
376
+ name: true,
377
+ containerId: true,
378
+ podmanHost: { name: true },
379
+ };
380
+ case DashboardComponentType.PodmanNetworkList:
381
+ case DashboardComponentType.PodmanVolumeList:
382
+ return {
383
+ _id: true,
384
+ name: true,
385
+ state: true,
386
+ podmanHost: { name: true },
387
+ };
388
+ case DashboardComponentType.ProxmoxNodeList:
389
+ return {
390
+ _id: true,
391
+ name: true,
392
+ externalId: true,
393
+ isUp: true,
394
+ latestCpuPercent: true,
395
+ latestMemoryPercent: true,
396
+ proxmoxClusterId: true,
397
+ proxmoxCluster: { name: true },
398
+ };
399
+ case DashboardComponentType.ProxmoxGuestList:
400
+ return {
401
+ _id: true,
402
+ name: true,
403
+ externalId: true,
404
+ vmid: true,
405
+ guestType: true,
406
+ parentNodeName: true,
407
+ isUp: true,
408
+ haState: true,
409
+ proxmoxClusterId: true,
410
+ proxmoxCluster: { name: true },
411
+ };
412
+ case DashboardComponentType.CephOsdList:
413
+ return {
414
+ _id: true,
415
+ name: true,
416
+ externalId: true,
417
+ hostname: true,
418
+ deviceClass: true,
419
+ isUp: true,
420
+ isIn: true,
421
+ statBytes: true,
422
+ statBytesUsed: true,
423
+ cephClusterId: true,
424
+ cephCluster: { name: true },
425
+ };
426
+ case DashboardComponentType.CephPoolList:
427
+ return {
428
+ _id: true,
429
+ name: true,
430
+ externalId: true,
431
+ storedBytes: true,
432
+ maxAvailBytes: true,
433
+ objects: true,
434
+ cephClusterId: true,
435
+ cephCluster: { name: true },
436
+ };
437
+ case DashboardComponentType.DockerSwarmNodeList:
438
+ return {
439
+ _id: true,
440
+ name: true,
441
+ externalId: true,
442
+ role: true,
443
+ state: true,
444
+ isReady: true,
445
+ latestCpuPercent: true,
446
+ latestMemoryPercent: true,
447
+ dockerSwarmClusterId: true,
448
+ dockerSwarmCluster: { name: true },
449
+ };
450
+ case DashboardComponentType.DockerSwarmServiceList:
451
+ return {
452
+ _id: true,
453
+ name: true,
454
+ externalId: true,
455
+ serviceMode: true,
456
+ desiredReplicas: true,
457
+ runningReplicas: true,
458
+ image: true,
459
+ isReady: true,
460
+ dockerSwarmClusterId: true,
461
+ dockerSwarmCluster: { name: true },
462
+ };
463
+ case DashboardComponentType.TraceList:
464
+ return {
465
+ startTime: true,
466
+ name: true,
467
+ statusCode: true,
468
+ durationUnixNano: true,
469
+ };
470
+ case DashboardComponentType.LogStream:
471
+ return {
472
+ time: true,
473
+ severityText: true,
474
+ body: true,
475
+ };
476
+ default:
477
+ throw new BadDataException(
478
+ "This dashboard widget cannot list public resources.",
479
+ );
480
+ }
481
+ }
482
+
483
+ private static buildDraft(data: {
484
+ componentType: DashboardComponentType;
485
+ argumentsObject: Record<string, unknown>;
486
+ requestedQuery: unknown;
487
+ }): PolicyDraft {
488
+ const { componentType, argumentsObject, requestedQuery } = data;
489
+
490
+ switch (componentType) {
491
+ case DashboardComponentType.IncidentList:
492
+ return PublicDashboardResourceListPolicy.buildIncidentPolicy(
493
+ argumentsObject,
494
+ );
495
+ case DashboardComponentType.AlertList:
496
+ return PublicDashboardResourceListPolicy.buildAlertPolicy(
497
+ argumentsObject,
498
+ );
499
+ case DashboardComponentType.MonitorList:
500
+ return PublicDashboardResourceListPolicy.buildMonitorPolicy(
501
+ argumentsObject,
502
+ );
503
+ case DashboardComponentType.NetworkMap:
504
+ return PublicDashboardResourceListPolicy.buildNetworkMapPolicy(
505
+ argumentsObject,
506
+ );
507
+ case DashboardComponentType.HostList:
508
+ return PublicDashboardResourceListPolicy.buildHostPolicy(
509
+ argumentsObject,
510
+ );
511
+ case DashboardComponentType.KubernetesPodList:
512
+ return PublicDashboardResourceListPolicy.buildKubernetesPolicy({
513
+ argumentsObject,
514
+ kind: "Pod",
515
+ attributeToColumn: KUBERNETES_POD_ATTRIBUTE_TO_COLUMN,
516
+ includeNamespaces: true,
517
+ componentType,
518
+ });
519
+ case DashboardComponentType.KubernetesNodeList:
520
+ return PublicDashboardResourceListPolicy.buildKubernetesPolicy({
521
+ argumentsObject,
522
+ kind: "Node",
523
+ attributeToColumn: KUBERNETES_NODE_ATTRIBUTE_TO_COLUMN,
524
+ includeNamespaces: false,
525
+ componentType,
526
+ });
527
+ case DashboardComponentType.KubernetesNamespaceList:
528
+ return PublicDashboardResourceListPolicy.buildKubernetesPolicy({
529
+ argumentsObject,
530
+ kind: "Namespace",
531
+ attributeToColumn: KUBERNETES_NAMESPACE_ATTRIBUTE_TO_COLUMN,
532
+ includeNamespaces: false,
533
+ componentType,
534
+ });
535
+ case DashboardComponentType.KubernetesDeploymentList:
536
+ return PublicDashboardResourceListPolicy.buildKubernetesPolicy({
537
+ argumentsObject,
538
+ kind: "Deployment",
539
+ attributeToColumn: KUBERNETES_DEPLOYMENT_ATTRIBUTE_TO_COLUMN,
540
+ includeNamespaces: true,
541
+ componentType,
542
+ });
543
+ case DashboardComponentType.KubernetesStatefulSetList:
544
+ return PublicDashboardResourceListPolicy.buildKubernetesPolicy({
545
+ argumentsObject,
546
+ kind: "StatefulSet",
547
+ attributeToColumn: KUBERNETES_STATEFUL_SET_ATTRIBUTE_TO_COLUMN,
548
+ includeNamespaces: true,
549
+ componentType,
550
+ });
551
+ case DashboardComponentType.KubernetesDaemonSetList:
552
+ return PublicDashboardResourceListPolicy.buildKubernetesPolicy({
553
+ argumentsObject,
554
+ kind: "DaemonSet",
555
+ attributeToColumn: KUBERNETES_DAEMON_SET_ATTRIBUTE_TO_COLUMN,
556
+ includeNamespaces: true,
557
+ componentType,
558
+ });
559
+ case DashboardComponentType.KubernetesJobList:
560
+ return PublicDashboardResourceListPolicy.buildKubernetesPolicy({
561
+ argumentsObject,
562
+ kind: "Job",
563
+ attributeToColumn: KUBERNETES_JOB_ATTRIBUTE_TO_COLUMN,
564
+ includeNamespaces: true,
565
+ componentType,
566
+ });
567
+ case DashboardComponentType.KubernetesCronJobList:
568
+ return PublicDashboardResourceListPolicy.buildKubernetesPolicy({
569
+ argumentsObject,
570
+ kind: "CronJob",
571
+ attributeToColumn: KUBERNETES_CRON_JOB_ATTRIBUTE_TO_COLUMN,
572
+ includeNamespaces: true,
573
+ componentType,
574
+ });
575
+ case DashboardComponentType.DockerHostList:
576
+ return PublicDashboardResourceListPolicy.buildContainerHostPolicy({
577
+ argumentsObject,
578
+ resourceType: "docker-host",
579
+ });
580
+ case DashboardComponentType.DockerContainerList:
581
+ return PublicDashboardResourceListPolicy.buildContainerPolicy({
582
+ argumentsObject,
583
+ resourceType: "docker-container",
584
+ hostIdKey: "dockerHostId",
585
+ storedHostIdsKey: "dockerHostIds",
586
+ });
587
+ case DashboardComponentType.DockerImageList:
588
+ return PublicDashboardResourceListPolicy.buildImagePolicy({
589
+ argumentsObject,
590
+ resourceType: "docker-image",
591
+ hostIdKey: "dockerHostId",
592
+ storedHostIdsKey: "dockerHostIds",
593
+ });
594
+ case DashboardComponentType.DockerNetworkList:
595
+ return PublicDashboardResourceListPolicy.buildContainerInventoryPolicy({
596
+ argumentsObject,
597
+ resourceType: "docker-network",
598
+ kind: "Network",
599
+ hostIdKey: "dockerHostId",
600
+ storedHostIdsKey: "dockerHostIds",
601
+ });
602
+ case DashboardComponentType.DockerVolumeList:
603
+ return PublicDashboardResourceListPolicy.buildContainerInventoryPolicy({
604
+ argumentsObject,
605
+ resourceType: "docker-volume",
606
+ kind: "Volume",
607
+ hostIdKey: "dockerHostId",
608
+ storedHostIdsKey: "dockerHostIds",
609
+ });
610
+ case DashboardComponentType.PodmanHostList:
611
+ return PublicDashboardResourceListPolicy.buildContainerHostPolicy({
612
+ argumentsObject,
613
+ resourceType: "podman-host",
614
+ });
615
+ case DashboardComponentType.PodmanContainerList:
616
+ return PublicDashboardResourceListPolicy.buildContainerPolicy({
617
+ argumentsObject,
618
+ resourceType: "podman-container",
619
+ hostIdKey: "podmanHostId",
620
+ storedHostIdsKey: "podmanHostIds",
621
+ });
622
+ case DashboardComponentType.PodmanImageList:
623
+ return PublicDashboardResourceListPolicy.buildImagePolicy({
624
+ argumentsObject,
625
+ resourceType: "podman-image",
626
+ hostIdKey: "podmanHostId",
627
+ storedHostIdsKey: "podmanHostIds",
628
+ });
629
+ case DashboardComponentType.PodmanNetworkList:
630
+ return PublicDashboardResourceListPolicy.buildContainerInventoryPolicy({
631
+ argumentsObject,
632
+ resourceType: "podman-network",
633
+ kind: "Network",
634
+ hostIdKey: "podmanHostId",
635
+ storedHostIdsKey: "podmanHostIds",
636
+ });
637
+ case DashboardComponentType.PodmanVolumeList:
638
+ return PublicDashboardResourceListPolicy.buildContainerInventoryPolicy({
639
+ argumentsObject,
640
+ resourceType: "podman-volume",
641
+ kind: "Volume",
642
+ hostIdKey: "podmanHostId",
643
+ storedHostIdsKey: "podmanHostIds",
644
+ });
645
+ case DashboardComponentType.ProxmoxNodeList:
646
+ return PublicDashboardResourceListPolicy.buildProxmoxNodePolicy(
647
+ argumentsObject,
648
+ );
649
+ case DashboardComponentType.ProxmoxGuestList:
650
+ return PublicDashboardResourceListPolicy.buildProxmoxGuestPolicy(
651
+ argumentsObject,
652
+ );
653
+ case DashboardComponentType.CephOsdList:
654
+ return PublicDashboardResourceListPolicy.buildCephOsdPolicy(
655
+ argumentsObject,
656
+ );
657
+ case DashboardComponentType.CephPoolList:
658
+ return PublicDashboardResourceListPolicy.buildCephPoolPolicy(
659
+ argumentsObject,
660
+ );
661
+ case DashboardComponentType.DockerSwarmNodeList:
662
+ return PublicDashboardResourceListPolicy.buildDockerSwarmNodePolicy(
663
+ argumentsObject,
664
+ );
665
+ case DashboardComponentType.DockerSwarmServiceList:
666
+ return PublicDashboardResourceListPolicy.buildDockerSwarmServicePolicy(
667
+ argumentsObject,
668
+ );
669
+ case DashboardComponentType.TraceList:
670
+ return PublicDashboardResourceListPolicy.buildTracePolicy({
671
+ argumentsObject,
672
+ requestedQuery,
673
+ });
674
+ case DashboardComponentType.LogStream:
675
+ return PublicDashboardResourceListPolicy.buildLogPolicy({
676
+ argumentsObject,
677
+ requestedQuery,
678
+ });
679
+ default:
680
+ throw new BadDataException(
681
+ `Unsupported public dashboard resource widget: ${componentType}`,
682
+ );
683
+ }
684
+ }
685
+
686
+ private static buildIncidentPolicy(
687
+ argumentsObject: Record<string, unknown>,
688
+ ): PolicyDraft {
689
+ const query: Record<string, unknown> = {};
690
+ const stateFilter: string | undefined =
691
+ PublicDashboardResourceListPolicy.optionalEnum(
692
+ argumentsObject,
693
+ "stateFilter",
694
+ ["unresolved", "resolved", "acknowledged"],
695
+ );
696
+
697
+ if (stateFilter === "unresolved") {
698
+ query["currentIncidentState"] = { isResolvedState: false };
699
+ } else if (stateFilter === "resolved") {
700
+ query["currentIncidentState"] = { isResolvedState: true };
701
+ } else if (stateFilter === "acknowledged") {
702
+ query["currentIncidentState"] = { isAcknowledgedState: true };
703
+ }
704
+
705
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
706
+ query,
707
+ queryKey: "incidentSeverityId",
708
+ argumentsObject,
709
+ argumentKey: "severityIds",
710
+ });
711
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
712
+ query,
713
+ queryKey: "currentIncidentStateId",
714
+ argumentsObject,
715
+ argumentKey: "stateIds",
716
+ });
717
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
718
+ query,
719
+ queryKey: "monitors",
720
+ argumentsObject,
721
+ argumentKey: "monitorIds",
722
+ });
723
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
724
+ query,
725
+ queryKey: "labels",
726
+ argumentsObject,
727
+ argumentKey: "labelIds",
728
+ });
729
+
730
+ return PublicDashboardResourceListPolicy.listDraft({
731
+ resourceType: "incident",
732
+ query,
733
+ sort: { createdAt: SortOrder.Descending },
734
+ argumentsObject,
735
+ });
736
+ }
737
+
738
+ private static buildAlertPolicy(
739
+ argumentsObject: Record<string, unknown>,
740
+ ): PolicyDraft {
741
+ const query: Record<string, unknown> = {};
742
+ const stateFilter: string | undefined =
743
+ PublicDashboardResourceListPolicy.optionalEnum(
744
+ argumentsObject,
745
+ "stateFilter",
746
+ ["unresolved", "resolved", "acknowledged"],
747
+ );
748
+
749
+ if (stateFilter === "unresolved") {
750
+ query["currentAlertState"] = { isResolvedState: false };
751
+ } else if (stateFilter === "resolved") {
752
+ query["currentAlertState"] = { isResolvedState: true };
753
+ } else if (stateFilter === "acknowledged") {
754
+ query["currentAlertState"] = { isAcknowledgedState: true };
755
+ }
756
+
757
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
758
+ query,
759
+ queryKey: "alertSeverityId",
760
+ argumentsObject,
761
+ argumentKey: "severityIds",
762
+ });
763
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
764
+ query,
765
+ queryKey: "currentAlertStateId",
766
+ argumentsObject,
767
+ argumentKey: "stateIds",
768
+ });
769
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
770
+ query,
771
+ queryKey: "monitorId",
772
+ argumentsObject,
773
+ argumentKey: "monitorIds",
774
+ });
775
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
776
+ query,
777
+ queryKey: "labels",
778
+ argumentsObject,
779
+ argumentKey: "labelIds",
780
+ });
781
+
782
+ return PublicDashboardResourceListPolicy.listDraft({
783
+ resourceType: "alert",
784
+ query,
785
+ sort: { createdAt: SortOrder.Descending },
786
+ argumentsObject,
787
+ });
788
+ }
789
+
790
+ private static buildMonitorPolicy(
791
+ argumentsObject: Record<string, unknown>,
792
+ ): PolicyDraft {
793
+ const query: Record<string, unknown> = {};
794
+ const statusFilter: string | undefined =
795
+ PublicDashboardResourceListPolicy.optionalEnum(
796
+ argumentsObject,
797
+ "statusFilter",
798
+ ["operational", "non-operational"],
799
+ );
800
+
801
+ if (statusFilter === "operational") {
802
+ query["currentMonitorStatus"] = { isOperationalState: true };
803
+ } else if (statusFilter === "non-operational") {
804
+ query["currentMonitorStatus"] = { isOperationalState: false };
805
+ }
806
+
807
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
808
+ query,
809
+ queryKey: "currentMonitorStatusId",
810
+ argumentsObject,
811
+ argumentKey: "monitorStatusIds",
812
+ });
813
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
814
+ query,
815
+ queryKey: "monitorType",
816
+ argumentsObject,
817
+ argumentKey: "monitorTypes",
818
+ });
819
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
820
+ query,
821
+ queryKey: "labels",
822
+ argumentsObject,
823
+ argumentKey: "labelIds",
824
+ });
825
+
826
+ return PublicDashboardResourceListPolicy.listDraft({
827
+ resourceType: "monitor",
828
+ query,
829
+ sort: { name: SortOrder.Ascending },
830
+ argumentsObject,
831
+ });
832
+ }
833
+
834
+ private static buildNetworkMapPolicy(
835
+ argumentsObject: Record<string, unknown>,
836
+ ): PolicyDraft {
837
+ const query: Record<string, unknown> = {};
838
+ const statusFilter: string | undefined =
839
+ PublicDashboardResourceListPolicy.optionalEnum(
840
+ argumentsObject,
841
+ "statusFilter",
842
+ ["down", "operational"],
843
+ );
844
+
845
+ if (statusFilter === "down") {
846
+ query["currentMonitorStatus"] = { isOperationalState: false };
847
+ } else if (statusFilter === "operational") {
848
+ query["currentMonitorStatus"] = { isOperationalState: true };
849
+ }
850
+
851
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
852
+ query,
853
+ queryKey: "networkSiteTypeId",
854
+ argumentsObject,
855
+ argumentKey: "networkSiteTypeIds",
856
+ });
857
+
858
+ const maxSites: number = PublicDashboardResourceListPolicy.storedLimit({
859
+ value: argumentsObject["maxSites"],
860
+ fallback: DEFAULT_NETWORK_MAP_MAX_SITES,
861
+ ceiling: LIMIT_PER_PROJECT - 1,
862
+ });
863
+
864
+ return {
865
+ resourceType: "network-site",
866
+ query,
867
+ sort: { name: SortOrder.Ascending },
868
+ // The map fetches one sentinel row to tell whether its display is capped.
869
+ limit: Math.min(maxSites + 1, LIMIT_PER_PROJECT),
870
+ };
871
+ }
872
+
873
+ private static buildHostPolicy(
874
+ argumentsObject: Record<string, unknown>,
875
+ ): PolicyDraft {
876
+ const query: Record<string, unknown> = {};
877
+ PublicDashboardResourceListPolicy.addCollectorStatusFilter(
878
+ query,
879
+ argumentsObject,
880
+ );
881
+
882
+ const osType: string | undefined =
883
+ PublicDashboardResourceListPolicy.optionalEnum(
884
+ argumentsObject,
885
+ "osTypeFilter",
886
+ ["linux", "darwin", "windows"],
887
+ );
888
+ if (osType) {
889
+ query["osType"] = osType;
890
+ }
891
+
892
+ return {
893
+ ...PublicDashboardResourceListPolicy.listDraft({
894
+ resourceType: "host",
895
+ query,
896
+ sort: { name: SortOrder.Ascending },
897
+ argumentsObject,
898
+ }),
899
+ attributeToColumn: HOST_ATTRIBUTE_TO_COLUMN,
900
+ };
901
+ }
902
+
903
+ private static buildKubernetesPolicy(data: {
904
+ argumentsObject: Record<string, unknown>;
905
+ kind: string;
906
+ attributeToColumn: AttributeToColumnMap;
907
+ includeNamespaces: boolean;
908
+ componentType: DashboardComponentType;
909
+ }): PolicyDraft {
910
+ const { argumentsObject } = data;
911
+ const query: Record<string, unknown> = { kind: data.kind };
912
+
913
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
914
+ query,
915
+ queryKey: "kubernetesClusterId",
916
+ argumentsObject,
917
+ argumentKey: "kubernetesClusterIds",
918
+ });
919
+
920
+ if (data.includeNamespaces) {
921
+ const namespaces: string | undefined =
922
+ PublicDashboardResourceListPolicy.optionalString(
923
+ argumentsObject,
924
+ "namespaces",
925
+ true,
926
+ );
927
+ if (namespaces) {
928
+ const parsedNamespaces: Array<string> = namespaces
929
+ .split(",")
930
+ .map((namespace: string) => {
931
+ return namespace.trim();
932
+ })
933
+ .filter((namespace: string) => {
934
+ return namespace.length > 0;
935
+ });
936
+ if (parsedNamespaces.length > 0) {
937
+ query["namespaceKey"] = new Includes(parsedNamespaces);
938
+ }
939
+ }
940
+ }
941
+
942
+ if (data.componentType === DashboardComponentType.KubernetesPodList) {
943
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
944
+ query,
945
+ queryKey: "phase",
946
+ argumentsObject,
947
+ argumentKey: "podPhases",
948
+ });
949
+ }
950
+
951
+ if (data.componentType === DashboardComponentType.KubernetesNodeList) {
952
+ const readinessFilter: string | undefined =
953
+ PublicDashboardResourceListPolicy.optionalEnum(
954
+ argumentsObject,
955
+ "readinessFilter",
956
+ ["ready", "not-ready"],
957
+ );
958
+ if (readinessFilter === "ready") {
959
+ query["isReady"] = true;
960
+ } else if (readinessFilter === "not-ready") {
961
+ query["isReady"] = false;
962
+ }
963
+ }
964
+
965
+ return {
966
+ ...PublicDashboardResourceListPolicy.listDraft({
967
+ resourceType: "kubernetes-resource",
968
+ query,
969
+ sort: {
970
+ namespaceKey: SortOrder.Ascending,
971
+ name: SortOrder.Ascending,
972
+ },
973
+ argumentsObject,
974
+ }),
975
+ attributeToColumn: data.attributeToColumn,
976
+ };
977
+ }
978
+
979
+ private static buildContainerHostPolicy(data: {
980
+ argumentsObject: Record<string, unknown>;
981
+ resourceType: string;
982
+ }): PolicyDraft {
983
+ const query: Record<string, unknown> = {};
984
+ PublicDashboardResourceListPolicy.addCollectorStatusFilter(
985
+ query,
986
+ data.argumentsObject,
987
+ );
988
+
989
+ return {
990
+ ...PublicDashboardResourceListPolicy.listDraft({
991
+ resourceType: data.resourceType,
992
+ query,
993
+ sort: { name: SortOrder.Ascending },
994
+ argumentsObject: data.argumentsObject,
995
+ }),
996
+ attributeToColumn: HOST_NAME_ATTRIBUTE_TO_COLUMN,
997
+ };
998
+ }
999
+
1000
+ private static buildContainerPolicy(data: {
1001
+ argumentsObject: Record<string, unknown>;
1002
+ resourceType: string;
1003
+ hostIdKey: string;
1004
+ storedHostIdsKey: string;
1005
+ }): PolicyDraft {
1006
+ const query: Record<string, unknown> = { kind: "Container" };
1007
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
1008
+ query,
1009
+ queryKey: data.hostIdKey,
1010
+ argumentsObject: data.argumentsObject,
1011
+ argumentKey: data.storedHostIdsKey,
1012
+ });
1013
+
1014
+ const imageName: string | undefined =
1015
+ PublicDashboardResourceListPolicy.optionalString(
1016
+ data.argumentsObject,
1017
+ "imageName",
1018
+ true,
1019
+ );
1020
+ if (imageName) {
1021
+ query["imageName"] = new Search(imageName);
1022
+ }
1023
+
1024
+ return {
1025
+ ...PublicDashboardResourceListPolicy.listDraft({
1026
+ resourceType: data.resourceType,
1027
+ query,
1028
+ sort: { name: SortOrder.Ascending },
1029
+ argumentsObject: data.argumentsObject,
1030
+ }),
1031
+ attributeToColumn: CONTAINER_ATTRIBUTE_TO_COLUMN,
1032
+ };
1033
+ }
1034
+
1035
+ private static buildImagePolicy(data: {
1036
+ argumentsObject: Record<string, unknown>;
1037
+ resourceType: string;
1038
+ hostIdKey: string;
1039
+ storedHostIdsKey: string;
1040
+ }): PolicyDraft {
1041
+ const query: Record<string, unknown> = { kind: "Image" };
1042
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
1043
+ query,
1044
+ queryKey: data.hostIdKey,
1045
+ argumentsObject: data.argumentsObject,
1046
+ argumentKey: data.storedHostIdsKey,
1047
+ });
1048
+
1049
+ const nameSearch: string | undefined =
1050
+ PublicDashboardResourceListPolicy.optionalString(
1051
+ data.argumentsObject,
1052
+ "nameSearch",
1053
+ true,
1054
+ );
1055
+ if (nameSearch) {
1056
+ query["name"] = new Search(nameSearch);
1057
+ }
1058
+
1059
+ return {
1060
+ ...PublicDashboardResourceListPolicy.listDraft({
1061
+ resourceType: data.resourceType,
1062
+ query,
1063
+ sort: { name: SortOrder.Ascending },
1064
+ argumentsObject: data.argumentsObject,
1065
+ }),
1066
+ attributeToColumn: IMAGE_ATTRIBUTE_TO_COLUMN,
1067
+ };
1068
+ }
1069
+
1070
+ private static buildContainerInventoryPolicy(data: {
1071
+ argumentsObject: Record<string, unknown>;
1072
+ resourceType: string;
1073
+ kind: string;
1074
+ hostIdKey: string;
1075
+ storedHostIdsKey: string;
1076
+ }): PolicyDraft {
1077
+ const query: Record<string, unknown> = { kind: data.kind };
1078
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
1079
+ query,
1080
+ queryKey: data.hostIdKey,
1081
+ argumentsObject: data.argumentsObject,
1082
+ argumentKey: data.storedHostIdsKey,
1083
+ });
1084
+
1085
+ return PublicDashboardResourceListPolicy.listDraft({
1086
+ resourceType: data.resourceType,
1087
+ query,
1088
+ sort: { name: SortOrder.Ascending },
1089
+ argumentsObject: data.argumentsObject,
1090
+ });
1091
+ }
1092
+
1093
+ private static buildProxmoxNodePolicy(
1094
+ argumentsObject: Record<string, unknown>,
1095
+ ): PolicyDraft {
1096
+ const query: Record<string, unknown> = { kind: "Node" };
1097
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
1098
+ query,
1099
+ queryKey: "proxmoxClusterId",
1100
+ argumentsObject,
1101
+ argumentKey: "proxmoxClusterIds",
1102
+ });
1103
+
1104
+ const statusFilter: string | undefined =
1105
+ PublicDashboardResourceListPolicy.optionalEnum(
1106
+ argumentsObject,
1107
+ "statusFilter",
1108
+ ["online", "offline"],
1109
+ );
1110
+ if (statusFilter === "online") {
1111
+ query["isUp"] = true;
1112
+ } else if (statusFilter === "offline") {
1113
+ query["isUp"] = false;
1114
+ }
1115
+
1116
+ return {
1117
+ ...PublicDashboardResourceListPolicy.listDraft({
1118
+ resourceType: "proxmox-resource",
1119
+ query,
1120
+ sort: { name: SortOrder.Ascending },
1121
+ argumentsObject,
1122
+ }),
1123
+ attributeToColumn: PROXMOX_NODE_ATTRIBUTE_TO_COLUMN,
1124
+ };
1125
+ }
1126
+
1127
+ private static buildProxmoxGuestPolicy(
1128
+ argumentsObject: Record<string, unknown>,
1129
+ ): PolicyDraft {
1130
+ const query: Record<string, unknown> = { kind: "Guest" };
1131
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
1132
+ query,
1133
+ queryKey: "proxmoxClusterId",
1134
+ argumentsObject,
1135
+ argumentKey: "proxmoxClusterIds",
1136
+ });
1137
+
1138
+ const guestType: string | undefined =
1139
+ PublicDashboardResourceListPolicy.optionalEnum(
1140
+ argumentsObject,
1141
+ "guestTypeFilter",
1142
+ ["qemu", "lxc"],
1143
+ );
1144
+ if (guestType) {
1145
+ query["guestType"] = guestType;
1146
+ }
1147
+
1148
+ const statusFilter: string | undefined =
1149
+ PublicDashboardResourceListPolicy.optionalEnum(
1150
+ argumentsObject,
1151
+ "statusFilter",
1152
+ ["running", "stopped"],
1153
+ );
1154
+ if (statusFilter === "running") {
1155
+ query["isUp"] = true;
1156
+ } else if (statusFilter === "stopped") {
1157
+ query["isUp"] = false;
1158
+ }
1159
+
1160
+ return PublicDashboardResourceListPolicy.listDraft({
1161
+ resourceType: "proxmox-resource",
1162
+ query,
1163
+ sort: { name: SortOrder.Ascending },
1164
+ argumentsObject,
1165
+ });
1166
+ }
1167
+
1168
+ private static buildCephOsdPolicy(
1169
+ argumentsObject: Record<string, unknown>,
1170
+ ): PolicyDraft {
1171
+ const query: Record<string, unknown> = { kind: "Osd" };
1172
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
1173
+ query,
1174
+ queryKey: "cephClusterId",
1175
+ argumentsObject,
1176
+ argumentKey: "cephClusterIds",
1177
+ });
1178
+
1179
+ const stateFilter: string | undefined =
1180
+ PublicDashboardResourceListPolicy.optionalEnum(
1181
+ argumentsObject,
1182
+ "stateFilter",
1183
+ ["up", "down", "out"],
1184
+ );
1185
+ if (stateFilter === "up") {
1186
+ query["isUp"] = true;
1187
+ } else if (stateFilter === "down") {
1188
+ query["isUp"] = false;
1189
+ } else if (stateFilter === "out") {
1190
+ query["isIn"] = false;
1191
+ }
1192
+
1193
+ return {
1194
+ ...PublicDashboardResourceListPolicy.listDraft({
1195
+ resourceType: "ceph-resource",
1196
+ query,
1197
+ sort: { externalId: SortOrder.Ascending },
1198
+ argumentsObject,
1199
+ }),
1200
+ attributeToColumn: CEPH_OSD_ATTRIBUTE_TO_COLUMN,
1201
+ };
1202
+ }
1203
+
1204
+ private static buildCephPoolPolicy(
1205
+ argumentsObject: Record<string, unknown>,
1206
+ ): PolicyDraft {
1207
+ const query: Record<string, unknown> = { kind: "Pool" };
1208
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
1209
+ query,
1210
+ queryKey: "cephClusterId",
1211
+ argumentsObject,
1212
+ argumentKey: "cephClusterIds",
1213
+ });
1214
+
1215
+ return {
1216
+ ...PublicDashboardResourceListPolicy.listDraft({
1217
+ resourceType: "ceph-resource",
1218
+ query,
1219
+ sort: { name: SortOrder.Ascending },
1220
+ argumentsObject,
1221
+ }),
1222
+ attributeToColumn: CEPH_POOL_ATTRIBUTE_TO_COLUMN,
1223
+ };
1224
+ }
1225
+
1226
+ private static buildDockerSwarmNodePolicy(
1227
+ argumentsObject: Record<string, unknown>,
1228
+ ): PolicyDraft {
1229
+ const query: Record<string, unknown> = { kind: "Node" };
1230
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
1231
+ query,
1232
+ queryKey: "dockerSwarmClusterId",
1233
+ argumentsObject,
1234
+ argumentKey: "dockerSwarmClusterIds",
1235
+ });
1236
+
1237
+ const role: string | undefined =
1238
+ PublicDashboardResourceListPolicy.optionalEnum(
1239
+ argumentsObject,
1240
+ "roleFilter",
1241
+ ["manager", "worker"],
1242
+ );
1243
+ if (role) {
1244
+ query["role"] = role;
1245
+ }
1246
+
1247
+ const statusFilter: string | undefined =
1248
+ PublicDashboardResourceListPolicy.optionalEnum(
1249
+ argumentsObject,
1250
+ "statusFilter",
1251
+ ["ready", "notready"],
1252
+ );
1253
+ if (statusFilter === "ready") {
1254
+ query["isReady"] = true;
1255
+ } else if (statusFilter === "notready") {
1256
+ query["isReady"] = false;
1257
+ }
1258
+
1259
+ return PublicDashboardResourceListPolicy.listDraft({
1260
+ resourceType: "docker-swarm-resource",
1261
+ query,
1262
+ sort: { name: SortOrder.Ascending },
1263
+ argumentsObject,
1264
+ });
1265
+ }
1266
+
1267
+ private static buildDockerSwarmServicePolicy(
1268
+ argumentsObject: Record<string, unknown>,
1269
+ ): PolicyDraft {
1270
+ const query: Record<string, unknown> = { kind: "Service" };
1271
+ PublicDashboardResourceListPolicy.addIncludesFromArgument({
1272
+ query,
1273
+ queryKey: "dockerSwarmClusterId",
1274
+ argumentsObject,
1275
+ argumentKey: "dockerSwarmClusterIds",
1276
+ });
1277
+
1278
+ const serviceMode: string | undefined =
1279
+ PublicDashboardResourceListPolicy.optionalEnum(
1280
+ argumentsObject,
1281
+ "serviceModeFilter",
1282
+ ["replicated", "global"],
1283
+ );
1284
+ if (serviceMode) {
1285
+ query["serviceMode"] = serviceMode;
1286
+ }
1287
+
1288
+ const statusFilter: string | undefined =
1289
+ PublicDashboardResourceListPolicy.optionalEnum(
1290
+ argumentsObject,
1291
+ "statusFilter",
1292
+ ["converged", "notconverged"],
1293
+ );
1294
+ if (statusFilter === "converged") {
1295
+ query["isReady"] = true;
1296
+ } else if (statusFilter === "notconverged") {
1297
+ query["isReady"] = false;
1298
+ }
1299
+
1300
+ return PublicDashboardResourceListPolicy.listDraft({
1301
+ resourceType: "docker-swarm-resource",
1302
+ query,
1303
+ sort: { name: SortOrder.Ascending },
1304
+ argumentsObject,
1305
+ });
1306
+ }
1307
+
1308
+ private static buildTracePolicy(data: {
1309
+ argumentsObject: Record<string, unknown>;
1310
+ requestedQuery: unknown;
1311
+ }): PolicyDraft {
1312
+ const query: Record<string, unknown> = {
1313
+ startTime: PublicDashboardResourceListPolicy.requiredTimeRange(
1314
+ data.requestedQuery,
1315
+ "startTime",
1316
+ ),
1317
+ };
1318
+
1319
+ const statusFilter: string | undefined =
1320
+ PublicDashboardResourceListPolicy.optionalEnum(
1321
+ data.argumentsObject,
1322
+ "statusFilter",
1323
+ ["0", "1", "2"],
1324
+ );
1325
+ if (statusFilter !== undefined) {
1326
+ query["statusCode"] = parseInt(statusFilter, 10);
1327
+ }
1328
+
1329
+ return PublicDashboardResourceListPolicy.listDraft({
1330
+ resourceType: "span",
1331
+ query,
1332
+ sort: { startTime: SortOrder.Descending },
1333
+ argumentsObject: data.argumentsObject,
1334
+ fallbackLimit: DEFAULT_TELEMETRY_LIMIT,
1335
+ });
1336
+ }
1337
+
1338
+ private static buildLogPolicy(data: {
1339
+ argumentsObject: Record<string, unknown>;
1340
+ requestedQuery: unknown;
1341
+ }): PolicyDraft {
1342
+ const query: Record<string, unknown> = {
1343
+ time: PublicDashboardResourceListPolicy.requiredTimeRange(
1344
+ data.requestedQuery,
1345
+ "time",
1346
+ ),
1347
+ };
1348
+
1349
+ const severity: string | undefined =
1350
+ PublicDashboardResourceListPolicy.optionalEnum(
1351
+ data.argumentsObject,
1352
+ "severityFilter",
1353
+ ["Trace", "Debug", "Information", "Warning", "Error", "Fatal"],
1354
+ );
1355
+ if (severity) {
1356
+ query["severityText"] = severity;
1357
+ }
1358
+
1359
+ const bodyContains: string | undefined =
1360
+ PublicDashboardResourceListPolicy.optionalString(
1361
+ data.argumentsObject,
1362
+ "bodyContains",
1363
+ true,
1364
+ );
1365
+ if (bodyContains) {
1366
+ query["body"] = bodyContains;
1367
+ }
1368
+
1369
+ const attributeFilterQuery: string | undefined =
1370
+ PublicDashboardResourceListPolicy.optionalString(
1371
+ data.argumentsObject,
1372
+ "attributeFilterQuery",
1373
+ true,
1374
+ );
1375
+ if (attributeFilterQuery) {
1376
+ const parsedFilter: LogFilter = queryStringToFilter(attributeFilterQuery);
1377
+ if (
1378
+ parsedFilter.attributes &&
1379
+ Object.keys(parsedFilter.attributes).length > 0
1380
+ ) {
1381
+ query["attributes"] = parsedFilter.attributes;
1382
+ }
1383
+ }
1384
+
1385
+ return {
1386
+ ...PublicDashboardResourceListPolicy.listDraft({
1387
+ resourceType: "log",
1388
+ query,
1389
+ sort: { time: SortOrder.Descending },
1390
+ argumentsObject: data.argumentsObject,
1391
+ fallbackLimit: DEFAULT_TELEMETRY_LIMIT,
1392
+ }),
1393
+ interpolateAttributeMap: true,
1394
+ };
1395
+ }
1396
+
1397
+ private static listDraft(data: {
1398
+ resourceType: string;
1399
+ query: Record<string, unknown>;
1400
+ sort: JSONObject;
1401
+ argumentsObject: Record<string, unknown>;
1402
+ fallbackLimit?: number | undefined;
1403
+ }): PolicyDraft {
1404
+ return {
1405
+ resourceType: data.resourceType,
1406
+ query: data.query,
1407
+ sort: data.sort,
1408
+ limit: PublicDashboardResourceListPolicy.storedLimit({
1409
+ value: data.argumentsObject["maxRows"],
1410
+ fallback: data.fallbackLimit || DEFAULT_LIST_LIMIT,
1411
+ ceiling: LIMIT_PER_PROJECT,
1412
+ }),
1413
+ };
1414
+ }
1415
+
1416
+ private static addCollectorStatusFilter(
1417
+ query: Record<string, unknown>,
1418
+ argumentsObject: Record<string, unknown>,
1419
+ ): void {
1420
+ const statusFilter: string | undefined =
1421
+ PublicDashboardResourceListPolicy.optionalEnum(
1422
+ argumentsObject,
1423
+ "statusFilter",
1424
+ ["connected", "disconnected"],
1425
+ );
1426
+ if (statusFilter) {
1427
+ query["otelCollectorStatus"] = statusFilter;
1428
+ }
1429
+ }
1430
+
1431
+ private static addIncludesFromArgument(data: {
1432
+ query: Record<string, unknown>;
1433
+ queryKey: string;
1434
+ argumentsObject: Record<string, unknown>;
1435
+ argumentKey: string;
1436
+ }): void {
1437
+ const values: Array<string> | undefined =
1438
+ PublicDashboardResourceListPolicy.optionalStringArray(
1439
+ data.argumentsObject,
1440
+ data.argumentKey,
1441
+ );
1442
+ if (values && values.length > 0) {
1443
+ data.query[data.queryKey] = new Includes(values);
1444
+ }
1445
+ }
1446
+
1447
+ private static optionalStringArray(
1448
+ object: Record<string, unknown>,
1449
+ key: string,
1450
+ ): Array<string> | undefined {
1451
+ const value: unknown = object[key];
1452
+ if (value === undefined || value === null) {
1453
+ return undefined;
1454
+ }
1455
+ if (!Array.isArray(value)) {
1456
+ throw new BadDataException(`Dashboard widget ${key} must be an array.`);
1457
+ }
1458
+
1459
+ const values: Array<string> = [];
1460
+ for (const item of value) {
1461
+ if (typeof item !== "string" || item.length === 0) {
1462
+ throw new BadDataException(
1463
+ `Dashboard widget ${key} contains an invalid value.`,
1464
+ );
1465
+ }
1466
+ values.push(item);
1467
+ }
1468
+ return values;
1469
+ }
1470
+
1471
+ private static optionalString(
1472
+ object: Record<string, unknown>,
1473
+ key: string,
1474
+ trim: boolean,
1475
+ ): string | undefined {
1476
+ const value: unknown = object[key];
1477
+ if (value === undefined || value === null || value === "") {
1478
+ return undefined;
1479
+ }
1480
+ if (typeof value !== "string") {
1481
+ throw new BadDataException(`Dashboard widget ${key} must be a string.`);
1482
+ }
1483
+
1484
+ const normalized: string = trim ? value.trim() : value;
1485
+ return normalized.length > 0 ? normalized : undefined;
1486
+ }
1487
+
1488
+ private static optionalEnum(
1489
+ object: Record<string, unknown>,
1490
+ key: string,
1491
+ allowedValues: Array<string>,
1492
+ ): string | undefined {
1493
+ const value: unknown = object[key];
1494
+ if (value === undefined || value === null || value === "") {
1495
+ return undefined;
1496
+ }
1497
+ if (typeof value !== "string" || !allowedValues.includes(value)) {
1498
+ throw new BadDataException(`Dashboard widget ${key} is invalid.`);
1499
+ }
1500
+ return value;
1501
+ }
1502
+
1503
+ private static storedLimit(data: {
1504
+ value: unknown;
1505
+ fallback: number;
1506
+ ceiling: number;
1507
+ }): number {
1508
+ const parsed: number = Number(
1509
+ typeof data.value === "string" ? data.value.trim() : data.value,
1510
+ );
1511
+ if (!Number.isFinite(parsed) || parsed < 1) {
1512
+ return data.fallback;
1513
+ }
1514
+ return Math.min(Math.floor(parsed), data.ceiling);
1515
+ }
1516
+
1517
+ private static requiredTimeRange(
1518
+ requestedQuery: unknown,
1519
+ key: "time" | "startTime",
1520
+ ): InBetween<Date> {
1521
+ const query: Record<string, unknown> =
1522
+ PublicDashboardResourceListPolicy.requireObject(
1523
+ requestedQuery,
1524
+ "Public dashboard telemetry query",
1525
+ );
1526
+ if (!Object.prototype.hasOwnProperty.call(query, key)) {
1527
+ throw new BadDataException(
1528
+ `Public dashboard telemetry query requires ${key}.`,
1529
+ );
1530
+ }
1531
+
1532
+ const deserialized: JSONValue = JSONFunctions.deserializeValue(
1533
+ query[key] as JSONValue,
1534
+ );
1535
+ if (!(deserialized instanceof InBetween)) {
1536
+ throw new BadDataException(
1537
+ `Public dashboard telemetry ${key} must be an InBetween range.`,
1538
+ );
1539
+ }
1540
+
1541
+ const start: Date = PublicDashboardResourceListPolicy.validDate(
1542
+ deserialized.startValue,
1543
+ key,
1544
+ );
1545
+ const end: Date = PublicDashboardResourceListPolicy.validDate(
1546
+ deserialized.endValue,
1547
+ key,
1548
+ );
1549
+ if (start.getTime() >= end.getTime()) {
1550
+ throw new BadDataException(
1551
+ `Public dashboard telemetry ${key} range is invalid.`,
1552
+ );
1553
+ }
1554
+
1555
+ return new InBetween<Date>(start, end);
1556
+ }
1557
+
1558
+ private static validDate(value: unknown, key: string): Date {
1559
+ if (value instanceof Date && Number.isFinite(value.getTime())) {
1560
+ return new Date(value.getTime());
1561
+ }
1562
+ if (typeof value === "string" && value.length <= 128) {
1563
+ const date: Date = new Date(value);
1564
+ if (Number.isFinite(date.getTime())) {
1565
+ return date;
1566
+ }
1567
+ }
1568
+ throw new BadDataException(
1569
+ `Public dashboard telemetry ${key} range contains an invalid date.`,
1570
+ );
1571
+ }
1572
+
1573
+ private static resolveDashboardVariableSelections(data: {
1574
+ dashboardViewConfig: unknown;
1575
+ requestedVariables: unknown;
1576
+ }): Array<DashboardVariable> {
1577
+ const dashboardViewConfig: Record<string, unknown> =
1578
+ PublicDashboardResourceListPolicy.requireObject(
1579
+ data.dashboardViewConfig,
1580
+ "Dashboard view config",
1581
+ );
1582
+ const storedVariablesValue: unknown = dashboardViewConfig["variables"];
1583
+ const storedVariables: Array<unknown> =
1584
+ storedVariablesValue === undefined || storedVariablesValue === null
1585
+ ? []
1586
+ : Array.isArray(storedVariablesValue)
1587
+ ? storedVariablesValue
1588
+ : (() => {
1589
+ throw new BadDataException(
1590
+ "Dashboard view config variables must be an array.",
1591
+ );
1592
+ })();
1593
+
1594
+ const requestedSelections: Map<
1595
+ string,
1596
+ Record<string, unknown>
1597
+ > = PublicDashboardResourceListPolicy.validateRequestedVariableSelections(
1598
+ data.requestedVariables,
1599
+ );
1600
+ const variables: Array<DashboardVariable> = [];
1601
+ const storedIds: Set<string> = new Set<string>();
1602
+
1603
+ for (const storedValue of storedVariables) {
1604
+ const stored: Record<string, unknown> =
1605
+ PublicDashboardResourceListPolicy.requireObject(
1606
+ storedValue,
1607
+ "Stored dashboard variable",
1608
+ );
1609
+ if (stored["type"] !== DashboardVariableType.TelemetryAttribute) {
1610
+ continue;
1611
+ }
1612
+
1613
+ const id: unknown = stored["id"];
1614
+ const attributeKey: unknown = stored["attributeKey"];
1615
+ if (
1616
+ typeof id !== "string" ||
1617
+ id.length === 0 ||
1618
+ id.length > MAX_VARIABLE_ID_LENGTH ||
1619
+ typeof attributeKey !== "string" ||
1620
+ attributeKey.trim().length === 0 ||
1621
+ attributeKey.length > MAX_VARIABLE_VALUE_LENGTH
1622
+ ) {
1623
+ throw new BadDataException("Stored dashboard variable is malformed.");
1624
+ }
1625
+ if (storedIds.has(id)) {
1626
+ throw new BadDataException("Dashboard variable IDs must be unique.");
1627
+ }
1628
+ storedIds.add(id);
1629
+
1630
+ const isMultiSelect: unknown = stored["isMultiSelect"];
1631
+ if (
1632
+ isMultiSelect !== undefined &&
1633
+ isMultiSelect !== null &&
1634
+ typeof isMultiSelect !== "boolean"
1635
+ ) {
1636
+ throw new BadDataException("Stored dashboard variable is malformed.");
1637
+ }
1638
+
1639
+ const defaultValue: unknown = stored["defaultValue"];
1640
+ if (
1641
+ defaultValue !== undefined &&
1642
+ defaultValue !== null &&
1643
+ (typeof defaultValue !== "string" ||
1644
+ defaultValue.length > MAX_VARIABLE_VALUE_LENGTH)
1645
+ ) {
1646
+ throw new BadDataException("Stored dashboard variable is malformed.");
1647
+ }
1648
+
1649
+ const selection: Record<string, unknown> | undefined =
1650
+ requestedSelections.get(id);
1651
+ const selectedValue: unknown = selection?.["selectedValue"];
1652
+ const selectedValues: unknown = selection?.["selectedValues"];
1653
+ const name: unknown = stored["name"];
1654
+ const storedIsMultiSelect: boolean = isMultiSelect === true;
1655
+
1656
+ variables.push({
1657
+ id,
1658
+ name: typeof name === "string" ? name : "",
1659
+ type: DashboardVariableType.TelemetryAttribute,
1660
+ attributeKey: attributeKey.trim(),
1661
+ isMultiSelect: storedIsMultiSelect,
1662
+ defaultValue:
1663
+ typeof defaultValue === "string" ? defaultValue : undefined,
1664
+ selectedValue:
1665
+ !storedIsMultiSelect && typeof selectedValue === "string"
1666
+ ? selectedValue
1667
+ : undefined,
1668
+ selectedValues:
1669
+ storedIsMultiSelect && Array.isArray(selectedValues)
1670
+ ? (selectedValues as Array<string>)
1671
+ : undefined,
1672
+ });
1673
+ }
1674
+
1675
+ return variables;
1676
+ }
1677
+
1678
+ private static validateRequestedVariableSelections(
1679
+ requestedVariables: unknown,
1680
+ ): Map<string, Record<string, unknown>> {
1681
+ const selections: Map<string, Record<string, unknown>> = new Map<
1682
+ string,
1683
+ Record<string, unknown>
1684
+ >();
1685
+ if (requestedVariables === undefined || requestedVariables === null) {
1686
+ return selections;
1687
+ }
1688
+ if (!Array.isArray(requestedVariables)) {
1689
+ throw new BadDataException(
1690
+ "Public dashboard variable selections must be an array.",
1691
+ );
1692
+ }
1693
+ if (requestedVariables.length > MAX_REQUESTED_VARIABLES) {
1694
+ throw new BadDataException(
1695
+ "Too many public dashboard variable selections.",
1696
+ );
1697
+ }
1698
+
1699
+ let totalSelectedValues: number = 0;
1700
+ for (const requestedValue of requestedVariables) {
1701
+ const requested: Record<string, unknown> =
1702
+ PublicDashboardResourceListPolicy.requireObject(
1703
+ requestedValue,
1704
+ "Public dashboard variable selection",
1705
+ );
1706
+ const id: unknown = requested["id"];
1707
+ if (
1708
+ typeof id !== "string" ||
1709
+ id.length === 0 ||
1710
+ id.length > MAX_VARIABLE_ID_LENGTH
1711
+ ) {
1712
+ throw new BadDataException(
1713
+ "Public dashboard variable selection has an invalid id.",
1714
+ );
1715
+ }
1716
+ if (selections.has(id)) {
1717
+ throw new BadDataException(
1718
+ "Public dashboard variable selections contain a duplicate id.",
1719
+ );
1720
+ }
1721
+
1722
+ const selectedValue: unknown = requested["selectedValue"];
1723
+ if (
1724
+ selectedValue !== undefined &&
1725
+ selectedValue !== null &&
1726
+ (typeof selectedValue !== "string" ||
1727
+ selectedValue.length > MAX_VARIABLE_VALUE_LENGTH)
1728
+ ) {
1729
+ throw new BadDataException(
1730
+ "Public dashboard variable selection has an invalid value.",
1731
+ );
1732
+ }
1733
+
1734
+ const selectedValues: unknown = requested["selectedValues"];
1735
+ if (
1736
+ selectedValues !== undefined &&
1737
+ selectedValues !== null &&
1738
+ !Array.isArray(selectedValues)
1739
+ ) {
1740
+ throw new BadDataException(
1741
+ "Public dashboard variable selection values must be an array.",
1742
+ );
1743
+ }
1744
+ if (
1745
+ Array.isArray(selectedValues) &&
1746
+ selectedValues.length > MAX_SELECTED_VALUES_PER_VARIABLE
1747
+ ) {
1748
+ throw new BadDataException(
1749
+ "Too many values in a public dashboard variable selection.",
1750
+ );
1751
+ }
1752
+
1753
+ if (Array.isArray(selectedValues)) {
1754
+ totalSelectedValues += selectedValues.length;
1755
+ if (totalSelectedValues > MAX_TOTAL_SELECTED_VALUES) {
1756
+ throw new BadDataException(
1757
+ "Too many public dashboard variable selection values.",
1758
+ );
1759
+ }
1760
+ for (const value of selectedValues) {
1761
+ if (
1762
+ typeof value !== "string" ||
1763
+ value.length > MAX_VARIABLE_VALUE_LENGTH
1764
+ ) {
1765
+ throw new BadDataException(
1766
+ "Public dashboard variable selection has an invalid value.",
1767
+ );
1768
+ }
1769
+ }
1770
+ }
1771
+
1772
+ selections.set(id, {
1773
+ selectedValue:
1774
+ typeof selectedValue === "string" ? selectedValue : undefined,
1775
+ selectedValues: Array.isArray(selectedValues)
1776
+ ? (selectedValues as Array<string>)
1777
+ : undefined,
1778
+ });
1779
+ }
1780
+
1781
+ return selections;
1782
+ }
1783
+
1784
+ private static requireObject(
1785
+ value: unknown,
1786
+ label: string,
1787
+ ): Record<string, unknown> {
1788
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1789
+ throw new BadDataException(`${label} must be an object.`);
1790
+ }
1791
+ return value as Record<string, unknown>;
1792
+ }
1793
+ }