@toa.io/operations 1.0.0-alpha.34 → 1.0.0-alpha.341

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +457 -0
  2. package/image/runtime.Dockerfile +20 -0
  3. package/package.json +10 -10
  4. package/readme.md +224 -0
  5. package/src/deployment/.deployment/.describe/components.js +1 -5
  6. package/src/deployment/.deployment/.describe/compositions.js +26 -7
  7. package/src/deployment/.deployment/.describe/dependencies.js +1 -6
  8. package/src/deployment/.deployment/.describe/events.js +63 -0
  9. package/src/deployment/.deployment/.describe/fold.js +42 -0
  10. package/src/deployment/.deployment/.describe/fold.test.js +108 -0
  11. package/src/deployment/.deployment/.describe/index.js +4 -13
  12. package/src/deployment/.deployment/.describe/mounts.js +17 -0
  13. package/src/deployment/.deployment/.describe/resources.js +129 -0
  14. package/src/deployment/.deployment/.describe/resources.test.js +129 -0
  15. package/src/deployment/.deployment/.describe/services.js +32 -6
  16. package/src/deployment/.deployment/.describe/services.test.js +78 -0
  17. package/src/deployment/.deployment/.describe/variables.js +5 -9
  18. package/src/deployment/.deployment/declare.js +1 -5
  19. package/src/deployment/.deployment/describe.js +168 -10
  20. package/src/deployment/.deployment/index.js +3 -9
  21. package/src/deployment/.deployment/merge.js +66 -6
  22. package/src/deployment/.deployment/merge.test.js +133 -0
  23. package/src/deployment/chart/templates/components.configmap.yaml +13 -0
  24. package/src/deployment/chart/templates/components.yaml +4 -3
  25. package/src/deployment/chart/templates/compositions.yaml +109 -4
  26. package/src/deployment/chart/templates/mono.yaml +199 -0
  27. package/src/deployment/chart/templates/services.yaml +97 -7
  28. package/src/deployment/chart/values.yaml +23 -1
  29. package/src/deployment/composition.js +8 -6
  30. package/src/deployment/deployment.js +175 -35
  31. package/src/deployment/drain.js +70 -0
  32. package/src/deployment/drain.test.js +64 -0
  33. package/src/deployment/factory.js +178 -37
  34. package/src/deployment/images/bundle.js +93 -0
  35. package/src/deployment/images/composition.Dockerfile +9 -17
  36. package/src/deployment/images/composition.js +9 -56
  37. package/src/deployment/images/dependencies.Dockerfile +23 -0
  38. package/src/deployment/images/dependencies.js +171 -0
  39. package/src/deployment/images/dependencies.test.js +271 -0
  40. package/src/deployment/images/factory.js +31 -15
  41. package/src/deployment/images/format.js +66 -0
  42. package/src/deployment/images/format.test.js +150 -0
  43. package/src/deployment/images/image.fixtures.js +17 -19
  44. package/src/deployment/images/image.js +79 -38
  45. package/src/deployment/images/image.test.js +11 -5
  46. package/src/deployment/images/index.js +1 -5
  47. package/src/deployment/images/mono.Dockerfile +11 -0
  48. package/src/deployment/images/mono.js +15 -0
  49. package/src/deployment/images/publish.js +91 -0
  50. package/src/deployment/images/runtime-base.test.js +97 -0
  51. package/src/deployment/images/service.Dockerfile +17 -5
  52. package/src/deployment/images/service.js +63 -14
  53. package/src/deployment/index.js +1 -5
  54. package/src/deployment/operator.js +25 -16
  55. package/src/deployment/operator.test.js +98 -7
  56. package/src/deployment/registry.js +210 -46
  57. package/src/deployment/registry.test.js +539 -0
  58. package/src/deployment/secrets.js +92 -0
  59. package/src/deployment/secrets.test.js +180 -0
  60. package/src/deployment/service.js +4 -6
  61. package/src/deployment/workspace.js +13 -8
  62. package/src/index.js +3 -2
  63. package/src/process.js +51 -13
  64. package/src/process.test.js +33 -0
  65. package/types/_deployment/composition.d.ts +2 -3
  66. package/types/_deployment/dependency.d.ts +15 -7
  67. package/types/_deployment/deployment.d.ts +10 -8
  68. package/types/_deployment/factory.d.ts +2 -4
  69. package/types/_deployment/images/factory.d.ts +6 -8
  70. package/types/_deployment/images/image.d.ts +16 -1
  71. package/types/_deployment/images/registry.d.ts +8 -11
  72. package/types/_deployment/operator.d.ts +10 -9
  73. package/types/_deployment/registry.d.ts +7 -4
  74. package/types/_deployment/service.d.ts +4 -3
  75. package/types/dependency.ts +79 -0
  76. package/types/index.ts +1 -0
  77. package/types/dependency.d.ts +0 -39
  78. package/types/index.d.ts +0 -1
@@ -0,0 +1,180 @@
1
+ import { it, describe, beforeEach, mock } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import { references, verify } from './secrets.js'
5
+
6
+ describe('references', () => {
7
+ it('should reference a secret by name and key', () => {
8
+ const variables = [
9
+ { name: 'TOA_CONTEXT', value: 'todos' },
10
+ { name: 'USERNAME', secret: { name: 'toa-mongodb.default', key: 'username' } },
11
+ { name: 'PASSWORD', secret: { name: 'toa-mongodb.default', key: 'password' } }
12
+ ]
13
+
14
+ assert.deepStrictEqual(references(variables), [
15
+ 'toa-mongodb.default/username',
16
+ 'toa-mongodb.default/password'
17
+ ])
18
+ })
19
+
20
+ it('should not reference an optional key', () => {
21
+ const variables = [
22
+ { name: 'KEY', secret: { name: 'toa-tokens', key: 'key0', optional: true } },
23
+ { name: 'USERNAME', secret: { name: 'toa-mongodb.default', key: 'username' } }
24
+ ]
25
+
26
+ assert.deepStrictEqual(references(variables), ['toa-mongodb.default/username'])
27
+ })
28
+
29
+ it('should reference a key read by two workloads once', () => {
30
+ const secret = { name: 'toa-mongodb.default', key: 'username' }
31
+
32
+ assert.deepStrictEqual(
33
+ references([
34
+ { name: 'A', secret },
35
+ { name: 'B', secret }
36
+ ]),
37
+ ['toa-mongodb.default/username']
38
+ )
39
+ })
40
+
41
+ it('should reference the image pull secret by name', () => {
42
+ const variables = [
43
+ { name: 'USERNAME', secret: { name: 'toa-mongodb.default', key: 'username' } }
44
+ ]
45
+
46
+ assert.deepStrictEqual(references(variables, 'registry-credentials'), [
47
+ 'registry-credentials',
48
+ 'toa-mongodb.default/username'
49
+ ])
50
+ })
51
+
52
+ it('should reference nothing where nothing is secret', () => {
53
+ assert.deepStrictEqual(references([{ name: 'TOA_ENV', value: 'production' }]), [])
54
+ })
55
+
56
+ it('should reference no pull secret where a context names none', () => {
57
+ // as the chart reads it: `credentials: ~` renders no `imagePullSecrets`
58
+ assert.deepStrictEqual(references([], null), [])
59
+ assert.deepStrictEqual(references([], ''), [])
60
+ })
61
+ })
62
+
63
+ describe('verify', () => {
64
+ /** @type {string} what `kubectl` answers */
65
+ let secrets
66
+
67
+ /** @type {toa.operations.Process} */
68
+ let process
69
+
70
+ beforeEach(() => {
71
+ secrets = ''
72
+ process = /** @type {toa.operations.Process} */ {
73
+ execute: mock.fn(async () => secrets)
74
+ }
75
+ })
76
+
77
+ it('should read the namespace deployed into', async () => {
78
+ secrets = 'toa-mongodb.default password username'
79
+
80
+ await verify(process, ['toa-mongodb.default/username'], { namespace: 'acme' })
81
+
82
+ const [cmd, args, options] = process.execute.mock.calls[0].arguments
83
+
84
+ assert.strictEqual(cmd, 'kubectl')
85
+ assert.deepStrictEqual(args.slice(0, 2), ['get', 'secrets'])
86
+ assert.deepStrictEqual(args.slice(-2), ['-n', 'acme'])
87
+ assert.deepStrictEqual(options, { silently: true })
88
+ })
89
+
90
+ it('should read the current namespace where none is given', async () => {
91
+ await verify(process, [], {})
92
+
93
+ assert.strictEqual(process.execute.mock.callCount(), 0)
94
+
95
+ await verify(process, ['toa-mongodb.default/username'], {}).catch(() => {})
96
+
97
+ const [, args] = process.execute.mock.calls[0].arguments
98
+
99
+ assert.strictEqual(args.includes('-n'), false)
100
+ })
101
+
102
+ it('should name every key that is not deployed', async () => {
103
+ secrets = 'toa-amqp-context.default password username'
104
+
105
+ await assert.rejects(
106
+ verify(
107
+ process,
108
+ [
109
+ 'toa-amqp-context.default/username',
110
+ 'toa-mongodb.default/username',
111
+ 'toa-mongodb.default/password'
112
+ ],
113
+ {}
114
+ ),
115
+ {
116
+ message:
117
+ 'Secrets are not deployed: toa-mongodb.default/username, ' +
118
+ 'toa-mongodb.default/password'
119
+ }
120
+ )
121
+ })
122
+
123
+ it('should name the key a deployed secret lacks', async () => {
124
+ secrets = 'toa-mongodb.default username'
125
+
126
+ await assert.rejects(
127
+ verify(
128
+ process,
129
+ ['toa-mongodb.default/username', 'toa-mongodb.default/password'],
130
+ {}
131
+ ),
132
+ { message: 'Secrets are not deployed: toa-mongodb.default/password' }
133
+ )
134
+ })
135
+
136
+ it('should name a secret referenced by name alone', async () => {
137
+ secrets = 'toa-mongodb.default password username'
138
+
139
+ await assert.rejects(verify(process, ['registry-credentials'], {}), {
140
+ message: 'Secrets are not deployed: registry-credentials'
141
+ })
142
+
143
+ secrets = 'registry-credentials .dockerconfigjson'
144
+
145
+ await verify(process, ['registry-credentials'], {})
146
+ })
147
+
148
+ it('should pass where the cluster holds every key', async () => {
149
+ secrets =
150
+ 'default-token\ntoa-amqp-context.default password username\n' +
151
+ 'toa-mongodb.default password username'
152
+
153
+ await verify(
154
+ process,
155
+ [
156
+ 'toa-amqp-context.default/username',
157
+ 'toa-amqp-context.default/password',
158
+ 'toa-mongodb.default/username',
159
+ 'toa-mongodb.default/password'
160
+ ],
161
+ {}
162
+ )
163
+ })
164
+
165
+ it('should not read the cluster where nothing is secret', async () => {
166
+ await verify(process, [], { namespace: 'acme' })
167
+
168
+ assert.strictEqual(process.execute.mock.callCount(), 0)
169
+ })
170
+
171
+ it('should fail as the error it is where the cluster cannot be read', async () => {
172
+ process.execute = mock.fn(async () => {
173
+ throw new Error('Command failed with exit code 1: kubectl get secrets')
174
+ })
175
+
176
+ await assert.rejects(verify(process, ['toa-mongodb.default/username'], {}), {
177
+ message: /^Command failed/
178
+ })
179
+ })
180
+ })
@@ -1,12 +1,10 @@
1
- 'use strict'
2
-
3
- class Service {
4
- constructor (service, image) {
1
+ // a service is what a deployment carries, and it is constructed
2
+ // oxlint-disable-next-line typescript/no-extraneous-class
3
+ export class Service {
4
+ constructor(service, image) {
5
5
  Object.assign(this, service)
6
6
 
7
7
  this.name = service.group + '-' + service.name
8
8
  this.image = image.reference
9
9
  }
10
10
  }
11
-
12
- exports.Service = Service
@@ -1,17 +1,22 @@
1
- 'use strict'
2
-
3
- const { directory } = require('@toa.io/filesystem')
1
+ import { mkdir, mkdtemp, readdir } from 'node:fs/promises'
2
+ import { join, resolve } from 'node:path'
3
+ import { tmpdir } from 'node:os'
4
4
 
5
5
  /**
6
6
  * @param {string} type
7
7
  * @param {string} [path]
8
8
  * @return {Promise<string>}
9
9
  */
10
- async function create (type, path) {
11
- if (path === undefined) path = await directory.temp('toa-' + type)
12
- else path = await directory.ensure(path)
10
+ export async function create(type, path) {
11
+ if (path === undefined) return await mkdtemp(join(tmpdir(), 'toa-' + type))
12
+
13
+ path = resolve(path)
14
+
15
+ await mkdir(path, { recursive: true })
16
+
17
+ const entries = await readdir(path)
18
+
19
+ if (entries.length > 0) throw new Error('Target directory must be empty')
13
20
 
14
21
  return path
15
22
  }
16
-
17
- exports.create = create
package/src/index.js CHANGED
@@ -1,3 +1,4 @@
1
- 'use strict'
1
+ export * as deployment from './deployment/index.js'
2
2
 
3
- exports.deployment = require('./deployment')
3
+ // what conceals a secret in the cluster a deployment goes to; the CLI needs no package of its own for it
4
+ export * as kubernetes from '@toa.io/kubernetes'
package/src/process.js CHANGED
@@ -1,27 +1,65 @@
1
- 'use strict'
2
-
3
- const execa = require('execa')
1
+ import { spawn } from 'node:child_process'
4
2
 
5
3
  /**
6
4
  * @implements {toa.operations.Process}
7
5
  */
8
- class Process {
9
- async execute (cmd, args, options = {}) {
6
+ export class Process {
7
+ async execute(cmd, args, options = {}) {
10
8
  console.log('toa>', cmd, args.join(' '))
11
9
 
12
- /** @type {execa.ExecaReturnValue<import('stream').Stream>} */
13
- const command = execa(cmd, args)
10
+ const child = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'pipe'] })
11
+ const stdout = []
12
+ const stderr = []
13
+
14
+ child.stdout.on('data', (chunk) => stdout.push(chunk))
15
+ child.stderr.on('data', (chunk) => stderr.push(chunk))
14
16
 
15
17
  if (options.silently !== true) {
16
- command.stdout.pipe(process.stdout)
17
- command.stderr.pipe(process.stderr)
18
+ child.stdout.pipe(process.stdout)
19
+ child.stderr.pipe(process.stderr)
18
20
  }
19
21
 
20
- /** @type {execa.ExecaReturnValue<string>} */
21
- const result = await command
22
+ await exit(child, cmd, args, () => Buffer.concat(stderr).toString())
22
23
 
23
- return result.stdout
24
+ return Buffer.concat(stdout).toString().replace(/\n$/, '')
24
25
  }
25
26
  }
26
27
 
27
- exports.Process = Process
28
+ /**
29
+ * Runs a command on this process's own streams, and answers once it has exited.
30
+ *
31
+ * @param {string} cmd
32
+ * @param {string[]} args
33
+ * @returns {Promise<void>}
34
+ */
35
+ export async function run(cmd, args) {
36
+ console.log('toa>', cmd, args.join(' '))
37
+
38
+ await exit(spawn(cmd, args, { stdio: 'inherit' }), cmd, args)
39
+ }
40
+
41
+ /**
42
+ * @param {import('node:child_process').ChildProcess} child
43
+ * @param {string} cmd
44
+ * @param {string[]} args
45
+ * @param {() => string} stderr
46
+ * @returns {Promise<void>}
47
+ */
48
+ const exit = (child, cmd, args, stderr = () => '') =>
49
+ new Promise((resolve, reject) => {
50
+ child.once('error', reject)
51
+
52
+ child.once('close', (code, signal) => {
53
+ if (code === 0) return resolve()
54
+
55
+ const output = stderr()
56
+ const reason = signal === null ? `exit code ${code}` : signal
57
+
58
+ reject(
59
+ new Error(
60
+ `Command failed with ${reason}: ${cmd} ${args.join(' ')}` +
61
+ (output === '' ? '' : '\n' + output.trimEnd())
62
+ )
63
+ )
64
+ })
65
+ })
@@ -0,0 +1,33 @@
1
+ import { it, describe } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import { Process } from './process.js'
5
+
6
+ describe('execute', () => {
7
+ it('should answer what the command wrote', async () => {
8
+ const output = await new Process().execute(
9
+ 'node',
10
+ ['-e', 'process.stdout.write("ok")'],
11
+ { silently: true }
12
+ )
13
+
14
+ assert.strictEqual(output, 'ok')
15
+ })
16
+
17
+ it('should reject what the command failed at, with what it wrote', async () => {
18
+ await assert.rejects(
19
+ new Process().execute(
20
+ 'node',
21
+ ['-e', 'process.stderr.write("broken"); process.exit(2)'],
22
+ { silently: true }
23
+ ),
24
+ (error) => /exit code 2: node/.test(error.message) && /broken/.test(error.message)
25
+ )
26
+ })
27
+
28
+ it('should reject a command that does not exist', async () => {
29
+ await assert.rejects(
30
+ new Process().execute('toa-no-such-command', [], { silently: true })
31
+ )
32
+ })
33
+ })
@@ -1,11 +1,10 @@
1
- import type * as _deployment from './deployment'
1
+ import type * as _deployment from './deployment.d.ts'
2
2
 
3
3
  declare namespace toa.deployment {
4
-
5
4
  interface Composition extends _deployment.Deployable {
6
5
  components: Array<string>
6
+ replicas?: number
7
7
  }
8
-
9
8
  }
10
9
 
11
10
  export type Composition = toa.deployment.Composition
@@ -1,11 +1,12 @@
1
- import * as _service from './service'
1
+ import * as _service from './service.d.ts'
2
2
  import { dependencies } from '@toa.io/norm/types/context'
3
3
 
4
4
  declare namespace toa.deployment {
5
-
6
5
  namespace dependency {
7
-
8
- type Constructor = (instances: dependencies.Instance[], annotation: any) => Declaration
6
+ type Constructor = (
7
+ instances: dependencies.Instance[],
8
+ annotation: any
9
+ ) => Declaration
9
10
 
10
11
  type Reference = {
11
12
  name: string
@@ -19,6 +20,11 @@ declare namespace toa.deployment {
19
20
  group: string
20
21
  name: string
21
22
  version: string
23
+
24
+ /** The repository the extension publishes this service's image to, without a tag.
25
+ * Stating it lets an application take the published image instead of building one. */
26
+ image?: string
27
+
22
28
  port: number
23
29
  ingress?: {
24
30
  host: string
@@ -36,8 +42,10 @@ declare namespace toa.deployment {
36
42
  name: string
37
43
  value?: string | number
38
44
  secret?: {
39
- name: string,
45
+ name: string
40
46
  key: string
47
+ /** The workload starts without it, so the cluster need not hold it. */
48
+ optional?: boolean
41
49
  }
42
50
  }
43
51
 
@@ -50,8 +58,8 @@ declare namespace toa.deployment {
50
58
  services?: Service[] // dependency.Service
51
59
  proxies?: Proxy[]
52
60
  variables?: Variables
61
+ events?: string[]
53
62
  }
54
-
55
63
  }
56
64
 
57
65
  type Dependency = {
@@ -59,8 +67,8 @@ declare namespace toa.deployment {
59
67
  services?: _service.Service[] // deployment.Service
60
68
  proxies?: dependency.Proxy[]
61
69
  variables?: dependency.Variables
70
+ events?: string[]
62
71
  }
63
-
64
72
  }
65
73
 
66
74
  export type Declaration = toa.deployment.dependency.Declaration
@@ -1,9 +1,8 @@
1
- import type * as _composition from './composition'
2
- import type * as _service from './service'
3
- import type * as _dependency from './dependency'
1
+ import type * as _composition from './composition.d.ts'
2
+ import type * as _service from './service.d.ts'
3
+ import type * as _dependency from './dependency.d.ts'
4
4
 
5
5
  declare namespace toa.deployment {
6
-
7
6
  interface Declaration {
8
7
  apiVersion: string
9
8
  type: string
@@ -25,13 +24,11 @@ declare namespace toa.deployment {
25
24
  }
26
25
 
27
26
  namespace installation {
28
-
29
27
  interface Options {
30
28
  wait?: boolean
31
29
  target?: string
32
30
  namespace?: string
33
31
  }
34
-
35
32
  }
36
33
 
37
34
  namespace template {
@@ -48,13 +45,18 @@ declare namespace toa.deployment {
48
45
  interface Deployment {
49
46
  export(target: string): Promise<void>
50
47
 
48
+ /** Raises where the cluster does not hold a secret the workloads read. */
49
+ verify(options: installation.Options): Promise<void>
50
+
51
51
  install(options: installation.Options): Promise<void>
52
52
 
53
53
  template(options: template.Options): Promise<string>
54
54
 
55
- variables(): _dependency.Variables
55
+ variables(options?: {
56
+ components?: string[]
57
+ services?: string[]
58
+ }): _dependency.Variable[]
56
59
  }
57
-
58
60
  }
59
61
 
60
62
  export namespace installation {
@@ -1,14 +1,12 @@
1
- import type * as _operator from './operator'
2
- import * as _registry from './registry'
1
+ import type * as _operator from './operator.d.ts'
2
+ import * as _registry from './registry.d.ts'
3
3
 
4
4
  declare namespace toa.deployment {
5
-
6
5
  interface Factory {
7
6
  operator(): _operator.Operator
8
7
 
9
8
  registry(): _registry.Registry
10
9
  }
11
-
12
10
  }
13
11
 
14
12
  export type Factory = toa.deployment.Factory
@@ -1,17 +1,15 @@
1
1
  // noinspection ES6UnusedImports
2
2
 
3
3
  import type { Composition } from '@toa.io/norm/types'
4
- import type { Image } from './image'
5
- import type { dependency } from '../dependency'
4
+ import type { Image } from './image.d.ts'
5
+ import type { dependency } from '../dependency.d.ts'
6
6
 
7
7
  declare namespace toa.deployment.images {
8
+ interface Factory {
9
+ composition(composition: Composition): Image
8
10
 
9
- interface Factory {
10
- composition(composition: Composition): Image
11
-
12
- service(path: string, service: dependency.Service): Image
13
- }
14
-
11
+ service(path: string, service: dependency.Service): Image
12
+ }
15
13
  }
16
14
 
17
15
  export type Factory = toa.deployment.images.Factory
@@ -1,14 +1,29 @@
1
1
  declare namespace toa.deployment.images {
2
-
3
2
  export interface Image {
4
3
  readonly reference: string
5
4
  readonly context: string
6
5
 
6
+ /** The image this one is laid over, built and pushed as an image of its own. */
7
+ readonly dependencies?: Image
8
+
9
+ /** Whether the build reads `registry.build.arguments`. */
10
+ readonly arguments?: boolean
11
+
12
+ name: string
13
+
7
14
  tag(): void
8
15
 
9
16
  prepare(root: string): Promise<string>
10
17
  }
11
18
 
19
+ /** Components in one image, laid over their dependencies. */
20
+ export interface Bundle extends Image {
21
+ readonly image?: string
22
+ readonly components: any[]
23
+
24
+ conflict(): string
25
+ }
12
26
  }
13
27
 
14
28
  export type Image = toa.deployment.images.Image
29
+ export type Bundle = toa.deployment.images.Bundle
@@ -1,20 +1,17 @@
1
1
  // noinspection ES6UnusedImports
2
2
 
3
3
  import type { Composition } from '@toa.io/norm'
4
- import type { dependency } from '../dependency'
5
- import type { Image } from "./image"
4
+ import type { dependency } from '../dependency.d.ts'
5
+ import type { Image } from './image.d.ts'
6
6
 
7
7
  declare namespace toa.deployment.images {
8
+ interface Registry {
9
+ composition(composition: Composition): Image
8
10
 
9
- interface Registry {
10
- composition(composition: Composition): Image
11
+ service(path: string, service: dependency.Service): Image
11
12
 
12
- service(path: string, service: dependency.Service): Image
13
-
14
- prepare(target: string): Promise<void>
15
-
16
- push(): Promise<void>
17
- }
13
+ prepare(target: string): Promise<void>
18
14
 
15
+ push(): Promise<void>
16
+ }
19
17
  }
20
-
@@ -1,20 +1,21 @@
1
- import * as _deployment from './deployment'
2
- import * as _dependency from './dependency'
1
+ import * as _deployment from './deployment.d.ts'
2
+ import * as _dependency from './dependency.d.ts'
3
3
 
4
4
  declare namespace toa.deployment {
5
-
6
5
  interface Operator {
7
- export (path?: string): Promise<string>
6
+ export(path?: string): Promise<string>
8
7
 
9
- install (options?: _deployment.installation.Options): Promise<void>
8
+ install(options?: _deployment.installation.Options): Promise<void>
10
9
 
11
- template (options?: _deployment.template.Options): Promise<string>
10
+ template(options?: _deployment.template.Options): Promise<string>
12
11
 
13
- variables (): _dependency.Variables
12
+ variables(options?: {
13
+ components?: string[]
14
+ services?: string[]
15
+ }): _dependency.Variable[]
14
16
 
15
- listVariables (): _dependency.Variable[]
17
+ listVariables(): _dependency.Variable[]
16
18
  }
17
-
18
19
  }
19
20
 
20
21
  export type Operator = toa.deployment.Operator
@@ -1,9 +1,8 @@
1
1
  import type * as _norm from '@toa.io/norm/types'
2
- import type * as _dependency from './dependency'
3
- import type * as _image from "./images/image"
2
+ import type * as _dependency from './dependency.d.ts'
3
+ import type * as _image from './images/image.d.ts'
4
4
 
5
5
  declare namespace toa.deployment {
6
-
7
6
  interface Registry {
8
7
  composition(composition: _norm.Composition): _image.Image
9
8
 
@@ -14,8 +13,12 @@ declare namespace toa.deployment {
14
13
  build(): Promise<void>
15
14
 
16
15
  push(): Promise<void>
17
- }
18
16
 
17
+ /** Point each workload image at `environment` (`:production`). `deps-*` is not tagged. */
18
+ alias(environment?: string): Promise<void>
19
+
20
+ tags(): string[]
21
+ }
19
22
  }
20
23
 
21
24
  export type Registry = toa.deployment.Registry
@@ -1,7 +1,6 @@
1
- import type * as _deployment from './deployment'
1
+ import type * as _deployment from './deployment.d.ts'
2
2
 
3
3
  declare namespace toa.deployment {
4
-
5
4
  interface Ingress {
6
5
  host: string
7
6
  class: string
@@ -11,8 +10,10 @@ declare namespace toa.deployment {
11
10
  interface Service extends _deployment.Deployable {
12
11
  port: number
13
12
  ingress?: Ingress
14
- }
15
13
 
14
+ /** Annotations for the Service itself, as opposed to `ingress.annotations`. */
15
+ annotations?: object
16
+ }
16
17
  }
17
18
 
18
19
  export type Service = toa.deployment.Service