Skip to content
1,215 changes: 638 additions & 577 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,28 @@
"krane": "./bin/run"
},
"dependencies": {
"@krane/common": "0.5.8",
"@krane/common": "0.5.93",
"@oclif/command": "^1.8.0",
"@oclif/config": "^1.15.1",
"@oclif/plugin-help": "^2.2.3",
"cli-ux": "^5.5.0",
"cli-ux": "^5.6.2",
"inquirer": "^7.1.0",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.21"
},
"devDependencies": {
"@oclif/dev-cli": "^1.22.2",
"tslib": "^1.11.1",
"@oclif/dev-cli": "^1.26.0",
"@types/inquirer": "^6.5.0",
"@types/jsonwebtoken": "^8.3.9",
"@types/node": "^10.17.21",
"@types/jsonwebtoken": "^8.5.2",
"@types/lodash": "^4.14.170",
"@types/node": "^10.17.60",
"eslint": "^5.16.0",
"eslint-config-oclif": "^3.1.0",
"eslint-config-oclif-typescript": "^0.1.0",
"globby": "^10.0.2",
"typescript": "^3.8.3",
"ts-node": "^8.10.1",
"@types/lodash": "^4.14.152"
"ts-node": "^8.10.2",
"tslib": "^1.11.1",
"typescript": "^3.9.10"
},
"engines": {
"node": ">=8.0.0"
Expand Down
89 changes: 78 additions & 11 deletions src/commands/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { Config } from "@krane/common";
import { Config, DeploymentEvent, KraneClient } from "@krane/common";
import { flags } from "@oclif/command";
import cli from "cli-ux";
import * as fs from "fs";
import * as path from "path";
import * as util from "util";
import BaseCommand from "../base";



const readFile = util.promisify(fs.readFile);

export default class Deploy extends BaseCommand {
static description = `Create or re-run a deployment
Check out https://www.krane.sh/#/docs/deployment for additional documentation`;
Expand All @@ -25,18 +23,14 @@ export default class Deploy extends BaseCommand {
const { flags } = this.parse(Deploy);

const config = await this.loadDeploymentConfig(flags.file);

if (config.scale == null) {
config.scale = 1;
}

const client = await this.getKraneClient();

try {
await this.subscribeToDeploymentEvents(config, client);
await client.saveDeployment(config);
await client.runDeployment(config.name);
} catch (e) {
this.error(e?.response?.data ?? "Unable run deployment");
this.error(`Unable to deploy ${e?.response?.data || e?.message}`);
}
}

Expand All @@ -47,6 +41,79 @@ export default class Deploy extends BaseCommand {
}

const contents = await readFile(pathToConfig);
return JSON.parse(contents.toString()) as Config;
const config = JSON.parse(contents.toString()) as Config;

if (config.scale == null) {
config.scale = 1;
}

return config;
}

private async subscribeToDeploymentEvents(
config: Config,
client: KraneClient
): Promise<void> {
return new Promise((resolve, reject) => {
client.subscribeToDeploymentEvents({
deployment: config.name,
onListening: resolve,
onError: reject,
eventHandlers: {
DEPLOYMENT_SETUP: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
PULL_IMAGE: (event: DeploymentEvent) => {
// Skip displaying docker pull image
// metadata events since they are VERY noisy.
if (event.message.startsWith("{")) return;
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
CONTAINER_CREATE: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
CONTAINER_START: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
DEPLOYMENT_HEALTHCHECK: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
DEPLOYMENT_CLEANUP: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
DEPLOYMENT_DONE: (event: DeploymentEvent, stopListening) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
cli.action.stop();

const deploymentURLs = config.alias
?.map((url) =>
config.secure ? `https://${url}` : `http://${url}`
)
.join("\n🔗 ") ?? [
"Visit https://krane.sh to learn how to configure a deployment alias",
];
this.log(
`\n✅ \`${config.name}\` was succesfully deployed!\n🔗 ${deploymentURLs}
\nTo view the status of \`${config.name}\` run:\n$ krane status ${config.name}`
);
stopListening();
},
DEPLOYMENT_ERROR: (event: DeploymentEvent, stopListening) => {
cli.action.stop();
this.log(
`\n❌ Failed to deploy \`${config.name}\`:\n${event.message}\n`
);
stopListening();
},
},
});
});
}
}
95 changes: 80 additions & 15 deletions src/commands/edit.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import * as path from "path";
import {
Config,
Deployment,
DeploymentEvent,
KraneClient,
} from "@krane/common";
import { flags } from "@oclif/command";
import { spawn, SpawnOptions } from "child_process";
import { cli } from "cli-ux";
import * as fs from "fs";

import { promisify } from "util";
import { isEqual } from "lodash";
import { spawn, SpawnOptions } from "child_process";

import { flags } from "@oclif/command";
import { Config, Deployment } from "@krane/common";

import * as path from "path";
import { promisify } from "util";
import BaseCommand from "../base";

const readFile = promisify(fs.readFile);
Expand Down Expand Up @@ -66,16 +69,22 @@ export default class Edit extends BaseCommand {
return;
}

this.log(
"Deployment configuration updated. Triggering new deployment run."
);

await client.saveDeployment(parsedConfig);
await client.runDeployment(parsedConfig.name);
this.log("→ Deployment configuration updated... done");
this.log("→ Triggering new deployment... done");

try {
await client.saveDeployment(parsedConfig);
await this.subscribeToDeploymentEvents(parsedConfig, client);
await client.runDeployment(parsedConfig.name);
} catch (e) {
this.error(
`Unable to edit deployment ${e?.response?.data || e?.message}`
);
}

if (flags.output) {
await this.save(parsedConfig, flags.output);
this.log(`Updated deployment configuration save to ${flags.output}`);
this.log(`→ Configuration saved to "${flags.output}"`);
}
});
}
Expand All @@ -93,4 +102,60 @@ export default class Edit extends BaseCommand {
await writeFile(filepath, serialized, "utf8");
return filepath;
}

private async subscribeToDeploymentEvents(
config: Config,
client: KraneClient
): Promise<void> {
return new Promise((resolve, reject) => {
client.subscribeToDeploymentEvents({
deployment: config.name,
onListening: resolve,
onError: reject,
eventHandlers: {
DEPLOYMENT_SETUP: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
PULL_IMAGE: (event: DeploymentEvent) => {
// Skip displaying docker pull image
// metadata events since they are VERY noisy.
if (event.message.startsWith("{")) return;
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
CONTAINER_CREATE: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
CONTAINER_START: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
DEPLOYMENT_HEALTHCHECK: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
DEPLOYMENT_CLEANUP: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
DEPLOYMENT_DONE: (event: DeploymentEvent, stopListening) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
cli.action.stop();
this.log(`\n✅ \`${config.name}\` was succesfully updated.`);
stopListening();
},
DEPLOYMENT_ERROR: (event: DeploymentEvent, stopListening) => {
cli.action.stop();
this.log(
`\n❌ Failed to deploy \`${config.name}\`:\n${event.message}\n`
);
stopListening();
},
},
});
});
}
}
42 changes: 40 additions & 2 deletions src/commands/remove.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DeploymentEvent, KraneClient } from "@krane/common";
import cli from "cli-ux";
import BaseCommand from "../base";

export default class Remove extends BaseCommand {
static description = "Remove a deployment and its resources";

Expand All @@ -19,9 +20,46 @@ export default class Remove extends BaseCommand {
const client = await this.getKraneClient();

try {
await this.subscribeToDeploymentEvents(args.deployment, client);
await client.deleteDeployment(args.deployment);
} catch (e) {
this.error(e?.response?.data ?? "Unable delete deployment");
this.error(`Unable to delete ${e?.response?.data || e?.message}`);
}
}

private async subscribeToDeploymentEvents(
deploymentName: string,
client: KraneClient
): Promise<void> {
return new Promise((resolve, reject) => {
client.subscribeToDeploymentEvents({
deployment: deploymentName,
onListening: resolve,
onError: reject,
eventHandlers: {
CONTAINER_REMOVE: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
DEPLOYMENT_CLEANUP: (event: DeploymentEvent) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
},
DEPLOYMENT_DONE: (event: DeploymentEvent, stopListening) => {
cli.action.stop();
cli.action.start(`→ ${event.message}`);
cli.action.stop();
stopListening();
},
DEPLOYMENT_ERROR: (event: DeploymentEvent, stopListening) => {
cli.action.stop();
this.log(
`\n❌ Failed to remove \`${deploymentName}\`:\n${event.message}\n`
);
stopListening();
},
},
});
});
}
}
Loading