mirror of https://github.com/pulumi/pulumi.git
225 lines
7.2 KiB
TypeScript
225 lines
7.2 KiB
TypeScript
// Copyright 2016-2022, Pulumi Corporation.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
import { LocalWorkspace, LocalWorkspaceOptions } from "./localWorkspace";
|
|
import { RemoteStack } from "./remoteStack";
|
|
import { Stack } from "./stack";
|
|
|
|
/**
|
|
* {@link RemoteWorkspace} is the execution context containing a single remote
|
|
* Pulumi project.
|
|
*/
|
|
export class RemoteWorkspace {
|
|
/**
|
|
* Creates a stack backed by a {@link RemoteWorkspace} with source code from
|
|
* the specified Git repository. Pulumi operations on the stack (preview,
|
|
* update, refresh, and destroy) are performed remotely.
|
|
*
|
|
* @param args
|
|
* A set of arguments to initialize a {@link RemoteStack} with a remote
|
|
* Pulumi program from a Git repository.
|
|
* @param opts
|
|
* Additional customizations to be applied to the Workspace.
|
|
*/
|
|
static async createStack(args: RemoteGitProgramArgs, opts?: RemoteWorkspaceOptions): Promise<RemoteStack> {
|
|
const ws = await createLocalWorkspace(args, opts);
|
|
const stack = await Stack.create(args.stackName, ws);
|
|
return RemoteStack.create(stack);
|
|
}
|
|
|
|
/**
|
|
* Selects an existing stack backed by a {@link RemoteWorkspace} with source
|
|
* code from the specified Git repository. Pulumi operations on the stack
|
|
* (preview, update, refresh, and destroy) are performed remotely.
|
|
*
|
|
* @param args
|
|
* A set of arguments to initialize a {@link RemoteStack} with a remote
|
|
* Pulumi program from a Git repository.
|
|
* @param opts
|
|
* Additional customizations to be applied to the Workspace.
|
|
*/
|
|
static async selectStack(args: RemoteGitProgramArgs, opts?: RemoteWorkspaceOptions): Promise<RemoteStack> {
|
|
const ws = await createLocalWorkspace(args, opts);
|
|
const stack = await Stack.select(args.stackName, ws);
|
|
return RemoteStack.create(stack);
|
|
}
|
|
/**
|
|
* Creates or selects an existing stack backed by a {@link RemoteWorkspace}
|
|
* with source code from the specified Git repository. Pulumi operations on
|
|
* the stack (preview, update, refresh, and destroy) are performed remotely.
|
|
*
|
|
* @param args
|
|
* A set of arguments to initialize a RemoteStack with a remote Pulumi program from a Git repository.
|
|
* @param opts
|
|
* Additional customizations to be applied to the Workspace.
|
|
*/
|
|
static async createOrSelectStack(args: RemoteGitProgramArgs, opts?: RemoteWorkspaceOptions): Promise<RemoteStack> {
|
|
const ws = await createLocalWorkspace(args, opts);
|
|
const stack = await Stack.createOrSelect(args.stackName, ws);
|
|
return RemoteStack.create(stack);
|
|
}
|
|
|
|
private constructor() {} // eslint-disable-line @typescript-eslint/no-empty-function
|
|
}
|
|
|
|
/**
|
|
* Description of a stack backed by a remote Pulumi program in a Git repository.
|
|
*/
|
|
export interface RemoteGitProgramArgs {
|
|
/**
|
|
* The associated stack name.
|
|
*/
|
|
stackName: string;
|
|
|
|
/**
|
|
* The URL of the repository.
|
|
*/
|
|
url?: string;
|
|
|
|
/**
|
|
* An optional path relative to the repo root specifying location of the Pulumi program.
|
|
*/
|
|
projectPath?: string;
|
|
|
|
/**
|
|
* An optional branch to checkout.
|
|
*/
|
|
branch?: string;
|
|
|
|
/**
|
|
* Optional commit to checkout.
|
|
*/
|
|
commitHash?: string;
|
|
|
|
/**
|
|
* Authentication options for the repository.
|
|
*/
|
|
auth?: RemoteGitAuthArgs;
|
|
}
|
|
|
|
/**
|
|
* Authentication options that can be specified for a private Git repository.
|
|
* There are three different authentication paths:
|
|
*
|
|
* - A Personal access token
|
|
* - An SSH private key (and its optional passphrase)
|
|
* - Username and password (basic authentication)
|
|
*
|
|
* Only one authentication path is valid.
|
|
*/
|
|
export interface RemoteGitAuthArgs {
|
|
/**
|
|
* The absolute path to a private key to be used for access to the Git repository.
|
|
*/
|
|
sshPrivateKeyPath?: string;
|
|
|
|
/**
|
|
* A string containing the contents of a private key to be used for access
|
|
* to the Git repository.
|
|
*/
|
|
sshPrivateKey?: string;
|
|
|
|
/**
|
|
* The password that pairs with a username as part of basic authentication,
|
|
* or the passphrase to be used with an SSH private key.
|
|
*/
|
|
password?: string;
|
|
|
|
/**
|
|
* A Git personal access token, to be used in replacement of a password.
|
|
*/
|
|
personalAccessToken?: string;
|
|
|
|
/**
|
|
* The username to use when authenticating to a Git repository with basic
|
|
* authentication.
|
|
*/
|
|
username?: string;
|
|
}
|
|
|
|
/**
|
|
* Extensibility options to configure a {@link RemoteWorkspace.}
|
|
*/
|
|
export interface RemoteWorkspaceOptions {
|
|
/**
|
|
* Environment values scoped to the remote workspace. These will be passed
|
|
* to remote operations.
|
|
*/
|
|
envVars?: { [key: string]: string | { secret: string } };
|
|
|
|
/**
|
|
* An optional list of arbitrary commands to run before a remote Pulumi
|
|
* operation is invoked.
|
|
*/
|
|
preRunCommands?: string[];
|
|
|
|
/**
|
|
* Whether to skip the default dependency installation step. Defaults to
|
|
* false.
|
|
*/
|
|
skipInstallDependencies?: boolean;
|
|
|
|
/**
|
|
* Whether to inherit the deployment settings set on the stack. Defaults to
|
|
* false.
|
|
*/
|
|
inheritSettings?: boolean;
|
|
}
|
|
|
|
async function createLocalWorkspace(
|
|
args: RemoteGitProgramArgs,
|
|
opts?: RemoteWorkspaceOptions,
|
|
): Promise<LocalWorkspace> {
|
|
if (!isFullyQualifiedStackName(args.stackName)) {
|
|
throw new Error(`stack name "${args.stackName}" must be fully qualified.`);
|
|
}
|
|
|
|
if (!args.url && !opts?.inheritSettings) {
|
|
throw new Error("url is required if inheritSettings is not set.");
|
|
}
|
|
if (args.branch && args.commitHash) {
|
|
throw new Error("branch and commitHash cannot both be specified.");
|
|
}
|
|
if (!args.branch && !args.commitHash && !opts?.inheritSettings) {
|
|
throw new Error("either branch or commitHash is required if inheritSettings is not set.");
|
|
}
|
|
if (args.auth) {
|
|
if (args.auth.sshPrivateKey && args.auth.sshPrivateKeyPath) {
|
|
throw new Error("sshPrivateKey and sshPrivateKeyPath cannot both be specified.");
|
|
}
|
|
}
|
|
|
|
const localOpts: LocalWorkspaceOptions = {
|
|
remote: true,
|
|
remoteGitProgramArgs: args,
|
|
remoteEnvVars: opts?.envVars,
|
|
remotePreRunCommands: opts?.preRunCommands,
|
|
remoteSkipInstallDependencies: opts?.skipInstallDependencies,
|
|
remoteInheritSettings: opts?.inheritSettings,
|
|
};
|
|
return await LocalWorkspace.create(localOpts);
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* Exported only so it can be tested.
|
|
*/
|
|
export function isFullyQualifiedStackName(stackName: string): boolean {
|
|
if (!stackName) {
|
|
return false;
|
|
}
|
|
const split = stackName.split("/");
|
|
return split.length === 3 && !!split[0] && !!split[1] && !!split[2];
|
|
}
|