only expose static create methods (and overloads) for Stack and LocalWorkspace

This commit is contained in:
evanboyle 2020-10-02 14:29:47 -07:00 committed by Evan Boyle
parent 6f622bc9e1
commit e77fc0a961
5 changed files with 152 additions and 181 deletions

View file

@ -25,7 +25,7 @@ import { asyncTest } from "../util";
describe("LocalWorkspace", () => {
it(`projectSettings from yaml/yml/json`, asyncTest(async () => {
for (const ext of ["yaml", "yml", "json"]) {
const ws = new LocalWorkspace({ workDir: upath.joinSafe(__dirname, "data", ext) });
const ws = await LocalWorkspace.create({ workDir: upath.joinSafe(__dirname, "data", ext) });
const settings = await ws.projectSettings();
assert(settings.name, "testproj");
assert(settings.runtime.name, "go");
@ -36,7 +36,7 @@ describe("LocalWorkspace", () => {
it(`stackSettings from yaml/yml/json`, asyncTest(async () => {
for (const ext of ["yaml", "yml", "json"]) {
const ws = new LocalWorkspace({ workDir: upath.joinSafe(__dirname, "data", ext) });
const ws = await LocalWorkspace.create({ workDir: upath.joinSafe(__dirname, "data", ext) });
const settings = await ws.stackSettings("dev");
assert.equal(settings.secretsProvider, "abc");
assert.equal(settings.config!["plain"].value, "plain");
@ -48,24 +48,22 @@ describe("LocalWorkspace", () => {
const projectSettings = new ProjectSettings();
projectSettings.name = "node_test";
projectSettings.runtime.name = "nodejs";
const ws = new LocalWorkspace({ projectSettings });
await ws.ready;
const ws = await LocalWorkspace.create({ projectSettings });
const stackName = `int_test${getTestSuffix()}`;
await ws.createStack(stackName);
await ws.selectStack(stackName);
await ws.removeStack(stackName);
}));
it(`Create/Select/Upsert Stack`, asyncTest(async () => {
it(`create/select/createOrSelect Stack`, asyncTest(async () => {
const projectSettings = new ProjectSettings();
projectSettings.name = "node_test";
projectSettings.runtime.name = "nodejs";
const ws = new LocalWorkspace({ projectSettings });
await ws.ready;
const ws = await LocalWorkspace.create({ projectSettings });
const stackName = `int_test${getTestSuffix()}`;
await Stack.Create(stackName, ws);
await Stack.Select(stackName, ws);
await Stack.Upsert(stackName, ws);
await Stack.create(stackName, ws);
await Stack.select(stackName, ws);
await Stack.createOrSelect(stackName, ws);
await ws.removeStack(stackName);
}));
it(`Config`, asyncTest(async () => {
@ -73,10 +71,9 @@ describe("LocalWorkspace", () => {
const projectSettings = new ProjectSettings();
projectSettings.name = projectName;
projectSettings.runtime.name = "nodejs";
const ws = new LocalWorkspace({ projectSettings });
await ws.ready;
const ws = await LocalWorkspace.create({ projectSettings });
const stackName = `int_test${getTestSuffix()}`;
const stack = await Stack.Create(stackName, ws);
const stack = await Stack.create(stackName, ws);
const config = {
plain: { value: "abc" },
@ -116,14 +113,13 @@ describe("LocalWorkspace", () => {
const projectSettings = new ProjectSettings();
projectSettings.name = `node_list_test${getTestSuffix()}`;
projectSettings.runtime.name = "nodejs";
const ws = new LocalWorkspace({ projectSettings });
await ws.ready;
const ws = await LocalWorkspace.create({ projectSettings });
const stackNamer = () => `int_test${getTestSuffix()}`;
const stackNames: string[] = [];
for (let i = 0; i < 2; i++) {
const stackName = stackNamer();
stackNames[i] = stackName;
await Stack.Create(stackName, ws);
await Stack.create(stackName, ws);
const stackSummary = await ws.stack();
assert.equal(stackSummary?.current, true);
const stacks = await ws.listStacks();
@ -138,10 +134,9 @@ describe("LocalWorkspace", () => {
const projectSettings = new ProjectSettings();
projectSettings.name = "node_test";
projectSettings.runtime.name = "nodejs";
const ws = new LocalWorkspace({ projectSettings });
await ws.ready;
const ws = await LocalWorkspace.create({ projectSettings });
const stackName = `int_test${getTestSuffix()}`;
const stack = await Stack.Create(stackName, ws);
const stack = await Stack.create(stackName, ws);
const histroy = await stack.history();
assert.equal(histroy.length, 0);
const info = await stack.info();
@ -151,7 +146,7 @@ describe("LocalWorkspace", () => {
it(`runs through the stack lifecycle with a local program`, asyncTest(async () => {
const stackName = `int_test${getTestSuffix()}`;
const workDir = upath.joinSafe(__dirname, "data", "testproj");
const stack = await LocalWorkspace.NewStackLocalSource(stackName, workDir);
const stack = await LocalWorkspace.createStack({ stackName, workDir });
const config: ConfigMap = {
"bar": { value: "abc" },
@ -188,16 +183,17 @@ describe("LocalWorkspace", () => {
await stack.getWorkspace().removeStack(stackName);
}));
it(`runs through the stack lifecycle with an inline program`, asyncTest(async () => {
const program = () => {
const program = async () => {
const config = new Config();
return Promise.resolve({
return {
exp_static: "foo",
exp_cfg: config.get("bar"),
exp_secret: config.getSecret("buzz"),
});
};
};
const stackName = `int_test${getTestSuffix()}`;
const stack = await LocalWorkspace.NewStackInlineSource(stackName, "inline_node", program);
const projectName = "inline_node";
const stack = await LocalWorkspace.createStack({ stackName, projectName, program });
const stackConfig: ConfigMap = {
"bar": { value: "abc" },

View file

@ -13,8 +13,8 @@
// limitations under the License.
import * as assert from "assert";
import { Output } from "../output";
import { CustomResource } from "../index";
import { Output } from "../output";
import * as runtime from "../runtime";
import { asyncTest } from "./util";

View file

@ -24,77 +24,78 @@ import { StackSettings } from "./stackSettings";
import { PulumiFn, StackSummary, Workspace } from "./workspace";
export class LocalWorkspace implements Workspace {
ready: Promise<any[]>;
private workDir: string;
private pulumiHome?: string;
private program?: PulumiFn;
private envVars: { [key: string]: string };
private secretsProvider?: string;
public static async NewStackLocalSource(
stackName: string, workDir: string, opts?: LocalWorkspaceOpts,
): Promise<Stack> {
return this.localSourceStackHelper(stackName, workDir, Stack.Create, opts);
readonly workDir: string;
readonly pulumiHome?: string;
readonly secretsProvider?: string;
public program?: PulumiFn;
public envVars: { [key: string]: string };
private ready: Promise<any[]>;
public static async create(opts: LocalWorkspaceOptions): Promise<LocalWorkspace> {
const ws = new LocalWorkspace(opts);
await ws.ready;
return ws;
}
public static async UpsertStackLocalSource(
stackName: string, workDir: string, opts?: LocalWorkspaceOpts,
): Promise<Stack> {
return this.localSourceStackHelper(stackName, workDir, Stack.Upsert, opts);
public static async createStack(args: LocalProgramArgs, opts?: LocalWorkspaceOptions): Promise<Stack>;
public static async createStack(args: InlineProgramArgs, opts?: LocalWorkspaceOptions): Promise<Stack>;
public static async createStack(args: InlineProgramArgs | LocalProgramArgs, opts?: LocalWorkspaceOptions): Promise<Stack> {
if (isInlineProgramArgs(args)) {
return await this.inlineSourceStackHelper(args, Stack.create, opts);
} else if (isLocalProgramArgs(args)) {
return await this.localSourceStackHelper(args, Stack.create, opts);
}
throw new Error(`unexpected args: ${args}`);
}
public static async SelectStackLocalSource(
stackName: string, workDir: string, opts?: LocalWorkspaceOpts,
): Promise<Stack> {
return this.localSourceStackHelper(stackName, workDir, Stack.Select, opts);
public static async selectStack(args: LocalProgramArgs, opts?: LocalWorkspaceOptions): Promise<Stack>;
public static async selectStack(args: InlineProgramArgs, opts?: LocalWorkspaceOptions): Promise<Stack>;
public static async selectStack(args: InlineProgramArgs | LocalProgramArgs, opts?: LocalWorkspaceOptions): Promise<Stack> {
if (isInlineProgramArgs(args)) {
return await this.inlineSourceStackHelper(args, Stack.select, opts);
} else if (isLocalProgramArgs(args)) {
return await this.localSourceStackHelper(args, Stack.select, opts);
}
throw new Error(`unexpected args: ${args}`);
}
public static async createOrSelectStack(args: LocalProgramArgs, opts?: LocalWorkspaceOptions): Promise<Stack>;
public static async createOrSelectStack(args: InlineProgramArgs, opts?: LocalWorkspaceOptions): Promise<Stack>;
public static async createOrSelectStack(args: InlineProgramArgs | LocalProgramArgs, opts?: LocalWorkspaceOptions): Promise<Stack> {
if (isInlineProgramArgs(args)) {
return await this.inlineSourceStackHelper(args, Stack.createOrSelect, opts);
} else if (isLocalProgramArgs(args)) {
return await this.localSourceStackHelper(args, Stack.createOrSelect, opts);
}
throw new Error(`unexpected args: ${args}`);
}
private static async localSourceStackHelper(
stackName: string, workDir: string, initFn: stackInitFunc, opts?: LocalWorkspaceOpts,
args: LocalProgramArgs, initFn: stackInitializer, opts?: LocalWorkspaceOptions,
): Promise<Stack> {
let wsOpts = { workDir };
let wsOpts = { workDir: args.workDir };
if (opts) {
wsOpts = { ...opts, workDir };
wsOpts = { ...opts, workDir: args.workDir };
}
const ws = new LocalWorkspace(wsOpts);
await ws.ready;
const stack = await initFn(stackName, ws);
return Promise.resolve(stack);
}
public static async NewStackInlineSource(
stackName: string, projectName: string, program: PulumiFn, opts?: LocalWorkspaceOpts,
): Promise<Stack> {
return this.inlineSourceStackHelper(stackName, projectName, program, Stack.Create, opts);
}
public static async UpsertStackInlineSource(
stackName: string, projectName: string, program: PulumiFn, opts?: LocalWorkspaceOpts,
): Promise<Stack> {
return this.inlineSourceStackHelper(stackName, projectName, program, Stack.Upsert, opts);
}
public static async SelectStackInlineSource(
stackName: string, projectName: string, program: PulumiFn, opts?: LocalWorkspaceOpts,
): Promise<Stack> {
return this.inlineSourceStackHelper(stackName, projectName, program, Stack.Select, opts);
return await initFn(args.stackName, ws);
}
private static async inlineSourceStackHelper(
stackName: string, projectName: string, program: PulumiFn, initFn: stackInitFunc, opts?: LocalWorkspaceOpts,
args: InlineProgramArgs, initFn: stackInitializer, opts?: LocalWorkspaceOptions,
): Promise<Stack> {
let wsOpts: LocalWorkspaceOpts = { program };
let wsOpts: LocalWorkspaceOptions = { program: args.program };
if (opts) {
wsOpts = { ...opts, program };
wsOpts = { ...opts, program: args.program };
}
if (!wsOpts.projectSettings) {
wsOpts.projectSettings = defaultProject(projectName);
wsOpts.projectSettings = defaultProject(args.projectName);
}
const ws = new LocalWorkspace(wsOpts);
await ws.ready;
const stack = await initFn(stackName, ws);
return Promise.resolve(stack);
return await initFn(args.stackName, ws);
}
constructor(opts?: LocalWorkspaceOpts) {
private constructor(opts?: LocalWorkspaceOptions) {
let dir = "";
let envs = {};
@ -135,11 +136,11 @@ export class LocalWorkspace implements Workspace {
if (!fs.existsSync(path)) { continue; }
const contents = fs.readFileSync(path).toString();
if (isJSON) {
return Promise.resolve(ProjectSettings.fromJSON(JSON.parse(contents)));
return ProjectSettings.fromJSON(JSON.parse(contents));
}
return Promise.resolve(ProjectSettings.fromYAML(contents));
return ProjectSettings.fromYAML(contents);
}
return Promise.reject(new Error(`failed to find project settings file in workdir: ${this.workDir}`));
throw new Error(`failed to find project settings file in workdir: ${this.workDir}`);
}
async saveProjectSettings(settings: ProjectSettings): Promise<void> {
let foundExt = ".yaml";
@ -158,7 +159,7 @@ export class LocalWorkspace implements Workspace {
else {
contents = settings.toYAML();
}
return Promise.resolve(fs.writeFileSync(path, contents));
return fs.writeFileSync(path, contents);
}
async stackSettings(stackName: string): Promise<StackSettings> {
const stackSettingsName = getStackSettingsName(stackName);
@ -168,11 +169,11 @@ export class LocalWorkspace implements Workspace {
if (!fs.existsSync(path)) { continue; }
const contents = fs.readFileSync(path).toString();
if (isJSON) {
return Promise.resolve(StackSettings.fromJSON(JSON.parse(contents)));
return StackSettings.fromJSON(JSON.parse(contents));
}
return Promise.resolve(StackSettings.fromYAML(contents));
return StackSettings.fromYAML(contents);
}
return Promise.reject(new Error(`failed to find stack settings file in workdir: ${this.workDir}`));
throw new Error(`failed to find stack settings file in workdir: ${this.workDir}`);
}
async saveStackSettings(settings: StackSettings, stackName: string): Promise<void> {
const stackSettingsName = getStackSettingsName(stackName);
@ -192,53 +193,37 @@ export class LocalWorkspace implements Workspace {
else {
contents = settings.toYAML();
}
return Promise.resolve(fs.writeFileSync(path, contents));
return fs.writeFileSync(path, contents);
}
async createStack(stackName: string): Promise<void> {
const args = ["stack", "init", stackName];
if (this.secretsProvider) {
args.push("--secrets-provider", this.secretsProvider);
}
try {
const result = await this.runPulumiCmd(args);
return Promise.resolve();
} catch (error) {
return Promise.reject(error);
}
await this.runPulumiCmd(args);
}
async selectStack(stackName: string): Promise<void> {
try {
const result = await this.runPulumiCmd(["stack", "select", stackName]);
return Promise.resolve();
} catch (error) {
return Promise.reject(error);
}
await this.runPulumiCmd(["stack", "select", stackName]);
}
async removeStack(stackName: string): Promise<void> {
try {
const result = await this.runPulumiCmd(["stack", "rm", "--yes", stackName]);
return Promise.resolve();
} catch (error) {
return Promise.reject(error);
}
await this.runPulumiCmd(["stack", "rm", "--yes", stackName]);
}
async getConfig(stackName: string, key: string): Promise<ConfigValue> {
await this.selectStack(stackName);
const result = await this.runPulumiCmd(["config", "get", key, "--json"]);
const val = JSON.parse(result.stdout);
return Promise.resolve(val);
return val;
}
async getAllConfig(stackName: string): Promise<ConfigMap> {
await this.selectStack(stackName);
const result = await this.runPulumiCmd(["config", "--show-secrets", "--json"]);
const val = JSON.parse(result.stdout);
return Promise.resolve(val);
return val;
}
async setConfig(stackName: string, key: string, value: ConfigValue): Promise<void> {
await this.selectStack(stackName);
const secretArg = value.secret ? "--secret" : "--plaintext";
await this.runPulumiCmd(["config", "set", key, value.value, secretArg]);
return Promise.resolve();
}
async setAllConfig(stackName: string, config: ConfigMap): Promise<void> {
const promises: Promise<void>[] = [];
@ -246,74 +231,48 @@ export class LocalWorkspace implements Workspace {
promises.push(this.setConfig(stackName, key, value));
}
await Promise.all(promises);
return Promise.resolve();
}
async removeConfig(stackName: string, key: string): Promise<void> {
await this.selectStack(stackName);
await this.runPulumiCmd(["config", "rm", key]);
return Promise.resolve();
}
async removeAllConfig(stackName: string, keys: string[]): Promise<void> {
const promises: Promise<void>[] = [];
for (const key of keys) {
promises.push(this.removeConfig(stackName, key));
}
return Promise.resolve(<any>{});
await Promise.all(promises);
}
async refreshConfig(stackName: string): Promise<ConfigMap> {
await this.selectStack(stackName);
await this.runPulumiCmd(["config", "refresh", "--force"]);
return this.getAllConfig(stackName);
}
getEnvVars(): { [key: string]: string } {
return this.envVars;
}
setEnvVars(envs: { [key: string]: string }): void {
this.envVars = { ...this.envVars, ...envs };
}
setEnvVar(key: string, value: string): void {
this.envVars[key] = value;
}
unsetEnvVar(key: string): void {
delete this.envVars[key];
}
getWorkDir(): string {
return this.workDir;
}
getPulumiHome(): string | undefined {
return this.pulumiHome;
}
async whoAmI(): Promise<string> {
const result = await this.runPulumiCmd(["whoami"]);
return Promise.resolve(result.stdout.trim());
return result.stdout.trim();
}
async stack(): Promise<StackSummary | undefined> {
const stacks = await this.listStacks();
for (const stack of stacks) {
if (stack.current) {
return Promise.resolve(stack);
return stack;
}
}
return Promise.resolve(undefined);
return undefined;
}
async listStacks(): Promise<StackSummary[]> {
const result = await this.runPulumiCmd(["stack", "ls", "--json"]);
const stacks: StackSummary[] = JSON.parse(result.stdout);
return Promise.resolve(stacks);
return stacks;
}
getProgram(): PulumiFn | undefined {
return this.program;
}
setProgram(program: PulumiFn): void {
this.program = program;
}
serializeArgsForOp(_: string): Promise<string[]> {
async serializeArgsForOp(_: string): Promise<string[]> {
// LocalWorkspace does not take advantage of this extensibility point.
return Promise.resolve([]);
return [];
}
postCommandCallback(_: string): Promise<void> {
async postCommandCallback(_: string): Promise<void> {
// LocalWorkspace does not take advantage of this extensibility point.
return Promise.resolve();
return;
}
private async runPulumiCmd(
args: string[],
@ -322,12 +281,23 @@ export class LocalWorkspace implements Workspace {
if (this.pulumiHome) {
envs["PULUMI_HOME"] = this.pulumiHome;
}
envs = { ...envs, ...this.getEnvVars() };
envs = { ...envs, ...this.envVars };
return runPulumiCmd(args, this.workDir, envs);
}
}
export type LocalWorkspaceOpts = {
export interface InlineProgramArgs {
stackName: string;
projectName: string;
program: PulumiFn;
}
export interface LocalProgramArgs {
stackName: string;
workDir: string;
}
export type LocalWorkspaceOptions = {
workDir?: string,
pulumiHome?: string,
program?: PulumiFn,
@ -337,21 +307,30 @@ export type LocalWorkspaceOpts = {
stackSettings?: { [key: string]: StackSettings },
};
function isLocalProgramArgs(args: LocalProgramArgs | InlineProgramArgs): args is LocalProgramArgs {
return (args as LocalProgramArgs).workDir !== undefined;
}
function isInlineProgramArgs(args: LocalProgramArgs | InlineProgramArgs): args is InlineProgramArgs {
return (args as InlineProgramArgs).projectName !== undefined &&
(args as InlineProgramArgs).program !== undefined;
}
export const settingsExtensions = [".yaml", ".yml", ".json"];
const getStackSettingsName = (name: string): string => {
function getStackSettingsName(name: string): string {
const parts = name.split("/");
if (parts.length < 1) {
return name;
}
return parts[parts.length - 1];
};
}
type stackInitFunc = (name: string, workspace: Workspace) => Promise<Stack>;
type stackInitializer = (name: string, workspace: Workspace) => Promise<Stack>;
const defaultProject = (projectName: string) => {
function defaultProject(projectName: string) {
const settings = new ProjectSettings();
settings.name = projectName;
settings.runtime.name = "nodejs";
return settings;
};
}

View file

@ -21,28 +21,26 @@ import { PulumiFn, Workspace } from "./workspace";
const langrpc = require("../../proto/language_grpc_pb.js");
export type StackInitMode = "create" | "select" | "upsert";
export class Stack {
ready: Promise<any>;
private name: string;
private workspace: Workspace;
public static async Create(name: string, workspace: Workspace): Promise<Stack> {
readonly name: string;
readonly workspace: Workspace;
private ready: Promise<any>;
public static async create(name: string, workspace: Workspace): Promise<Stack> {
const stack = new Stack(name, workspace, "create");
await stack.ready;
return Promise.resolve(stack);
return stack;
}
public static async Select(name: string, workspace: Workspace): Promise<Stack> {
public static async select(name: string, workspace: Workspace): Promise<Stack> {
const stack = new Stack(name, workspace, "select");
await stack.ready;
return Promise.resolve(stack);
return stack;
}
public static async Upsert(name: string, workspace: Workspace): Promise<Stack> {
const stack = new Stack(name, workspace, "upsert");
public static async createOrSelect(name: string, workspace: Workspace): Promise<Stack> {
const stack = new Stack(name, workspace, "createOrSelect");
await stack.ready;
return Promise.resolve(stack);
return stack;
}
constructor(name: string, workspace: Workspace, mode: StackInitMode) {
private constructor(name: string, workspace: Workspace, mode: StackInitMode) {
this.name = name;
this.workspace = workspace;
@ -53,7 +51,7 @@ export class Stack {
case "select":
this.ready = workspace.selectStack(name);
return this;
case "upsert":
case "createOrSelect":
// TODO update this based on structured errors (check for 409)
this.ready = workspace.createStack(name).catch(() => {
return workspace.selectStack(name);
@ -66,7 +64,7 @@ export class Stack {
async up(opts?: UpOptions): Promise<UpResult> {
const args = ["up", "--yes", "--skip-preview"];
let kind = execKind.local;
let program: PulumiFn | undefined = this.workspace.getProgram();
let program = this.workspace.program;
await this.workspace.selectStack(this.name);
if (opts) {
@ -133,13 +131,13 @@ export class Stack {
summary: status[0]!,
outputs: status[1]!,
};
return Promise.resolve(result);
return result;
}
async preview(opts?: PreviewOptions): Promise<PreviewResult> {
// TODO JSON
const args = ["preview"];
let kind = execKind.local;
let program: PulumiFn | undefined = this.workspace.getProgram();
let program = this.workspace.program;
await this.workspace.selectStack(this.name);
if (opts) {
@ -205,7 +203,7 @@ export class Stack {
stderr: preResult.stderr,
summary: summary!,
};
return Promise.resolve(result);
return result;
}
async refresh(opts?: RefreshOptions): Promise<RefreshResult> {
const args = ["refresh", "--yes", "--skip-preview"];
@ -235,7 +233,7 @@ export class Stack {
stderr: refResult.stderr,
summary: summary!,
};
return Promise.resolve(result);
return result;
}
async destroy(opts?: DestroyOptions): Promise<DestroyResult> {
const args = ["destroy", "--yes", "--skip-preview"];
@ -265,7 +263,7 @@ export class Stack {
stderr: preResult.stderr,
summary: summary!,
};
return Promise.resolve(result);
return result;
}
getName(): string { return this.name; }
getWorkspace(): Workspace { return this.workspace; }
@ -304,34 +302,33 @@ export class Stack {
outputs[key] = { value, secret };
}
return Promise.resolve(outputs);
return outputs;
}
async history(): Promise<UpdateSummary[]> {
const result = await this.runPulumiCmd(["history", "--json", "--show-secrets"]);
const summaries: UpdateSummary[] = JSON.parse(result.stdout);
return Promise.resolve(summaries);
return summaries;
}
async info(): Promise<UpdateSummary | undefined> {
const history = await this.history();
if (!history || history.length === 0) {
return Promise.resolve(undefined);
return undefined;
}
return Promise.resolve(history[0]);
return history[0];
}
private async runPulumiCmd(args: string[], onOutput?: (out: string) => void): Promise<CommandResult> {
const ws = this.getWorkspace();
let envs: { [key: string]: string } = {};
const pulumiHome = ws.getPulumiHome();
const pulumiHome = ws.pulumiHome;
if (pulumiHome) {
envs["PULUMI_HOME"] = pulumiHome;
}
const additionalEnvs = await ws.getEnvVars();
envs = { ...envs, ...additionalEnvs };
envs = { ...envs, ...ws.envVars };
const additionalArgs = await ws.serializeArgsForOp(this.name);
args = [...args, ...additionalArgs];
const result = await runPulumiCmd(args, ws.getWorkDir(), envs, onOutput);
const result = await runPulumiCmd(args, ws.workDir, envs, onOutput);
await ws.postCommandCallback(this.name);
return Promise.resolve(result);
return result;
}
}
@ -440,3 +437,5 @@ const execKind = {
local: "auto.local",
inline: "auto.inline",
};
type StackInitMode = "create" | "select" | "createOrSelect";

View file

@ -17,6 +17,11 @@ import { ProjectSettings } from "./projectSettings";
import { StackSettings } from "./stackSettings";
export interface Workspace {
readonly workDir: string;
readonly pulumiHome?: string;
readonly secretsProvider?: string;
program?: PulumiFn;
envVars: { [key: string]: string };
projectSettings(): Promise<ProjectSettings>;
saveProjectSettings(settings: ProjectSettings): Promise<void>;
stackSettings(stackName: string): Promise<StackSettings>;
@ -30,20 +35,12 @@ export interface Workspace {
removeConfig(stackName: string, key: string): Promise<void>;
removeAllConfig(stackName: string, keys: string[]): Promise<void>;
refreshConfig(stackName: string): Promise<ConfigMap>;
getEnvVars(): { [key: string]: string };
setEnvVars(envs: { [key: string]: string }): void;
setEnvVar(key: string, value: string): void;
unsetEnvVar(key: string): void;
getWorkDir(): string;
getPulumiHome(): string | undefined;
whoAmI(): Promise<string>;
stack(): Promise<StackSummary | undefined>;
createStack(stackName: string): Promise<void>;
selectStack(stackName: string): Promise<void>;
removeStack(stackName: string): Promise<void>;
listStacks(): Promise<StackSummary[]>;
getProgram(): PulumiFn | undefined;
setProgram(program: PulumiFn): void;
// TODO import/export
}
@ -56,4 +53,4 @@ export type StackSummary = {
url?: string,
};
export type PulumiFn = () => Promise<any>;
export type PulumiFn = () => Promise<Record<string, any> | void>;