@oneuptime/common 10.4.13 → 10.4.14
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.
- package/Models/DatabaseModels/Alert.ts +2 -0
- package/Models/DatabaseModels/AlertFeed.ts +1 -0
- package/Models/DatabaseModels/CallLog.ts +2 -0
- package/Models/DatabaseModels/DockerHost.ts +34 -0
- package/Models/DatabaseModels/EmailLog.ts +2 -0
- package/Models/DatabaseModels/Host.ts +34 -0
- package/Models/DatabaseModels/Incident.ts +1 -0
- package/Models/DatabaseModels/IncidentFeed.ts +1 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +34 -0
- package/Models/DatabaseModels/MonitorFeed.ts +1 -0
- package/Models/DatabaseModels/MonitorProbe.ts +1 -0
- package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +3 -0
- package/Models/DatabaseModels/SmsLog.ts +2 -0
- package/Models/DatabaseModels/StatusPageSubscriber.ts +2 -0
- package/Models/DatabaseModels/TelemetryException.ts +2 -0
- package/Models/DatabaseModels/UserOnCallLog.ts +1 -0
- package/Models/DatabaseModels/WorkflowLog.ts +1 -0
- package/Server/API/ProjectAPI.ts +52 -15
- package/Server/EnvironmentConfig.ts +69 -0
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +26 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1779392865146-AddAgentVersionToKubernetesDockerHost.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1779392970424-AddPerformanceIndexes.ts +160 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Infrastructure/PostgresDatabase.ts +2 -5
- package/Server/Middleware/ProjectAuthorization.ts +31 -53
- package/Server/Middleware/UserAuthorization.ts +106 -64
- package/Server/Services/ApiKeyService.ts +100 -1
- package/Server/Services/DockerHostService.ts +5 -0
- package/Server/Services/HostService.ts +6 -0
- package/Server/Services/KubernetesClusterService.ts +33 -10
- package/Server/Services/MonitorService.ts +10 -3
- package/Server/Services/ProjectService.ts +72 -1
- package/Server/Services/TeamMemberService.ts +36 -0
- package/Server/Services/UserService.ts +38 -0
- package/build/dist/Models/DatabaseModels/Alert.js +3 -1
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -1
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CallLog.js +4 -1
- package/build/dist/Models/DatabaseModels/CallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +35 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/EmailLog.js +4 -1
- package/build/dist/Models/DatabaseModels/EmailLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +35 -0
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +2 -1
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -1
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +35 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorFeed.js +2 -1
- package/build/dist/Models/DatabaseModels/MonitorFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorProbe.js +2 -0
- package/build/dist/Models/DatabaseModels/MonitorProbe.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +3 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/SmsLog.js +4 -1
- package/build/dist/Models/DatabaseModels/SmsLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +4 -1
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryException.js +3 -1
- package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js +1 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLog.js +2 -1
- package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +42 -14
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +41 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +20 -2
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1779392865146-AddAgentVersionToKubernetesDockerHost.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1779392865146-AddAgentVersionToKubernetesDockerHost.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1779392970424-AddPerformanceIndexes.js +63 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1779392970424-AddPerformanceIndexes.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/PostgresDatabase.js +2 -2
- package/build/dist/Server/Infrastructure/PostgresDatabase.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +21 -39
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +83 -50
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyService.js +86 -0
- package/build/dist/Server/Services/ApiKeyService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +5 -1
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +5 -1
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +21 -11
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +8 -3
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +65 -1
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +24 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +36 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/package.json +1 -1
|
@@ -114,6 +114,7 @@ import NotificationRuleWorkspaceChannel from "../../Types/Workspace/Notification
|
|
|
114
114
|
delete: true,
|
|
115
115
|
},
|
|
116
116
|
})
|
|
117
|
+
@Index(["projectId", "currentAlertStateId"]) // Active-alert counters on dashboard
|
|
117
118
|
export default class Alert extends BaseModel {
|
|
118
119
|
@ColumnAccessControl({
|
|
119
120
|
create: [
|
|
@@ -484,6 +485,7 @@ export default class Alert extends BaseModel {
|
|
|
484
485
|
Permission.EditAlert,
|
|
485
486
|
],
|
|
486
487
|
})
|
|
488
|
+
@Index()
|
|
487
489
|
@TableColumn({
|
|
488
490
|
type: TableColumnType.ObjectID,
|
|
489
491
|
title: "Monitor ID",
|
|
@@ -91,6 +91,7 @@ export enum AlertFeedEventType {
|
|
|
91
91
|
tableDescription:
|
|
92
92
|
"Log of the entire alert state change. This is a log of all the alert state changes, public notes, more etc.",
|
|
93
93
|
})
|
|
94
|
+
@Index(["alertId", "postedAt"]) // Alert detail page: feed sorted by postedAt
|
|
94
95
|
export default class AlertFeed extends BaseModel {
|
|
95
96
|
@ColumnAccessControl({
|
|
96
97
|
create: [
|
|
@@ -61,6 +61,8 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
|
|
61
61
|
tableDescription:
|
|
62
62
|
"Logs of all the Call sent out to all users and subscribers for this project.",
|
|
63
63
|
})
|
|
64
|
+
@Index(["projectId", "createdAt"]) // Notification logs table: time-range filter per project
|
|
65
|
+
@Index(["projectId", "status"]) // Notification logs table: status filter per project
|
|
64
66
|
export default class CallLog extends BaseModel {
|
|
65
67
|
@ColumnAccessControl({
|
|
66
68
|
create: [],
|
|
@@ -358,6 +358,40 @@ export default class DockerHost extends BaseModel {
|
|
|
358
358
|
})
|
|
359
359
|
public otelCollectorStatus?: string = undefined;
|
|
360
360
|
|
|
361
|
+
@ColumnAccessControl({
|
|
362
|
+
create: [],
|
|
363
|
+
read: [
|
|
364
|
+
Permission.ProjectOwner,
|
|
365
|
+
Permission.ProjectAdmin,
|
|
366
|
+
Permission.ProjectMember,
|
|
367
|
+
Permission.Viewer,
|
|
368
|
+
Permission.SettingsAdmin,
|
|
369
|
+
Permission.SettingsMember,
|
|
370
|
+
Permission.SettingsViewer,
|
|
371
|
+
Permission.ReadDockerHost,
|
|
372
|
+
],
|
|
373
|
+
update: [
|
|
374
|
+
Permission.ProjectOwner,
|
|
375
|
+
Permission.ProjectAdmin,
|
|
376
|
+
Permission.EditDockerHost,
|
|
377
|
+
],
|
|
378
|
+
})
|
|
379
|
+
@TableColumn({
|
|
380
|
+
required: false,
|
|
381
|
+
type: TableColumnType.ShortText,
|
|
382
|
+
canReadOnRelationQuery: true,
|
|
383
|
+
title: "Agent Version",
|
|
384
|
+
description:
|
|
385
|
+
"Version of the OneUptime Docker agent reporting telemetry, as self-reported via the oneuptime.agent.version resource attribute",
|
|
386
|
+
example: "1.0.0",
|
|
387
|
+
})
|
|
388
|
+
@Column({
|
|
389
|
+
nullable: true,
|
|
390
|
+
type: ColumnType.ShortText,
|
|
391
|
+
length: ColumnLength.ShortText,
|
|
392
|
+
})
|
|
393
|
+
public agentVersion?: string = undefined;
|
|
394
|
+
|
|
361
395
|
@ColumnAccessControl({
|
|
362
396
|
create: [],
|
|
363
397
|
read: [
|
|
@@ -62,6 +62,8 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
|
|
62
62
|
tableDescription:
|
|
63
63
|
"Logs of all the Email sent out to all users and subscribers for this project.",
|
|
64
64
|
})
|
|
65
|
+
@Index(["projectId", "createdAt"]) // Notification logs table: time-range filter per project
|
|
66
|
+
@Index(["projectId", "status"]) // Notification logs table: status filter per project
|
|
65
67
|
export default class EmailLog extends BaseModel {
|
|
66
68
|
@ColumnAccessControl({
|
|
67
69
|
create: [],
|
|
@@ -360,6 +360,40 @@ export default class Host extends BaseModel {
|
|
|
360
360
|
})
|
|
361
361
|
public otelCollectorStatus?: string = undefined;
|
|
362
362
|
|
|
363
|
+
@ColumnAccessControl({
|
|
364
|
+
create: [],
|
|
365
|
+
read: [
|
|
366
|
+
Permission.ProjectOwner,
|
|
367
|
+
Permission.ProjectAdmin,
|
|
368
|
+
Permission.ProjectMember,
|
|
369
|
+
Permission.Viewer,
|
|
370
|
+
Permission.SettingsAdmin,
|
|
371
|
+
Permission.SettingsMember,
|
|
372
|
+
Permission.SettingsViewer,
|
|
373
|
+
Permission.ReadHost,
|
|
374
|
+
],
|
|
375
|
+
update: [
|
|
376
|
+
Permission.ProjectOwner,
|
|
377
|
+
Permission.ProjectAdmin,
|
|
378
|
+
Permission.EditHost,
|
|
379
|
+
],
|
|
380
|
+
})
|
|
381
|
+
@TableColumn({
|
|
382
|
+
required: false,
|
|
383
|
+
type: TableColumnType.ShortText,
|
|
384
|
+
canReadOnRelationQuery: true,
|
|
385
|
+
title: "Agent Version",
|
|
386
|
+
description:
|
|
387
|
+
"Version of the OneUptime agent reporting telemetry on this host, as self-reported via the oneuptime.agent.version resource attribute",
|
|
388
|
+
example: "1.0.0",
|
|
389
|
+
})
|
|
390
|
+
@Column({
|
|
391
|
+
nullable: true,
|
|
392
|
+
type: ColumnType.ShortText,
|
|
393
|
+
length: ColumnLength.ShortText,
|
|
394
|
+
})
|
|
395
|
+
public agentVersion?: string = undefined;
|
|
396
|
+
|
|
363
397
|
@ColumnAccessControl({
|
|
364
398
|
create: [],
|
|
365
399
|
read: [
|
|
@@ -118,6 +118,7 @@ import NotificationRuleWorkspaceChannel from "../../Types/Workspace/Notification
|
|
|
118
118
|
delete: true,
|
|
119
119
|
},
|
|
120
120
|
})
|
|
121
|
+
@Index(["projectId", "currentIncidentStateId"]) // Active-incident counters on dashboard
|
|
121
122
|
export default class Incident extends BaseModel {
|
|
122
123
|
@ColumnAccessControl({
|
|
123
124
|
create: [
|
|
@@ -91,6 +91,7 @@ export enum IncidentFeedEventType {
|
|
|
91
91
|
tableDescription:
|
|
92
92
|
"Log of the entire incident state change. This is a log of all the incident state changes, public notes, more etc.",
|
|
93
93
|
})
|
|
94
|
+
@Index(["incidentId", "postedAt"]) // Incident detail page: feed sorted by postedAt
|
|
94
95
|
export default class IncidentFeed extends BaseModel {
|
|
95
96
|
@ColumnAccessControl({
|
|
96
97
|
create: [
|
|
@@ -410,6 +410,40 @@ export default class KubernetesCluster extends BaseModel {
|
|
|
410
410
|
})
|
|
411
411
|
public otelCollectorStatus?: string = undefined;
|
|
412
412
|
|
|
413
|
+
@ColumnAccessControl({
|
|
414
|
+
create: [],
|
|
415
|
+
read: [
|
|
416
|
+
Permission.ProjectOwner,
|
|
417
|
+
Permission.ProjectAdmin,
|
|
418
|
+
Permission.ProjectMember,
|
|
419
|
+
Permission.Viewer,
|
|
420
|
+
Permission.SettingsAdmin,
|
|
421
|
+
Permission.SettingsMember,
|
|
422
|
+
Permission.SettingsViewer,
|
|
423
|
+
Permission.ReadKubernetesCluster,
|
|
424
|
+
],
|
|
425
|
+
update: [
|
|
426
|
+
Permission.ProjectOwner,
|
|
427
|
+
Permission.ProjectAdmin,
|
|
428
|
+
Permission.EditKubernetesCluster,
|
|
429
|
+
],
|
|
430
|
+
})
|
|
431
|
+
@TableColumn({
|
|
432
|
+
required: false,
|
|
433
|
+
type: TableColumnType.ShortText,
|
|
434
|
+
canReadOnRelationQuery: true,
|
|
435
|
+
title: "Agent Version",
|
|
436
|
+
description:
|
|
437
|
+
"Version of the OneUptime Kubernetes agent reporting telemetry, as self-reported via the oneuptime.agent.version resource attribute",
|
|
438
|
+
example: "1.0.0",
|
|
439
|
+
})
|
|
440
|
+
@Column({
|
|
441
|
+
nullable: true,
|
|
442
|
+
type: ColumnType.ShortText,
|
|
443
|
+
length: ColumnLength.ShortText,
|
|
444
|
+
})
|
|
445
|
+
public agentVersion?: string = undefined;
|
|
446
|
+
|
|
413
447
|
@ColumnAccessControl({
|
|
414
448
|
create: [],
|
|
415
449
|
read: [
|
|
@@ -80,6 +80,7 @@ export enum MonitorFeedEventType {
|
|
|
80
80
|
tableDescription:
|
|
81
81
|
"Log of the entire monitor state change. This is a log of all the monitor state changes, public notes, more etc.",
|
|
82
82
|
})
|
|
83
|
+
@Index(["monitorId", "postedAt"]) // Monitor detail page: feed sorted by postedAt
|
|
83
84
|
export default class MonitorFeed extends BaseModel {
|
|
84
85
|
@ColumnAccessControl({
|
|
85
86
|
create: [
|
|
@@ -27,6 +27,7 @@ export type MonitorStepProbeResponse = Dictionary<ProbeMonitorResponse>;
|
|
|
27
27
|
@TenantColumn("projectId")
|
|
28
28
|
@Index(["monitorId", "probeId"]) // Composite index for efficient monitor-probe relationship queries
|
|
29
29
|
@Index(["monitorId", "projectId"]) // Alternative index for monitor queries within project
|
|
30
|
+
@Index(["probeId", "isEnabled", "nextPingAt"]) // Scheduler hot path: pick due probes per probeId
|
|
30
31
|
@TableAccessControl({
|
|
31
32
|
create: [
|
|
32
33
|
Permission.ProjectOwner,
|
|
@@ -483,6 +483,7 @@ export default class OnCallDutyPolicyTimeLog extends BaseModel {
|
|
|
483
483
|
],
|
|
484
484
|
update: [],
|
|
485
485
|
})
|
|
486
|
+
@Index()
|
|
486
487
|
@TableColumn({
|
|
487
488
|
type: TableColumnType.ObjectID,
|
|
488
489
|
required: true,
|
|
@@ -497,6 +498,7 @@ export default class OnCallDutyPolicyTimeLog extends BaseModel {
|
|
|
497
498
|
})
|
|
498
499
|
public userId?: ObjectID = undefined;
|
|
499
500
|
|
|
501
|
+
@Index()
|
|
500
502
|
@TableColumn({
|
|
501
503
|
title: "Start At",
|
|
502
504
|
type: TableColumnType.Date,
|
|
@@ -530,6 +532,7 @@ export default class OnCallDutyPolicyTimeLog extends BaseModel {
|
|
|
530
532
|
})
|
|
531
533
|
public startsAt?: Date = undefined;
|
|
532
534
|
|
|
535
|
+
@Index()
|
|
533
536
|
@TableColumn({
|
|
534
537
|
title: "Ends At",
|
|
535
538
|
type: TableColumnType.Date,
|
|
@@ -61,6 +61,8 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
|
|
61
61
|
tableDescription:
|
|
62
62
|
"Logs of all the SMS sent out to all users and subscribers for this project.",
|
|
63
63
|
})
|
|
64
|
+
@Index(["projectId", "createdAt"]) // Notification logs table: time-range filter per project
|
|
65
|
+
@Index(["projectId", "status"]) // Notification logs table: status filter per project
|
|
64
66
|
export default class SmsLog extends BaseModel {
|
|
65
67
|
@ColumnAccessControl({
|
|
66
68
|
create: [],
|
|
@@ -94,6 +94,8 @@ import StatusPageEventType from "../../Types/StatusPage/StatusPageEventType";
|
|
|
94
94
|
@Entity({
|
|
95
95
|
name: "StatusPageSubscriber",
|
|
96
96
|
})
|
|
97
|
+
@Index(["statusPageId", "subscriberEmail"]) // Dedupe lookup on email subscribe
|
|
98
|
+
@Index(["statusPageId", "subscriberPhone"]) // Dedupe lookup on phone subscribe
|
|
97
99
|
export default class StatusPageSubscriber extends BaseModel {
|
|
98
100
|
@ColumnAccessControl({
|
|
99
101
|
create: [
|
|
@@ -62,6 +62,7 @@ import Service from "./Service";
|
|
|
62
62
|
@Entity({
|
|
63
63
|
name: "TelemetryException",
|
|
64
64
|
})
|
|
65
|
+
@Index(["projectId", "isResolved", "isArchived"]) // Exceptions dashboard counts/filters
|
|
65
66
|
export default class TelemetryException extends DatabaseBaseModel {
|
|
66
67
|
@ColumnAccessControl({
|
|
67
68
|
create: [
|
|
@@ -1096,6 +1097,7 @@ export default class TelemetryException extends DatabaseBaseModel {
|
|
|
1096
1097
|
Permission.EditTelemetryException,
|
|
1097
1098
|
],
|
|
1098
1099
|
})
|
|
1100
|
+
@Index()
|
|
1099
1101
|
@TableColumn({
|
|
1100
1102
|
title: "Occurances",
|
|
1101
1103
|
description: "Number of times this exception has occurred",
|
|
@@ -60,6 +60,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
|
|
60
60
|
icon: IconProp.Logs,
|
|
61
61
|
tableDescription: "Logs of the workflows executed",
|
|
62
62
|
})
|
|
63
|
+
@Index(["workflowStatus", "createdAt"]) // Worker sweep for scheduled/timed-out runs
|
|
63
64
|
export default class WorkflowLog extends BaseModel {
|
|
64
65
|
@ColumnAccessControl({
|
|
65
66
|
create: [],
|
package/Server/API/ProjectAPI.ts
CHANGED
|
@@ -5,6 +5,7 @@ import ProjectService, {
|
|
|
5
5
|
} from "../Services/ProjectService";
|
|
6
6
|
import ResellerService from "../Services/ResellerService";
|
|
7
7
|
import TeamMemberService from "../Services/TeamMemberService";
|
|
8
|
+
import QueryHelper from "../Types/Database/QueryHelper";
|
|
8
9
|
import Select from "../Types/Database/Select";
|
|
9
10
|
import {
|
|
10
11
|
ExpressRequest,
|
|
@@ -223,25 +224,61 @@ export default class ProjectAPI extends BaseAPI<Project, ProjectServiceType> {
|
|
|
223
224
|
}
|
|
224
225
|
}
|
|
225
226
|
|
|
226
|
-
|
|
227
|
+
/*
|
|
228
|
+
* Batch-fetch resellers for every project in one query instead of
|
|
229
|
+
* one findOneById per project.
|
|
230
|
+
*/
|
|
231
|
+
const resellerIds: Array<ObjectID> = [];
|
|
232
|
+
const seenResellerIds: Set<string> = new Set<string>();
|
|
227
233
|
for (const project of projects) {
|
|
228
|
-
if (
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
isRoot: true,
|
|
237
|
-
},
|
|
238
|
-
});
|
|
234
|
+
if (
|
|
235
|
+
project.resellerId &&
|
|
236
|
+
!seenResellerIds.has(project.resellerId.toString())
|
|
237
|
+
) {
|
|
238
|
+
seenResellerIds.add(project.resellerId.toString());
|
|
239
|
+
resellerIds.push(project.resellerId);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
239
242
|
|
|
240
|
-
|
|
241
|
-
|
|
243
|
+
if (resellerIds.length > 0) {
|
|
244
|
+
const resellers: Array<Reseller> = await ResellerService.findBy({
|
|
245
|
+
query: {
|
|
246
|
+
_id: QueryHelper.any(
|
|
247
|
+
resellerIds.map((id: ObjectID) => {
|
|
248
|
+
return id.toString();
|
|
249
|
+
}),
|
|
250
|
+
),
|
|
251
|
+
},
|
|
252
|
+
select: {
|
|
253
|
+
_id: true,
|
|
254
|
+
enableTelemetryFeatures: true,
|
|
255
|
+
},
|
|
256
|
+
limit: LIMIT_PER_PROJECT,
|
|
257
|
+
skip: 0,
|
|
258
|
+
props: {
|
|
259
|
+
isRoot: true,
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const resellersById: Map<string, Reseller> = new Map<
|
|
264
|
+
string,
|
|
265
|
+
Reseller
|
|
266
|
+
>();
|
|
267
|
+
for (const reseller of resellers) {
|
|
268
|
+
if (reseller._id) {
|
|
269
|
+
resellersById.set(reseller._id.toString(), reseller);
|
|
242
270
|
}
|
|
271
|
+
}
|
|
243
272
|
|
|
244
|
-
|
|
273
|
+
for (const project of projects) {
|
|
274
|
+
if (project.resellerId) {
|
|
275
|
+
const reseller: Reseller | undefined = resellersById.get(
|
|
276
|
+
project.resellerId.toString(),
|
|
277
|
+
);
|
|
278
|
+
if (reseller) {
|
|
279
|
+
project.reseller = reseller;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
245
282
|
}
|
|
246
283
|
}
|
|
247
284
|
|
|
@@ -145,6 +145,75 @@ export const ShouldDatabaseSslEnable: boolean = Boolean(
|
|
|
145
145
|
DatabaseSslCa || (DatabaseSslCert && DatabaseSslKey),
|
|
146
146
|
);
|
|
147
147
|
|
|
148
|
+
/*
|
|
149
|
+
* Postgres pool size per API/Worker node. TypeORM's default is 10 which
|
|
150
|
+
* starves the API under any meaningful load — pick a number that, when
|
|
151
|
+
* multiplied by the number of running Node processes, stays under the
|
|
152
|
+
* Postgres server's `max_connections` (default 100 on a stock cluster).
|
|
153
|
+
*/
|
|
154
|
+
export const MaxPostgresConnections: number = parseInt(
|
|
155
|
+
process.env["DATABASE_MAX_OPEN_CONNECTIONS"] || "50",
|
|
156
|
+
10,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* Postgres-side statement timeout (ms). Caps the wall-clock time of any
|
|
161
|
+
* single SQL statement. Without this, a single runaway query can pin a
|
|
162
|
+
* connection forever and starve the pool.
|
|
163
|
+
*/
|
|
164
|
+
export const PostgresStatementTimeoutMs: number = parseInt(
|
|
165
|
+
process.env["DATABASE_STATEMENT_TIMEOUT_MS"] || "30000",
|
|
166
|
+
10,
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
/*
|
|
170
|
+
* Node-postgres client-side query timeout (ms). Belt-and-braces for the
|
|
171
|
+
* server-side statement_timeout — fires even if the connection has gone
|
|
172
|
+
* silent or the server-side timeout doesn't kick in.
|
|
173
|
+
*/
|
|
174
|
+
export const PostgresQueryTimeoutMs: number = parseInt(
|
|
175
|
+
process.env["DATABASE_QUERY_TIMEOUT_MS"] || "30000",
|
|
176
|
+
10,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
/*
|
|
180
|
+
* Postgres-side idle-in-transaction timeout (ms). Kills connections that
|
|
181
|
+
* are stuck holding row locks inside a BEGIN without committing.
|
|
182
|
+
*/
|
|
183
|
+
export const PostgresIdleInTransactionTimeoutMs: number = parseInt(
|
|
184
|
+
process.env["DATABASE_IDLE_IN_TRANSACTION_TIMEOUT_MS"] || "60000",
|
|
185
|
+
10,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
/*
|
|
189
|
+
* pg-pool acquire timeout (ms). How long a query waits for a free
|
|
190
|
+
* connection before failing. Without this, requests pile up invisibly
|
|
191
|
+
* when the pool is exhausted.
|
|
192
|
+
*/
|
|
193
|
+
export const PostgresConnectionAcquireTimeoutMs: number = parseInt(
|
|
194
|
+
process.env["DATABASE_CONNECTION_TIMEOUT_MS"] || "5000",
|
|
195
|
+
10,
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
/*
|
|
199
|
+
* pg-pool idle connection timeout (ms). Closes connections that have
|
|
200
|
+
* been sitting unused for this long, freeing server-side slots.
|
|
201
|
+
*/
|
|
202
|
+
export const PostgresIdleTimeoutMs: number = parseInt(
|
|
203
|
+
process.env["DATABASE_IDLE_TIMEOUT_MS"] || "30000",
|
|
204
|
+
10,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
/*
|
|
208
|
+
* TypeORM slow-query log threshold (ms). Any query exceeding this is
|
|
209
|
+
* logged so we can find offenders in production without per-query
|
|
210
|
+
* tracing. Set to 0 to disable.
|
|
211
|
+
*/
|
|
212
|
+
export const PostgresSlowQueryLogThresholdMs: number = parseInt(
|
|
213
|
+
process.env["DATABASE_SLOW_QUERY_LOG_THRESHOLD_MS"] || "1000",
|
|
214
|
+
10,
|
|
215
|
+
);
|
|
216
|
+
|
|
148
217
|
export const EncryptionSecret: ObjectID = new ObjectID(
|
|
149
218
|
process.env["ENCRYPTION_SECRET"] || "secret",
|
|
150
219
|
);
|
|
@@ -8,6 +8,13 @@ import {
|
|
|
8
8
|
DatabaseSslCert,
|
|
9
9
|
DatabaseSslKey,
|
|
10
10
|
DatabaseUsername,
|
|
11
|
+
MaxPostgresConnections,
|
|
12
|
+
PostgresConnectionAcquireTimeoutMs,
|
|
13
|
+
PostgresIdleInTransactionTimeoutMs,
|
|
14
|
+
PostgresIdleTimeoutMs,
|
|
15
|
+
PostgresQueryTimeoutMs,
|
|
16
|
+
PostgresSlowQueryLogThresholdMs,
|
|
17
|
+
PostgresStatementTimeoutMs,
|
|
11
18
|
ShouldDatabaseSslEnable,
|
|
12
19
|
} from "../../../Server/EnvironmentConfig";
|
|
13
20
|
import Migrations from "./SchemaMigrations/Index";
|
|
@@ -35,7 +42,25 @@ const dataSourceOptions: DataSourceOptions = {
|
|
|
35
42
|
cert: DatabaseSslCert,
|
|
36
43
|
}
|
|
37
44
|
: false,
|
|
38
|
-
|
|
45
|
+
/*
|
|
46
|
+
* Anything in `extra` is forwarded to the underlying node-postgres pool
|
|
47
|
+
* and client. Pool sizing + timeouts live here because TypeORM's defaults
|
|
48
|
+
* (10 connections, no timeouts) are too small for any non-trivial load.
|
|
49
|
+
*/
|
|
50
|
+
extra: {
|
|
51
|
+
max: MaxPostgresConnections,
|
|
52
|
+
idleTimeoutMillis: PostgresIdleTimeoutMs,
|
|
53
|
+
connectionTimeoutMillis: PostgresConnectionAcquireTimeoutMs,
|
|
54
|
+
statement_timeout: PostgresStatementTimeoutMs,
|
|
55
|
+
query_timeout: PostgresQueryTimeoutMs,
|
|
56
|
+
idle_in_transaction_session_timeout: PostgresIdleInTransactionTimeoutMs,
|
|
57
|
+
},
|
|
58
|
+
/*
|
|
59
|
+
* Log any query slower than the configured threshold so we can find
|
|
60
|
+
* offenders in production. TypeORM emits these via the configured
|
|
61
|
+
* logger; the default `advanced-console` logger writes to stdout.
|
|
62
|
+
*/
|
|
63
|
+
maxQueryExecutionTime: PostgresSlowQueryLogThresholdMs,
|
|
39
64
|
synchronize: false,
|
|
40
65
|
};
|
|
41
66
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class AddAgentVersionToKubernetesDockerHost1779392865146
|
|
4
|
+
implements MigrationInterface
|
|
5
|
+
{
|
|
6
|
+
name = "AddAgentVersionToKubernetesDockerHost1779392865146";
|
|
7
|
+
|
|
8
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
9
|
+
await queryRunner.query(
|
|
10
|
+
`ALTER TABLE "KubernetesCluster" ADD "agentVersion" character varying(100)`,
|
|
11
|
+
);
|
|
12
|
+
await queryRunner.query(
|
|
13
|
+
`ALTER TABLE "DockerHost" ADD "agentVersion" character varying(100)`,
|
|
14
|
+
);
|
|
15
|
+
await queryRunner.query(
|
|
16
|
+
`ALTER TABLE "Host" ADD "agentVersion" character varying(100)`,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
21
|
+
await queryRunner.query(`ALTER TABLE "Host" DROP COLUMN "agentVersion"`);
|
|
22
|
+
await queryRunner.query(
|
|
23
|
+
`ALTER TABLE "DockerHost" DROP COLUMN "agentVersion"`,
|
|
24
|
+
);
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "KubernetesCluster" DROP COLUMN "agentVersion"`,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|