gitpod/components/gitpod-protocol/src/workspace-cluster.ts
Andrew Farries 076f35a1f2 Make deleteByName take an applicationCluster
Deleting a workspace cluster by name only makes sense in the context of
a particular workspace cluster.
2022-10-26 17:26:42 +02:00

111 lines
4.1 KiB
TypeScript

/**
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
* Licensed under the GNU Affero General Public License (AGPL).
* See License-AGPL.txt in the project root for license information.
*/
import * as fs from "fs";
import { filePathTelepresenceAware } from "./env";
import { DeepPartial } from "./util/deep-partial";
import { PermissionName } from "./permission";
export interface WorkspaceCluster {
// Name of the workspace cluster.
// This is the string set in each
// Must be identical to the installationShortname of the cluster it represents!
name: string;
// The name of the application cluster to which this cluster should be registered.
// The name can be at most 60 characters.
applicationCluster: string;
// URL of the cluster's ws-manager API
url: string;
// TLS contains the keys and certificates necessary to use mTLS between server and clients
tls?: TLSConfig;
// Current state of the cluster
state: WorkspaceClusterState;
// Maximum value score can reach for this cluster
maxScore: number;
// Score used for cluster selection when starting workspace instances
score: number;
// True if this bridge should control this cluster
govern: boolean;
// An optional set of constraints that limit who can start workspaces on the cluster
admissionConstraints?: AdmissionConstraint[];
}
export type WorkspaceClusterState = "available" | "cordoned" | "draining";
export interface TLSConfig {
// the CA shared between client and server (base64 encoded)
ca: string;
// the private key (base64 encoded)
key: string;
// the certificate signed with the shared CA (base64 encoded)
crt: string;
}
export namespace TLSConfig {
export const loadFromBase64File = (path: string): string =>
fs.readFileSync(filePathTelepresenceAware(path)).toString("base64");
}
export type WorkspaceClusterWoTLS = Omit<WorkspaceCluster, "tls">;
export type WorkspaceManagerConnectionInfo = Pick<WorkspaceCluster, "name" | "url" | "tls">;
export type AdmissionConstraint =
| AdmissionConstraintFeaturePreview
| AdmissionConstraintHasPermission
| AdmissionConstraintHasClass;
export type AdmissionConstraintFeaturePreview = { type: "has-feature-preview" };
export type AdmissionConstraintHasPermission = { type: "has-permission"; permission: PermissionName };
export type AdmissionConstraintHasClass = { type: "has-class"; id: string; displayName: string };
export namespace AdmissionConstraint {
export function is(o: any): o is AdmissionConstraint {
return !!o && "type" in o;
}
export function isHasPermissionConstraint(o: any): o is AdmissionConstraintHasPermission {
return is(o) && o.type === "has-permission";
}
export function hasPermission(ac: AdmissionConstraint, permission: PermissionName): boolean {
return isHasPermissionConstraint(ac) && ac.permission === permission;
}
}
export const WorkspaceClusterDB = Symbol("WorkspaceClusterDB");
export interface WorkspaceClusterDB {
/**
* Stores the given WorkspaceCluster to the cluster-local DB in a consistent manner.
* If there already is an entry with the same name it's merged and updated with the given state.
* @param cluster
*/
save(cluster: WorkspaceCluster): Promise<void>;
/**
* Deletes the cluster identified by this name, if any.
* @param name
*/
deleteByName(name: string, applicationCluster: string): Promise<void>;
/**
* Finds a WorkspaceCluster with the given name. If there is none, `undefined` is returned.
* @param name
*/
findByName(name: string, applicationCluster: string): Promise<WorkspaceCluster | undefined>;
/**
* Lists all WorkspaceClusterWoTls for which the given predicate is true (does not return TLS for size/speed concerns)
* @param predicate
*/
findFiltered(predicate: WorkspaceClusterFilter): Promise<WorkspaceClusterWoTLS[]>;
}
export type WorkspaceClusterFilter = Pick<WorkspaceCluster, "applicationCluster"> &
DeepPartial<Pick<WorkspaceCluster, "name" | "state" | "govern" | "url">> &
Partial<{ minScore: number }>;