@gitpod/gitpod-protocol 0.1.5-release-2022.6.1.1 → 0.1.5-release-2022.11.2.5
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/data/gitpod-schema.json +79 -129
- package/lib/accounting-protocol.d.ts +1 -0
- package/lib/accounting-protocol.d.ts.map +1 -1
- package/lib/accounting-protocol.js +4 -0
- package/lib/accounting-protocol.js.map +1 -1
- package/lib/admin-protocol.d.ts +4 -1
- package/lib/admin-protocol.d.ts.map +1 -1
- package/lib/admin-protocol.js.map +1 -1
- package/lib/attribution.d.ts +4 -0
- package/lib/attribution.d.ts.map +1 -1
- package/lib/attribution.js +14 -0
- package/lib/attribution.js.map +1 -1
- package/lib/billing-mode.d.ts +45 -0
- package/lib/billing-mode.d.ts.map +1 -0
- package/lib/billing-mode.js +44 -0
- package/lib/billing-mode.js.map +1 -0
- package/lib/encryption/encryption-engine.d.ts.map +1 -1
- package/lib/encryption/encryption-engine.js +3 -3
- package/lib/encryption/encryption-engine.js.map +1 -1
- package/lib/encryption/encryption-engine.spec.js +1 -1
- package/lib/encryption/encryption-engine.spec.js.map +1 -1
- package/lib/encryption/key-provider.js +1 -1
- package/lib/encryption/key-provider.js.map +1 -1
- package/lib/experiments/configcat-server.d.ts +2 -0
- package/lib/experiments/configcat-server.d.ts.map +1 -1
- package/lib/experiments/configcat-server.js +2 -1
- package/lib/experiments/configcat-server.js.map +1 -1
- package/lib/experiments/configcat.d.ts +1 -2
- package/lib/experiments/configcat.d.ts.map +1 -1
- package/lib/experiments/configcat.js +4 -6
- package/lib/experiments/configcat.js.map +1 -1
- package/lib/experiments/types.d.ts +2 -3
- package/lib/experiments/types.d.ts.map +1 -1
- package/lib/experiments/types.js.map +1 -1
- package/lib/gitpod-service.d.ts +32 -28
- package/lib/gitpod-service.d.ts.map +1 -1
- package/lib/gitpod-service.js +13 -1
- package/lib/gitpod-service.js.map +1 -1
- package/lib/ide-protocol.d.ts +8 -0
- package/lib/ide-protocol.d.ts.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/messaging/client-call-metrics.d.ts +1 -17
- package/lib/messaging/client-call-metrics.d.ts.map +1 -1
- package/lib/messaging/client-call-metrics.js +1 -2
- package/lib/messaging/client-call-metrics.js.map +1 -1
- package/lib/messaging/error.d.ts +6 -1
- package/lib/messaging/error.d.ts.map +1 -1
- package/lib/messaging/error.js +13 -3
- package/lib/messaging/error.js.map +1 -1
- package/lib/plans.d.ts +1 -0
- package/lib/plans.d.ts.map +1 -1
- package/lib/plans.js +6 -2
- package/lib/plans.js.map +1 -1
- package/lib/protocol.d.ts +50 -28
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +35 -21
- package/lib/protocol.js.map +1 -1
- package/lib/team-subscription-protocol.d.ts +1 -0
- package/lib/team-subscription-protocol.d.ts.map +1 -1
- package/lib/team-subscription-protocol.js +4 -0
- package/lib/team-subscription-protocol.js.map +1 -1
- package/lib/teams-projects-protocol.d.ts +17 -2
- package/lib/teams-projects-protocol.d.ts.map +1 -1
- package/lib/teams-projects-protocol.js.map +1 -1
- package/lib/usage.d.ts +61 -10
- package/lib/usage.d.ts.map +1 -1
- package/lib/usage.js +12 -107
- package/lib/usage.js.map +1 -1
- package/lib/util/garbage-collected-cache.d.ts.map +1 -1
- package/lib/util/garbage-collected-cache.js +5 -0
- package/lib/util/garbage-collected-cache.js.map +1 -1
- package/lib/util/gitpod-host-url.d.ts +3 -0
- package/lib/util/gitpod-host-url.d.ts.map +1 -1
- package/lib/util/gitpod-host-url.js +18 -0
- package/lib/util/gitpod-host-url.js.map +1 -1
- package/lib/util/grpc.d.ts +19 -0
- package/lib/util/grpc.d.ts.map +1 -1
- package/lib/util/grpc.js +73 -1
- package/lib/util/grpc.js.map +1 -1
- package/lib/util/logging.spec.d.ts +7 -0
- package/lib/util/logging.spec.d.ts.map +1 -0
- package/lib/util/logging.spec.js +52 -0
- package/lib/util/logging.spec.js.map +1 -0
- package/lib/util/nice-grpc.d.ts +9 -0
- package/lib/util/nice-grpc.d.ts.map +1 -0
- package/lib/util/nice-grpc.js +119 -0
- package/lib/util/nice-grpc.js.map +1 -0
- package/lib/util/timeutil.d.ts +1 -0
- package/lib/util/timeutil.d.ts.map +1 -1
- package/lib/util/timeutil.js +7 -1
- package/lib/util/timeutil.js.map +1 -1
- package/lib/util/timeutil.spec.d.ts +2 -0
- package/lib/util/timeutil.spec.d.ts.map +1 -1
- package/lib/util/timeutil.spec.js +34 -0
- package/lib/util/timeutil.spec.js.map +1 -1
- package/lib/workspace-class.d.ts +14 -0
- package/lib/workspace-class.d.ts.map +1 -0
- package/lib/workspace-class.js +8 -0
- package/lib/workspace-class.js.map +1 -0
- package/lib/workspace-cluster.d.ts +6 -5
- package/lib/workspace-cluster.d.ts.map +1 -1
- package/lib/workspace-cluster.js.map +1 -1
- package/lib/workspace-instance.d.ts +1 -0
- package/lib/workspace-instance.d.ts.map +1 -1
- package/lib/wsready.js +1 -1
- package/package.json +7 -2
- package/pkg-yarn.lock +5 -2
- package/provenance-bundle.jsonl +1 -1
- package/src/accounting-protocol.ts +3 -0
- package/src/admin-protocol.ts +4 -1
- package/src/attribution.ts +15 -0
- package/src/billing-mode.ts +84 -0
- package/src/encryption/encryption-engine.spec.ts +1 -1
- package/src/encryption/encryption-engine.ts +7 -3
- package/src/encryption/key-provider.ts +1 -1
- package/src/experiments/configcat-server.ts +3 -0
- package/src/experiments/configcat.ts +3 -5
- package/src/experiments/types.ts +4 -5
- package/src/gitpod-service.ts +49 -30
- package/src/ide-protocol.ts +10 -0
- package/src/index.ts +0 -1
- package/src/messaging/client-call-metrics.ts +1 -20
- package/src/messaging/error.ts +19 -4
- package/src/plans.ts +6 -2
- package/src/protocol.ts +78 -40
- package/src/team-subscription-protocol.ts +3 -0
- package/src/teams-projects-protocol.ts +21 -3
- package/src/usage.ts +65 -126
- package/src/util/garbage-collected-cache.ts +5 -0
- package/src/util/gitpod-host-url.ts +21 -0
- package/src/util/grpc.ts +89 -0
- package/src/util/logging.spec.ts +23 -0
- package/src/util/nice-grpc.ts +93 -0
- package/src/util/timeutil.spec.ts +28 -1
- package/src/util/timeutil.ts +6 -0
- package/src/workspace-class.ts +14 -0
- package/src/workspace-cluster.ts +11 -6
- package/src/workspace-instance.ts +3 -0
- package/src/wsready.ts +1 -1
- package/lib/email-protocol.d.ts +0 -49
- package/lib/email-protocol.d.ts.map +0 -1
- package/lib/email-protocol.js +0 -28
- package/lib/email-protocol.js.map +0 -1
- package/src/email-protocol.ts +0 -65
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* See License-AGPL.txt in the project root for license information.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { PrebuiltWorkspaceState } from "./protocol";
|
|
7
|
+
import { PrebuiltWorkspaceState, WorkspaceClasses } from "./protocol";
|
|
8
8
|
import { v4 as uuidv4 } from "uuid";
|
|
9
9
|
import { DeepPartial } from "./util/deep-partial";
|
|
10
|
+
import { WebhookEvent } from "./webhook-event";
|
|
10
11
|
|
|
11
12
|
export interface ProjectConfig {
|
|
12
13
|
".gitpod.yml": string;
|
|
@@ -16,6 +17,12 @@ export interface ProjectSettings {
|
|
|
16
17
|
useIncrementalPrebuilds?: boolean;
|
|
17
18
|
usePersistentVolumeClaim?: boolean;
|
|
18
19
|
keepOutdatedPrebuildsRunning?: boolean;
|
|
20
|
+
// whether new workspaces can start on older prebuilds and incrementally update
|
|
21
|
+
allowUsingPreviousPrebuilds?: boolean;
|
|
22
|
+
// how many commits in the commit history a prebuild is good (undefined and 0 means every commit is prebuilt)
|
|
23
|
+
prebuildEveryNthCommit?: number;
|
|
24
|
+
// preferred workspace classes
|
|
25
|
+
workspaceClasses?: WorkspaceClasses;
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
export interface Project {
|
|
@@ -26,7 +33,6 @@ export interface Project {
|
|
|
26
33
|
teamId?: string;
|
|
27
34
|
userId?: string;
|
|
28
35
|
appInstallationId: string;
|
|
29
|
-
config?: ProjectConfig;
|
|
30
36
|
settings?: ProjectSettings;
|
|
31
37
|
creationTime: string;
|
|
32
38
|
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
@@ -45,6 +51,7 @@ export namespace Project {
|
|
|
45
51
|
|
|
46
52
|
export interface Overview {
|
|
47
53
|
branches: BranchDetails[];
|
|
54
|
+
isConsideredInactive?: boolean;
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
export namespace Overview {
|
|
@@ -119,7 +126,6 @@ export interface StartPrebuildResult {
|
|
|
119
126
|
wsid: string;
|
|
120
127
|
done: boolean;
|
|
121
128
|
}
|
|
122
|
-
|
|
123
129
|
export interface Team {
|
|
124
130
|
id: string;
|
|
125
131
|
name: string;
|
|
@@ -152,3 +158,15 @@ export interface TeamMembershipInvite {
|
|
|
152
158
|
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
153
159
|
deleted?: boolean;
|
|
154
160
|
}
|
|
161
|
+
|
|
162
|
+
export interface PrebuildEvent {
|
|
163
|
+
id: string;
|
|
164
|
+
creationTime: string;
|
|
165
|
+
status: WebhookEvent.Status | WebhookEvent.PrebuildStatus;
|
|
166
|
+
message?: string;
|
|
167
|
+
prebuildId?: string;
|
|
168
|
+
projectId?: string;
|
|
169
|
+
cloneUrl?: string;
|
|
170
|
+
branch?: string;
|
|
171
|
+
commit?: string;
|
|
172
|
+
}
|
package/src/usage.ts
CHANGED
|
@@ -6,141 +6,80 @@
|
|
|
6
6
|
|
|
7
7
|
import { WorkspaceType } from "./protocol";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// types below are copied over from components/usage-api/typescript/src/usage/v1/usage_pb.d.ts
|
|
10
|
+
export interface ListUsageRequest {
|
|
11
11
|
attributionId: string;
|
|
12
|
+
from?: number;
|
|
13
|
+
to?: number;
|
|
14
|
+
order: Ordering;
|
|
15
|
+
pagination?: PaginationRequest;
|
|
16
|
+
}
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
export enum Ordering {
|
|
19
|
+
ORDERING_DESCENDING = 0,
|
|
20
|
+
ORDERING_ASCENDING = 1,
|
|
21
|
+
}
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
export interface PaginationRequest {
|
|
24
|
+
perPage: number;
|
|
25
|
+
page: number;
|
|
26
|
+
}
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
export interface ListUsageResponse {
|
|
29
|
+
usageEntriesList: Usage[];
|
|
30
|
+
pagination?: PaginationResponse;
|
|
31
|
+
creditsUsed: number;
|
|
32
|
+
}
|
|
20
33
|
|
|
21
|
-
|
|
34
|
+
export interface PaginationResponse {
|
|
35
|
+
perPage: number;
|
|
36
|
+
totalPages: number;
|
|
37
|
+
total: number;
|
|
38
|
+
page: number;
|
|
39
|
+
}
|
|
22
40
|
|
|
23
|
-
|
|
24
|
-
|
|
41
|
+
export type UsageKind = "workspaceinstance" | "invoice";
|
|
42
|
+
export interface Usage {
|
|
43
|
+
id: string;
|
|
44
|
+
attributionId: string;
|
|
45
|
+
description: string;
|
|
46
|
+
credits: number;
|
|
47
|
+
effectiveTime?: number;
|
|
48
|
+
kind: UsageKind;
|
|
49
|
+
workspaceInstanceId: string;
|
|
50
|
+
draft: boolean;
|
|
51
|
+
metadata: WorkspaceInstanceUsageData | InvoiceUsageData;
|
|
52
|
+
}
|
|
25
53
|
|
|
26
|
-
|
|
54
|
+
// the equivalent golang shape is maintained in `/workspace/gitpod/`components/usage/pkg/db/usage.go`
|
|
55
|
+
export interface WorkspaceInstanceUsageData {
|
|
56
|
+
workspaceId: string;
|
|
57
|
+
workspaceType: WorkspaceType;
|
|
58
|
+
workspaceClass: string;
|
|
59
|
+
contextURL: string;
|
|
27
60
|
startTime: string;
|
|
61
|
+
endTime?: string;
|
|
62
|
+
userId: string;
|
|
63
|
+
userName: string;
|
|
64
|
+
userAvatarURL: string;
|
|
65
|
+
}
|
|
28
66
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
credits: number;
|
|
34
|
-
|
|
35
|
-
// TODO - maybe
|
|
36
|
-
projectId?: string;
|
|
67
|
+
export interface InvoiceUsageData {
|
|
68
|
+
invoiceId: string;
|
|
69
|
+
startDate: string;
|
|
70
|
+
endDate: string;
|
|
37
71
|
}
|
|
38
72
|
|
|
39
|
-
export
|
|
73
|
+
export interface CostCenterJSON {
|
|
74
|
+
attributionId: string;
|
|
75
|
+
spendingLimit: number;
|
|
76
|
+
billingStrategy: CostCenter_BillingStrategy;
|
|
77
|
+
nextBillingTime?: string;
|
|
78
|
+
billingCycleStart?: string;
|
|
79
|
+
}
|
|
40
80
|
|
|
41
|
-
export
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
instanceId: "some-instance-id",
|
|
47
|
-
workspaceId: "some-workspace-id",
|
|
48
|
-
workspaceType: "prebuild",
|
|
49
|
-
workspaceClass: "XL",
|
|
50
|
-
startTime: new Date(Date.now() + -3 * 24 * 3600 * 1000).toISOString(), // 3 days ago
|
|
51
|
-
endTime: new Date().toISOString(),
|
|
52
|
-
credits: 320,
|
|
53
|
-
projectId: "project-123",
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
attributionId: "some-attribution-id2",
|
|
57
|
-
userId: "some-user",
|
|
58
|
-
teamId: "some-team",
|
|
59
|
-
instanceId: "some-instance-id2",
|
|
60
|
-
workspaceId: "some-workspace-id2",
|
|
61
|
-
workspaceType: "regular",
|
|
62
|
-
workspaceClass: "standard",
|
|
63
|
-
startTime: new Date(Date.now() + -5 * 24 * 3600 * 1000).toISOString(),
|
|
64
|
-
endTime: new Date().toISOString(),
|
|
65
|
-
credits: 130,
|
|
66
|
-
projectId: "project-123",
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
attributionId: "some-attribution-id3",
|
|
70
|
-
userId: "some-other-user",
|
|
71
|
-
teamId: "some-other-team",
|
|
72
|
-
instanceId: "some-instance-id3",
|
|
73
|
-
workspaceId: "some-workspace-id3",
|
|
74
|
-
workspaceType: "regular",
|
|
75
|
-
workspaceClass: "XL",
|
|
76
|
-
startTime: new Date(Date.now() + -5 * 24 * 3600 * 1000).toISOString(),
|
|
77
|
-
endTime: new Date(Date.now() + -4 * 24 * 3600 * 1000).toISOString(),
|
|
78
|
-
credits: 150,
|
|
79
|
-
projectId: "project-134",
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
attributionId: "some-attribution-id4",
|
|
83
|
-
userId: "some-other-user2",
|
|
84
|
-
teamId: "some-other-team2",
|
|
85
|
-
instanceId: "some-instance-id4",
|
|
86
|
-
workspaceId: "some-workspace-id4",
|
|
87
|
-
workspaceType: "regular",
|
|
88
|
-
workspaceClass: "standard",
|
|
89
|
-
startTime: new Date(Date.now() + -10 * 24 * 3600 * 1000).toISOString(),
|
|
90
|
-
endTime: new Date(Date.now() + -9 * 24 * 3600 * 1000).toISOString(),
|
|
91
|
-
credits: 330,
|
|
92
|
-
projectId: "project-137",
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
attributionId: "some-attribution-id5",
|
|
96
|
-
userId: "some-other-user3",
|
|
97
|
-
teamId: "some-other-team3",
|
|
98
|
-
instanceId: "some-instance-id5",
|
|
99
|
-
workspaceId: "some-workspace-id5",
|
|
100
|
-
workspaceType: "regular",
|
|
101
|
-
workspaceClass: "XL",
|
|
102
|
-
startTime: new Date(Date.now() + -2 * 24 * 3600 * 1000).toISOString(),
|
|
103
|
-
endTime: new Date().toISOString(),
|
|
104
|
-
credits: 222,
|
|
105
|
-
projectId: "project-138",
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
attributionId: "some-attribution-id6",
|
|
109
|
-
userId: "some-other-user4",
|
|
110
|
-
teamId: "some-other-team4",
|
|
111
|
-
instanceId: "some-instance-id6",
|
|
112
|
-
workspaceId: "some-workspace-id3",
|
|
113
|
-
workspaceType: "regular",
|
|
114
|
-
workspaceClass: "XL",
|
|
115
|
-
startTime: new Date(Date.now() + -7 * 24 * 3600 * 1000).toISOString(),
|
|
116
|
-
endTime: new Date(Date.now() + -6 * 24 * 3600 * 1000).toISOString(),
|
|
117
|
-
credits: 300,
|
|
118
|
-
projectId: "project-134",
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
attributionId: "some-attribution-id8",
|
|
122
|
-
userId: "some-other-user5",
|
|
123
|
-
teamId: "some-other-team5",
|
|
124
|
-
instanceId: "some-instance-id8",
|
|
125
|
-
workspaceId: "some-workspace-id3",
|
|
126
|
-
workspaceType: "regular",
|
|
127
|
-
workspaceClass: "standard",
|
|
128
|
-
startTime: new Date(Date.now() + -1 * 24 * 3600 * 1000).toISOString(),
|
|
129
|
-
endTime: new Date().toISOString(),
|
|
130
|
-
credits: 100,
|
|
131
|
-
projectId: "project-567",
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
attributionId: "some-attribution-id7",
|
|
135
|
-
userId: "prebuild",
|
|
136
|
-
teamId: "some-other-team7",
|
|
137
|
-
instanceId: "some-instance-id7",
|
|
138
|
-
workspaceId: "some-workspace-id7",
|
|
139
|
-
workspaceType: "prebuild",
|
|
140
|
-
workspaceClass: "XL",
|
|
141
|
-
startTime: new Date(Date.now() + -1 * 24 * 3600 * 1000).toISOString(),
|
|
142
|
-
endTime: new Date().toISOString(),
|
|
143
|
-
credits: 200,
|
|
144
|
-
projectId: "project-345",
|
|
145
|
-
},
|
|
146
|
-
];
|
|
81
|
+
export enum CostCenter_BillingStrategy {
|
|
82
|
+
BILLING_STRATEGY_STRIPE = "BILLING_STRATEGY_STRIPE",
|
|
83
|
+
BILLING_STRATEGY_OTHER = "BILLING_STRATEGY_OTHER",
|
|
84
|
+
UNRECOGNIZED = "UNRECOGNIZED",
|
|
85
|
+
}
|
|
@@ -85,6 +85,10 @@ export class GitpodHostUrl {
|
|
|
85
85
|
return this.with((url) => ({ protocol: url.protocol === "https:" ? "wss:" : "ws:" }));
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
asWorkspacePage(): GitpodHostUrl {
|
|
89
|
+
return this.with((url) => ({ pathname: "/workspaces" }));
|
|
90
|
+
}
|
|
91
|
+
|
|
88
92
|
asDashboard(): GitpodHostUrl {
|
|
89
93
|
return this.with((url) => ({ pathname: "/" }));
|
|
90
94
|
}
|
|
@@ -171,4 +175,21 @@ export class GitpodHostUrl {
|
|
|
171
175
|
asApiLogout(): GitpodHostUrl {
|
|
172
176
|
return this.withApi((url) => ({ pathname: "/logout/" }));
|
|
173
177
|
}
|
|
178
|
+
|
|
179
|
+
asIDEProxy(): GitpodHostUrl {
|
|
180
|
+
const hostSegments = this.url.host.split(".");
|
|
181
|
+
if (hostSegments[0] === "ide") {
|
|
182
|
+
return this;
|
|
183
|
+
}
|
|
184
|
+
return this.with((url) => ({ host: "ide." + url.host }));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
asIDEMetrics(): GitpodHostUrl {
|
|
188
|
+
let newUrl: GitpodHostUrl = this;
|
|
189
|
+
const hostSegments = this.url.host.split(".");
|
|
190
|
+
if (hostSegments[0] !== "ide") {
|
|
191
|
+
newUrl = newUrl.asIDEProxy();
|
|
192
|
+
}
|
|
193
|
+
return newUrl.with((url) => ({ pathname: "/metrics-api" }));
|
|
194
|
+
}
|
|
174
195
|
}
|
package/src/util/grpc.ts
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* See License-AGPL.txt in the project root for license information.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import * as grpc from "@grpc/grpc-js";
|
|
8
|
+
import { Status } from "@grpc/grpc-js/build/src/constants";
|
|
9
|
+
|
|
7
10
|
export const defaultGRPCOptions = {
|
|
8
11
|
"grpc.keepalive_timeout_ms": 10000,
|
|
9
12
|
"grpc.keepalive_time_ms": 60000,
|
|
@@ -13,3 +16,89 @@ export const defaultGRPCOptions = {
|
|
|
13
16
|
"grpc.max_reconnect_backoff_ms": 5000,
|
|
14
17
|
"grpc.max_receive_message_length": 1024 * 1024 * 16,
|
|
15
18
|
};
|
|
19
|
+
|
|
20
|
+
export type GrpcMethodType = "unary" | "client_stream" | "server_stream" | "bidi_stream";
|
|
21
|
+
|
|
22
|
+
export interface IGrpcCallMetricsLabels {
|
|
23
|
+
service: string;
|
|
24
|
+
method: string;
|
|
25
|
+
type: GrpcMethodType;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface IGrpcCallMetricsLabelsWithCode extends IGrpcCallMetricsLabels {
|
|
29
|
+
code: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const IClientCallMetrics = Symbol("IClientCallMetrics");
|
|
33
|
+
|
|
34
|
+
export interface IClientCallMetrics {
|
|
35
|
+
started(labels: IGrpcCallMetricsLabels): void;
|
|
36
|
+
sent(labels: IGrpcCallMetricsLabels): void;
|
|
37
|
+
received(labels: IGrpcCallMetricsLabels): void;
|
|
38
|
+
handled(labels: IGrpcCallMetricsLabelsWithCode): void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function getGrpcMethodType(requestStream: boolean, responseStream: boolean): GrpcMethodType {
|
|
42
|
+
if (requestStream) {
|
|
43
|
+
if (responseStream) {
|
|
44
|
+
return "bidi_stream";
|
|
45
|
+
} else {
|
|
46
|
+
return "client_stream";
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
if (responseStream) {
|
|
50
|
+
return "server_stream";
|
|
51
|
+
} else {
|
|
52
|
+
return "unary";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function createClientCallMetricsInterceptor(metrics: IClientCallMetrics): grpc.Interceptor {
|
|
58
|
+
return (options, nextCall): grpc.InterceptingCall => {
|
|
59
|
+
const methodDef = options.method_definition;
|
|
60
|
+
const method = methodDef.path.substring(methodDef.path.lastIndexOf("/") + 1);
|
|
61
|
+
const service = methodDef.path.substring(1, methodDef.path.length - method.length - 1);
|
|
62
|
+
const labels = {
|
|
63
|
+
service,
|
|
64
|
+
method,
|
|
65
|
+
type: getGrpcMethodType(options.method_definition.requestStream, options.method_definition.responseStream),
|
|
66
|
+
};
|
|
67
|
+
const requester = new grpc.RequesterBuilder()
|
|
68
|
+
.withStart((metadata, listener, next) => {
|
|
69
|
+
const newListener = new grpc.ListenerBuilder()
|
|
70
|
+
.withOnReceiveStatus((status, next) => {
|
|
71
|
+
try {
|
|
72
|
+
metrics.handled({
|
|
73
|
+
...labels,
|
|
74
|
+
code: Status[status.code],
|
|
75
|
+
});
|
|
76
|
+
} finally {
|
|
77
|
+
next(status);
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
.withOnReceiveMessage((message, next) => {
|
|
81
|
+
try {
|
|
82
|
+
metrics.received(labels);
|
|
83
|
+
} finally {
|
|
84
|
+
next(message);
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
.build();
|
|
88
|
+
try {
|
|
89
|
+
metrics.started(labels);
|
|
90
|
+
} finally {
|
|
91
|
+
next(metadata, newListener);
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
.withSendMessage((message, next) => {
|
|
95
|
+
try {
|
|
96
|
+
metrics.sent(labels);
|
|
97
|
+
} finally {
|
|
98
|
+
next(message);
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
.build();
|
|
102
|
+
return new grpc.InterceptingCall(nextCall(options), requester);
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2021 Gitpod GmbH. All rights reserved.
|
|
3
|
+
* Licensed under the GNU Affero General Public License (AGPL).
|
|
4
|
+
* See License-AGPL.txt in the project root for license information.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { suite, test } from "mocha-typescript";
|
|
8
|
+
import { log } from "./logging";
|
|
9
|
+
|
|
10
|
+
@suite
|
|
11
|
+
class TestLogging {
|
|
12
|
+
@test public async testLogInfo_output() {
|
|
13
|
+
const testObj = {
|
|
14
|
+
null: null,
|
|
15
|
+
undefined: undefined,
|
|
16
|
+
empty: "",
|
|
17
|
+
foo: "bar",
|
|
18
|
+
number: 0,
|
|
19
|
+
};
|
|
20
|
+
log.info("info logging test", testObj);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
module.exports = new TestLogging();
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
|
|
3
|
+
* Licensed under the GNU Affero General Public License (AGPL).
|
|
4
|
+
* See License-AGPL.txt in the project root for license information.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { isAbortError } from "abort-controller-x";
|
|
8
|
+
import {
|
|
9
|
+
CallOptions,
|
|
10
|
+
ClientError,
|
|
11
|
+
ClientMiddleware,
|
|
12
|
+
ClientMiddlewareCall,
|
|
13
|
+
Status,
|
|
14
|
+
MethodDescriptor,
|
|
15
|
+
} from "nice-grpc-common";
|
|
16
|
+
import { GrpcMethodType, IClientCallMetrics } from "./grpc";
|
|
17
|
+
|
|
18
|
+
function getLabels(method: MethodDescriptor) {
|
|
19
|
+
const callType = method.requestStream
|
|
20
|
+
? method.responseStream
|
|
21
|
+
? "bidi_stream"
|
|
22
|
+
: "client_stream"
|
|
23
|
+
: method.responseStream
|
|
24
|
+
? "server_stream"
|
|
25
|
+
: "unary";
|
|
26
|
+
const { path } = method;
|
|
27
|
+
const [serviceName, methodName] = path.split("/").slice(1);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
type: callType as GrpcMethodType,
|
|
31
|
+
service: serviceName,
|
|
32
|
+
method: methodName,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function* incrementStreamMessagesCounter<T>(iterable: AsyncIterable<T>, callback: () => void): AsyncIterable<T> {
|
|
37
|
+
for await (const item of iterable) {
|
|
38
|
+
callback();
|
|
39
|
+
yield item;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function prometheusClientMiddleware(metrics: IClientCallMetrics): ClientMiddleware {
|
|
44
|
+
return async function* prometheusClientMiddlewareGenerator<Request, Response>(
|
|
45
|
+
call: ClientMiddlewareCall<Request, Response>,
|
|
46
|
+
options: CallOptions,
|
|
47
|
+
): AsyncGenerator<Response, Response | void, undefined> {
|
|
48
|
+
const labels = getLabels(call.method);
|
|
49
|
+
|
|
50
|
+
metrics.started(labels);
|
|
51
|
+
|
|
52
|
+
let settled = false;
|
|
53
|
+
let status: Status = Status.OK;
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
let request;
|
|
57
|
+
|
|
58
|
+
if (!call.requestStream) {
|
|
59
|
+
request = call.request;
|
|
60
|
+
} else {
|
|
61
|
+
request = incrementStreamMessagesCounter(call.request, metrics.sent.bind(metrics, labels));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!call.responseStream) {
|
|
65
|
+
const response = yield* call.next(request, options);
|
|
66
|
+
settled = true;
|
|
67
|
+
return response;
|
|
68
|
+
} else {
|
|
69
|
+
yield* incrementStreamMessagesCounter(
|
|
70
|
+
call.next(request, options),
|
|
71
|
+
metrics.received.bind(metrics, labels),
|
|
72
|
+
);
|
|
73
|
+
settled = true;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
} catch (err) {
|
|
77
|
+
settled = true;
|
|
78
|
+
if (err instanceof ClientError) {
|
|
79
|
+
status = err.code;
|
|
80
|
+
} else if (isAbortError(err)) {
|
|
81
|
+
status = Status.CANCELLED;
|
|
82
|
+
} else {
|
|
83
|
+
status = Status.UNKNOWN;
|
|
84
|
+
}
|
|
85
|
+
throw err;
|
|
86
|
+
} finally {
|
|
87
|
+
if (!settled) {
|
|
88
|
+
status = Status.CANCELLED;
|
|
89
|
+
}
|
|
90
|
+
metrics.handled({ ...labels, code: Status[status] });
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -7,10 +7,16 @@
|
|
|
7
7
|
import * as chai from "chai";
|
|
8
8
|
const expect = chai.expect;
|
|
9
9
|
import { suite, test } from "mocha-typescript";
|
|
10
|
-
import { oneMonthLater } from "./timeutil";
|
|
10
|
+
import { daysBefore, hoursBefore, oneMonthLater } from "./timeutil";
|
|
11
11
|
|
|
12
12
|
@suite()
|
|
13
13
|
export class TimeutilSpec {
|
|
14
|
+
@test
|
|
15
|
+
testDaysBefore() {
|
|
16
|
+
const now = new Date().toISOString();
|
|
17
|
+
expect(daysBefore(now, 2)).to.be.eq(hoursBefore(now, 48));
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
@test
|
|
15
21
|
testTimeutil() {
|
|
16
22
|
// targeting a 1st, 1th of Jan => 1st of Feb
|
|
@@ -39,4 +45,25 @@ export class TimeutilSpec {
|
|
|
39
45
|
const later = oneMonthLater(from.toISOString(), day);
|
|
40
46
|
expect(later, `expected ${later} to be equal ${expectation}`).to.be.equal(expectation.toISOString());
|
|
41
47
|
}
|
|
48
|
+
|
|
49
|
+
@test
|
|
50
|
+
testDaysBefore2() {
|
|
51
|
+
const tests: { date: Date; daysEarlier: number; expectation: string }[] = [
|
|
52
|
+
{
|
|
53
|
+
date: new Date("2021-07-13T00:00:00.000Z"),
|
|
54
|
+
daysEarlier: 365,
|
|
55
|
+
expectation: "2020-07-13T00:00:00.000Z",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
date: new Date("2019-02-01T00:00:00.000Z"),
|
|
59
|
+
daysEarlier: 365,
|
|
60
|
+
expectation: "2018-02-01T00:00:00.000Z",
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
for (const t of tests) {
|
|
65
|
+
const actual = daysBefore(t.date.toISOString(), t.daysEarlier);
|
|
66
|
+
expect(actual).to.equal(t.expectation, `expected ${actual} to be equal ${t.expectation}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
42
69
|
}
|
package/src/util/timeutil.ts
CHANGED
|
@@ -47,6 +47,12 @@ export const orderAsc = (d1: string, d2: string): number => liftDate(d1, d2, (d1
|
|
|
47
47
|
export const liftDate1 = <T>(d1: string, f: (d1: Date) => T): T => f(new Date(d1));
|
|
48
48
|
export const liftDate = <T>(d1: string, d2: string, f: (d1: Date, d2: Date) => T): T => f(new Date(d1), new Date(d2));
|
|
49
49
|
|
|
50
|
+
export function daysBefore(date: string, days: number): string {
|
|
51
|
+
const result = new Date(date);
|
|
52
|
+
result.setDate(result.getDate() - days);
|
|
53
|
+
return result.toISOString();
|
|
54
|
+
}
|
|
55
|
+
|
|
50
56
|
export function hoursBefore(date: string, hours: number): string {
|
|
51
57
|
const result = new Date(date);
|
|
52
58
|
result.setHours(result.getHours() - hours);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
|
|
3
|
+
* Licensed under the GNU Affero General Public License (AGPL).
|
|
4
|
+
* See License-AGPL.txt in the project root for license information.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface SupportedWorkspaceClass {
|
|
8
|
+
id: string;
|
|
9
|
+
category: string;
|
|
10
|
+
displayName: string;
|
|
11
|
+
description: string;
|
|
12
|
+
powerups: number;
|
|
13
|
+
isSelected: boolean;
|
|
14
|
+
}
|
package/src/workspace-cluster.ts
CHANGED
|
@@ -15,6 +15,10 @@ export interface WorkspaceCluster {
|
|
|
15
15
|
// Must be identical to the installationShortname of the cluster it represents!
|
|
16
16
|
name: string;
|
|
17
17
|
|
|
18
|
+
// The name of the application cluster to which this cluster should be registered.
|
|
19
|
+
// The name can be at most 60 characters.
|
|
20
|
+
applicationCluster: string;
|
|
21
|
+
|
|
18
22
|
// URL of the cluster's ws-manager API
|
|
19
23
|
url: string;
|
|
20
24
|
|
|
@@ -86,20 +90,21 @@ export interface WorkspaceClusterDB {
|
|
|
86
90
|
* Deletes the cluster identified by this name, if any.
|
|
87
91
|
* @param name
|
|
88
92
|
*/
|
|
89
|
-
deleteByName(name: string): Promise<void>;
|
|
93
|
+
deleteByName(name: string, applicationCluster: string): Promise<void>;
|
|
90
94
|
|
|
91
95
|
/**
|
|
92
96
|
* Finds a WorkspaceCluster with the given name. If there is none, `undefined` is returned.
|
|
93
97
|
* @param name
|
|
94
98
|
*/
|
|
95
|
-
findByName(name: string): Promise<WorkspaceCluster | undefined>;
|
|
99
|
+
findByName(name: string, applicationCluster: string): Promise<WorkspaceCluster | undefined>;
|
|
96
100
|
|
|
97
101
|
/**
|
|
98
102
|
* Lists all WorkspaceClusterWoTls for which the given predicate is true (does not return TLS for size/speed concerns)
|
|
99
103
|
* @param predicate
|
|
100
104
|
*/
|
|
101
|
-
findFiltered(predicate:
|
|
102
|
-
}
|
|
103
|
-
export interface WorkspaceClusterFilter extends Pick<WorkspaceCluster, "state" | "govern" | "url"> {
|
|
104
|
-
minScore: number;
|
|
105
|
+
findFiltered(predicate: WorkspaceClusterFilter): Promise<WorkspaceClusterWoTLS[]>;
|
|
105
106
|
}
|
|
107
|
+
|
|
108
|
+
export type WorkspaceClusterFilter = Pick<WorkspaceCluster, "applicationCluster"> &
|
|
109
|
+
DeepPartial<Pick<WorkspaceCluster, "name" | "state" | "govern" | "url">> &
|
|
110
|
+
Partial<{ minScore: number }>;
|
|
@@ -246,6 +246,9 @@ export interface WorkspaceInstanceConfiguration {
|
|
|
246
246
|
// desktopIdeImage is the ref of the desktop IDE image this instance uses.
|
|
247
247
|
desktopIdeImage?: string;
|
|
248
248
|
|
|
249
|
+
// desktopIdePluginImage is the ref of the desktop IDE plugin image this instance uses.
|
|
250
|
+
desktopIdePluginImage?: string;
|
|
251
|
+
|
|
249
252
|
// supervisorImage is the ref of the supervisor image this instance uses.
|
|
250
253
|
supervisorImage?: string;
|
|
251
254
|
|
package/src/wsready.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* See License-AGPL.txt in the project root for license information.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
// generated using github.com/32leaves/bel on 2022-
|
|
7
|
+
// generated using github.com/32leaves/bel on 2022-10-10 21:41:56.018177383 +0000 UTC m=+0.010324839
|
|
8
8
|
// DO NOT MODIFY
|
|
9
9
|
|
|
10
10
|
export enum WorkspaceInitSource {
|