@oneuptime/common 10.4.11 → 10.4.13

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 (117) hide show
  1. package/Models/DatabaseModels/Alert.ts +332 -0
  2. package/Models/DatabaseModels/Incident.ts +332 -0
  3. package/Models/DatabaseModels/RunbookAgent.ts +16 -2
  4. package/Server/EnvironmentConfig.ts +16 -0
  5. package/Server/Infrastructure/ClickhouseConfig.ts +14 -0
  6. package/Server/Infrastructure/ClickhouseDatabase.ts +20 -3
  7. package/Server/Infrastructure/InMemoryTTLCache.ts +61 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1779302536475-AttachKubernetesAndDockerToIncidentAndAlert.ts +253 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/1779303924241-AttachServiceToIncidentAndAlert.ts +60 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  11. package/Server/Middleware/TelemetryIngest.ts +6 -38
  12. package/Server/Middleware/UserAuthorization.ts +1 -11
  13. package/Server/Services/AnalyticsDatabaseService.ts +33 -1
  14. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +6 -0
  15. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +1 -0
  16. package/Server/Services/OnCallDutyPolicyScheduleService.ts +17 -0
  17. package/Server/Services/TelemetryIngestionKeyService.ts +90 -1
  18. package/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.ts +108 -0
  19. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +13 -0
  20. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +25 -0
  21. package/Tests/Server/Middleware/UserAuthorization.test.ts +0 -7
  22. package/Types/Dashboard/DashboardComponentType.ts +0 -1
  23. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +2 -0
  24. package/Types/Dashboard/DashboardComponents/DashboardTableComponent.ts +74 -1
  25. package/Types/Dashboard/DashboardTemplates.ts +164 -51
  26. package/Types/Monitor/CriteriaFilter.ts +13 -0
  27. package/Types/Monitor/DnssecMonitor/DnssecMonitorResponse.ts +69 -0
  28. package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
  29. package/Types/Monitor/MonitorStep.ts +39 -0
  30. package/Types/Monitor/MonitorStepDnssecMonitor.ts +59 -0
  31. package/Types/Monitor/MonitorType.ts +18 -2
  32. package/Types/OnCallDutyPolicy/UserOverrideUtil.ts +36 -9
  33. package/Types/Probe/ProbeMonitorResponse.ts +2 -0
  34. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +51 -0
  35. package/Utils/Dashboard/Components/DashboardTableComponent.ts +80 -17
  36. package/Utils/Dashboard/Components/Index.ts +0 -7
  37. package/Utils/Monitor/MonitorMetricType.ts +1 -0
  38. package/build/dist/Models/DatabaseModels/Alert.js +324 -0
  39. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  40. package/build/dist/Models/DatabaseModels/Incident.js +324 -0
  41. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  42. package/build/dist/Models/DatabaseModels/RunbookAgent.js +16 -2
  43. package/build/dist/Models/DatabaseModels/RunbookAgent.js.map +1 -1
  44. package/build/dist/Server/EnvironmentConfig.js +8 -0
  45. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  46. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +9 -1
  47. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  48. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +12 -3
  49. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
  50. package/build/dist/Server/Infrastructure/InMemoryTTLCache.js +49 -0
  51. package/build/dist/Server/Infrastructure/InMemoryTTLCache.js.map +1 -0
  52. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1779302536475-AttachKubernetesAndDockerToIncidentAndAlert.js +100 -0
  53. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1779302536475-AttachKubernetesAndDockerToIncidentAndAlert.js.map +1 -0
  54. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1779303924241-AttachServiceToIncidentAndAlert.js +28 -0
  55. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1779303924241-AttachServiceToIncidentAndAlert.js.map +1 -0
  56. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  57. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  58. package/build/dist/Server/Middleware/TelemetryIngest.js +2 -26
  59. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  60. package/build/dist/Server/Middleware/UserAuthorization.js +1 -7
  61. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  62. package/build/dist/Server/Services/AnalyticsDatabaseService.js +23 -2
  63. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  64. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +28 -24
  65. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  66. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +1 -1
  67. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  68. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +18 -2
  69. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  70. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +83 -0
  71. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  72. package/build/dist/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.js +94 -0
  73. package/build/dist/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.js.map +1 -0
  74. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +10 -0
  75. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  76. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -3
  77. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  78. package/build/dist/Tests/Server/Middleware/UserAuthorization.test.js +0 -7
  79. package/build/dist/Tests/Server/Middleware/UserAuthorization.test.js.map +1 -1
  80. package/build/dist/Types/Dashboard/DashboardComponentType.js +0 -1
  81. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  82. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +2 -0
  83. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  84. package/build/dist/Types/Dashboard/DashboardComponents/DashboardTableComponent.js +13 -1
  85. package/build/dist/Types/Dashboard/DashboardComponents/DashboardTableComponent.js.map +1 -1
  86. package/build/dist/Types/Dashboard/DashboardTemplates.js +142 -42
  87. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  88. package/build/dist/Types/Monitor/CriteriaFilter.js +12 -0
  89. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  90. package/build/dist/Types/Monitor/DnssecMonitor/DnssecMonitorResponse.js +2 -0
  91. package/build/dist/Types/Monitor/DnssecMonitor/DnssecMonitorResponse.js.map +1 -0
  92. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
  93. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  94. package/build/dist/Types/Monitor/MonitorStep.js +26 -0
  95. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  96. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js +42 -0
  97. package/build/dist/Types/Monitor/MonitorStepDnssecMonitor.js.map +1 -0
  98. package/build/dist/Types/Monitor/MonitorType.js +16 -2
  99. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  100. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js +27 -7
  101. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js.map +1 -1
  102. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +47 -0
  103. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  104. package/build/dist/Utils/Dashboard/Components/DashboardTableComponent.js +68 -16
  105. package/build/dist/Utils/Dashboard/Components/DashboardTableComponent.js.map +1 -1
  106. package/build/dist/Utils/Dashboard/Components/Index.js +0 -4
  107. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  108. package/build/dist/Utils/Monitor/MonitorMetricType.js +1 -0
  109. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  110. package/package.json +1 -2
  111. package/Types/Dashboard/DashboardComponents/DashboardHostMetricChartComponent.ts +0 -27
  112. package/Typings/elkjs.d.ts +0 -30
  113. package/Utils/Dashboard/Components/DashboardHostMetricChartComponent.ts +0 -132
  114. package/build/dist/Types/Dashboard/DashboardComponents/DashboardHostMetricChartComponent.js +0 -11
  115. package/build/dist/Types/Dashboard/DashboardComponents/DashboardHostMetricChartComponent.js.map +0 -1
  116. package/build/dist/Utils/Dashboard/Components/DashboardHostMetricChartComponent.js +0 -113
  117. package/build/dist/Utils/Dashboard/Components/DashboardHostMetricChartComponent.js.map +0 -1
@@ -0,0 +1,59 @@
1
+ import { JSONObject } from "../JSON";
2
+
3
+ export default interface MonitorStepDnssecMonitor {
4
+ domainName: string;
5
+ resolvers: Array<string>;
6
+ checkNameserverConsistency: boolean;
7
+ signatureExpiryWarningDays: number;
8
+ timeout: number;
9
+ retries: number;
10
+ }
11
+
12
+ export class MonitorStepDnssecMonitorUtil {
13
+ public static getDefault(): MonitorStepDnssecMonitor {
14
+ return {
15
+ domainName: "",
16
+ resolvers: ["1.1.1.1", "8.8.8.8", "9.9.9.9"],
17
+ checkNameserverConsistency: true,
18
+ signatureExpiryWarningDays: 7,
19
+ timeout: 10000,
20
+ retries: 3,
21
+ };
22
+ }
23
+
24
+ public static fromJSON(json: JSONObject): MonitorStepDnssecMonitor {
25
+ const defaults: MonitorStepDnssecMonitor =
26
+ MonitorStepDnssecMonitorUtil.getDefault();
27
+
28
+ const resolvers: Array<string> = Array.isArray(json["resolvers"])
29
+ ? (json["resolvers"] as Array<string>).filter((value: unknown) => {
30
+ return typeof value === "string" && value.length > 0;
31
+ })
32
+ : defaults.resolvers;
33
+
34
+ return {
35
+ domainName: (json["domainName"] as string) || "",
36
+ resolvers: resolvers.length > 0 ? resolvers : defaults.resolvers,
37
+ checkNameserverConsistency:
38
+ typeof json["checkNameserverConsistency"] === "boolean"
39
+ ? (json["checkNameserverConsistency"] as boolean)
40
+ : defaults.checkNameserverConsistency,
41
+ signatureExpiryWarningDays:
42
+ (json["signatureExpiryWarningDays"] as number) ||
43
+ defaults.signatureExpiryWarningDays,
44
+ timeout: (json["timeout"] as number) || defaults.timeout,
45
+ retries: (json["retries"] as number) || defaults.retries,
46
+ };
47
+ }
48
+
49
+ public static toJSON(monitor: MonitorStepDnssecMonitor): JSONObject {
50
+ return {
51
+ domainName: monitor.domainName,
52
+ resolvers: monitor.resolvers,
53
+ checkNameserverConsistency: monitor.checkNameserverConsistency,
54
+ signatureExpiryWarningDays: monitor.signatureExpiryWarningDays,
55
+ timeout: monitor.timeout,
56
+ retries: monitor.retries,
57
+ };
58
+ }
59
+ }
@@ -32,6 +32,9 @@ enum MonitorType {
32
32
  // DNS monitoring
33
33
  DNS = "DNS",
34
34
 
35
+ // DNSSEC validation monitoring
36
+ DNSSEC = "DNSSEC",
37
+
35
38
  // Domain registration monitoring
36
39
  Domain = "Domain",
37
40
 
@@ -64,12 +67,15 @@ export class MonitorTypeHelper {
64
67
  MonitorType.Ping,
65
68
  MonitorType.IP,
66
69
  MonitorType.Port,
67
- MonitorType.DNS,
68
70
  MonitorType.SSLCertificate,
69
71
  MonitorType.Domain,
70
72
  MonitorType.ExternalStatusPage,
71
73
  ],
72
74
  },
75
+ {
76
+ label: "DNS Monitoring",
77
+ monitorTypes: [MonitorType.DNS, MonitorType.DNSSEC],
78
+ },
73
79
  {
74
80
  label: "Synthetic Monitoring",
75
81
  monitorTypes: [
@@ -83,7 +89,7 @@ export class MonitorTypeHelper {
83
89
  },
84
90
  {
85
91
  label: "Infrastructure",
86
- monitorTypes: [MonitorType.Server, MonitorType.SNMP],
92
+ monitorTypes: [MonitorType.SNMP],
87
93
  },
88
94
  {
89
95
  label: "Kubernetes",
@@ -273,6 +279,13 @@ export class MonitorTypeHelper {
273
279
  "This monitor type lets you monitor DNS resolution for your domains, verify record values, and check DNSSEC validity.",
274
280
  icon: IconProp.GlobeAlt,
275
281
  },
282
+ {
283
+ monitorType: MonitorType.DNSSEC,
284
+ title: "DNSSEC",
285
+ description:
286
+ "This monitor type performs full DNSSEC validation — DNSKEY, DS at the parent zone, RRSIG validity windows, AD-flag/SERVFAIL behavior across public resolvers, and primary/secondary nameserver consistency.",
287
+ icon: IconProp.Key,
288
+ },
276
289
  {
277
290
  monitorType: MonitorType.Domain,
278
291
  title: "Domain",
@@ -334,6 +347,7 @@ export class MonitorTypeHelper {
334
347
  monitorType === MonitorType.CustomJavaScriptCode ||
335
348
  monitorType === MonitorType.SNMP ||
336
349
  monitorType === MonitorType.DNS ||
350
+ monitorType === MonitorType.DNSSEC ||
337
351
  monitorType === MonitorType.Domain ||
338
352
  monitorType === MonitorType.ExternalStatusPage;
339
353
  return isProbeableMonitor;
@@ -359,6 +373,7 @@ export class MonitorTypeHelper {
359
373
  MonitorType.Profiles,
360
374
  MonitorType.SNMP,
361
375
  MonitorType.DNS,
376
+ MonitorType.DNSSEC,
362
377
  MonitorType.Domain,
363
378
  MonitorType.ExternalStatusPage,
364
379
  MonitorType.Kubernetes,
@@ -397,6 +412,7 @@ export class MonitorTypeHelper {
397
412
  monitorType === MonitorType.CustomJavaScriptCode ||
398
413
  monitorType === MonitorType.SNMP ||
399
414
  monitorType === MonitorType.DNS ||
415
+ monitorType === MonitorType.DNSSEC ||
400
416
  monitorType === MonitorType.Domain ||
401
417
  monitorType === MonitorType.ExternalStatusPage
402
418
  ) {
@@ -27,22 +27,49 @@ export const OVERRIDE_META_KEY: string = "_override";
27
27
 
28
28
  export default class UserOverrideUtil {
29
29
  /**
30
- * Returns true when this override should be applied on top of the schedule
31
- * events. Global overrides always apply; policy-scoped overrides apply to
32
- * any schedule, since a schedule's calendar shows coverage information for
33
- * every user who could potentially be paged through it.
30
+ * Decides whether an override should affect resolution for a given policy
31
+ * context. Global overrides (no policy id) always apply. Policy-scoped
32
+ * overrides only apply when their policy matches the caller's policy.
33
+ * When the caller has no policy context, only global overrides apply.
34
34
  */
35
- public static isOverrideApplicable(_override: UserOverrideRecord): boolean {
36
- return true;
35
+ public static isOverrideApplicable(
36
+ override: UserOverrideRecord,
37
+ currentOnCallDutyPolicyId?: string | null | undefined,
38
+ ): boolean {
39
+ if (!override.onCallDutyPolicyId) {
40
+ return true;
41
+ }
42
+
43
+ if (!currentOnCallDutyPolicyId) {
44
+ return false;
45
+ }
46
+
47
+ return override.onCallDutyPolicyId === currentOnCallDutyPolicyId;
37
48
  }
38
49
 
39
50
  public static applyOverridesToEvents(data: {
40
51
  events: Array<CalendarEvent>;
41
52
  overrides: Array<UserOverrideRecord>;
53
+ currentOnCallDutyPolicyId?: string | null | undefined;
42
54
  }): Array<CalendarEvent> {
43
- const applicable: Array<UserOverrideRecord> = data.overrides.filter(
44
- UserOverrideUtil.isOverrideApplicable,
45
- );
55
+ const applicable: Array<UserOverrideRecord> = data.overrides
56
+ .filter((o: UserOverrideRecord) => {
57
+ return UserOverrideUtil.isOverrideApplicable(
58
+ o,
59
+ data.currentOnCallDutyPolicyId,
60
+ );
61
+ })
62
+ /*
63
+ * Apply policy-specific overrides before globals so that when both
64
+ * target the same user/window, the policy-specific substitution wins.
65
+ * splitEventByOverride only matches on the original user id, so the
66
+ * first override that consumes a segment claims it.
67
+ */
68
+ .sort((a: UserOverrideRecord, b: UserOverrideRecord) => {
69
+ const aPolicyScoped: number = a.onCallDutyPolicyId ? 0 : 1;
70
+ const bPolicyScoped: number = b.onCallDutyPolicyId ? 0 : 1;
71
+ return aPolicyScoped - bPolicyScoped;
72
+ });
46
73
 
47
74
  if (applicable.length === 0) {
48
75
  return data.events;
@@ -9,6 +9,7 @@ import SyntheticMonitorResponse from "../Monitor/SyntheticMonitors/SyntheticMoni
9
9
  import SnmpMonitorResponse from "../Monitor/SnmpMonitor/SnmpMonitorResponse";
10
10
  import DnsMonitorResponse from "../Monitor/DnsMonitor/DnsMonitorResponse";
11
11
  import DomainMonitorResponse from "../Monitor/DomainMonitor/DomainMonitorResponse";
12
+ import DnssecMonitorResponse from "../Monitor/DnssecMonitor/DnssecMonitorResponse";
12
13
  import ExternalStatusPageMonitorResponse from "../Monitor/ExternalStatusPageMonitor/ExternalStatusPageMonitorResponse";
13
14
  import MonitorEvaluationSummary from "../Monitor/MonitorEvaluationSummary";
14
15
  import ObjectID from "../ObjectID";
@@ -35,6 +36,7 @@ export default interface ProbeMonitorResponse {
35
36
  snmpResponse?: SnmpMonitorResponse | undefined;
36
37
  dnsResponse?: DnsMonitorResponse | undefined;
37
38
  domainResponse?: DomainMonitorResponse | undefined;
39
+ dnssecResponse?: DnssecMonitorResponse | undefined;
38
40
  externalStatusPageResponse?: ExternalStatusPageMonitorResponse | undefined;
39
41
  monitoredAt: Date;
40
42
  isTimeout?: boolean | undefined;
@@ -405,6 +405,57 @@ export default class TemplateVariablesCatalog {
405
405
  ],
406
406
  };
407
407
 
408
+ case MonitorType.DNSSEC:
409
+ return {
410
+ title: "DNSSEC",
411
+ variables: [
412
+ {
413
+ key: "isOnline",
414
+ description: "True if the DNSSEC check completed.",
415
+ },
416
+ { key: "domainName", description: "Zone queried." },
417
+ {
418
+ key: "isZoneSigned",
419
+ description: "True if any DNSKEY records exist for the zone.",
420
+ },
421
+ {
422
+ key: "isParentDsPresent",
423
+ description: "True if DS records exist at the parent zone.",
424
+ },
425
+ {
426
+ key: "isChainValid",
427
+ description:
428
+ "True if DNSKEY, DS, RRSIG, and resolver AD-flag all check out.",
429
+ },
430
+ {
431
+ key: "resolverConsensusAd",
432
+ description:
433
+ "True if every configured resolver returned the AD flag.",
434
+ },
435
+ {
436
+ key: "isNameserverConsistent",
437
+ description:
438
+ "True if every authoritative nameserver returned the same SOA serial.",
439
+ },
440
+ {
441
+ key: "earliestSignatureExpiration",
442
+ description: "Earliest RRSIG expiration timestamp (ISO).",
443
+ },
444
+ {
445
+ key: "daysUntilSignatureExpiry",
446
+ description: "Days until the earliest RRSIG expires.",
447
+ },
448
+ { key: "dnskeyCount", description: "Number of DNSKEY records." },
449
+ {
450
+ key: "dsRecordCount",
451
+ description: "Number of DS records at the parent.",
452
+ },
453
+ { key: "rrsigCount", description: "Number of RRSIG records seen." },
454
+ { key: "responseTimeInMs", description: "Total check duration." },
455
+ { key: "failureCause", description: "Failure reason." },
456
+ ],
457
+ };
458
+
408
459
  case MonitorType.ExternalStatusPage:
409
460
  return {
410
461
  title: "External Status Page",
@@ -1,5 +1,9 @@
1
- import DashboardTableComponent from "../../../Types/Dashboard/DashboardComponents/DashboardTableComponent";
1
+ import DashboardTableComponent, {
2
+ TableColumnKind,
3
+ TableReduce,
4
+ } from "../../../Types/Dashboard/DashboardComponents/DashboardTableComponent";
2
5
  import { ObjectType } from "../../../Types/JSON";
6
+ import MetricsAggregationType from "../../../Types/Metrics/MetricsAggregationType";
3
7
  import ObjectID from "../../../Types/ObjectID";
4
8
  import DashboardBaseComponentUtil from "./DashboardBaseComponent";
5
9
  import {
@@ -9,15 +13,16 @@ import {
9
13
  } from "../../../Types/Dashboard/DashboardComponents/ComponentArgument";
10
14
  import DashboardComponentType from "../../../Types/Dashboard/DashboardComponentType";
11
15
 
12
- const DataSourceSection: ComponentArgumentSection = {
13
- name: "Data Source",
14
- description: "Configure which metrics to display in the table",
16
+ const DataSection: ComponentArgumentSection = {
17
+ name: "Data",
18
+ description:
19
+ "Pick how rows are grouped, then add columns for metrics and formulas",
15
20
  order: 1,
16
21
  };
17
22
 
18
23
  const DisplaySection: ComponentArgumentSection = {
19
24
  name: "Display Options",
20
- description: "Customize the table appearance",
25
+ description: "Customize how the table renders",
21
26
  order: 2,
22
27
  defaultCollapsed: true,
23
28
  };
@@ -35,13 +40,22 @@ export default class DashboardTableComponentUtil extends DashboardBaseComponentU
35
40
  minHeightInDashboardUnits: 3,
36
41
  minWidthInDashboardUnits: 4,
37
42
  arguments: {
38
- metricQueryConfig: {
39
- metricQueryData: {
40
- filterData: {},
41
- groupBy: undefined,
43
+ groupByAttributes: [],
44
+ columns: [
45
+ {
46
+ id: ObjectID.generate().toString(),
47
+ variable: "a",
48
+ header: "Value",
49
+ kind: TableColumnKind.Metric,
50
+ showAsColumn: true,
51
+ metricName: undefined,
52
+ aggregation: MetricsAggregationType.Avg,
53
+ decimals: 2,
42
54
  },
43
- },
44
- maxRows: 20,
55
+ ],
56
+ maxRows: 25,
57
+ reduce: TableReduce.Last,
58
+ decimals: 2,
45
59
  },
46
60
  };
47
61
  }
@@ -54,12 +68,23 @@ export default class DashboardTableComponentUtil extends DashboardBaseComponentU
54
68
  > = [];
55
69
 
56
70
  componentArguments.push({
57
- name: "Metric Query",
58
- description: "Select the metrics to display in the table",
71
+ name: "Group By Attributes",
72
+ description:
73
+ "Each unique combination of these attribute values becomes one row. Customize the column header for each picked attribute below. Leave empty for a time-bucketed table.",
74
+ required: false,
75
+ type: ComponentInputType.TableGroupBy,
76
+ id: "groupByAttributes",
77
+ section: DataSection,
78
+ });
79
+
80
+ componentArguments.push({
81
+ name: "Metrics & Columns",
82
+ description:
83
+ "Define metrics (data sources) and formulas. Each is auto-assigned a variable letter (a, b, c…) — formulas reference these. Toggle 'Show as column' off for metrics that should only feed formulas without appearing in the table.",
59
84
  required: true,
60
- type: ComponentInputType.MetricsQueryConfig,
61
- id: "metricQueryConfig",
62
- section: DataSourceSection,
85
+ type: ComponentInputType.TableColumns,
86
+ id: "columns",
87
+ section: DataSection,
63
88
  });
64
89
 
65
90
  componentArguments.push({
@@ -71,13 +96,51 @@ export default class DashboardTableComponentUtil extends DashboardBaseComponentU
71
96
  section: DisplaySection,
72
97
  });
73
98
 
99
+ componentArguments.push({
100
+ name: "Description",
101
+ description: "Subtitle shown below the title",
102
+ required: false,
103
+ type: ComponentInputType.LongText,
104
+ id: "tableDescription",
105
+ section: DisplaySection,
106
+ });
107
+
108
+ componentArguments.push({
109
+ name: "Reduce across time",
110
+ description:
111
+ "When Group By is set, how to collapse the time series into one value per row",
112
+ required: false,
113
+ type: ComponentInputType.Dropdown,
114
+ id: "reduce",
115
+ placeholder: TableReduce.Last,
116
+ section: DisplaySection,
117
+ dropdownOptions: [
118
+ { label: "Last value", value: TableReduce.Last },
119
+ { label: "Average", value: TableReduce.Avg },
120
+ { label: "Sum", value: TableReduce.Sum },
121
+ { label: "Min", value: TableReduce.Min },
122
+ { label: "Max", value: TableReduce.Max },
123
+ ],
124
+ });
125
+
126
+ componentArguments.push({
127
+ name: "Decimals",
128
+ description:
129
+ "Default decimals for value columns (overridable per column)",
130
+ required: false,
131
+ type: ComponentInputType.Number,
132
+ id: "decimals",
133
+ placeholder: "2",
134
+ section: DisplaySection,
135
+ });
136
+
74
137
  componentArguments.push({
75
138
  name: "Max Rows",
76
139
  description: "Maximum number of rows to show",
77
140
  required: false,
78
141
  type: ComponentInputType.Number,
79
142
  id: "maxRows",
80
- placeholder: "20",
143
+ placeholder: "25",
81
144
  section: DisplaySection,
82
145
  });
83
146
 
@@ -11,7 +11,6 @@ import DashboardDockerNetworkListComponentUtil from "./DashboardDockerNetworkLis
11
11
  import DashboardDockerVolumeListComponentUtil from "./DashboardDockerVolumeListComponent";
12
12
  import DashboardGaugeComponentUtil from "./DashboardGaugeComponent";
13
13
  import DashboardHostListComponentUtil from "./DashboardHostListComponent";
14
- import DashboardHostMetricChartComponentUtil from "./DashboardHostMetricChartComponent";
15
14
  import DashboardIncidentListComponentUtil from "./DashboardIncidentListComponent";
16
15
  import DashboardKubernetesCronJobListComponentUtil from "./DashboardKubernetesCronJobListComponent";
17
16
  import DashboardKubernetesDaemonSetListComponentUtil from "./DashboardKubernetesDaemonSetListComponent";
@@ -187,12 +186,6 @@ export default class DashboardComponentsUtil {
187
186
  >;
188
187
  }
189
188
 
190
- if (dashboardComponentType === DashboardComponentType.HostMetricChart) {
191
- return DashboardHostMetricChartComponentUtil.getComponentConfigArguments() as Array<
192
- ComponentArgument<DashboardBaseComponent>
193
- >;
194
- }
195
-
196
189
  throw new BadDataException(
197
190
  `Unknown dashboard component type: ${dashboardComponentType}`,
198
191
  );
@@ -171,6 +171,7 @@ class MonitorMetricTypeUtil {
171
171
  monitorType === MonitorType.Port ||
172
172
  monitorType === MonitorType.SNMP ||
173
173
  monitorType === MonitorType.DNS ||
174
+ monitorType === MonitorType.DNSSEC ||
174
175
  monitorType === MonitorType.Domain ||
175
176
  monitorType === MonitorType.ExternalStatusPage
176
177
  ) {