Skip to content

Commit 45ee534

Browse files
committed
Add region admission preference
1 parent b0a97a4 commit 45ee534

File tree

15 files changed

+496
-42
lines changed

15 files changed

+496
-42
lines changed

components/gitpod-protocol/src/gitpod-service.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
WhitelistedRepository, WorkspaceImageBuild, AuthProviderInfo, Branding, CreateWorkspaceMode,
1010
Token, UserEnvVarValue, ResolvePluginsParams, PreparePluginUploadParams, Terms,
1111
ResolvedPlugins, Configuration, InstallPluginsParams, UninstallPluginParams, UserInfo, GitpodTokenType,
12-
GitpodToken, AuthProviderEntry, GuessGitTokenScopesParams, GuessedGitTokenScopes
12+
GitpodToken, AuthProviderEntry, GuessGitTokenScopesParams, GuessedGitTokenScopes, WorkspaceClusterPreference
1313
} from './protocol';
1414
import {
1515
Team, TeamMemberInfo,
@@ -237,6 +237,9 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
237237
trackEvent(event: RemoteTrackMessage): Promise<void>;
238238
trackLocation(event: RemotePageMessage): Promise<void>;
239239
identifyUser(event: RemoteIdentifyMessage): Promise<void>;
240+
241+
listWorkspaceClusterRTTEndpoints(): Promise<{ endpoint: string; region: string }[]>;
242+
setWorkspaceClusterPreferences(pref: WorkspaceClusterPreference): Promise<void>;
240243
}
241244

242245
export interface CreateProjectParams {

components/gitpod-protocol/src/protocol.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ export interface AdditionalUserData {
107107

108108
// Git clone URL pointing to the user's dotfile repo
109109
dotfileRepo?: string;
110+
111+
// cluster preferences collect data useful for workspace cluster selection
112+
clusterPreferences?: WorkspaceClusterPreference;
110113
}
111114

112115
export interface EmailNotificationSettings {
@@ -1248,3 +1251,7 @@ export interface Terms {
12481251
readonly content: string;
12491252
readonly formElements?: object;
12501253
}
1254+
1255+
export interface WorkspaceClusterPreference {
1256+
region?: string;
1257+
}

components/gitpod-protocol/src/workspace-cluster.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,13 @@ export type AdmissionConstraintFeaturePreview = { type: "has-feature-preview" };
6060
export type AdmissionConstraintHasRole = { type: "has-permission", permission: PermissionName };
6161
export type AdmissionConstraintHasUserLevel = { type: "has-user-level", level: string };
6262

63-
export type AdmissionPreference = AdmissionPreferenceUserLevel;
63+
export type AdmissionPreference = AdmissionPreferenceUserLevel | AdmissionPreferenceRegion;
6464
export type AdmissionPreferenceUserLevel = { type: 'user-level', level: string };
65+
export type AdmissionPreferenceRegion = { type: 'region', rttEndpoint: string, name: string };
6566

67+
export function isAdmissionPreferenceRegion(arg: any): arg is AdmissionPreferenceRegion {
68+
return "type" in arg && arg.type === "region" && "rttEndpoint" in arg && "region" in arg;
69+
}
6670

6771
export const WorkspaceClusterDB = Symbol("WorkspaceClusterDB");
6872
export interface WorkspaceClusterDB {

components/server/src/auth/rate-limiter.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ function getConfig(config: RateLimiterConfig): RateLimiterConfig {
174174
"trackLocation": { group: "default", points: 1},
175175
"identifyUser": { group: "default", points: 1},
176176
"getIDEOptions": { group: "default", points: 1 },
177+
178+
"listWorkspaceClusterRTTEndpoints": { group: "default", points: 1 },
179+
"setWorkspaceClusterPreferences": { group: "default", points: 1 },
177180
};
178181

179182
return {

components/server/src/workspace/gitpod-server-impl.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import { DownloadUrlRequest, DownloadUrlResponse, UploadUrlRequest, UploadUrlResponse } from '@gitpod/content-service/lib/blobs_pb';
88
import { AppInstallationDB, UserDB, UserMessageViewsDB, WorkspaceDB, DBWithTracing, TracedWorkspaceDB, DBGitpodToken, DBUser, UserStorageResourcesDB, TeamDB } from '@gitpod/gitpod-db/lib';
9-
import { AuthProviderEntry, AuthProviderInfo, Branding, CommitContext, Configuration, CreateWorkspaceMode, DisposableCollection, GetWorkspaceTimeoutResult, GitpodClient as GitpodApiClient, GitpodServer, GitpodToken, GitpodTokenType, InstallPluginsParams, PermissionName, PortVisibility, PrebuiltWorkspace, PrebuiltWorkspaceContext, PreparePluginUploadParams, ResolvedPlugins, ResolvePluginsParams, SetWorkspaceTimeoutResult, StartPrebuildContext, StartWorkspaceResult, Terms, Token, UninstallPluginParams, User, UserEnvVar, UserEnvVarValue, UserInfo, WhitelistedRepository, Workspace, WorkspaceContext, WorkspaceCreationResult, WorkspaceImageBuild, WorkspaceInfo, WorkspaceInstance, WorkspaceInstancePort, WorkspaceInstanceUser, WorkspaceTimeoutDuration, GuessGitTokenScopesParams, GuessedGitTokenScopes, Team, TeamMemberInfo, TeamMembershipInvite, CreateProjectParams, Project, ProviderRepository, TeamMemberRole, WithDefaultConfig, FindPrebuildsParams, PrebuildWithStatus, StartPrebuildResult, ClientHeaderFields } from '@gitpod/gitpod-protocol';
9+
import { AuthProviderEntry, AuthProviderInfo, Branding, CommitContext, Configuration, CreateWorkspaceMode, DisposableCollection, GetWorkspaceTimeoutResult, GitpodClient as GitpodApiClient, GitpodServer, GitpodToken, GitpodTokenType, InstallPluginsParams, PermissionName, PortVisibility, PrebuiltWorkspace, PrebuiltWorkspaceContext, PreparePluginUploadParams, ResolvedPlugins, ResolvePluginsParams, SetWorkspaceTimeoutResult, StartPrebuildContext, StartWorkspaceResult, Terms, Token, UninstallPluginParams, User, UserEnvVar, UserEnvVarValue, UserInfo, WhitelistedRepository, Workspace, WorkspaceContext, WorkspaceCreationResult, WorkspaceImageBuild, WorkspaceInfo, WorkspaceInstance, WorkspaceInstancePort, WorkspaceInstanceUser, WorkspaceTimeoutDuration, GuessGitTokenScopesParams, GuessedGitTokenScopes, Team, TeamMemberInfo, TeamMembershipInvite, CreateProjectParams, Project, ProviderRepository, TeamMemberRole, WithDefaultConfig, FindPrebuildsParams, PrebuildWithStatus, StartPrebuildResult, ClientHeaderFields, WorkspaceClusterPreference } from '@gitpod/gitpod-protocol';
1010
import { AccountStatement } from "@gitpod/gitpod-protocol/lib/accounting-protocol";
1111
import { AdminBlockUserRequest, AdminGetListRequest, AdminGetListResult, AdminGetWorkspacesRequest, AdminModifyPermanentWorkspaceFeatureFlagRequest, AdminModifyRoleOrPermissionRequest, WorkspaceAndInstance } from '@gitpod/gitpod-protocol/lib/admin-protocol';
1212
import { GetLicenseInfoResult, LicenseFeature, LicenseValidationResult } from '@gitpod/gitpod-protocol/lib/license-protocol';
@@ -56,6 +56,7 @@ import { IDEConfigService } from '../ide-config';
5656
import { PartialProject } from '@gitpod/gitpod-protocol/src/teams-projects-protocol';
5757
import { ClientMetadata } from '../websocket/websocket-connection-manager';
5858
import { ConfigurationService } from '../config/configuration-service';
59+
import { AdmissionPreferenceRegion, WorkspaceClusterDB } from '@gitpod/gitpod-protocol/lib/workspace-cluster';
5960

6061
// shortcut
6162
export const traceWI = (ctx: TraceContext, wi: Omit<LogContext, "userId">) => TraceContext.setOWI(ctx, wi); // userId is already taken care of in WebsocketConnectionManager
@@ -113,6 +114,8 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
113114

114115
@inject(IDEConfigService) protected readonly ideConfigService: IDEConfigService;
115116

117+
@inject(WorkspaceClusterDB) protected readonly workspaceClusterDB: WorkspaceClusterDB;
118+
116119
/** Id the uniquely identifies this server instance */
117120
public readonly uuid: string = uuidv4();
118121
public readonly clientMetadata: ClientMetadata;
@@ -2182,6 +2185,34 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
21822185
return ideConfig.ideOptions;
21832186
}
21842187

2188+
async listWorkspaceClusterRTTEndpoints(ctx: TraceContext): Promise<{ region: string; endpoint: string; }[]> {
2189+
const candidates = await this.workspaceClusterDB.findFiltered({state: 'available'});
2190+
const allEndpoints = candidates.flatMap(c => (c.admissionPreferences || []).filter(ap => ap.type === 'region')).map(ap => {
2191+
const rap = ap as AdmissionPreferenceRegion;
2192+
return {
2193+
region: rap.name,
2194+
endpoint: rap.rttEndpoint,
2195+
};
2196+
});
2197+
2198+
return [...new Set(allEndpoints)];
2199+
}
2200+
2201+
async setWorkspaceClusterPreferences(ctx: TraceContext, pref: WorkspaceClusterPreference): Promise<void> {
2202+
const user = this.checkUser("setWorkspaceClusterPreferences");
2203+
2204+
const data = user.additionalData || {};
2205+
const clusterPref = data.clusterPreferences || {};
2206+
2207+
// don't just dump `pref` in here, we have no idea what it contains.
2208+
clusterPref.region = pref.region;
2209+
2210+
data.clusterPreferences = clusterPref;
2211+
user.additionalData = data;
2212+
2213+
await this.userDB.updateUserPartial(user);
2214+
}
2215+
21852216
//#region gitpod.io concerns
21862217
//
21872218
async adminGetAccountStatement(ctx: TraceContext, userId: string): Promise<AccountStatement> {

components/ws-manager-api/typescript/src/client-provider.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ function admissionPreferencesFilter(user: ExtendedUser): (c: WorkspaceClusterWoT
199199
switch (pref.type) {
200200
case "user-level":
201201
return pref.level === user.level;
202+
case "region":
203+
return pref.name === user.additionalData?.clusterPreferences?.region;
202204
default:
203205
return false;
204206
}

components/ws-manager-bridge-api/cluster-service.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,14 @@ message AdmissionConstraint {
5252
}
5353

5454
message AdmissionPreference {
55+
message Region {
56+
string name = 1;
57+
string rtt_endpoint = 2;
58+
}
59+
5560
oneof preference {
5661
string user_level = 1;
62+
Region region = 2;
5763
}
5864
}
5965

0 commit comments

Comments
 (0)