@toa.io/cli 1.0.0-alpha.18 → 1.0.0-alpha.189
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/package.json +9 -8
- package/readme.md +20 -3
- package/src/commands/deploy.js +6 -0
- package/src/commands/export/manifest.js +6 -0
- package/src/commands/export/secrets.js +23 -0
- package/src/commands/export/tags.js +23 -0
- package/src/commands/limits.js +7 -0
- package/src/handlers/compose.js +3 -0
- package/src/handlers/deploy.js +1 -0
- package/src/handlers/export/deployment.js +0 -1
- package/src/handlers/export/images.js +0 -1
- package/src/handlers/export/manifest.js +5 -2
- package/src/handlers/export/secrets.js +40 -0
- package/src/handlers/export/tags.js +20 -0
- package/src/handlers/lib/graceful.js +16 -0
- package/src/handlers/limits.js +19 -0
- package/src/handlers/serve.js +3 -3
- package/src/program.js +3 -3
- package/types/deploy.d.ts +8 -7
- package/src/commands/export/entity.js +0 -26
- package/src/handlers/export/entity.js +0 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/cli",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.189",
|
|
4
4
|
"description": "Toa CLI",
|
|
5
5
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -22,16 +22,17 @@
|
|
|
22
22
|
"@toa.io/runtime": "*"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@toa.io/
|
|
26
|
-
"@toa.io/
|
|
27
|
-
"@toa.io/
|
|
28
|
-
"@toa.io/
|
|
29
|
-
"@toa.io/
|
|
30
|
-
"@toa.io/yaml": "1.0.0-alpha.18",
|
|
25
|
+
"@toa.io/generic": "1.0.0-alpha.173",
|
|
26
|
+
"@toa.io/kubernetes": "1.0.0-alpha.63",
|
|
27
|
+
"@toa.io/norm": "1.0.0-alpha.182",
|
|
28
|
+
"@toa.io/operations": "1.0.0-alpha.189",
|
|
29
|
+
"@toa.io/yaml": "1.0.0-alpha.182",
|
|
31
30
|
"dotenv": "16.1.1",
|
|
32
31
|
"find-up": "5.0.0",
|
|
32
|
+
"jsonpath": "1.1.1",
|
|
33
|
+
"openspan": "1.0.0-alpha.173",
|
|
33
34
|
"paseto": "3.1.4",
|
|
34
35
|
"yargs": "17.6.2"
|
|
35
36
|
},
|
|
36
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "05962df02addd3a03d9215eb3f7c9c0d6570a714"
|
|
37
38
|
}
|
package/readme.md
CHANGED
|
@@ -66,15 +66,32 @@ Credentials specified in the output file are preserved.
|
|
|
66
66
|
<dt><code>toa export manifest</code></dt>
|
|
67
67
|
<dd>Print normalized manifest.
|
|
68
68
|
|
|
69
|
-
<code>--path</code> path to component (default <code>.</code>)<br/>
|
|
69
|
+
<code>--path</code> path to a component (default <code>.</code>)<br/>
|
|
70
|
+
<code>--jsonpath</code> JSONPath expression to filter the output<br/>
|
|
70
71
|
<code>--error</code> print errors only<br/>
|
|
71
72
|
<code>--output</code> output format (default <code>yaml</code>)
|
|
72
73
|
</dd>
|
|
73
74
|
</dl>
|
|
74
75
|
|
|
75
|
-
### export
|
|
76
|
+
### export secrets
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
<dl>
|
|
79
|
+
<dt><code>toa export secrets <environment></code></dt>
|
|
80
|
+
<dd>Print deployment secrets.
|
|
81
|
+
|
|
82
|
+
<code>--path</code> path to context (default <code>.</code>)<br/>
|
|
83
|
+
</dd>
|
|
84
|
+
</dl>
|
|
85
|
+
|
|
86
|
+
### export image tags
|
|
87
|
+
|
|
88
|
+
<dl>
|
|
89
|
+
<dt><code>toa export tags <environment></code></dt>
|
|
90
|
+
<dd>Print image tags.
|
|
91
|
+
|
|
92
|
+
<code>--path</code> path to context (default <code>.</code>)<br/>
|
|
93
|
+
</dd>
|
|
94
|
+
</dl>
|
|
78
95
|
|
|
79
96
|
## Operations
|
|
80
97
|
|
package/src/commands/deploy.js
CHANGED
|
@@ -34,6 +34,12 @@ const builder = (yargs) => {
|
|
|
34
34
|
boolean: true,
|
|
35
35
|
desc: 'Wait for deployment ready state'
|
|
36
36
|
})
|
|
37
|
+
.option('timeout', {
|
|
38
|
+
alias: 't',
|
|
39
|
+
group: 'Command options:',
|
|
40
|
+
type: 'string',
|
|
41
|
+
desc: 'Deployment timeout'
|
|
42
|
+
})
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
exports.command = 'deploy [environment]'
|
|
@@ -17,6 +17,12 @@ const builder = (yargs) => {
|
|
|
17
17
|
desc: 'Path to a component',
|
|
18
18
|
default: '.'
|
|
19
19
|
})
|
|
20
|
+
.option('jsonpath', {
|
|
21
|
+
alias: 'j',
|
|
22
|
+
group: 'Command options:',
|
|
23
|
+
type: 'string',
|
|
24
|
+
desc: 'JSONPath expression'
|
|
25
|
+
})
|
|
20
26
|
.option('output', {
|
|
21
27
|
alias: 'o',
|
|
22
28
|
group: 'Command options:',
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { secrets } = require('../../handlers/export/secrets')
|
|
4
|
+
|
|
5
|
+
const builder = (yargs) => {
|
|
6
|
+
yargs
|
|
7
|
+
.positional('environment', {
|
|
8
|
+
type: 'string',
|
|
9
|
+
desc: 'Deployment environment'
|
|
10
|
+
})
|
|
11
|
+
.option('path', {
|
|
12
|
+
alias: 'p',
|
|
13
|
+
group: 'Command options:',
|
|
14
|
+
type: 'string',
|
|
15
|
+
desc: 'Path to context',
|
|
16
|
+
default: '.'
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.command = ['secrets <environment>']
|
|
21
|
+
exports.desc = 'Export deployment secrets'
|
|
22
|
+
exports.builder = builder
|
|
23
|
+
exports.handler = secrets
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { tags } = require('../../handlers/export/tags')
|
|
4
|
+
|
|
5
|
+
const builder = (yargs) => {
|
|
6
|
+
yargs
|
|
7
|
+
.positional('environment', {
|
|
8
|
+
type: 'string',
|
|
9
|
+
desc: 'Deployment environment'
|
|
10
|
+
})
|
|
11
|
+
.option('path', {
|
|
12
|
+
alias: 'p',
|
|
13
|
+
group: 'Command options:',
|
|
14
|
+
type: 'string',
|
|
15
|
+
desc: 'Path to context',
|
|
16
|
+
default: '.'
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.command = ['tags <environment>']
|
|
21
|
+
exports.desc = 'Export image tags'
|
|
22
|
+
exports.builder = builder
|
|
23
|
+
exports.handler = tags
|
package/src/handlers/compose.js
CHANGED
|
@@ -5,6 +5,7 @@ const boot = require('@toa.io/boot')
|
|
|
5
5
|
const { version } = require('@toa.io/runtime')
|
|
6
6
|
|
|
7
7
|
const docker = require('./docker')
|
|
8
|
+
const { graceful } = require('./lib/graceful')
|
|
8
9
|
const { components: find } = require('../util/find')
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -19,6 +20,8 @@ async function compose (argv) {
|
|
|
19
20
|
const paths = find(argv.paths)
|
|
20
21
|
const composition = await boot.composition(paths, argv)
|
|
21
22
|
|
|
23
|
+
graceful(composition)
|
|
24
|
+
|
|
22
25
|
await composition.connect()
|
|
23
26
|
|
|
24
27
|
if (argv.kill === true) await composition.disconnect()
|
package/src/handlers/deploy.js
CHANGED
|
@@ -25,6 +25,7 @@ const deploy = async (argv) => {
|
|
|
25
25
|
|
|
26
26
|
if (argv.namespace !== undefined) options.namespace = argv.namespace
|
|
27
27
|
if (argv.wait === true) options.wait = true
|
|
28
|
+
if (argv.timeout !== undefined) options.timeout = argv.timeout
|
|
28
29
|
|
|
29
30
|
await operator.install(options)
|
|
30
31
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const jsonpath = require('jsonpath')
|
|
3
4
|
const { component } = require('@toa.io/norm')
|
|
4
|
-
const { console } = require('@toa.io/console')
|
|
5
5
|
const yaml = require('@toa.io/yaml')
|
|
6
6
|
|
|
7
7
|
const { components: find } = require('../../util/find')
|
|
@@ -11,7 +11,10 @@ const print = async (argv) => {
|
|
|
11
11
|
|
|
12
12
|
if (path === undefined) throw new Error(`No component found in ${argv.path}`)
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
let manifest = await component(path)
|
|
15
|
+
|
|
16
|
+
if (argv.jsonpath !== undefined)
|
|
17
|
+
manifest = jsonpath.value(manifest, argv.jsonpath)
|
|
15
18
|
|
|
16
19
|
if (argv.error !== true) {
|
|
17
20
|
const result = argv.output === 'json'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { context: find } = require('../../util/find')
|
|
4
|
+
const { deployment: { Factory } } = require('@toa.io/operations')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {{ path: string, target: string, environment: string }} argv
|
|
8
|
+
* @returns {Promise<void>}
|
|
9
|
+
*/
|
|
10
|
+
const secrets = async (argv) => {
|
|
11
|
+
const path = find(argv.path)
|
|
12
|
+
const factory = await Factory.create(path, argv.environment)
|
|
13
|
+
const operator = factory.operator()
|
|
14
|
+
const secrets = operator
|
|
15
|
+
.variables()
|
|
16
|
+
.filter(({ secret }) => secret !== undefined)
|
|
17
|
+
.map(({ secret }) => secret)
|
|
18
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
19
|
+
|
|
20
|
+
const groups = []
|
|
21
|
+
let current = null
|
|
22
|
+
|
|
23
|
+
for (const secret of secrets) {
|
|
24
|
+
if (current === null || current.name !== secret.name) {
|
|
25
|
+
current = { name: secret.name, keys: new Map() }
|
|
26
|
+
groups.push(current)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
current.keys.set(secret.key, secret.optional)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for (const group of groups) {
|
|
33
|
+
console.log(`${group.name}:`)
|
|
34
|
+
|
|
35
|
+
for (const [key, optional] of group.keys)
|
|
36
|
+
console.log(' ' + key + (optional ? ' (optional)' : ''))
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
exports.secrets = secrets
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { context: find } = require('../../util/find')
|
|
4
|
+
const { deployment: { Factory } } = require('@toa.io/operations')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {{ path: string, target: string, environment: string }} argv
|
|
8
|
+
* @returns {Promise<void>}
|
|
9
|
+
*/
|
|
10
|
+
const tags = async (argv) => {
|
|
11
|
+
const path = find(argv.path)
|
|
12
|
+
const factory = await Factory.create(path, argv.environment)
|
|
13
|
+
const operator = factory.operator()
|
|
14
|
+
const tags = operator.tags()
|
|
15
|
+
|
|
16
|
+
for (const tag of tags)
|
|
17
|
+
console.log(tag)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.tags = tags
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { console } = require('openspan')
|
|
4
|
+
|
|
5
|
+
function graceful (connector) {
|
|
6
|
+
['SIGTERM', 'SIGINT']
|
|
7
|
+
.forEach(signal => process.once(signal, async () => {
|
|
8
|
+
console.info('Shutting down', { signal })
|
|
9
|
+
|
|
10
|
+
await connector.disconnect(true)
|
|
11
|
+
|
|
12
|
+
process.exit(0)
|
|
13
|
+
}))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.graceful = graceful
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
kubectl get pods -o=custom-columns='NAME:.metadata.name,CPU_REQUEST:.spec.containers[*].resources.requests.cpu,CPU_LIMIT:.spec.containers[*].resources.limits.cpu,MEM_REQUEST:.spec.containers[*].resources.requests.memory,MEM_LIMIT:.spec.containers[*].resources.limits.memory'
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { spawn } = require('node:child_process')
|
|
8
|
+
|
|
9
|
+
const limits = async (argv) => {
|
|
10
|
+
const args = [
|
|
11
|
+
'get',
|
|
12
|
+
'pods',
|
|
13
|
+
'-o=custom-columns=NAME:.metadata.name,CPU:.spec.containers[*].resources.requests.cpu,:.spec.containers[*].resources.limits.cpu,MEM:.spec.containers[*].resources.requests.memory,:.spec.containers[*].resources.limits.memory'
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
await spawn('kubectl', args, { stdio: 'inherit' })
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
exports.limits = limits
|
package/src/handlers/serve.js
CHANGED
|
@@ -4,6 +4,7 @@ const boot = require('@toa.io/boot')
|
|
|
4
4
|
const { shortcuts } = require('@toa.io/norm')
|
|
5
5
|
const { directory: { find } } = require('@toa.io/filesystem')
|
|
6
6
|
const { version } = require('@toa.io/runtime')
|
|
7
|
+
const { graceful } = require('./lib/graceful')
|
|
7
8
|
|
|
8
9
|
const serve = async (argv) => {
|
|
9
10
|
console.log('Runtime', version)
|
|
@@ -20,10 +21,9 @@ const serve = async (argv) => {
|
|
|
20
21
|
|
|
21
22
|
const service = factory.service()
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
graceful(service)
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
return service
|
|
26
|
+
await service.connect()
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
exports.serve = serve
|
package/src/program.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
const yargs = require('yargs/yargs')
|
|
6
6
|
|
|
7
|
-
const { console } = require('@toa.io/console')
|
|
8
7
|
const { version } = require('@toa.io/runtime')
|
|
9
8
|
|
|
10
9
|
yargs(process.argv.slice(2))
|
|
@@ -13,8 +12,6 @@ yargs(process.argv.slice(2))
|
|
|
13
12
|
})
|
|
14
13
|
.middleware((argv) => {
|
|
15
14
|
if (argv.log === undefined) argv.log = process.env.TOA_DEBUG === '1' ? 'debug' : 'info'
|
|
16
|
-
|
|
17
|
-
console.level(argv.log)
|
|
18
15
|
})
|
|
19
16
|
.middleware(async (argv) => {
|
|
20
17
|
if (argv.env === undefined) return
|
|
@@ -31,6 +28,9 @@ yargs(process.argv.slice(2))
|
|
|
31
28
|
.option('log', {
|
|
32
29
|
describe: 'Log level'
|
|
33
30
|
})
|
|
31
|
+
.option('wtf', {
|
|
32
|
+
describe: 'Enable wtf'
|
|
33
|
+
})
|
|
34
34
|
.option('env', {
|
|
35
35
|
type: 'string',
|
|
36
36
|
describe: 'Path to environment variables file (.env format)'
|
package/types/deploy.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
declare namespace toa.cli.deploy {
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
interface Arguments {
|
|
4
|
+
path: string
|
|
5
|
+
environment?: string
|
|
6
|
+
namespace?: string
|
|
7
|
+
dry: boolean
|
|
8
|
+
wait: boolean
|
|
9
|
+
timeout: string
|
|
10
|
+
}
|
|
10
11
|
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { manifest } = require('../../handlers/export/entity')
|
|
4
|
-
|
|
5
|
-
const builder = (yargs) => {
|
|
6
|
-
yargs
|
|
7
|
-
.option('path', {
|
|
8
|
-
alias: 'p',
|
|
9
|
-
group: 'Command options:',
|
|
10
|
-
type: 'string',
|
|
11
|
-
desc: 'Path to a component',
|
|
12
|
-
default: '.'
|
|
13
|
-
})
|
|
14
|
-
.option('output', {
|
|
15
|
-
alias: 'o',
|
|
16
|
-
group: 'Command options:',
|
|
17
|
-
choices: ['yaml', 'json'],
|
|
18
|
-
desc: 'Output format',
|
|
19
|
-
default: 'yaml'
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
exports.command = 'entity'
|
|
24
|
-
exports.desc = 'Print entity'
|
|
25
|
-
exports.builder = builder
|
|
26
|
-
exports.handler = manifest
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { component } = require('@toa.io/norm')
|
|
4
|
-
const { console } = require('@toa.io/console')
|
|
5
|
-
const yaml = require('@toa.io/yaml')
|
|
6
|
-
|
|
7
|
-
const { components: find } = require('../../util/find')
|
|
8
|
-
|
|
9
|
-
const print = async (argv) => {
|
|
10
|
-
const path = find(argv.path)
|
|
11
|
-
|
|
12
|
-
if (path === undefined) throw new Error(`No component found in ${argv.path}`)
|
|
13
|
-
|
|
14
|
-
const manifest = await component(path)
|
|
15
|
-
const entity = manifest.entity
|
|
16
|
-
|
|
17
|
-
if (entity === undefined)
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
const result = argv.output === 'json'
|
|
21
|
-
? JSON.stringify(entity, null, 2)
|
|
22
|
-
: yaml.dump(entity)
|
|
23
|
-
|
|
24
|
-
console.log(result)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
exports.manifest = print
|