@agilecustoms/envctl 1.9.0 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/HttpClient.js +9 -7
- package/dist/commands/_keys.js +0 -1
- package/dist/commands/configure.js +14 -15
- package/dist/commands/createEphemeral.js +7 -8
- package/dist/commands/delete.js +6 -10
- package/dist/commands/deploy.js +5 -10
- package/dist/commands/destroy.js +6 -10
- package/dist/commands/logs.js +5 -10
- package/dist/commands/plan.js +5 -10
- package/dist/commands/status.js +6 -10
- package/dist/container.js +14 -12
- package/dist/index.js +14 -12
- package/package.json +22 -22
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
1
|
import { BusinessException, HttpException, NotFoundException } from '../exceptions.js';
|
|
3
2
|
import { logger } from '../logger.js';
|
|
4
3
|
const HOST = 'cli.maintenance.agilecustoms.com';
|
|
@@ -6,8 +5,12 @@ export function toUrl(path) {
|
|
|
6
5
|
return `https://${HOST}/env-api${path}`;
|
|
7
6
|
}
|
|
8
7
|
export class HttpClient {
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
version;
|
|
9
|
+
commandId;
|
|
10
|
+
constructor(version, commandId) {
|
|
11
|
+
this.version = version;
|
|
12
|
+
this.commandId = commandId;
|
|
13
|
+
}
|
|
11
14
|
async post(path, body, options = {}) {
|
|
12
15
|
options.method = 'POST';
|
|
13
16
|
if (body) {
|
|
@@ -24,15 +27,14 @@ export class HttpClient {
|
|
|
24
27
|
const url = toUrl(path);
|
|
25
28
|
const headers = new Headers(options.headers);
|
|
26
29
|
headers.set('x-command-id', this.commandId);
|
|
30
|
+
headers.set('x-client-version', this.version);
|
|
27
31
|
const req = {
|
|
28
32
|
...options,
|
|
29
33
|
method: options.method ?? 'GET',
|
|
30
34
|
headers,
|
|
31
35
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
headers: Object.fromEntries(headers.entries()),
|
|
35
|
-
})}`);
|
|
36
|
+
const reqJson = JSON.stringify({ ...req, headers: Object.fromEntries(headers.entries()) });
|
|
37
|
+
logger.debug(`--> ${req.method} ${url} ${reqJson}`);
|
|
36
38
|
let response;
|
|
37
39
|
try {
|
|
38
40
|
response = await fetch(url, options);
|
package/dist/commands/_keys.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export const _keys = {
|
|
2
|
-
CWD: 'Working directory (default: current directory)',
|
|
3
2
|
FORCE: 'Force deletion without confirmation',
|
|
4
3
|
KEY: 'Environment name/identifier - taken from remote stake key, must be unique for a given customer',
|
|
5
4
|
KIND: 'Environment kind: complete project (default) or some slice such as tt-core + tt-web',
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import inquirer from 'inquirer';
|
|
3
|
-
import {
|
|
3
|
+
import { ConfigService } from '../service/index.js';
|
|
4
4
|
import { _keys } from './_keys.js';
|
|
5
5
|
import { wrap } from './_utils.js';
|
|
6
|
-
export function configure(program) {
|
|
6
|
+
export function configure(program, configService) {
|
|
7
7
|
program
|
|
8
8
|
.command('configure')
|
|
9
9
|
.description('Configure user settings on your local machine')
|
|
10
10
|
.option('-v, --verbose', _keys.VERBOSE)
|
|
11
|
-
.action(wrap(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
configService.saveConfig({ userName: answers.userName });
|
|
11
|
+
.action(wrap(async () => {
|
|
12
|
+
const answers = await inquirer.prompt([
|
|
13
|
+
{
|
|
14
|
+
type: 'input',
|
|
15
|
+
name: 'userName',
|
|
16
|
+
message: 'userName is required to deploy any env\n'
|
|
17
|
+
+ '(prefer GitHub username)\n'
|
|
18
|
+
+ 'userName:',
|
|
19
|
+
},
|
|
20
|
+
]);
|
|
21
|
+
configService.saveConfig({ userName: answers.userName });
|
|
22
|
+
}));
|
|
24
23
|
}
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import { EnvService } from '../service/index.js';
|
|
3
3
|
import { _keys } from './_keys.js';
|
|
4
4
|
import { wrap } from './_utils.js';
|
|
5
|
-
export function createEphemeral(program) {
|
|
5
|
+
export function createEphemeral(program, envService) {
|
|
6
6
|
program
|
|
7
7
|
.command('create-ephemeral')
|
|
8
8
|
.description('Create bare env w/o resources. Used in CI as first step just to pre-generate token for extension')
|
|
9
9
|
.requiredOption('--key <key>', _keys.KEY)
|
|
10
10
|
.option('-v, --verbose', _keys.VERBOSE)
|
|
11
|
-
.action(wrap(
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
console.log(token);
|
|
11
|
+
.action(wrap(async (options) => {
|
|
12
|
+
const { key } = options;
|
|
13
|
+
const token = await envService.createEphemeral(key);
|
|
14
|
+
console.log(token);
|
|
15
|
+
}));
|
|
17
16
|
}
|
package/dist/commands/delete.js
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import { EnvService } from '../service/index.js';
|
|
3
3
|
import { _keys } from './_keys.js';
|
|
4
4
|
import { wrap } from './_utils.js';
|
|
5
|
-
export function deleteIt(program) {
|
|
5
|
+
export function deleteIt(program, envService) {
|
|
6
6
|
program
|
|
7
7
|
.command('delete')
|
|
8
8
|
.description('Delete a development environment')
|
|
9
9
|
.option('--key <key>', _keys.KEY)
|
|
10
10
|
.option('--force', _keys.FORCE)
|
|
11
|
-
.option('--cwd <cwd>', _keys.CWD)
|
|
12
11
|
.option('-v, --verbose', _keys.VERBOSE)
|
|
13
|
-
.action(wrap(
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (cwd)
|
|
18
|
-
process.chdir(cwd);
|
|
19
|
-
await envService.delete(Boolean(force), key);
|
|
12
|
+
.action(wrap(async (options) => {
|
|
13
|
+
const { key, force } = options;
|
|
14
|
+
await envService.delete(Boolean(force), key);
|
|
15
|
+
}));
|
|
20
16
|
}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import { EnvService } from '../service/index.js';
|
|
3
3
|
import { _keys } from './_keys.js';
|
|
4
4
|
import { wrap } from './_utils.js';
|
|
5
|
-
export function deploy(program) {
|
|
5
|
+
export function deploy(program, envService) {
|
|
6
6
|
program
|
|
7
7
|
.command('deploy')
|
|
8
8
|
.description('Create new or update existing environment')
|
|
9
|
-
.option('--cwd <cwd>', _keys.CWD)
|
|
10
9
|
.option('-v, --verbose', _keys.VERBOSE)
|
|
11
10
|
.allowUnknownOption(true)
|
|
12
11
|
.argument('[args...]')
|
|
13
|
-
.action(wrap(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const { cwd } = options;
|
|
17
|
-
if (cwd)
|
|
18
|
-
process.chdir(cwd);
|
|
19
|
-
await envService.deploy(tfArgs);
|
|
12
|
+
.action(wrap(async (tfArgs) => {
|
|
13
|
+
await envService.deploy(tfArgs);
|
|
14
|
+
}));
|
|
20
15
|
}
|
package/dist/commands/destroy.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import { EnvService } from '../service/index.js';
|
|
3
3
|
import { _keys } from './_keys.js';
|
|
4
4
|
import { wrap } from './_utils.js';
|
|
5
|
-
export function destroy(program) {
|
|
5
|
+
export function destroy(program, envService) {
|
|
6
6
|
program
|
|
7
7
|
.command('destroy')
|
|
8
8
|
.description('Destroy environment resources. This is thin wrapper for terraform destroy.'
|
|
@@ -10,15 +10,11 @@ export function destroy(program) {
|
|
|
10
10
|
+ ' Unlike "delete" command, this command doesn\'t have --key option, it can only delete env after key you provided during terraform init.'
|
|
11
11
|
+ ' Main use case - test deletion process, basically that you have enough permissions to delete resources')
|
|
12
12
|
.option('--force', _keys.FORCE)
|
|
13
|
-
.option('--cwd <cwd>', _keys.CWD)
|
|
14
13
|
.option('-v, --verbose', _keys.VERBOSE)
|
|
15
14
|
.allowUnknownOption(true)
|
|
16
15
|
.argument('[args...]')
|
|
17
|
-
.action(wrap(
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (cwd)
|
|
22
|
-
process.chdir(cwd);
|
|
23
|
-
await envService.destroy(tfArgs, Boolean(force));
|
|
16
|
+
.action(wrap(async (tfArgs, options) => {
|
|
17
|
+
const { force } = options;
|
|
18
|
+
await envService.destroy(tfArgs, Boolean(force));
|
|
19
|
+
}));
|
|
24
20
|
}
|
package/dist/commands/logs.js
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { logService } from '../container.js';
|
|
3
2
|
import { _keys } from './_keys.js';
|
|
4
3
|
import { wrap } from './_utils.js';
|
|
5
|
-
export function logs(program) {
|
|
4
|
+
export function logs(program, logService) {
|
|
6
5
|
program
|
|
7
6
|
.command('logs')
|
|
8
7
|
.description('Get most recent env destroy logs')
|
|
9
8
|
.option('--key <key>', _keys.KEY)
|
|
10
|
-
.option('--cwd <cwd>', _keys.CWD)
|
|
11
9
|
.option('-v, --verbose', _keys.VERBOSE)
|
|
12
|
-
.action(wrap(
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (cwd)
|
|
17
|
-
process.chdir(cwd);
|
|
18
|
-
await logService.getLogs(key);
|
|
10
|
+
.action(wrap(async (options) => {
|
|
11
|
+
const { key } = options;
|
|
12
|
+
await logService.getLogs(key);
|
|
13
|
+
}));
|
|
19
14
|
}
|
package/dist/commands/plan.js
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import { EnvService } from '../service/index.js';
|
|
3
3
|
import { _keys } from './_keys.js';
|
|
4
4
|
import { wrap } from './_utils.js';
|
|
5
|
-
export function plan(program) {
|
|
5
|
+
export function plan(program, envService) {
|
|
6
6
|
program
|
|
7
7
|
.command('plan')
|
|
8
8
|
.description('High level wrapper for terraform plan. Compliments deploy command: if you plan to deploy env with envctl deploy,'
|
|
9
9
|
+ ' then it is recommended to do plan with envctl plan to guarantee consistent behavior')
|
|
10
|
-
.option('--cwd <cwd>', _keys.CWD)
|
|
11
10
|
.option('-v, --verbose', _keys.VERBOSE)
|
|
12
11
|
.allowUnknownOption(true)
|
|
13
12
|
.argument('[args...]')
|
|
14
|
-
.action(wrap(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const { cwd } = options;
|
|
18
|
-
if (cwd)
|
|
19
|
-
process.chdir(cwd);
|
|
20
|
-
await envService.plan(tfArgs);
|
|
13
|
+
.action(wrap(async (tfArgs) => {
|
|
14
|
+
await envService.plan(tfArgs);
|
|
15
|
+
}));
|
|
21
16
|
}
|
package/dist/commands/status.js
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import { EnvService } from '../service/index.js';
|
|
3
3
|
import { _keys } from './_keys.js';
|
|
4
4
|
import { wrap } from './_utils.js';
|
|
5
|
-
export function status(program) {
|
|
5
|
+
export function status(program, envService) {
|
|
6
6
|
program
|
|
7
7
|
.command('status')
|
|
8
8
|
.description('Get env status')
|
|
9
9
|
.option('--key <key>', _keys.KEY)
|
|
10
|
-
.option('--cwd <cwd>', _keys.CWD)
|
|
11
10
|
.option('-v, --verbose', _keys.VERBOSE)
|
|
12
|
-
.action(wrap(
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (cwd)
|
|
17
|
-
process.chdir(cwd);
|
|
18
|
-
await envService.status(key);
|
|
11
|
+
.action(wrap(async (options) => {
|
|
12
|
+
const { key } = options;
|
|
13
|
+
await envService.status(key);
|
|
14
|
+
}));
|
|
19
15
|
}
|
package/dist/container.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { S3Backend } from './backend/S3Backend.js';
|
|
2
3
|
import { Cli } from './client/Cli.js';
|
|
3
4
|
import { EnvApiClient, HttpClient } from './client/index.js';
|
|
4
5
|
import { ConfigService, EnvService, TerraformAdapter } from './service/index.js';
|
|
5
6
|
import { LocalStateService } from './service/LocalStateService.js';
|
|
6
7
|
import { LogService } from './service/LogService.js';
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
new S3Backend()
|
|
11
|
-
|
|
12
|
-
const httpClient = new HttpClient();
|
|
13
|
-
const envApiClient = new EnvApiClient(httpClient);
|
|
14
|
-
const localStateService = new LocalStateService();
|
|
15
|
-
const terraformAdapter = new TerraformAdapter(Date.now, cli, localStateService, backends);
|
|
16
|
-
const envService = new EnvService(cli, envApiClient, terraformAdapter);
|
|
17
|
-
const logService = new LogService(cli, envApiClient, terraformAdapter);
|
|
18
|
-
|
|
8
|
+
export function buildContainer(appVersion) {
|
|
9
|
+
const cli = new Cli();
|
|
10
|
+
const configService = new ConfigService();
|
|
11
|
+
const backends = [new S3Backend()];
|
|
12
|
+
const commandId = randomUUID();
|
|
13
|
+
const httpClient = new HttpClient(appVersion, commandId);
|
|
14
|
+
const envApiClient = new EnvApiClient(httpClient);
|
|
15
|
+
const localStateService = new LocalStateService();
|
|
16
|
+
const terraformAdapter = new TerraformAdapter(Date.now, cli, localStateService, backends);
|
|
17
|
+
const envService = new EnvService(cli, envApiClient, terraformAdapter);
|
|
18
|
+
const logService = new LogService(cli, envApiClient, terraformAdapter);
|
|
19
|
+
return { configService, envService, logService };
|
|
20
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -3,20 +3,22 @@ import { createRequire } from 'module';
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import updateNotifier from 'update-notifier';
|
|
5
5
|
import { configure, createEphemeral, deleteIt, deploy, destroy, logs, plan, status } from './commands/index.js';
|
|
6
|
+
import { buildContainer } from './container.js';
|
|
6
7
|
const require = createRequire(import.meta.url);
|
|
7
8
|
const pkg = require('../package.json');
|
|
8
9
|
updateNotifier({ pkg, updateCheckInterval: 0 }).notify();
|
|
10
|
+
if (process.env.TEST_CWD) {
|
|
11
|
+
process.chdir(process.env.TEST_CWD);
|
|
12
|
+
}
|
|
13
|
+
const { configService, envService, logService } = buildContainer(pkg.version);
|
|
9
14
|
const program = new Command();
|
|
10
|
-
program
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
logs(program);
|
|
20
|
-
plan(program);
|
|
21
|
-
status(program);
|
|
15
|
+
program.name('envctl').description('CLI to manage environments').version(pkg.version);
|
|
16
|
+
configure(program, configService);
|
|
17
|
+
createEphemeral(program, envService);
|
|
18
|
+
deleteIt(program, envService);
|
|
19
|
+
deploy(program, envService);
|
|
20
|
+
destroy(program, envService);
|
|
21
|
+
logs(program, logService);
|
|
22
|
+
plan(program, envService);
|
|
23
|
+
status(program, envService);
|
|
22
24
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agilecustoms/envctl",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "node.js CLI client for manage environments",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"terraform wrapper",
|
|
@@ -36,33 +36,33 @@
|
|
|
36
36
|
"lint:fix": "npm run lint -- --fix",
|
|
37
37
|
"test": "vitest run --coverage",
|
|
38
38
|
"build": "tsc -p tsconfig.build.json",
|
|
39
|
-
"
|
|
40
|
-
"run-help": " npm run
|
|
41
|
-
"run-version": " npm run
|
|
42
|
-
"run-configure": "npm run
|
|
39
|
+
"it": "tsc -p tsconfig.build.json --sourceMap true && TEST_CWD=\"$CWD\" node dist/index.js",
|
|
40
|
+
"run-help": " npm run it -- deploy --help",
|
|
41
|
+
"run-version": " npm run it -- --version",
|
|
42
|
+
"run-configure": "npm run it -- configure",
|
|
43
43
|
"~": "",
|
|
44
44
|
"run-core-init": " cd ../tt-core && terraform init -upgrade -backend-config=key=laxa1986 -reconfigure",
|
|
45
|
-
"run-core-status": " npm run
|
|
46
|
-
"run-core-plan": " npm run
|
|
47
|
-
"run-core-deployp": "npm run
|
|
48
|
-
"run-core-deploy": " npm run
|
|
49
|
-
"run-core-delete": " npm run
|
|
50
|
-
"run-core-destroy": "npm run
|
|
51
|
-
"run-core-logs": " npm run
|
|
45
|
+
"run-core-status": " CWD=../tt-core npm run it -- status -v",
|
|
46
|
+
"run-core-plan": " CWD=../tt-core npm run it -- plan -out=.terraform/plan",
|
|
47
|
+
"run-core-deployp": "CWD=../tt-core npm run it -- deploy .terraform/plan",
|
|
48
|
+
"run-core-deploy": " CWD=../tt-core npm run it -- deploy -var=\"env_size=min\"",
|
|
49
|
+
"run-core-delete": " CWD=../tt-core npm run it -- delete",
|
|
50
|
+
"run-core-destroy": "CWD=../tt-core npm run it -- destroy",
|
|
51
|
+
"run-core-logs": " CWD=../tt-core npm run it -- logs",
|
|
52
52
|
"*": "",
|
|
53
53
|
"run-init": "cd ../tt-gitops && terraform init -upgrade -backend-config=key=laxa1986 -reconfigure",
|
|
54
|
-
"run-status": " npm run
|
|
55
|
-
"run-plan": " AWS_PROFILE=ac-tt-dev-deployer npm run
|
|
56
|
-
"run-deploy": " AWS_PROFILE=ac-tt-dev-deployer npm run
|
|
57
|
-
"run-delete": " npm run
|
|
58
|
-
"run-destroy": "AWS_PROFILE=ac-tt-dev-destroyer npm run
|
|
54
|
+
"run-status": " CWD=../tt-gitops npm run it -- status",
|
|
55
|
+
"run-plan": " AWS_PROFILE=ac-tt-dev-deployer CWD=../tt-gitops npm run it -- plan -var=\"env_size=min\" -var-file=versions.tfvars",
|
|
56
|
+
"run-deploy": " AWS_PROFILE=ac-tt-dev-deployer CWD=../tt-gitops npm run it -- deploy -var=\"env_size=min\" -var-file=versions.tfvars",
|
|
57
|
+
"run-delete": " CWD=../tt-gitops npm run it -- delete",
|
|
58
|
+
"run-destroy": "AWS_PROFILE=ac-tt-dev-destroyer CWD=../tt-gitops npm run it -- destroy -var=\"env_size=min\" -var-file=versions.tfvars",
|
|
59
59
|
"-": "",
|
|
60
|
-
"run-ephemeral-create": " npm run
|
|
60
|
+
"run-ephemeral-create": " npm run it -- create-ephemeral --key test",
|
|
61
61
|
"run-ephemeral-init": "cd ../tt-gitops && terraform init -upgrade -backend-config=key=test -reconfigure",
|
|
62
|
-
"run-ephemeral-status": " npm run
|
|
63
|
-
"run-ephemeral-deploy": " npm run
|
|
64
|
-
"run-ephemeral-delete": " npm run
|
|
65
|
-
"run-ephemeral-destroy": "npm run
|
|
62
|
+
"run-ephemeral-status": " CWD=../tt-gitops npm run it -- status --key test",
|
|
63
|
+
"run-ephemeral-deploy": " CWD=../tt-gitops npm run it -- deploy -var-file=versions.tfvars",
|
|
64
|
+
"run-ephemeral-delete": " CWD=../tt-gitops npm run it -- delete --force",
|
|
65
|
+
"run-ephemeral-destroy": "CWD=../tt-gitops npm run it -- destroy --force -var-file=versions.tfvars"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
68
|
"commander": "^14.0.0",
|