@toa.io/operations 0.20.0-dev.8 → 0.20.0
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 +6 -5
- package/readme.md +14 -2
- package/src/deployment/.deployment/.describe/components.js +1 -0
- package/src/deployment/.deployment/.describe/compositions.js +11 -0
- package/src/deployment/.deployment/.describe/index.js +4 -0
- package/src/deployment/.deployment/.describe/services.js +11 -0
- package/src/deployment/.deployment/.describe/variables.js +13 -13
- package/src/deployment/.deployment/describe.js +9 -12
- package/src/deployment/.deployment/merge.js +0 -8
- package/src/deployment/chart/templates/compositions.yaml +7 -12
- package/src/deployment/chart/templates/services.yaml +10 -10
- package/src/deployment/chart/values.yaml +13 -13
- package/src/deployment/composition.js +0 -12
- package/src/deployment/deployment.js +28 -25
- package/src/deployment/factory.js +3 -29
- package/src/deployment/images/composition.Dockerfile +6 -5
- package/src/deployment/images/composition.js +1 -1
- package/src/deployment/images/image.js +2 -6
- package/src/deployment/images/image.test.js +1 -1
- package/src/deployment/images/service.Dockerfile +7 -5
- package/src/deployment/images/service.js +4 -1
- package/src/deployment/operator.js +0 -3
- package/src/deployment/service.js +2 -15
- package/types/_deployment/operator.d.ts +20 -0
- package/types/dependency.d.ts +29 -0
- package/types/index.d.ts +1 -0
- package/src/deployment/chart/templates/proxies.yaml +0 -10
- package/src/deployment/deployment.fixtures.js +0 -42
- package/src/deployment/deployment.test.js +0 -78
- package/types/deployment/operator.d.ts +0 -18
- package/types/process.d.ts +0 -13
- /package/types/{deployment → _deployment}/composition.d.ts +0 -0
- /package/types/{deployment → _deployment}/dependency.d.ts +0 -0
- /package/types/{deployment → _deployment}/deployment.d.ts +0 -0
- /package/types/{deployment → _deployment}/factory.d.ts +0 -0
- /package/types/{deployment → _deployment}/images/factory.d.ts +0 -0
- /package/types/{deployment → _deployment}/images/image.d.ts +0 -0
- /package/types/{deployment → _deployment}/images/registry.d.ts +0 -0
- /package/types/{deployment → _deployment}/registry.d.ts +0 -0
- /package/types/{deployment → _deployment}/service.d.ts +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/operations",
|
|
3
|
-
"version": "0.20.0
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Toa Deployment",
|
|
5
5
|
"homepage": "https://toa.io",
|
|
6
6
|
"author": {
|
|
@@ -22,14 +22,15 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"main": "src/index.js",
|
|
25
|
+
"types": "types/index.d.ts",
|
|
25
26
|
"scripts": {
|
|
26
27
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"@toa.io/filesystem": "0.20.0
|
|
30
|
-
"@toa.io/generic": "0.20.0
|
|
31
|
-
"@toa.io/yaml": "0.20.0
|
|
30
|
+
"@toa.io/filesystem": "0.20.0",
|
|
31
|
+
"@toa.io/generic": "0.20.0",
|
|
32
|
+
"@toa.io/yaml": "0.20.0",
|
|
32
33
|
"execa": "5.1.1"
|
|
33
34
|
},
|
|
34
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "28fc4b45c224c3683acaaf0e4abd1eb04e07b408"
|
|
35
36
|
}
|
package/readme.md
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
registry:
|
|
13
13
|
build:
|
|
14
|
-
arguments: [
|
|
15
|
-
run:
|
|
14
|
+
arguments: [GITHUB_TOKEN]
|
|
15
|
+
run: npm config set //npm.pkg.github.com/:_authToken ${GITHUB_TOKEN}
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
`arguments` is a list of environemt varialbes to be passed to `docker build`.
|
|
@@ -28,3 +28,15 @@ registry:
|
|
|
28
28
|
echo test > .test
|
|
29
29
|
rm .test
|
|
30
30
|
```
|
|
31
|
+
|
|
32
|
+
#### Registry Credentials
|
|
33
|
+
|
|
34
|
+
When using private container registry,
|
|
35
|
+
a secret containing required credentials can be specified using `registry.credentials` option.
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
# context.toa.yaml
|
|
39
|
+
|
|
40
|
+
registry:
|
|
41
|
+
credentials: docker-credentials-secret-name
|
|
42
|
+
```
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const { dependencies } = require('./dependencies')
|
|
4
4
|
const { components } = require('./components')
|
|
5
|
+
const { compositions } = require('./compositions')
|
|
5
6
|
const { variables } = require('./variables')
|
|
7
|
+
const { services } = require('./services')
|
|
6
8
|
|
|
7
9
|
exports.dependencies = dependencies
|
|
8
10
|
exports.components = components
|
|
11
|
+
exports.compositions = compositions
|
|
9
12
|
exports.variables = variables
|
|
13
|
+
exports.services = services
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* @param {toa.deployment.dependency.Variables} variables
|
|
6
|
-
* @returns {toa.deployment.dependency.Variables}
|
|
7
|
-
*/
|
|
8
|
-
const variables = (context, variables) => {
|
|
9
|
-
if (variables.global === undefined) variables.global = []
|
|
3
|
+
function addVariables (deployment, variables) {
|
|
4
|
+
const used = new Set()
|
|
10
5
|
|
|
11
|
-
|
|
12
|
-
const variable = { name: 'TOA_ENV', value: context.environment }
|
|
6
|
+
deployment.variables ??= []
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
for (const [key, set] of Object.entries(variables)) {
|
|
9
|
+
if (key !== 'global' && !deployment.components?.includes(key)) continue
|
|
10
|
+
|
|
11
|
+
for (const variable of set) {
|
|
12
|
+
if (used.has(variable.name)) continue
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
deployment.variables.push(variable)
|
|
15
|
+
used.add(variable.name)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
exports.
|
|
20
|
+
exports.addVariables = addVariables
|
|
@@ -2,26 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
const get = require('./.describe')
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* @param {toa.norm.Context} context
|
|
7
|
-
* @param {toa.deployment.Composition[]} compositions
|
|
8
|
-
* @param {toa.deployment.Dependency} dependency
|
|
9
|
-
* @returns {toa.deployment.Contents}
|
|
10
|
-
*/
|
|
11
5
|
const describe = (context, compositions, dependency) => {
|
|
12
|
-
const {
|
|
6
|
+
const { services } = dependency
|
|
7
|
+
|
|
8
|
+
dependency.variables.global ??= []
|
|
9
|
+
dependency.variables.global.unshift({ name: 'TOA_ENV', value: context.environment })
|
|
13
10
|
|
|
14
11
|
const components = get.components(compositions)
|
|
15
|
-
const
|
|
16
|
-
|
|
12
|
+
const credentials = context.registry?.credentials
|
|
13
|
+
|
|
14
|
+
get.compositions(compositions, dependency.variables, context.environment)
|
|
15
|
+
get.services(services, dependency.variables)
|
|
17
16
|
|
|
18
17
|
return {
|
|
19
18
|
compositions,
|
|
20
19
|
components,
|
|
21
20
|
services,
|
|
22
|
-
|
|
23
|
-
variables,
|
|
24
|
-
...dependencies
|
|
21
|
+
credentials,
|
|
25
22
|
}
|
|
26
23
|
}
|
|
27
24
|
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* @param {toa.deployment.Dependency[]} dependencies
|
|
5
|
-
* @returns {toa.deployment.Dependency}
|
|
6
|
-
*/
|
|
7
3
|
const merge = (dependencies) => {
|
|
8
4
|
/** @type {toa.deployment.dependency.Reference[]} */
|
|
9
5
|
const references = []
|
|
@@ -27,10 +23,6 @@ const merge = (dependencies) => {
|
|
|
27
23
|
return { references, services, proxies, variables }
|
|
28
24
|
}
|
|
29
25
|
|
|
30
|
-
/**
|
|
31
|
-
* @param {toa.deployment.dependency.Variables} merged
|
|
32
|
-
* @param {toa.deployment.dependency.Variables} variables
|
|
33
|
-
*/
|
|
34
26
|
const append = (merged, variables) => {
|
|
35
27
|
for (const [component, vars] of Object.entries(variables)) {
|
|
36
28
|
if (merged[component] === undefined) merged[component] = []
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
apiVersion: apps/v1
|
|
3
3
|
kind: Deployment
|
|
4
4
|
metadata:
|
|
5
|
-
name: composition-{{ required "
|
|
5
|
+
name: composition-{{ required "composition name is required" .name }}
|
|
6
6
|
spec:
|
|
7
7
|
replicas: {{ .replicas | default 2 }}
|
|
8
8
|
selector:
|
|
@@ -19,20 +19,15 @@ spec:
|
|
|
19
19
|
containers:
|
|
20
20
|
- name: {{ .name }}
|
|
21
21
|
image: {{ .image }}
|
|
22
|
-
{{- if
|
|
22
|
+
{{- if .variables }}
|
|
23
23
|
env:
|
|
24
|
-
{{- range
|
|
25
|
-
{{- range $key, $vars := $.Values.variables }}
|
|
26
|
-
{{- if eq $component $key }}
|
|
27
|
-
{{- range $vars }}
|
|
28
|
-
{{- include "env.var" . | indent 12 }}
|
|
29
|
-
{{- end }}
|
|
30
|
-
{{- end }}
|
|
31
|
-
{{- end }}
|
|
32
|
-
{{- end }}
|
|
33
|
-
{{- range $.Values.variables.global }}
|
|
24
|
+
{{- range .variables }}
|
|
34
25
|
{{- include "env.var" . | indent 12 }}
|
|
35
26
|
{{- end }}
|
|
36
27
|
{{- end }}
|
|
28
|
+
{{- if $.Values.credentials }}
|
|
29
|
+
imagePullSecrets:
|
|
30
|
+
- name: {{ $.Values.credentials }}
|
|
31
|
+
{{- end }}
|
|
37
32
|
---
|
|
38
33
|
{{- end }}
|
|
@@ -2,23 +2,23 @@
|
|
|
2
2
|
apiVersion: apps/v1
|
|
3
3
|
kind: Deployment
|
|
4
4
|
metadata:
|
|
5
|
-
name:
|
|
5
|
+
name: extension-{{ required "deployment name is required" .name }}
|
|
6
6
|
spec:
|
|
7
7
|
replicas: {{ .replicas | default 2 }}
|
|
8
8
|
selector:
|
|
9
9
|
matchLabels:
|
|
10
|
-
toa.io/service: {{ .name }}
|
|
10
|
+
toa.io/service: extension-{{ .name }}
|
|
11
11
|
template:
|
|
12
12
|
metadata:
|
|
13
13
|
labels:
|
|
14
|
-
toa.io/service: {{ .name }}
|
|
14
|
+
toa.io/service: extension-{{ .name }}
|
|
15
15
|
spec:
|
|
16
16
|
containers:
|
|
17
|
-
- name: {{ .name }}
|
|
17
|
+
- name: extension-{{ .name }}
|
|
18
18
|
image: {{ .image }}
|
|
19
|
-
{{- if
|
|
19
|
+
{{- if .variables }}
|
|
20
20
|
env:
|
|
21
|
-
{{- range
|
|
21
|
+
{{- range .variables }}
|
|
22
22
|
{{- include "env.var" . | indent 12 }}
|
|
23
23
|
{{- end }}
|
|
24
24
|
{{- end }}
|
|
@@ -26,11 +26,11 @@ spec:
|
|
|
26
26
|
apiVersion: v1
|
|
27
27
|
kind: Service
|
|
28
28
|
metadata:
|
|
29
|
-
name:
|
|
29
|
+
name: extension-{{ .name }}
|
|
30
30
|
spec:
|
|
31
31
|
type: ClusterIP
|
|
32
32
|
selector:
|
|
33
|
-
toa.io/service: {{ .name }}
|
|
33
|
+
toa.io/service: extension-{{ .name }}
|
|
34
34
|
ports:
|
|
35
35
|
- name: port-{{ .port }}
|
|
36
36
|
protocol: TCP
|
|
@@ -41,7 +41,7 @@ spec:
|
|
|
41
41
|
apiVersion: networking.k8s.io/v1
|
|
42
42
|
kind: Ingress
|
|
43
43
|
metadata:
|
|
44
|
-
name: {{ .name }}
|
|
44
|
+
name: extension-{{ .name }}
|
|
45
45
|
{{- if .ingress.annotations }}
|
|
46
46
|
annotations:
|
|
47
47
|
{{ toYaml .ingress.annotations | indent 4 }}
|
|
@@ -58,7 +58,7 @@ spec:
|
|
|
58
58
|
pathType: Prefix
|
|
59
59
|
backend:
|
|
60
60
|
service:
|
|
61
|
-
name:
|
|
61
|
+
name: extension-{{ .name }}
|
|
62
62
|
port:
|
|
63
63
|
number: 8000
|
|
64
64
|
{{- end }}
|
|
@@ -6,6 +6,12 @@ compositions:
|
|
|
6
6
|
components:
|
|
7
7
|
- todos-tasks
|
|
8
8
|
- todos-stats
|
|
9
|
+
variables:
|
|
10
|
+
- name: TOA_CONFIGURATION_TODOS_TASKS
|
|
11
|
+
value: foo
|
|
12
|
+
secret:
|
|
13
|
+
name: secret-name
|
|
14
|
+
key: secret-key
|
|
9
15
|
- name: users
|
|
10
16
|
image: localhost:5000/composition-users:0.0.0
|
|
11
17
|
replicas: 3
|
|
@@ -16,19 +22,6 @@ components:
|
|
|
16
22
|
- todos-tasks
|
|
17
23
|
- todos-stats
|
|
18
24
|
- users-users
|
|
19
|
-
variables:
|
|
20
|
-
global:
|
|
21
|
-
- name: TOA_BINDINGS_AMQP_SYSTEM_USERNAME
|
|
22
|
-
value: foo
|
|
23
|
-
secret:
|
|
24
|
-
name: secret-name
|
|
25
|
-
key: secret-key
|
|
26
|
-
todos-tasks:
|
|
27
|
-
- name: TOA_CONFIGURATION_TODOS_TASKS
|
|
28
|
-
value: foo
|
|
29
|
-
secret:
|
|
30
|
-
name: secret-name
|
|
31
|
-
key: secret-key
|
|
32
25
|
services:
|
|
33
26
|
- name: resources-gateway
|
|
34
27
|
image: localhost:5000/resources-gateway:0.0.0
|
|
@@ -41,7 +34,14 @@ services:
|
|
|
41
34
|
alb.ingress.kubernetes.io/scheme: internet-facing
|
|
42
35
|
alb.ingress.kubernetes.io/target-type: ip
|
|
43
36
|
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
|
|
37
|
+
variables:
|
|
38
|
+
- name: TOA_CONFIGURATION_TODOS_TASKS
|
|
39
|
+
value: foo
|
|
40
|
+
secret:
|
|
41
|
+
name: secret-name
|
|
42
|
+
key: secret-key
|
|
44
43
|
proxies:
|
|
45
44
|
- name: storage-proxy
|
|
46
45
|
target: host.docker.internal
|
|
47
46
|
environment: development
|
|
47
|
+
credentials: docker-credentials
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
// noinspection JSClosureCompilerSyntax
|
|
4
|
-
/**
|
|
5
|
-
* @implements {toa.deployment.Composition}
|
|
6
|
-
*/
|
|
7
3
|
class Composition {
|
|
8
4
|
name
|
|
9
5
|
image
|
|
10
6
|
/** @type {string[]} */
|
|
11
7
|
components
|
|
12
8
|
|
|
13
|
-
/**
|
|
14
|
-
* @param composition {toa.norm.context.Composition}
|
|
15
|
-
* @param image {toa.deployment.images.Image}
|
|
16
|
-
*/
|
|
17
9
|
constructor (composition, image) {
|
|
18
10
|
this.name = composition.name
|
|
19
11
|
this.image = image.reference
|
|
@@ -21,10 +13,6 @@ class Composition {
|
|
|
21
13
|
}
|
|
22
14
|
}
|
|
23
15
|
|
|
24
|
-
/**
|
|
25
|
-
* @param {toa.norm.Component} component
|
|
26
|
-
* @returns {string}
|
|
27
|
-
*/
|
|
28
16
|
const component = (component) => component.locator.label
|
|
29
17
|
|
|
30
18
|
exports.Composition = Composition
|
|
@@ -7,39 +7,23 @@ const { dump } = require('@toa.io/yaml')
|
|
|
7
7
|
|
|
8
8
|
const { merge, declare, describe } = require('./.deployment')
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
* @implements {toa.deployment.Deployment}
|
|
12
|
-
*/
|
|
13
10
|
class Deployment {
|
|
14
|
-
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
/** @type {toa.deployment.Contents} */
|
|
18
|
-
#contents
|
|
19
|
-
|
|
20
|
-
/** @type {toa.operations.Process} */
|
|
11
|
+
#chart
|
|
12
|
+
#values
|
|
21
13
|
#process
|
|
22
|
-
|
|
23
|
-
/** @type {string} */
|
|
24
14
|
#target
|
|
25
15
|
|
|
26
|
-
/**
|
|
27
|
-
* @param context {toa.norm.Context}
|
|
28
|
-
* @param compositions {toa.deployment.Composition[]}
|
|
29
|
-
* @param dependencies {toa.deployment.Dependency[]}
|
|
30
|
-
* @param process {toa.operations.Process}
|
|
31
|
-
*/
|
|
32
16
|
constructor (context, compositions, dependencies, process) {
|
|
33
17
|
const dependency = merge(dependencies)
|
|
34
18
|
|
|
35
|
-
this.#
|
|
36
|
-
this.#
|
|
19
|
+
this.#chart = declare(context, dependency)
|
|
20
|
+
this.#values = describe(context, compositions, dependency)
|
|
37
21
|
this.#process = process
|
|
38
22
|
}
|
|
39
23
|
|
|
40
24
|
async export (target) {
|
|
41
|
-
const chart = dump(this.#
|
|
42
|
-
const values = dump(this.#
|
|
25
|
+
const chart = dump(this.#chart)
|
|
26
|
+
const values = dump(this.#values)
|
|
43
27
|
|
|
44
28
|
await Promise.all([
|
|
45
29
|
write(join(target, 'Chart.yaml'), chart),
|
|
@@ -60,7 +44,7 @@ class Deployment {
|
|
|
60
44
|
if (options.wait === true) args.push('--wait')
|
|
61
45
|
|
|
62
46
|
await this.#process.execute('helm', ['dependency', 'update', this.#target])
|
|
63
|
-
await this.#process.execute('helm', ['upgrade', this.#
|
|
47
|
+
await this.#process.execute('helm', ['upgrade', this.#chart.name, '-i', ...args, this.#target])
|
|
64
48
|
}
|
|
65
49
|
|
|
66
50
|
async template (options) {
|
|
@@ -73,12 +57,31 @@ class Deployment {
|
|
|
73
57
|
if (options.namespace !== undefined) args.push('-n', options.namespace)
|
|
74
58
|
|
|
75
59
|
return await this.#process.execute('helm',
|
|
76
|
-
['template', this.#
|
|
60
|
+
['template', this.#chart.name, ...args, this.#target],
|
|
77
61
|
{ silently: true })
|
|
78
62
|
}
|
|
79
63
|
|
|
80
64
|
variables () {
|
|
81
|
-
|
|
65
|
+
const variables = []
|
|
66
|
+
const used = new Set()
|
|
67
|
+
|
|
68
|
+
addVariables(this.#values.compositions, variables, used)
|
|
69
|
+
addVariables(this.#values.services, variables, used)
|
|
70
|
+
|
|
71
|
+
return variables
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function addVariables (list, variables, used = new Set()) {
|
|
76
|
+
for (const item of list) {
|
|
77
|
+
if (item.variables === undefined) continue
|
|
78
|
+
|
|
79
|
+
for (const variable of item.variables) {
|
|
80
|
+
if (used.has(variable.name)) continue
|
|
81
|
+
|
|
82
|
+
variables.push(variable)
|
|
83
|
+
used.add(variable.name)
|
|
84
|
+
}
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -8,28 +8,14 @@ const { Registry } = require('./registry')
|
|
|
8
8
|
const { Composition } = require('./composition')
|
|
9
9
|
const { Service } = require('./service')
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* @implements {toa.deployment.Factory}
|
|
13
|
-
*/
|
|
14
11
|
class Factory {
|
|
15
|
-
/** @type {toa.norm.Context} */
|
|
16
12
|
#context
|
|
17
|
-
|
|
18
|
-
/** @type {Composition[]} */
|
|
19
13
|
#compositions
|
|
20
|
-
|
|
21
|
-
/** @type {toa.deployment.Dependency[]} */
|
|
22
14
|
#dependencies
|
|
23
|
-
|
|
24
|
-
/** @type {toa.deployment.Registry} */
|
|
25
15
|
#registry
|
|
26
|
-
|
|
27
|
-
/** @type {toa.operations.Process} */
|
|
28
16
|
#process
|
|
17
|
+
#extensionComponents = []
|
|
29
18
|
|
|
30
|
-
/**
|
|
31
|
-
* @param context {toa.norm.Context}
|
|
32
|
-
*/
|
|
33
19
|
constructor (context) {
|
|
34
20
|
this.#context = context
|
|
35
21
|
this.#process = new Process()
|
|
@@ -51,19 +37,12 @@ class Factory {
|
|
|
51
37
|
return this.#registry
|
|
52
38
|
}
|
|
53
39
|
|
|
54
|
-
/**
|
|
55
|
-
* @param composition {toa.norm.context.Composition}
|
|
56
|
-
* @returns {Composition}
|
|
57
|
-
*/
|
|
58
40
|
#composition (composition) {
|
|
59
41
|
const image = this.#registry.composition(composition)
|
|
60
42
|
|
|
61
43
|
return new Composition(composition, image)
|
|
62
44
|
}
|
|
63
45
|
|
|
64
|
-
/**
|
|
65
|
-
* @returns {toa.deployment.Dependency[]}
|
|
66
|
-
*/
|
|
67
46
|
#getDependencies () {
|
|
68
47
|
/** @type {toa.deployment.Dependency[]} */
|
|
69
48
|
const dependencies = []
|
|
@@ -79,21 +58,16 @@ class Factory {
|
|
|
79
58
|
return dependencies
|
|
80
59
|
}
|
|
81
60
|
|
|
82
|
-
/**
|
|
83
|
-
* @param {string} path
|
|
84
|
-
* @param {toa.norm.context.dependencies.Instance[]} instances
|
|
85
|
-
* @returns {toa.deployment.Dependency | undefined}
|
|
86
|
-
*/
|
|
87
61
|
#getDependency (path, instances) {
|
|
88
62
|
const module = require(path)
|
|
89
63
|
const pkg = require(path + '/package.json')
|
|
90
64
|
|
|
91
65
|
if (module.deployment === undefined) return
|
|
92
66
|
|
|
93
|
-
const
|
|
67
|
+
const annotation = this.#context.annotations?.[pkg.name]
|
|
94
68
|
|
|
95
69
|
/** @type {toa.deployment.dependency.Declaration} */
|
|
96
|
-
const dependency = module.deployment(instances,
|
|
70
|
+
const dependency = module.deployment(instances, annotation)
|
|
97
71
|
|
|
98
72
|
/** @type {toa.deployment.Service[]} */
|
|
99
73
|
const services = dependency.services?.map((service) => this.#service(path, service))
|
|
@@ -3,16 +3,17 @@ FROM node:18.16.0-alpine3.17
|
|
|
3
3
|
{{build.arguments}}
|
|
4
4
|
|
|
5
5
|
ENV NODE_ENV=production
|
|
6
|
-
RUN if [ {{runtime.registry}} !=
|
|
7
|
-
RUN if [ {{runtime.proxy}} !=
|
|
8
|
-
RUN npm i -g @toa.io/runtime@{{runtime.version}}
|
|
6
|
+
RUN if [ "{{runtime.registry}}" != "" ]; then npm set registry {{runtime.registry}}; fi
|
|
7
|
+
RUN if [ "{{runtime.proxy}}" != "" ]; then npm set proxy {{runtime.proxy}}; fi
|
|
8
|
+
RUN npm i -g @toa.io/runtime@{{runtime.version}} --omit=dev
|
|
9
9
|
|
|
10
10
|
WORKDIR /composition
|
|
11
|
-
|
|
11
|
+
COPY --chown=node:node . /composition
|
|
12
12
|
|
|
13
13
|
{{build.run}}
|
|
14
14
|
|
|
15
15
|
# run 'npm i' in each component
|
|
16
|
-
RUN
|
|
16
|
+
RUN for entry in *; do if [ -f "$entry/package.json" ]; then (cd $entry && npm i --omit=dev); fi; done
|
|
17
17
|
|
|
18
|
+
USER node
|
|
18
19
|
CMD toa compose *
|
|
@@ -29,9 +29,6 @@ class Image {
|
|
|
29
29
|
/** @type {toa.norm.context.Runtime} */
|
|
30
30
|
#runtime
|
|
31
31
|
|
|
32
|
-
/** @type {string} */
|
|
33
|
-
#type
|
|
34
|
-
|
|
35
32
|
/** @type {{ runtime?: Partial<toa.norm.context.Runtime>, build: object }} */
|
|
36
33
|
#values = { build: { command: 'echo hello' } }
|
|
37
34
|
|
|
@@ -44,7 +41,6 @@ class Image {
|
|
|
44
41
|
this.#scope = scope
|
|
45
42
|
this.#registry = registry
|
|
46
43
|
this.#runtime = runtime
|
|
47
|
-
this.#type = this.constructor.name.toLowerCase()
|
|
48
44
|
|
|
49
45
|
this.#setValues()
|
|
50
46
|
}
|
|
@@ -52,7 +48,7 @@ class Image {
|
|
|
52
48
|
tag () {
|
|
53
49
|
const tag = hash(this.#runtime?.version + ';' + this.version)
|
|
54
50
|
|
|
55
|
-
this.reference = posix.join(this.#registry.base ?? '', this.#scope, `${this
|
|
51
|
+
this.reference = posix.join(this.#registry.base ?? '', this.#scope, `${this.name}:${tag}`)
|
|
56
52
|
}
|
|
57
53
|
|
|
58
54
|
/**
|
|
@@ -72,7 +68,7 @@ class Image {
|
|
|
72
68
|
async prepare (root) {
|
|
73
69
|
if (this.dockerfile === undefined) throw new Error('Dockerfile isn\'t specified')
|
|
74
70
|
|
|
75
|
-
const path = join(root, `${this
|
|
71
|
+
const path = join(root, `${this.name}.${this.version}`)
|
|
76
72
|
|
|
77
73
|
await directory.ensure(path)
|
|
78
74
|
|
|
@@ -13,7 +13,7 @@ beforeEach(() => {
|
|
|
13
13
|
it('should assign url', () => {
|
|
14
14
|
instance.tag()
|
|
15
15
|
|
|
16
|
-
expect(instance.reference).toEqual(`${fixtures.registry.base}/${fixtures.scope}
|
|
16
|
+
expect(instance.reference).toEqual(`${fixtures.registry.base}/${fixtures.scope}/${fixtures.name}:${fixtures.version}`)
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
describe('prepare', () => {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
FROM node:18.16.0-alpine3.17
|
|
2
2
|
|
|
3
3
|
ENV NODE_ENV=production
|
|
4
|
-
RUN if [ {{runtime.registry}} !=
|
|
5
|
-
RUN if [ {{runtime.proxy}} !=
|
|
6
|
-
RUN npm i -g @toa.io/runtime@{{runtime.version}}
|
|
4
|
+
RUN if [ "{{runtime.registry}}" != "" ]; then npm set registry {{runtime.registry}}; fi
|
|
5
|
+
RUN if [ "{{runtime.proxy}}" != "" ]; then npm set proxy {{runtime.proxy}}; fi
|
|
6
|
+
RUN npm i -g @toa.io/runtime@{{runtime.version}} --omit=dev
|
|
7
7
|
|
|
8
8
|
WORKDIR /service
|
|
9
|
-
|
|
10
|
-
RUN npm i
|
|
9
|
+
COPY --chown=node:node . /service
|
|
11
10
|
|
|
11
|
+
RUN npm i --omit=dev
|
|
12
|
+
|
|
13
|
+
USER node
|
|
12
14
|
CMD toa serve .
|
|
@@ -18,10 +18,13 @@ class Service extends Image {
|
|
|
18
18
|
|
|
19
19
|
/** @type {string} */
|
|
20
20
|
#group
|
|
21
|
+
|
|
21
22
|
/** @type {string} */
|
|
22
23
|
#name
|
|
24
|
+
|
|
23
25
|
/** @type {string} */
|
|
24
26
|
#path
|
|
27
|
+
|
|
25
28
|
/** @type {string} */
|
|
26
29
|
#version
|
|
27
30
|
|
|
@@ -44,7 +47,7 @@ class Service extends Image {
|
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
get name () {
|
|
47
|
-
return this.#group + '-' + this.#name
|
|
50
|
+
return 'extension-' + this.#group + '-' + this.#name
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
get version () {
|
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
// noinspection JSClosureCompilerSyntax
|
|
4
|
-
/**
|
|
5
|
-
* @implements {toa.deployment.Service}
|
|
6
|
-
*/
|
|
7
3
|
class Service {
|
|
8
|
-
name
|
|
9
|
-
image
|
|
10
|
-
port
|
|
11
|
-
ingress
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @param service {toa.deployment.dependency.Service}
|
|
15
|
-
* @param image {toa.deployment.images.Image}
|
|
16
|
-
*/
|
|
17
4
|
constructor (service, image) {
|
|
5
|
+
Object.assign(this, service)
|
|
6
|
+
|
|
18
7
|
this.name = service.group + '-' + service.name
|
|
19
|
-
this.port = service.port
|
|
20
8
|
this.image = image.reference
|
|
21
|
-
this.ingress = service.ingress
|
|
22
9
|
}
|
|
23
10
|
}
|
|
24
11
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as _deployment from './deployment'
|
|
2
|
+
import * as _dependency from './dependency'
|
|
3
|
+
|
|
4
|
+
declare namespace toa.deployment {
|
|
5
|
+
|
|
6
|
+
interface Operator {
|
|
7
|
+
export (path?: string): Promise<string>
|
|
8
|
+
|
|
9
|
+
install (options?: _deployment.installation.Options): Promise<void>
|
|
10
|
+
|
|
11
|
+
template (options?: _deployment.template.Options): Promise<string>
|
|
12
|
+
|
|
13
|
+
variables (): _dependency.Variables
|
|
14
|
+
|
|
15
|
+
listVariables (): _dependency.Variable[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type Operator = toa.deployment.Operator
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type Service = {
|
|
2
|
+
group: string
|
|
3
|
+
name: string
|
|
4
|
+
version: string
|
|
5
|
+
port: number
|
|
6
|
+
ingress?: {
|
|
7
|
+
host: string
|
|
8
|
+
class?: string
|
|
9
|
+
annotations?: object
|
|
10
|
+
}
|
|
11
|
+
variables: Variable[]
|
|
12
|
+
components?: string[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type Variable = {
|
|
16
|
+
name: string
|
|
17
|
+
value?: string
|
|
18
|
+
secret?: {
|
|
19
|
+
name: string,
|
|
20
|
+
key: string
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type Variables = Record<string, Variable[]>
|
|
25
|
+
|
|
26
|
+
export type Dependency = {
|
|
27
|
+
services?: Service[]
|
|
28
|
+
variables?: Variables
|
|
29
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dependency'
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { generate } = require('randomstring')
|
|
4
|
-
|
|
5
|
-
const context = /** @type {toa.norm.Context} */ { name: generate() }
|
|
6
|
-
const compositions = []
|
|
7
|
-
/** @type {toa.deployment.Dependency[]} */
|
|
8
|
-
|
|
9
|
-
/** @type {toa.deployment.dependency.Variable} */
|
|
10
|
-
const bindingVariable = {
|
|
11
|
-
name: 'TOA_BINDINGS_AMQP_POINTER',
|
|
12
|
-
value: 'eyJkZWZhdWx0IjoiYW1xcDovL3doYXRldmVyIiwic3lzdGVtIjoiYW1xcDovL2hvc3QwIn0='
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** @type {toa.deployment.dependency.Variable} */
|
|
16
|
-
const secretVariable = {
|
|
17
|
-
name: 'TOA_BINDINGS_AMQP_DEFAULT_USERNAME',
|
|
18
|
-
secret: {
|
|
19
|
-
name: 'toa-bindings-amqp-default',
|
|
20
|
-
key: 'username'
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** @type {toa.deployment.Dependency[]} */
|
|
25
|
-
const dependencies = [{
|
|
26
|
-
variables: { global: [bindingVariable, secretVariable] }
|
|
27
|
-
}]
|
|
28
|
-
|
|
29
|
-
const process = /** @type {toa.operations.Process} */ { execute: jest.fn() }
|
|
30
|
-
|
|
31
|
-
const options = /** @type {toa.deployment.installation.Options} */ {
|
|
32
|
-
namespace: generate(),
|
|
33
|
-
target: generate()
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
exports.context = context
|
|
37
|
-
exports.compositions = compositions
|
|
38
|
-
exports.dependencies = dependencies
|
|
39
|
-
exports.process = process
|
|
40
|
-
exports.options = options
|
|
41
|
-
exports.bindingVariable = bindingVariable
|
|
42
|
-
exports.secretVariable = secretVariable
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const clone = require('clone-deep')
|
|
4
|
-
|
|
5
|
-
const fixtures = require('./deployment.fixtures')
|
|
6
|
-
const { Deployment } = require('../../src/deployment/deployment')
|
|
7
|
-
|
|
8
|
-
/** @type {toa.deployment.Deployment} */
|
|
9
|
-
let deployment
|
|
10
|
-
/** @type {toa.deployment.installation.Options} */
|
|
11
|
-
let options
|
|
12
|
-
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
deployment = new Deployment(fixtures.context, fixtures.compositions, fixtures.dependencies, fixtures.process)
|
|
15
|
-
options = clone(fixtures.options)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('should pass -n argument if options.namespace is set', async () => {
|
|
19
|
-
await deployment.install(options)
|
|
20
|
-
|
|
21
|
-
const call = fixtures.process.execute.mock.calls.find((call) => call[0] === 'helm' && call[1][0] === 'upgrade')
|
|
22
|
-
|
|
23
|
-
expect(call).toBeDefined()
|
|
24
|
-
|
|
25
|
-
const args = call[1]
|
|
26
|
-
const index = args.findIndex((value) => value === '-n')
|
|
27
|
-
const namespace = args[index + 1]
|
|
28
|
-
|
|
29
|
-
expect(index).not.toStrictEqual(-1)
|
|
30
|
-
expect(namespace).toStrictEqual(fixtures.options.namespace)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
describe('variables', () => {
|
|
34
|
-
let deployment /** @type {toa.deployment.Deployment} */
|
|
35
|
-
|
|
36
|
-
it('should be define', () => {
|
|
37
|
-
const context = clone(fixtures.context)
|
|
38
|
-
|
|
39
|
-
deployment = new Deployment(context, fixtures.compositions, fixtures.dependencies, fixtures.process)
|
|
40
|
-
|
|
41
|
-
expect(typeof deployment.variables).toBe('function')
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('should return variables', () => {
|
|
45
|
-
const context = clone(fixtures.context)
|
|
46
|
-
const [{ variables }] = fixtures.dependencies
|
|
47
|
-
|
|
48
|
-
deployment = new Deployment(context, fixtures.compositions, fixtures.dependencies, fixtures.process)
|
|
49
|
-
expect(deployment.variables()).toEqual(variables)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('should return variables', () => {
|
|
53
|
-
const context = clone(fixtures.context)
|
|
54
|
-
const [{ variables }] = fixtures.dependencies
|
|
55
|
-
|
|
56
|
-
deployment = new Deployment(context, fixtures.compositions, fixtures.dependencies, fixtures.process)
|
|
57
|
-
|
|
58
|
-
expect(deployment.variables()).toEqual(variables)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
it('should merge all variables', () => {
|
|
62
|
-
const context = clone(fixtures.context)
|
|
63
|
-
|
|
64
|
-
/** @type {toa.deployment.Dependency} */
|
|
65
|
-
const dep1 = { variables: { global: [fixtures.secretVariable] } }
|
|
66
|
-
|
|
67
|
-
/** @type {toa.deployment.Dependency} */
|
|
68
|
-
const dep2 = { variables: { global: [fixtures.bindingVariable] } }
|
|
69
|
-
|
|
70
|
-
deployment = new Deployment(context, fixtures.compositions, [dep1, dep2], fixtures.process)
|
|
71
|
-
|
|
72
|
-
const result = deployment.variables()
|
|
73
|
-
const expectedVariables = [fixtures.bindingVariable, fixtures.secretVariable]
|
|
74
|
-
|
|
75
|
-
expect(result.global.length).toBe(expectedVariables.length)
|
|
76
|
-
expect(result.global).toStrictEqual(expect.arrayContaining(expectedVariables))
|
|
77
|
-
})
|
|
78
|
-
})
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import * as _deployment from './deployment'
|
|
2
|
-
import * as _dependency from './dependency'
|
|
3
|
-
|
|
4
|
-
declare namespace toa.deployment {
|
|
5
|
-
|
|
6
|
-
interface Operator {
|
|
7
|
-
export(path?: string): Promise<string>
|
|
8
|
-
|
|
9
|
-
install(options?: _deployment.installation.Options): Promise<void>
|
|
10
|
-
|
|
11
|
-
template(options?: _deployment.template.Options): Promise<string>
|
|
12
|
-
|
|
13
|
-
variables(): _dependency.Variables
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type Operator = toa.deployment.Operator
|
package/types/process.d.ts
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|