@oneuptime/common 10.0.34 → 10.0.36

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 (130) hide show
  1. package/Models/DatabaseModels/Index.ts +3 -0
  2. package/Models/DatabaseModels/KubernetesCluster.ts +640 -0
  3. package/Server/API/IPWhitelistAPI.ts +31 -0
  4. package/Server/API/Index.ts +2 -0
  5. package/Server/EnvironmentConfig.ts +2 -0
  6. package/Server/Infrastructure/Postgres/SchemaMigrations/1774000000000-MigrationName.ts +80 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/1774000000001-MigrationName.ts +137 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  9. package/Server/Services/KubernetesClusterService.ts +109 -0
  10. package/Server/Services/UserService.ts +6 -0
  11. package/Server/Services/UserSessionService.ts +23 -0
  12. package/Server/Types/Markdown.ts +11 -3
  13. package/Server/Utils/Express.ts +0 -6
  14. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +4 -1
  15. package/Server/Utils/StartServer.ts +7 -3
  16. package/Server/Utils/VM/VMRunner.ts +3 -0
  17. package/Types/Code/CodeType.ts +1 -1
  18. package/Types/Icon/IconProp.ts +1 -0
  19. package/Types/Metrics/MetricQueryConfigData.ts +1 -0
  20. package/Types/Monitor/CriteriaFilter.ts +19 -0
  21. package/Types/Monitor/KubernetesAlertTemplates.ts +703 -0
  22. package/Types/Monitor/KubernetesMetricCatalog.ts +347 -0
  23. package/Types/Monitor/MonitorCriteriaInstance.ts +86 -0
  24. package/Types/Monitor/MonitorStep.ts +36 -1
  25. package/Types/Monitor/MonitorStepKubernetesMonitor.ts +50 -0
  26. package/Types/Monitor/MonitorType.ts +14 -10
  27. package/Types/Permission.ts +42 -0
  28. package/UI/Components/AlertBanner/AlertBanner.tsx +69 -0
  29. package/UI/Components/ConditionsTable/ConditionsTable.tsx +149 -0
  30. package/UI/Components/Dictionary/DictionaryOfStingsViewer.tsx +35 -15
  31. package/UI/Components/ExpandableText/ExpandableText.tsx +42 -0
  32. package/UI/Components/FilterButtons/FilterButtons.tsx +60 -0
  33. package/UI/Components/Icon/Icon.tsx +51 -0
  34. package/UI/Components/LogsViewer/LogsViewer.tsx +2 -0
  35. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +25 -0
  36. package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +4 -1
  37. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +85 -53
  38. package/UI/Components/Navbar/NavBarMenu.tsx +2 -2
  39. package/UI/Components/ResourceUsageBar/ResourceUsageBar.tsx +58 -0
  40. package/UI/Components/StackedProgressBar/StackedProgressBar.tsx +81 -0
  41. package/UI/Components/StatusBadge/StatusBadge.tsx +44 -0
  42. package/UI/Components/Tabs/Tabs.tsx +36 -8
  43. package/UI/Utils/Dropdown.ts +2 -1
  44. package/Utils/Traces/CriticalPath.ts +348 -0
  45. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  46. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  47. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +661 -0
  48. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -0
  49. package/build/dist/Server/API/IPWhitelistAPI.js +24 -0
  50. package/build/dist/Server/API/IPWhitelistAPI.js.map +1 -0
  51. package/build/dist/Server/API/Index.js +2 -0
  52. package/build/dist/Server/API/Index.js.map +1 -1
  53. package/build/dist/Server/EnvironmentConfig.js +1 -0
  54. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  55. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774000000000-MigrationName.js +35 -0
  56. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774000000000-MigrationName.js.map +1 -0
  57. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774000000001-MigrationName.js +52 -0
  58. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774000000001-MigrationName.js.map +1 -0
  59. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  60. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  61. package/build/dist/Server/Services/KubernetesClusterService.js +117 -0
  62. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -0
  63. package/build/dist/Server/Services/UserService.js +5 -0
  64. package/build/dist/Server/Services/UserService.js.map +1 -1
  65. package/build/dist/Server/Services/UserSessionService.js +20 -0
  66. package/build/dist/Server/Services/UserSessionService.js.map +1 -1
  67. package/build/dist/Server/Types/Markdown.js +10 -2
  68. package/build/dist/Server/Types/Markdown.js.map +1 -1
  69. package/build/dist/Server/Utils/Express.js +1 -42
  70. package/build/dist/Server/Utils/Express.js.map +1 -1
  71. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +2 -1
  72. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  73. package/build/dist/Server/Utils/StartServer.js +4 -3
  74. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  75. package/build/dist/Server/Utils/VM/VMRunner.js +3 -0
  76. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  77. package/build/dist/Types/Code/CodeType.js +1 -1
  78. package/build/dist/Types/Code/CodeType.js.map +1 -1
  79. package/build/dist/Types/Icon/IconProp.js +1 -0
  80. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  81. package/build/dist/Types/Monitor/CriteriaFilter.js +18 -0
  82. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  83. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +594 -0
  84. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -0
  85. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +311 -0
  86. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -0
  87. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +78 -0
  88. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  89. package/build/dist/Types/Monitor/MonitorStep.js +24 -1
  90. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  91. package/build/dist/Types/Monitor/MonitorStepKubernetesMonitor.js +30 -0
  92. package/build/dist/Types/Monitor/MonitorStepKubernetesMonitor.js.map +1 -0
  93. package/build/dist/Types/Monitor/MonitorType.js +13 -10
  94. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  95. package/build/dist/Types/Permission.js +36 -0
  96. package/build/dist/Types/Permission.js.map +1 -1
  97. package/build/dist/UI/Components/AlertBanner/AlertBanner.js +42 -0
  98. package/build/dist/UI/Components/AlertBanner/AlertBanner.js.map +1 -0
  99. package/build/dist/UI/Components/ConditionsTable/ConditionsTable.js +83 -0
  100. package/build/dist/UI/Components/ConditionsTable/ConditionsTable.js.map +1 -0
  101. package/build/dist/UI/Components/Dictionary/DictionaryOfStingsViewer.js +14 -8
  102. package/build/dist/UI/Components/Dictionary/DictionaryOfStingsViewer.js.map +1 -1
  103. package/build/dist/UI/Components/ExpandableText/ExpandableText.js +19 -0
  104. package/build/dist/UI/Components/ExpandableText/ExpandableText.js.map +1 -0
  105. package/build/dist/UI/Components/FilterButtons/FilterButtons.js +17 -0
  106. package/build/dist/UI/Components/FilterButtons/FilterButtons.js.map +1 -0
  107. package/build/dist/UI/Components/Icon/Icon.js +27 -0
  108. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  109. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +1 -1
  110. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  111. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +4 -0
  112. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  113. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +3 -1
  114. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
  115. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +50 -43
  116. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  117. package/build/dist/UI/Components/Navbar/NavBarMenu.js +2 -2
  118. package/build/dist/UI/Components/ResourceUsageBar/ResourceUsageBar.js +23 -0
  119. package/build/dist/UI/Components/ResourceUsageBar/ResourceUsageBar.js.map +1 -0
  120. package/build/dist/UI/Components/StackedProgressBar/StackedProgressBar.js +34 -0
  121. package/build/dist/UI/Components/StackedProgressBar/StackedProgressBar.js.map +1 -0
  122. package/build/dist/UI/Components/StatusBadge/StatusBadge.js +22 -0
  123. package/build/dist/UI/Components/StatusBadge/StatusBadge.js.map +1 -0
  124. package/build/dist/UI/Components/Tabs/Tabs.js +32 -9
  125. package/build/dist/UI/Components/Tabs/Tabs.js.map +1 -1
  126. package/build/dist/UI/Utils/Dropdown.js +2 -1
  127. package/build/dist/UI/Utils/Dropdown.js.map +1 -1
  128. package/build/dist/Utils/Traces/CriticalPath.js +240 -0
  129. package/build/dist/Utils/Traces/CriticalPath.js.map +1 -0
  130. package/package.json +1 -1
@@ -0,0 +1,80 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1774000000000 implements MigrationInterface {
4
+ public name = "MigrationName1774000000000";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `CREATE TABLE "KubernetesCluster" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "projectId" uuid NOT NULL, "name" character varying(100) NOT NULL, "slug" character varying(100) NOT NULL, "description" character varying(500), "clusterIdentifier" character varying(100) NOT NULL, "provider" character varying(100) DEFAULT 'unknown', "otelCollectorStatus" character varying(100) DEFAULT 'disconnected', "lastSeenAt" TIMESTAMP WITH TIME ZONE, "nodeCount" integer DEFAULT '0', "podCount" integer DEFAULT '0', "namespaceCount" integer DEFAULT '0', "createdByUserId" uuid, "deletedByUserId" uuid, CONSTRAINT "PK_kubernetes_cluster_id" PRIMARY KEY ("_id"))`,
9
+ );
10
+ await queryRunner.query(
11
+ `CREATE INDEX "IDX_kubernetes_cluster_projectId" ON "KubernetesCluster" ("projectId")`,
12
+ );
13
+ await queryRunner.query(
14
+ `CREATE INDEX "IDX_kubernetes_cluster_clusterIdentifier" ON "KubernetesCluster" ("clusterIdentifier")`,
15
+ );
16
+ await queryRunner.query(
17
+ `CREATE UNIQUE INDEX "IDX_kubernetes_cluster_slug" ON "KubernetesCluster" ("slug")`,
18
+ );
19
+ await queryRunner.query(
20
+ `ALTER TABLE "KubernetesCluster" ADD CONSTRAINT "FK_kubernetes_cluster_projectId" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
21
+ );
22
+ await queryRunner.query(
23
+ `ALTER TABLE "KubernetesCluster" ADD CONSTRAINT "FK_kubernetes_cluster_createdByUserId" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
24
+ );
25
+ await queryRunner.query(
26
+ `ALTER TABLE "KubernetesCluster" ADD CONSTRAINT "FK_kubernetes_cluster_deletedByUserId" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
27
+ );
28
+ // Label join table
29
+ await queryRunner.query(
30
+ `CREATE TABLE "KubernetesClusterLabel" ("kubernetesClusterId" uuid NOT NULL, "labelId" uuid NOT NULL, CONSTRAINT "PK_kubernetes_cluster_label" PRIMARY KEY ("kubernetesClusterId", "labelId"))`,
31
+ );
32
+ await queryRunner.query(
33
+ `CREATE INDEX "IDX_kubernetes_cluster_label_clusterId" ON "KubernetesClusterLabel" ("kubernetesClusterId")`,
34
+ );
35
+ await queryRunner.query(
36
+ `CREATE INDEX "IDX_kubernetes_cluster_label_labelId" ON "KubernetesClusterLabel" ("labelId")`,
37
+ );
38
+ await queryRunner.query(
39
+ `ALTER TABLE "KubernetesClusterLabel" ADD CONSTRAINT "FK_kubernetes_cluster_label_clusterId" FOREIGN KEY ("kubernetesClusterId") REFERENCES "KubernetesCluster"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
40
+ );
41
+ await queryRunner.query(
42
+ `ALTER TABLE "KubernetesClusterLabel" ADD CONSTRAINT "FK_kubernetes_cluster_label_labelId" FOREIGN KEY ("labelId") REFERENCES "Label"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
43
+ );
44
+ }
45
+
46
+ public async down(queryRunner: QueryRunner): Promise<void> {
47
+ await queryRunner.query(
48
+ `ALTER TABLE "KubernetesClusterLabel" DROP CONSTRAINT "FK_kubernetes_cluster_label_labelId"`,
49
+ );
50
+ await queryRunner.query(
51
+ `ALTER TABLE "KubernetesClusterLabel" DROP CONSTRAINT "FK_kubernetes_cluster_label_clusterId"`,
52
+ );
53
+ await queryRunner.query(
54
+ `DROP INDEX "public"."IDX_kubernetes_cluster_label_labelId"`,
55
+ );
56
+ await queryRunner.query(
57
+ `DROP INDEX "public"."IDX_kubernetes_cluster_label_clusterId"`,
58
+ );
59
+ await queryRunner.query(`DROP TABLE "KubernetesClusterLabel"`);
60
+ await queryRunner.query(
61
+ `ALTER TABLE "KubernetesCluster" DROP CONSTRAINT "FK_kubernetes_cluster_deletedByUserId"`,
62
+ );
63
+ await queryRunner.query(
64
+ `ALTER TABLE "KubernetesCluster" DROP CONSTRAINT "FK_kubernetes_cluster_createdByUserId"`,
65
+ );
66
+ await queryRunner.query(
67
+ `ALTER TABLE "KubernetesCluster" DROP CONSTRAINT "FK_kubernetes_cluster_projectId"`,
68
+ );
69
+ await queryRunner.query(
70
+ `DROP INDEX "public"."IDX_kubernetes_cluster_slug"`,
71
+ );
72
+ await queryRunner.query(
73
+ `DROP INDEX "public"."IDX_kubernetes_cluster_clusterIdentifier"`,
74
+ );
75
+ await queryRunner.query(
76
+ `DROP INDEX "public"."IDX_kubernetes_cluster_projectId"`,
77
+ );
78
+ await queryRunner.query(`DROP TABLE "KubernetesCluster"`);
79
+ }
80
+ }
@@ -0,0 +1,137 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1774000000001 implements MigrationInterface {
4
+ public name = "MigrationName1774000000001";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `ALTER TABLE "KubernetesCluster" DROP CONSTRAINT "FK_kubernetes_cluster_projectId"`,
9
+ );
10
+ await queryRunner.query(
11
+ `ALTER TABLE "KubernetesCluster" DROP CONSTRAINT "FK_kubernetes_cluster_createdByUserId"`,
12
+ );
13
+ await queryRunner.query(
14
+ `ALTER TABLE "KubernetesCluster" DROP CONSTRAINT "FK_kubernetes_cluster_deletedByUserId"`,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "KubernetesClusterLabel" DROP CONSTRAINT "FK_kubernetes_cluster_label_clusterId"`,
18
+ );
19
+ await queryRunner.query(
20
+ `ALTER TABLE "KubernetesClusterLabel" DROP CONSTRAINT "FK_kubernetes_cluster_label_labelId"`,
21
+ );
22
+ await queryRunner.query(
23
+ `DROP INDEX "public"."IDX_kubernetes_cluster_projectId"`,
24
+ );
25
+ await queryRunner.query(
26
+ `DROP INDEX "public"."IDX_kubernetes_cluster_clusterIdentifier"`,
27
+ );
28
+ await queryRunner.query(
29
+ `DROP INDEX "public"."IDX_kubernetes_cluster_slug"`,
30
+ );
31
+ await queryRunner.query(
32
+ `DROP INDEX "public"."IDX_kubernetes_cluster_label_clusterId"`,
33
+ );
34
+ await queryRunner.query(
35
+ `DROP INDEX "public"."IDX_kubernetes_cluster_label_labelId"`,
36
+ );
37
+ await queryRunner.query(
38
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
39
+ );
40
+ await queryRunner.query(
41
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
42
+ );
43
+ await queryRunner.query(
44
+ `CREATE INDEX "IDX_5ae5bbb0c93c048b0b76b1d426" ON "KubernetesCluster" ("projectId") `,
45
+ );
46
+ await queryRunner.query(
47
+ `CREATE INDEX "IDX_b9259f6741a7965a518e258f61" ON "KubernetesCluster" ("clusterIdentifier") `,
48
+ );
49
+ await queryRunner.query(
50
+ `CREATE INDEX "IDX_ed1b53bd041aa21b44ca8cdab5" ON "KubernetesClusterLabel" ("kubernetesClusterId") `,
51
+ );
52
+ await queryRunner.query(
53
+ `CREATE INDEX "IDX_2ec82ad068e84cf762c32ad7c7" ON "KubernetesClusterLabel" ("labelId") `,
54
+ );
55
+ await queryRunner.query(
56
+ `ALTER TABLE "KubernetesCluster" ADD CONSTRAINT "FK_5ae5bbb0c93c048b0b76b1d4268" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
57
+ );
58
+ await queryRunner.query(
59
+ `ALTER TABLE "KubernetesCluster" ADD CONSTRAINT "FK_1bee392c44b1aebe754932133a8" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
60
+ );
61
+ await queryRunner.query(
62
+ `ALTER TABLE "KubernetesCluster" ADD CONSTRAINT "FK_b0f6c98aac521060f8b68fe5c87" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
63
+ );
64
+ await queryRunner.query(
65
+ `ALTER TABLE "KubernetesClusterLabel" ADD CONSTRAINT "FK_ed1b53bd041aa21b44ca8cdab5e" FOREIGN KEY ("kubernetesClusterId") REFERENCES "KubernetesCluster"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
66
+ );
67
+ await queryRunner.query(
68
+ `ALTER TABLE "KubernetesClusterLabel" ADD CONSTRAINT "FK_2ec82ad068e84cf762c32ad7c76" FOREIGN KEY ("labelId") REFERENCES "Label"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
69
+ );
70
+ }
71
+
72
+ public async down(queryRunner: QueryRunner): Promise<void> {
73
+ await queryRunner.query(
74
+ `ALTER TABLE "KubernetesClusterLabel" DROP CONSTRAINT "FK_2ec82ad068e84cf762c32ad7c76"`,
75
+ );
76
+ await queryRunner.query(
77
+ `ALTER TABLE "KubernetesClusterLabel" DROP CONSTRAINT "FK_ed1b53bd041aa21b44ca8cdab5e"`,
78
+ );
79
+ await queryRunner.query(
80
+ `ALTER TABLE "KubernetesCluster" DROP CONSTRAINT "FK_b0f6c98aac521060f8b68fe5c87"`,
81
+ );
82
+ await queryRunner.query(
83
+ `ALTER TABLE "KubernetesCluster" DROP CONSTRAINT "FK_1bee392c44b1aebe754932133a8"`,
84
+ );
85
+ await queryRunner.query(
86
+ `ALTER TABLE "KubernetesCluster" DROP CONSTRAINT "FK_5ae5bbb0c93c048b0b76b1d4268"`,
87
+ );
88
+ await queryRunner.query(
89
+ `DROP INDEX "public"."IDX_2ec82ad068e84cf762c32ad7c7"`,
90
+ );
91
+ await queryRunner.query(
92
+ `DROP INDEX "public"."IDX_ed1b53bd041aa21b44ca8cdab5"`,
93
+ );
94
+ await queryRunner.query(
95
+ `DROP INDEX "public"."IDX_b9259f6741a7965a518e258f61"`,
96
+ );
97
+ await queryRunner.query(
98
+ `DROP INDEX "public"."IDX_5ae5bbb0c93c048b0b76b1d426"`,
99
+ );
100
+ await queryRunner.query(
101
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
102
+ );
103
+ await queryRunner.query(
104
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
105
+ );
106
+ await queryRunner.query(
107
+ `CREATE INDEX "IDX_kubernetes_cluster_label_labelId" ON "KubernetesClusterLabel" ("labelId") `,
108
+ );
109
+ await queryRunner.query(
110
+ `CREATE INDEX "IDX_kubernetes_cluster_label_clusterId" ON "KubernetesClusterLabel" ("kubernetesClusterId") `,
111
+ );
112
+ await queryRunner.query(
113
+ `CREATE UNIQUE INDEX "IDX_kubernetes_cluster_slug" ON "KubernetesCluster" ("slug") `,
114
+ );
115
+ await queryRunner.query(
116
+ `CREATE INDEX "IDX_kubernetes_cluster_clusterIdentifier" ON "KubernetesCluster" ("clusterIdentifier") `,
117
+ );
118
+ await queryRunner.query(
119
+ `CREATE INDEX "IDX_kubernetes_cluster_projectId" ON "KubernetesCluster" ("projectId") `,
120
+ );
121
+ await queryRunner.query(
122
+ `ALTER TABLE "KubernetesClusterLabel" ADD CONSTRAINT "FK_kubernetes_cluster_label_labelId" FOREIGN KEY ("labelId") REFERENCES "Label"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
123
+ );
124
+ await queryRunner.query(
125
+ `ALTER TABLE "KubernetesClusterLabel" ADD CONSTRAINT "FK_kubernetes_cluster_label_clusterId" FOREIGN KEY ("kubernetesClusterId") REFERENCES "KubernetesCluster"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
126
+ );
127
+ await queryRunner.query(
128
+ `ALTER TABLE "KubernetesCluster" ADD CONSTRAINT "FK_kubernetes_cluster_deletedByUserId" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
129
+ );
130
+ await queryRunner.query(
131
+ `ALTER TABLE "KubernetesCluster" ADD CONSTRAINT "FK_kubernetes_cluster_createdByUserId" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
132
+ );
133
+ await queryRunner.query(
134
+ `ALTER TABLE "KubernetesCluster" ADD CONSTRAINT "FK_kubernetes_cluster_projectId" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
135
+ );
136
+ }
137
+ }
@@ -266,6 +266,8 @@ import { AddLogSavedView1772355000000 } from "./1772355000000-AddLogSavedView";
266
266
  import { MigrationName1773344537755 } from "./1773344537755-MigrationName";
267
267
  import { MigrationName1773402621107 } from "./1773402621107-MigrationName";
268
268
  import { MigrationName1773676206197 } from "./1773676206197-MigrationName";
269
+ import { MigrationName1774000000000 } from "./1774000000000-MigrationName";
270
+ import { MigrationName1774000000001 } from "./1774000000001-MigrationName";
269
271
 
270
272
  export default [
271
273
  InitialMigration,
@@ -536,4 +538,6 @@ export default [
536
538
  MigrationName1773344537755,
537
539
  MigrationName1773402621107,
538
540
  MigrationName1773676206197,
541
+ MigrationName1774000000000,
542
+ MigrationName1774000000001,
539
543
  ];
@@ -0,0 +1,109 @@
1
+ import DatabaseService from "./DatabaseService";
2
+ import Model from "../../Models/DatabaseModels/KubernetesCluster";
3
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
4
+ import ObjectID from "../../Types/ObjectID";
5
+ import QueryHelper from "../Types/Database/QueryHelper";
6
+ import OneUptimeDate from "../../Types/Date";
7
+ import LIMIT_MAX from "../../Types/Database/LimitMax";
8
+
9
+ export class Service extends DatabaseService<Model> {
10
+ public constructor() {
11
+ super(Model);
12
+ }
13
+
14
+ @CaptureSpan()
15
+ public async findOrCreateByClusterIdentifier(data: {
16
+ projectId: ObjectID;
17
+ clusterIdentifier: string;
18
+ }): Promise<Model> {
19
+ // Try to find existing cluster
20
+ const existingCluster: Model | null = await this.findOneBy({
21
+ query: {
22
+ projectId: data.projectId,
23
+ clusterIdentifier: data.clusterIdentifier,
24
+ },
25
+ select: {
26
+ _id: true,
27
+ projectId: true,
28
+ clusterIdentifier: true,
29
+ },
30
+ props: {
31
+ isRoot: true,
32
+ },
33
+ });
34
+
35
+ if (existingCluster) {
36
+ return existingCluster;
37
+ }
38
+
39
+ // Create new cluster
40
+ const newCluster: Model = new Model();
41
+ newCluster.projectId = data.projectId;
42
+ newCluster.name = data.clusterIdentifier;
43
+ newCluster.clusterIdentifier = data.clusterIdentifier;
44
+ newCluster.otelCollectorStatus = "connected";
45
+ newCluster.lastSeenAt = OneUptimeDate.getCurrentDate();
46
+
47
+ const createdCluster: Model = await this.create({
48
+ data: newCluster,
49
+ props: {
50
+ isRoot: true,
51
+ },
52
+ });
53
+
54
+ return createdCluster;
55
+ }
56
+
57
+ @CaptureSpan()
58
+ public async updateLastSeen(clusterId: ObjectID): Promise<void> {
59
+ await this.updateOneById({
60
+ id: clusterId,
61
+ data: {
62
+ lastSeenAt: OneUptimeDate.getCurrentDate(),
63
+ otelCollectorStatus: "connected",
64
+ },
65
+ props: {
66
+ isRoot: true,
67
+ },
68
+ });
69
+ }
70
+
71
+ @CaptureSpan()
72
+ public async markDisconnectedClusters(): Promise<void> {
73
+ const fiveMinutesAgo: Date = OneUptimeDate.addRemoveMinutes(
74
+ OneUptimeDate.getCurrentDate(),
75
+ -5,
76
+ );
77
+
78
+ const connectedClusters: Array<Model> = await this.findBy({
79
+ query: {
80
+ otelCollectorStatus: "connected",
81
+ lastSeenAt: QueryHelper.lessThan(fiveMinutesAgo),
82
+ },
83
+ select: {
84
+ _id: true,
85
+ },
86
+ limit: LIMIT_MAX,
87
+ skip: 0,
88
+ props: {
89
+ isRoot: true,
90
+ },
91
+ });
92
+
93
+ for (const cluster of connectedClusters) {
94
+ if (cluster._id) {
95
+ await this.updateOneById({
96
+ id: new ObjectID(cluster._id.toString()),
97
+ data: {
98
+ otelCollectorStatus: "disconnected",
99
+ },
100
+ props: {
101
+ isRoot: true,
102
+ },
103
+ });
104
+ }
105
+ }
106
+ }
107
+ }
108
+
109
+ export default new Service();
@@ -13,6 +13,7 @@ import MailService from "./MailService";
13
13
  import TeamMemberService from "./TeamMemberService";
14
14
  import UserNotificationRuleService from "./UserNotificationRuleService";
15
15
  import UserNotificationSettingService from "./UserNotificationSettingService";
16
+ import UserSessionService from "./UserSessionService";
16
17
  import { AccountsRoute } from "../../ServiceRoute";
17
18
  import Hostname from "../../Types/API/Hostname";
18
19
  import Protocol from "../../Types/API/Protocol";
@@ -252,6 +253,11 @@ export class Service extends DatabaseService<Model> {
252
253
  const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
253
254
 
254
255
  for (const user of onUpdate.carryForward) {
256
+ // Revoke all active sessions for this user on password change
257
+ await UserSessionService.revokeAllSessionsByUserId(user.id!, {
258
+ reason: "Password changed",
259
+ });
260
+
255
261
  // password changed, send password changed mail
256
262
  MailService.sendMail({
257
263
  toEmail: user.email!,
@@ -1,6 +1,7 @@
1
1
  import DatabaseService from "./DatabaseService";
2
2
  import Model from "../../Models/DatabaseModels/UserSession";
3
3
  import ObjectID from "../../Types/ObjectID";
4
+ import LIMIT_MAX from "../../Types/Database/LimitMax";
4
5
  import { JSONObject } from "../../Types/JSON";
5
6
  import HashedString from "../../Types/HashedString";
6
7
  import { EncryptionSecret } from "../EnvironmentConfig";
@@ -275,6 +276,28 @@ export class Service extends DatabaseService<Model> {
275
276
  await this.revokeSessionById(session.id, options);
276
277
  }
277
278
 
279
+ public async revokeAllSessionsByUserId(
280
+ userId: ObjectID,
281
+ options?: RevokeSessionOptions,
282
+ ): Promise<void> {
283
+ await this.updateBy({
284
+ query: {
285
+ userId: userId,
286
+ isRevoked: false,
287
+ },
288
+ data: {
289
+ isRevoked: true,
290
+ revokedAt: OneUptimeDate.getCurrentDate(),
291
+ revokedReason: options?.reason ?? null,
292
+ },
293
+ limit: LIMIT_MAX,
294
+ skip: 0,
295
+ props: {
296
+ isRoot: true,
297
+ },
298
+ });
299
+ }
300
+
278
301
  private buildSessionModel(
279
302
  options: CreateSessionOptions,
280
303
  tokenMeta: { refreshToken: string; refreshTokenExpiresAt: Date },
@@ -79,9 +79,6 @@ export default class Markdown {
79
79
  markdown: string,
80
80
  contentType: MarkdownContentType,
81
81
  ): Promise<string> {
82
- // Basic sanitization: neutralize script tags but preserve markdown syntax like '>' for blockquotes.
83
- markdown = markdown.replace(/<script/gi, "&lt;script");
84
-
85
82
  let renderer: Renderer | null = null;
86
83
 
87
84
  if (contentType === MarkdownContentType.Blog) {
@@ -96,6 +93,17 @@ export default class Markdown {
96
93
  renderer = this.getEmailRenderer();
97
94
  }
98
95
 
96
+ /*
97
+ * Escape raw HTML tokens in the markdown source to prevent XSS.
98
+ * This only affects raw HTML that users type directly (e.g. <img onerror=...>),
99
+ * not HTML generated by the renderer methods (headings, paragraphs, etc.).
100
+ */
101
+ if (renderer) {
102
+ renderer.html = (html: string): string => {
103
+ return Markdown.escapeHtml(html);
104
+ };
105
+ }
106
+
99
107
  const htmlBody: string = await marked(markdown, {
100
108
  renderer: renderer,
101
109
  });
@@ -13,7 +13,6 @@ import UserType from "../../Types/UserType";
13
13
  import "ejs";
14
14
  import express from "express";
15
15
  import { Server, createServer } from "http";
16
- import CaptureSpan from "./Telemetry/CaptureSpan";
17
16
 
18
17
  export type RequestHandler = express.RequestHandler;
19
18
  export type NextFunction = express.NextFunction;
@@ -61,22 +60,18 @@ class Express {
61
60
  private static app: express.Application;
62
61
  private static httpServer: Server;
63
62
 
64
- @CaptureSpan()
65
63
  public static getRouter(): express.Router {
66
64
  return express.Router();
67
65
  }
68
66
 
69
- @CaptureSpan()
70
67
  public static setupExpress(): void {
71
68
  this.app = express();
72
69
  }
73
70
 
74
- @CaptureSpan()
75
71
  public static getHttpServer(): Server {
76
72
  return this.httpServer;
77
73
  }
78
74
 
79
- @CaptureSpan()
80
75
  public static getExpressApp(): express.Application {
81
76
  if (!this.app) {
82
77
  this.setupExpress();
@@ -85,7 +80,6 @@ class Express {
85
80
  return this.app;
86
81
  }
87
82
 
88
- @CaptureSpan()
89
83
  public static async launchApplication(
90
84
  appName: string,
91
85
  port?: Port,
@@ -447,7 +447,10 @@ ${contextBlock}
447
447
  }
448
448
  }
449
449
 
450
- if (input.monitor.monitorType === MonitorType.Metrics) {
450
+ if (
451
+ input.monitor.monitorType === MonitorType.Metrics ||
452
+ input.monitor.monitorType === MonitorType.Kubernetes
453
+ ) {
451
454
  const metricMonitorResult: string | null =
452
455
  await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
453
456
  dataToProcess: input.dataToProcess,
@@ -37,6 +37,7 @@ import Typeof from "../../Types/Typeof";
37
37
  import CookieParser from "cookie-parser";
38
38
  import cors from "cors";
39
39
  import zlib from "zlib";
40
+ import path from "path";
40
41
  import "ejs";
41
42
  // Make sure we have stack trace for debugging.
42
43
  Error.stackTraceLimit = Infinity;
@@ -240,12 +241,15 @@ const init: InitFunction = async (
240
241
  },
241
242
  );
242
243
 
243
- app.use(`/${appName}`, ExpressStatic("/usr/src/app/public"));
244
+ app.use(
245
+ `/${appName}`,
246
+ ExpressStatic(path.resolve(process.cwd(), "public")),
247
+ );
244
248
 
245
249
  app.get(
246
250
  `/${appName}/dist/Index.js`,
247
251
  (_req: ExpressRequest, res: ExpressResponse) => {
248
- res.sendFile("/usr/src/app/public/dist/Index.js");
252
+ res.sendFile(path.resolve(process.cwd(), "public/dist/Index.js"));
249
253
  },
250
254
  );
251
255
 
@@ -285,7 +289,7 @@ const init: InitFunction = async (
285
289
  return;
286
290
  }
287
291
 
288
- return res.render("/usr/src/app/views/index.ejs", {
292
+ return res.render(path.resolve(process.cwd(), "views/index.ejs"), {
289
293
  enableGoogleTagManager: IsBillingEnabled || false,
290
294
  ...variables,
291
295
  });
@@ -28,9 +28,12 @@ const BLOCKED_SANDBOX_PROPERTIES: ReadonlySet<string> = new Set([
28
28
  * and traversal via page.context().browser().browserType().launch(...)
29
29
  */
30
30
  "browserType", // Browser → BrowserType (which has launch/connect)
31
+ "_browserType", // Internal alias for browserType — same escape vector
31
32
  "launch", // BrowserType.launch() spawns a child process
33
+ "launchServer", // BrowserType.launchServer() spawns a browser server process
32
34
  "launchPersistentContext", // BrowserType.launchPersistentContext() spawns a child process
33
35
  "connectOverCDP", // BrowserType.connectOverCDP() connects via Chrome DevTools Protocol
36
+ "connect", // BrowserType.connect() connects to a remote browser
34
37
  "newCDPSession", // BrowserContext/Page.newCDPSession() opens raw CDP sessions
35
38
  ]);
36
39
 
@@ -6,7 +6,7 @@ enum CodeType {
6
6
  Markdown = "markdown",
7
7
  SQL = "sql",
8
8
  Text = "text",
9
- // TODO add more mime types.
9
+ YAML = "yaml",
10
10
  }
11
11
 
12
12
  export default CodeType;
@@ -320,6 +320,7 @@ enum IconProp {
320
320
  TableCellsIcon = "TableCellsIcon",
321
321
  UserIcon = "UserIcon",
322
322
  XCircle = "XCircle",
323
+ Kubernetes = "Kubernetes",
323
324
  }
324
325
 
325
326
  export default IconProp;
@@ -16,4 +16,5 @@ export default interface MetricQueryConfigData {
16
16
  metricQueryData: MetricQueryData;
17
17
  getSeries?: ((data: AggregatedModel) => ChartSeries) | undefined;
18
18
  chartType?: MetricChartType | undefined;
19
+ yAxisValueFormatter?: ((value: number) => string) | undefined;
19
20
  }
@@ -226,6 +226,25 @@ export class CriteriaFilterUtil {
226
226
  ];
227
227
  }
228
228
 
229
+ public static getInverseFilterType(filterType: FilterType): FilterType {
230
+ switch (filterType) {
231
+ case FilterType.GreaterThan:
232
+ return FilterType.LessThanOrEqualTo;
233
+ case FilterType.LessThan:
234
+ return FilterType.GreaterThanOrEqualTo;
235
+ case FilterType.GreaterThanOrEqualTo:
236
+ return FilterType.LessThan;
237
+ case FilterType.LessThanOrEqualTo:
238
+ return FilterType.GreaterThan;
239
+ case FilterType.EqualTo:
240
+ return FilterType.NotEqualTo;
241
+ case FilterType.NotEqualTo:
242
+ return FilterType.EqualTo;
243
+ default:
244
+ return filterType;
245
+ }
246
+ }
247
+
229
248
  public static isEvaluateOverTimeFilter(checkOn: CheckOn): boolean {
230
249
  return (
231
250
  checkOn === CheckOn.ResponseStatusCode ||