@gitpod/gitpod-protocol 0.1.5-pd-gen47-patch-test.0 → 0.1.5-pd-ide-metrics.33
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 +16 -0
- package/lib/admin-protocol.d.ts +4 -0
- package/lib/admin-protocol.d.ts.map +1 -1
- package/lib/admin-protocol.js.map +1 -1
- package/lib/attribution.d.ts +20 -0
- package/lib/attribution.d.ts.map +1 -0
- package/lib/attribution.js +40 -0
- package/lib/attribution.js.map +1 -0
- package/lib/blocked-repositories-protocol.d.ts +13 -0
- package/lib/blocked-repositories-protocol.d.ts.map +1 -0
- package/lib/blocked-repositories-protocol.js +8 -0
- package/lib/blocked-repositories-protocol.js.map +1 -0
- package/lib/context-url.js +1 -1
- package/lib/context-url.js.map +1 -1
- package/lib/experiments/always-default.d.ts +8 -0
- package/lib/experiments/always-default.d.ts.map +1 -0
- package/lib/experiments/always-default.js +20 -0
- package/lib/experiments/always-default.js.map +1 -0
- package/lib/experiments/configcat-server.d.ts +8 -0
- package/lib/experiments/configcat-server.d.ts.map +1 -0
- package/lib/experiments/configcat-server.js +35 -0
- package/lib/experiments/configcat-server.js.map +1 -0
- package/lib/experiments/configcat.d.ts +22 -0
- package/lib/experiments/configcat.d.ts.map +1 -0
- package/lib/experiments/configcat.js +53 -0
- package/lib/experiments/configcat.js.map +1 -0
- package/lib/experiments/types.d.ts +23 -0
- package/lib/experiments/types.d.ts.map +1 -0
- package/lib/experiments/types.js +10 -0
- package/lib/experiments/types.js.map +1 -0
- package/lib/gitpod-service.d.ts +23 -2
- package/lib/gitpod-service.d.ts.map +1 -1
- package/lib/gitpod-service.js +1 -1
- package/lib/gitpod-service.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/installation-admin-protocol.d.ts +3 -0
- package/lib/installation-admin-protocol.d.ts.map +1 -1
- package/lib/installation-admin-protocol.js +1 -0
- package/lib/installation-admin-protocol.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 +1 -0
- package/lib/messaging/error.d.ts.map +1 -1
- package/lib/messaging/error.js +2 -0
- package/lib/messaging/error.js.map +1 -1
- package/lib/protocol.d.ts +34 -1
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +42 -2
- package/lib/protocol.js.map +1 -1
- package/lib/teams-projects-protocol.d.ts +14 -0
- package/lib/teams-projects-protocol.d.ts.map +1 -1
- package/lib/teams-projects-protocol.js.map +1 -1
- package/lib/usage.d.ts +31 -0
- package/lib/usage.d.ts.map +1 -0
- package/lib/usage.js +14 -0
- package/lib/usage.js.map +1 -0
- package/lib/util/debug-app.d.ts +25 -0
- package/lib/util/debug-app.d.ts.map +1 -0
- package/lib/util/debug-app.js +100 -0
- package/lib/util/debug-app.js.map +1 -0
- package/lib/util/gitpod-host-url.d.ts +1 -0
- package/lib/util/gitpod-host-url.d.ts.map +1 -1
- package/lib/util/gitpod-host-url.js +3 -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.d.ts.map +1 -1
- package/lib/util/logging.js +8 -1
- package/lib/util/logging.js.map +1 -1
- 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/webhook-event.d.ts +44 -0
- package/lib/webhook-event.d.ts.map +1 -0
- package/lib/webhook-event.js +8 -0
- package/lib/webhook-event.js.map +1 -0
- 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 +5 -7
- package/lib/workspace-cluster.d.ts.map +1 -1
- package/lib/workspace-cluster.js.map +1 -1
- package/lib/workspace-instance.d.ts +11 -0
- package/lib/workspace-instance.d.ts.map +1 -1
- package/lib/wsready.d.ts +3 -3
- package/lib/wsready.d.ts.map +1 -1
- package/lib/wsready.js +0 -2
- package/lib/wsready.js.map +1 -1
- package/package.json +12 -6
- package/pkg-yarn.lock +8 -5
- package/provenance-bundle.jsonl +1 -1
- package/src/admin-protocol.ts +7 -0
- package/src/attribution.ts +48 -0
- package/src/blocked-repositories-protocol.ts +13 -0
- package/src/context-url.ts +1 -1
- package/src/experiments/always-default.ts +24 -0
- package/src/experiments/configcat-server.ts +38 -0
- package/src/experiments/configcat.ts +58 -0
- package/src/experiments/types.ts +35 -0
- package/src/gitpod-service.ts +29 -1
- package/src/index.ts +1 -0
- package/src/installation-admin-protocol.ts +3 -0
- package/src/messaging/client-call-metrics.ts +1 -20
- package/src/messaging/error.ts +3 -0
- package/src/protocol.ts +85 -4
- package/src/teams-projects-protocol.ts +15 -0
- package/src/usage.ts +50 -0
- package/src/util/debug-app.ts +81 -0
- package/src/util/gitpod-host-url.ts +4 -0
- package/src/util/grpc.ts +89 -0
- package/src/util/logging.ts +11 -2
- package/src/util/timeutil.ts +6 -0
- package/src/webhook-event.ts +55 -0
- package/src/workspace-class.ts +14 -0
- package/src/workspace-cluster.ts +2 -4
- package/src/workspace-instance.ts +17 -0
- package/src/wsready.ts +5 -4
|
@@ -0,0 +1,48 @@
|
|
|
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 type AttributionId = UserAttributionId | TeamAttributionId;
|
|
8
|
+
export type AttributionTarget = "user" | "team";
|
|
9
|
+
|
|
10
|
+
export interface UserAttributionId {
|
|
11
|
+
kind: "user";
|
|
12
|
+
userId: string;
|
|
13
|
+
}
|
|
14
|
+
export interface TeamAttributionId {
|
|
15
|
+
kind: "team";
|
|
16
|
+
teamId: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export namespace AttributionId {
|
|
20
|
+
const SEPARATOR = ":";
|
|
21
|
+
|
|
22
|
+
export function parse(s: string): UserAttributionId | TeamAttributionId | undefined {
|
|
23
|
+
if (!s) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const parts = s.split(":");
|
|
27
|
+
if (parts.length !== 2) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
switch (parts[0]) {
|
|
31
|
+
case "user":
|
|
32
|
+
return { kind: "user", userId: parts[1] };
|
|
33
|
+
case "team":
|
|
34
|
+
return { kind: "team", teamId: parts[1] };
|
|
35
|
+
default:
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function render(id: AttributionId): string {
|
|
41
|
+
switch (id.kind) {
|
|
42
|
+
case "user":
|
|
43
|
+
return `user${SEPARATOR}${id.userId}`;
|
|
44
|
+
case "team":
|
|
45
|
+
return `team${SEPARATOR}${id.teamId}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
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 BlockedRepository {
|
|
8
|
+
id: number;
|
|
9
|
+
urlRegexp: string;
|
|
10
|
+
blockUser: boolean;
|
|
11
|
+
createdAt: string;
|
|
12
|
+
updatedAt: string;
|
|
13
|
+
}
|
package/src/context-url.ts
CHANGED
|
@@ -38,7 +38,7 @@ export namespace ContextURL {
|
|
|
38
38
|
try {
|
|
39
39
|
return new URL(normalized);
|
|
40
40
|
} catch (err) {
|
|
41
|
-
console.
|
|
41
|
+
console.debug(`unable to parse URL from normalized contextURL: '${normalized}'`);
|
|
42
42
|
}
|
|
43
43
|
return undefined;
|
|
44
44
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
import { Attributes, Client } from "./types";
|
|
7
|
+
|
|
8
|
+
// AlwaysReturningDefaultValueClient is an implemention of an experiments.Client which performs no lookup/network operation
|
|
9
|
+
// and always returns the default value for a given experimentName.
|
|
10
|
+
// This client is used for non-SaaS version of Gitpod, in particular for self-hosted installations where external
|
|
11
|
+
// network connections are not desirable or even possible.
|
|
12
|
+
class AlwaysReturningDefaultValueClient implements Client {
|
|
13
|
+
getValueAsync<T>(experimentName: string, defaultValue: T, attributes: Attributes): Promise<T> {
|
|
14
|
+
return Promise.resolve(defaultValue);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
dispose(): void {
|
|
18
|
+
// there is nothing to dispose, no-op.
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function newAlwaysReturningDefaultValueClient(): Client {
|
|
23
|
+
return new AlwaysReturningDefaultValueClient();
|
|
24
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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 { Client } from "./types";
|
|
8
|
+
import * as configcat from "configcat-node";
|
|
9
|
+
import { LogLevel } from "configcat-common";
|
|
10
|
+
import { ConfigCatClient } from "./configcat";
|
|
11
|
+
import { newAlwaysReturningDefaultValueClient } from "./always-default";
|
|
12
|
+
|
|
13
|
+
let client: Client | undefined;
|
|
14
|
+
|
|
15
|
+
export function getExperimentsClientForBackend(): Client {
|
|
16
|
+
// We have already instantiated a client, we can just re-use it.
|
|
17
|
+
if (client !== undefined) {
|
|
18
|
+
return client;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Retrieve SDK key from ENV Variable
|
|
22
|
+
const sdkKey = process.env.CONFIGCAT_SDK_KEY;
|
|
23
|
+
|
|
24
|
+
// Self-hosted installations do not set the ConfigCat SDK key, so always use a client which returns the default value.
|
|
25
|
+
if (sdkKey === undefined || sdkKey === "") {
|
|
26
|
+
client = newAlwaysReturningDefaultValueClient();
|
|
27
|
+
return client;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const configCatClient = configcat.createClient(sdkKey, {
|
|
31
|
+
pollIntervalSeconds: 3 * 60, // 3 minutes
|
|
32
|
+
logger: configcat.createConsoleLogger(LogLevel.Error),
|
|
33
|
+
maxInitWaitTimeSeconds: 0,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
client = new ConfigCatClient(configCatClient);
|
|
37
|
+
return client;
|
|
38
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
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 { Attributes, Client } from "./types";
|
|
8
|
+
import { User as ConfigCatUser } from "configcat-common/lib/RolloutEvaluator";
|
|
9
|
+
import { IConfigCatClient } from "configcat-common/lib/ConfigCatClient";
|
|
10
|
+
import { User } from "../protocol";
|
|
11
|
+
|
|
12
|
+
export const USER_ID_ATTRIBUTE = "user_id";
|
|
13
|
+
export const PROJECT_ID_ATTRIBUTE = "project_id";
|
|
14
|
+
export const TEAM_ID_ATTRIBUTE = "team_id";
|
|
15
|
+
export const TEAM_IDS_ATTRIBUTE = "team_ids";
|
|
16
|
+
export const TEAM_NAME_ATTRIBUTE = "team_name";
|
|
17
|
+
export const TEAM_NAMES_ATTRIBUTE = "team_names";
|
|
18
|
+
|
|
19
|
+
export class ConfigCatClient implements Client {
|
|
20
|
+
private client: IConfigCatClient;
|
|
21
|
+
|
|
22
|
+
constructor(cc: IConfigCatClient) {
|
|
23
|
+
this.client = cc;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getValueAsync<T>(experimentName: string, defaultValue: T, attributes: Attributes): Promise<T> {
|
|
27
|
+
return this.client.getValueAsync(experimentName, defaultValue, attributesToUser(attributes));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
dispose(): void {
|
|
31
|
+
return this.client.dispose();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function attributesToUser(attributes: Attributes): ConfigCatUser {
|
|
36
|
+
const userId = attributes.user?.id || "";
|
|
37
|
+
const email = User.is(attributes.user) ? User.getPrimaryEmail(attributes.user) : attributes.user?.email || "";
|
|
38
|
+
|
|
39
|
+
const custom: { [key: string]: string } = {};
|
|
40
|
+
if (userId) {
|
|
41
|
+
custom[USER_ID_ATTRIBUTE] = userId;
|
|
42
|
+
}
|
|
43
|
+
if (attributes.projectId) {
|
|
44
|
+
custom[PROJECT_ID_ATTRIBUTE] = attributes.projectId;
|
|
45
|
+
}
|
|
46
|
+
if (attributes.teamId) {
|
|
47
|
+
custom[TEAM_ID_ATTRIBUTE] = attributes.teamId;
|
|
48
|
+
}
|
|
49
|
+
if (attributes.teamName) {
|
|
50
|
+
custom[TEAM_NAME_ATTRIBUTE] = attributes.teamName;
|
|
51
|
+
}
|
|
52
|
+
if (attributes.teams) {
|
|
53
|
+
custom[TEAM_NAMES_ATTRIBUTE] = attributes.teams.map((t) => t.name).join(",");
|
|
54
|
+
custom[TEAM_IDS_ATTRIBUTE] = attributes.teams.map((t) => t.id).join(",");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return new ConfigCatUser(userId, email, "", custom);
|
|
58
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
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 { User } from "../protocol";
|
|
8
|
+
import { Team } from "../teams-projects-protocol";
|
|
9
|
+
|
|
10
|
+
export const Client = Symbol("Client");
|
|
11
|
+
|
|
12
|
+
// Attributes define attributes which can be used to segment audiences.
|
|
13
|
+
// Set the attributes which you want to use to group audiences into.
|
|
14
|
+
export interface Attributes {
|
|
15
|
+
// user.id is mapped to ConfigCat's "identifier" + "custom.user_id"
|
|
16
|
+
user?: User | { id: string; email?: string };
|
|
17
|
+
|
|
18
|
+
// Currently selected Gitpod Project ID (mapped to "custom.project_id")
|
|
19
|
+
projectId?: string;
|
|
20
|
+
|
|
21
|
+
// Currently selected Gitpod Team ID (mapped to "custom.team_id")
|
|
22
|
+
teamId?: string;
|
|
23
|
+
// Currently selected Gitpod Team Name (mapped to "custom.team_name")
|
|
24
|
+
teamName?: string;
|
|
25
|
+
|
|
26
|
+
// All the Gitpod Teams that the user is a member (or owner) of (mapped to "custom.team_names" and "custom.team_ids")
|
|
27
|
+
teams?: Team[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface Client {
|
|
31
|
+
getValueAsync<T>(experimentName: string, defaultValue: T, attributes: Attributes): Promise<T>;
|
|
32
|
+
|
|
33
|
+
// dispose will dispose of the client, no longer retrieving flags
|
|
34
|
+
dispose(): void;
|
|
35
|
+
}
|
package/src/gitpod-service.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
GuessGitTokenScopesParams,
|
|
25
25
|
GuessedGitTokenScopes,
|
|
26
26
|
ProjectEnvVar,
|
|
27
|
+
PrebuiltWorkspace,
|
|
27
28
|
UserSSHPublicKeyValue,
|
|
28
29
|
SSHPublicKeyValue,
|
|
29
30
|
} from "./protocol";
|
|
@@ -36,6 +37,7 @@ import {
|
|
|
36
37
|
PrebuildWithStatus,
|
|
37
38
|
StartPrebuildResult,
|
|
38
39
|
PartialProject,
|
|
40
|
+
PrebuildEvent,
|
|
39
41
|
} from "./teams-projects-protocol";
|
|
40
42
|
import { JsonRpcProxy, JsonRpcServer } from "./messaging/proxy-factory";
|
|
41
43
|
import { Disposable, CancellationTokenSource } from "vscode-jsonrpc";
|
|
@@ -58,6 +60,9 @@ import {
|
|
|
58
60
|
import { RemotePageMessage, RemoteTrackMessage, RemoteIdentifyMessage } from "./analytics";
|
|
59
61
|
import { IDEServer } from "./ide-protocol";
|
|
60
62
|
import { InstallationAdminSettings, TelemetryData } from "./installation-admin-protocol";
|
|
63
|
+
import { Currency } from "./plans";
|
|
64
|
+
import { BillableSession, BillableSessionRequest } from "./usage";
|
|
65
|
+
import { SupportedWorkspaceClass } from "./workspace-class";
|
|
61
66
|
|
|
62
67
|
export interface GitpodClient {
|
|
63
68
|
onInstanceUpdate(instance: WorkspaceInstance): void;
|
|
@@ -178,7 +183,10 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
|
|
|
178
183
|
getTeamProjects(teamId: string): Promise<Project[]>;
|
|
179
184
|
getUserProjects(): Promise<Project[]>;
|
|
180
185
|
getProjectOverview(projectId: string): Promise<Project.Overview | undefined>;
|
|
186
|
+
getPrebuildEvents(projectId: string): Promise<PrebuildEvent[]>;
|
|
181
187
|
findPrebuilds(params: FindPrebuildsParams): Promise<PrebuildWithStatus[]>;
|
|
188
|
+
findPrebuildByWorkspaceID(workspaceId: string): Promise<PrebuiltWorkspace | undefined>;
|
|
189
|
+
getPrebuild(prebuildId: string): Promise<PrebuildWithStatus | undefined>;
|
|
182
190
|
triggerPrebuild(projectId: string, branchName: string | null): Promise<StartPrebuildResult>;
|
|
183
191
|
cancelPrebuild(projectId: string, prebuildId: string): Promise<void>;
|
|
184
192
|
fetchProjectRepositoryConfiguration(projectId: string): Promise<string | undefined>;
|
|
@@ -278,12 +286,31 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
|
|
|
278
286
|
|
|
279
287
|
getGithubUpgradeUrls(): Promise<GithubUpgradeURL[]>;
|
|
280
288
|
|
|
289
|
+
getStripePublishableKey(): Promise<string>;
|
|
290
|
+
getStripeSetupIntentClientSecret(): Promise<string>;
|
|
291
|
+
findStripeSubscriptionIdForTeam(teamId: string): Promise<string | undefined>;
|
|
292
|
+
subscribeTeamToStripe(teamId: string, setupIntentId: string, currency: Currency): Promise<void>;
|
|
293
|
+
getStripePortalUrlForTeam(teamId: string): Promise<string>;
|
|
294
|
+
getSpendingLimitForTeam(teamId: string): Promise<number | undefined>;
|
|
295
|
+
setSpendingLimitForTeam(teamId: string, spendingLimit: number): Promise<void>;
|
|
296
|
+
|
|
297
|
+
listBilledUsage(req: BillableSessionRequest): Promise<BillableSession[]>;
|
|
298
|
+
|
|
299
|
+
setUsageAttribution(usageAttribution: string): Promise<void>;
|
|
300
|
+
|
|
281
301
|
/**
|
|
282
302
|
* Analytics
|
|
283
303
|
*/
|
|
284
304
|
trackEvent(event: RemoteTrackMessage): Promise<void>;
|
|
285
305
|
trackLocation(event: RemotePageMessage): Promise<void>;
|
|
286
306
|
identifyUser(event: RemoteIdentifyMessage): Promise<void>;
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Frontend notifications
|
|
310
|
+
*/
|
|
311
|
+
getNotifications(): Promise<string[]>;
|
|
312
|
+
|
|
313
|
+
getSupportedWorkspaceClasses(): Promise<SupportedWorkspaceClass[]>;
|
|
287
314
|
}
|
|
288
315
|
|
|
289
316
|
export interface RateLimiterError {
|
|
@@ -365,7 +392,7 @@ export const createServerMock = function <C extends GitpodClient, S extends Gitp
|
|
|
365
392
|
get: (target: S, property: keyof S) => {
|
|
366
393
|
const result = target[property];
|
|
367
394
|
if (!result) {
|
|
368
|
-
throw new Error(`Method ${property} not implemented`);
|
|
395
|
+
throw new Error(`Method ${String(property)} not implemented`);
|
|
369
396
|
}
|
|
370
397
|
return result;
|
|
371
398
|
},
|
|
@@ -381,6 +408,7 @@ export interface SetWorkspaceTimeoutResult {
|
|
|
381
408
|
|
|
382
409
|
export interface GetWorkspaceTimeoutResult {
|
|
383
410
|
duration: WorkspaceTimeoutDuration;
|
|
411
|
+
durationRaw: string;
|
|
384
412
|
canChange: boolean;
|
|
385
413
|
}
|
|
386
414
|
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { v4 as uuidv4 } from "uuid";
|
|
|
8
8
|
|
|
9
9
|
const InstallationAdminSettingsPrototype = {
|
|
10
10
|
sendTelemetry: true,
|
|
11
|
+
sendCustomerID: true,
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
export type InstallationAdminSettings = typeof InstallationAdminSettingsPrototype;
|
|
@@ -28,6 +29,8 @@ export interface TelemetryData {
|
|
|
28
29
|
totalUsers: number;
|
|
29
30
|
totalWorkspaces: number;
|
|
30
31
|
totalInstances: number;
|
|
32
|
+
licenseType: string;
|
|
33
|
+
customerID?: string;
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
export namespace InstallationAdmin {
|
|
@@ -6,26 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { injectable } from "inversify";
|
|
8
8
|
import * as prometheusClient from "prom-client";
|
|
9
|
-
|
|
10
|
-
type GrpcMethodType = "unary" | "client_stream" | "server_stream" | "bidi_stream";
|
|
11
|
-
export interface IGrpcCallMetricsLabels {
|
|
12
|
-
service: string;
|
|
13
|
-
method: string;
|
|
14
|
-
type: GrpcMethodType;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface IGrpcCallMetricsLabelsWithCode extends IGrpcCallMetricsLabels {
|
|
18
|
-
code: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const IClientCallMetrics = Symbol("IClientCallMetrics");
|
|
22
|
-
|
|
23
|
-
export interface IClientCallMetrics {
|
|
24
|
-
started(labels: IGrpcCallMetricsLabels): void;
|
|
25
|
-
sent(labels: IGrpcCallMetricsLabels): void;
|
|
26
|
-
received(labels: IGrpcCallMetricsLabels): void;
|
|
27
|
-
handled(labels: IGrpcCallMetricsLabelsWithCode): void;
|
|
28
|
-
}
|
|
9
|
+
import { IClientCallMetrics, IGrpcCallMetricsLabels, IGrpcCallMetricsLabelsWithCode } from "../util/grpc";
|
|
29
10
|
|
|
30
11
|
@injectable()
|
|
31
12
|
export class PrometheusClientCallMetrics implements IClientCallMetrics {
|
package/src/messaging/error.ts
CHANGED
|
@@ -62,6 +62,9 @@ export namespace ErrorCodes {
|
|
|
62
62
|
// 490 Too Many Running Workspace
|
|
63
63
|
export const TOO_MANY_RUNNING_WORKSPACES = 490;
|
|
64
64
|
|
|
65
|
+
// 500 Internal Server Error
|
|
66
|
+
export const INTERNAL_SERVER_ERROR = 500;
|
|
67
|
+
|
|
65
68
|
// 501 EE Feature
|
|
66
69
|
export const EE_FEATURE = 501;
|
|
67
70
|
|
package/src/protocol.ts
CHANGED
|
@@ -45,6 +45,9 @@ export interface User {
|
|
|
45
45
|
markedDeleted?: boolean;
|
|
46
46
|
|
|
47
47
|
additionalData?: AdditionalUserData;
|
|
48
|
+
|
|
49
|
+
// Identifies an explicit team or user ID to which all the user's workspace usage should be attributed to (e.g. for billing purposes)
|
|
50
|
+
usageAttributionId?: string;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
export namespace User {
|
|
@@ -70,11 +73,14 @@ export namespace User {
|
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
/**
|
|
73
|
-
*
|
|
76
|
+
* Returns the stored email or if it doesn't exist returns the primaryEmail of the first identity this user signed up with.
|
|
74
77
|
* @param user
|
|
75
78
|
* @returns A primaryEmail, or undefined if there is none.
|
|
76
79
|
*/
|
|
77
80
|
export function getPrimaryEmail(user: User): string | undefined {
|
|
81
|
+
if (user.additionalData?.profile?.emailAddress) {
|
|
82
|
+
return user.additionalData?.profile?.emailAddress;
|
|
83
|
+
}
|
|
78
84
|
const identities = user.identities.filter((i) => !!i.primaryEmail);
|
|
79
85
|
if (identities.length <= 0) {
|
|
80
86
|
return undefined;
|
|
@@ -136,6 +142,50 @@ export namespace User {
|
|
|
136
142
|
}
|
|
137
143
|
user.additionalData.ideSettings = newIDESettings;
|
|
138
144
|
}
|
|
145
|
+
|
|
146
|
+
export function getProfile(user: User): Profile {
|
|
147
|
+
return {
|
|
148
|
+
name: User.getName(user!) || "",
|
|
149
|
+
email: User.getPrimaryEmail(user!) || "",
|
|
150
|
+
company: user?.additionalData?.profile?.companyName,
|
|
151
|
+
avatarURL: user?.avatarUrl,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function setProfile(user: User, profile: Profile): User {
|
|
156
|
+
user.fullName = profile.name;
|
|
157
|
+
user.avatarUrl = profile.avatarURL;
|
|
158
|
+
|
|
159
|
+
if (!user.additionalData) {
|
|
160
|
+
user.additionalData = {};
|
|
161
|
+
}
|
|
162
|
+
if (!user.additionalData.profile) {
|
|
163
|
+
user.additionalData.profile = {};
|
|
164
|
+
}
|
|
165
|
+
user.additionalData.profile.emailAddress = profile.email;
|
|
166
|
+
user.additionalData.profile.companyName = profile.company;
|
|
167
|
+
user.additionalData.profile.lastUpdatedDetailsNudge = new Date().toISOString();
|
|
168
|
+
|
|
169
|
+
return user;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// The actual Profile of a User
|
|
173
|
+
export interface Profile {
|
|
174
|
+
name: string;
|
|
175
|
+
email: string;
|
|
176
|
+
company?: string;
|
|
177
|
+
avatarURL?: string;
|
|
178
|
+
}
|
|
179
|
+
export namespace Profile {
|
|
180
|
+
export function hasChanges(before: Profile, after: Profile) {
|
|
181
|
+
return (
|
|
182
|
+
before.name !== after.name ||
|
|
183
|
+
before.email !== after.email ||
|
|
184
|
+
before.company !== after.company ||
|
|
185
|
+
before.avatarURL !== after.avatarURL
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
139
189
|
}
|
|
140
190
|
|
|
141
191
|
export interface AdditionalUserData {
|
|
@@ -150,9 +200,22 @@ export interface AdditionalUserData {
|
|
|
150
200
|
oauthClientsApproved?: { [key: string]: string };
|
|
151
201
|
// to remember GH Orgs the user installed/updated the GH App for
|
|
152
202
|
knownGitHubOrgs?: string[];
|
|
153
|
-
|
|
154
203
|
// Git clone URL pointing to the user's dotfile repo
|
|
155
204
|
dotfileRepo?: string;
|
|
205
|
+
// preferred workspace classes
|
|
206
|
+
workspaceClasses?: WorkspaceClasses;
|
|
207
|
+
// additional user profile data
|
|
208
|
+
profile?: ProfileDetails;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// The format in which we store User Profiles in
|
|
212
|
+
export interface ProfileDetails {
|
|
213
|
+
// when was the last time the user updated their profile information or has been nudged to do so.
|
|
214
|
+
lastUpdatedDetailsNudge?: string;
|
|
215
|
+
// the user's company name
|
|
216
|
+
companyName?: string;
|
|
217
|
+
// the user's email
|
|
218
|
+
emailAddress?: string;
|
|
156
219
|
}
|
|
157
220
|
|
|
158
221
|
export interface EmailNotificationSettings {
|
|
@@ -171,6 +234,11 @@ export type IDESettings = {
|
|
|
171
234
|
useLatestVersion?: boolean;
|
|
172
235
|
};
|
|
173
236
|
|
|
237
|
+
export interface WorkspaceClasses {
|
|
238
|
+
regular: string;
|
|
239
|
+
prebuild: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
174
242
|
export interface UserPlatform {
|
|
175
243
|
uid: string;
|
|
176
244
|
userAgent: string;
|
|
@@ -205,6 +273,7 @@ export const WorkspaceFeatureFlags = {
|
|
|
205
273
|
full_workspace_backup: undefined,
|
|
206
274
|
fixed_resources: undefined,
|
|
207
275
|
persistent_volume_claim: undefined,
|
|
276
|
+
protected_secrets: undefined,
|
|
208
277
|
};
|
|
209
278
|
export type NamedWorkspaceFeatureFlag = keyof typeof WorkspaceFeatureFlags;
|
|
210
279
|
|
|
@@ -552,6 +621,7 @@ export interface Snapshot {
|
|
|
552
621
|
|
|
553
622
|
export interface VolumeSnapshot {
|
|
554
623
|
id: string;
|
|
624
|
+
workspaceId: string;
|
|
555
625
|
creationTime: string;
|
|
556
626
|
volumeHandle: string;
|
|
557
627
|
}
|
|
@@ -625,7 +695,7 @@ export interface Workspace {
|
|
|
625
695
|
|
|
626
696
|
export type WorkspaceSoftDeletion = "user" | "gc";
|
|
627
697
|
|
|
628
|
-
export type WorkspaceType = "regular" | "prebuild" | "probe";
|
|
698
|
+
export type WorkspaceType = "regular" | "prebuild" | "probe"; // TODO(gpl) Removed prove here
|
|
629
699
|
|
|
630
700
|
export namespace Workspace {
|
|
631
701
|
export function getFullRepositoryName(ws: Workspace): string | undefined {
|
|
@@ -701,6 +771,7 @@ export interface JetBrainsConfig {
|
|
|
701
771
|
}
|
|
702
772
|
export interface JetBrainsProductConfig {
|
|
703
773
|
prebuilds?: JetBrainsPrebuilds;
|
|
774
|
+
vmoptions?: string;
|
|
704
775
|
}
|
|
705
776
|
export interface JetBrainsPrebuilds {
|
|
706
777
|
version?: "stable" | "latest" | "both";
|
|
@@ -816,7 +887,9 @@ export interface PrebuiltWorkspace {
|
|
|
816
887
|
|
|
817
888
|
export namespace PrebuiltWorkspace {
|
|
818
889
|
export function isDone(pws: PrebuiltWorkspace) {
|
|
819
|
-
return
|
|
890
|
+
return (
|
|
891
|
+
pws.state === "available" || pws.state === "timeout" || pws.state === "aborted" || pws.state === "failed"
|
|
892
|
+
);
|
|
820
893
|
}
|
|
821
894
|
|
|
822
895
|
export function isAvailable(pws: PrebuiltWorkspace) {
|
|
@@ -1409,3 +1482,11 @@ export interface Terms {
|
|
|
1409
1482
|
readonly content: string;
|
|
1410
1483
|
readonly formElements?: object;
|
|
1411
1484
|
}
|
|
1485
|
+
|
|
1486
|
+
export interface CostCenter {
|
|
1487
|
+
readonly id: string;
|
|
1488
|
+
/**
|
|
1489
|
+
* Unit: credits
|
|
1490
|
+
*/
|
|
1491
|
+
spendingLimit: number;
|
|
1492
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { PrebuiltWorkspaceState } 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;
|
|
@@ -14,6 +15,8 @@ export interface ProjectConfig {
|
|
|
14
15
|
|
|
15
16
|
export interface ProjectSettings {
|
|
16
17
|
useIncrementalPrebuilds?: boolean;
|
|
18
|
+
usePersistentVolumeClaim?: boolean;
|
|
19
|
+
keepOutdatedPrebuildsRunning?: boolean;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
export interface Project {
|
|
@@ -150,3 +153,15 @@ export interface TeamMembershipInvite {
|
|
|
150
153
|
/** This is a flag that triggers the HARD DELETION of this entity */
|
|
151
154
|
deleted?: boolean;
|
|
152
155
|
}
|
|
156
|
+
|
|
157
|
+
export interface PrebuildEvent {
|
|
158
|
+
id: string;
|
|
159
|
+
creationTime: string;
|
|
160
|
+
status: WebhookEvent.Status | WebhookEvent.PrebuildStatus;
|
|
161
|
+
message?: string;
|
|
162
|
+
prebuildId?: string;
|
|
163
|
+
projectId?: string;
|
|
164
|
+
cloneUrl?: string;
|
|
165
|
+
branch?: string;
|
|
166
|
+
commit?: string;
|
|
167
|
+
}
|
package/src/usage.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
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 { WorkspaceType } from "./protocol";
|
|
8
|
+
|
|
9
|
+
export interface BillableSession {
|
|
10
|
+
// The id of the one paying the bill
|
|
11
|
+
attributionId: string;
|
|
12
|
+
|
|
13
|
+
// Relevant for workspace type. When prebuild, shows "prebuild"
|
|
14
|
+
userId?: string;
|
|
15
|
+
teamId?: string;
|
|
16
|
+
|
|
17
|
+
instanceId: string;
|
|
18
|
+
|
|
19
|
+
workspaceId: string;
|
|
20
|
+
|
|
21
|
+
workspaceType: BillableWorkspaceType;
|
|
22
|
+
|
|
23
|
+
workspaceClass: string;
|
|
24
|
+
|
|
25
|
+
// When the workspace started
|
|
26
|
+
startTime: string;
|
|
27
|
+
|
|
28
|
+
// When the workspace ended. Not set when the workspace is still running.
|
|
29
|
+
endTime?: string;
|
|
30
|
+
|
|
31
|
+
// The credits used for this session
|
|
32
|
+
credits: number;
|
|
33
|
+
|
|
34
|
+
// TODO - maybe
|
|
35
|
+
projectId?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface BillableSessionRequest {
|
|
39
|
+
attributionId: string;
|
|
40
|
+
startedTimeOrder: SortOrder;
|
|
41
|
+
from?: number;
|
|
42
|
+
to?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type BillableWorkspaceType = WorkspaceType;
|
|
46
|
+
|
|
47
|
+
export enum SortOrder {
|
|
48
|
+
Descending = 0,
|
|
49
|
+
Ascending = 1,
|
|
50
|
+
}
|