k8ts 0.6.0 → 0.7.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/dist/env/env.d.ts +32 -0
- package/dist/env/env.d.ts.map +1 -0
- package/dist/env/env.js +120 -0
- package/dist/env/env.js.map +1 -0
- package/dist/env/index.d.ts +3 -0
- package/dist/env/index.d.ts.map +1 -0
- package/dist/env/index.js +7 -0
- package/dist/env/index.js.map +1 -0
- package/dist/env/types.d.ts +15 -0
- package/dist/env/types.d.ts.map +1 -0
- package/dist/env/types.js +3 -0
- package/dist/env/types.js.map +1 -0
- package/dist/env/validate-name.d.ts +2 -0
- package/dist/env/validate-name.d.ts.map +1 -0
- package/dist/env/validate-name.js +12 -0
- package/dist/env/validate-name.js.map +1 -0
- package/dist/resources/pod/container/container.d.ts +2 -1
- package/dist/resources/pod/container/container.d.ts.map +1 -1
- package/dist/resources/pod/container/container.js +2 -1
- package/dist/resources/pod/container/container.js.map +1 -1
- package/dist/resources/service/service-port.d.ts.map +1 -1
- package/dist/resources/service/service-port.js +1 -0
- package/dist/resources/service/service-port.js.map +1 -1
- package/dist/resources/service/service.d.ts.map +1 -1
- package/dist/resources/service/service.js +2 -1
- package/dist/resources/service/service.js.map +1 -1
- package/dist/resources/utils/adapters.d.ts +1 -2
- package/dist/resources/utils/adapters.d.ts.map +1 -1
- package/dist/resources/utils/adapters.js +0 -9
- package/dist/resources/utils/adapters.js.map +1 -1
- package/dist/src.tsbuildinfo +1 -1
- package/package.json +5 -4
- package/src/env/env.ts +128 -0
- package/src/env/index.ts +2 -0
- package/src/env/types.ts +17 -0
- package/src/env/validate-name.ts +10 -0
- package/src/resources/pod/container/container.ts +3 -5
- package/src/resources/service/service-port.ts +1 -0
- package/src/resources/service/service.ts +2 -1
- package/src/resources/utils/adapters.ts +1 -11
- package/src/tsconfig.json +1 -1
package/src/env/env.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Map, type MapOf } from "immutable"
|
|
2
|
+
import { isObject } from "what-are-you"
|
|
3
|
+
import type { CDK } from "../_imports"
|
|
4
|
+
import { MakeError } from "../error"
|
|
5
|
+
import { api } from "../kinds"
|
|
6
|
+
import type { EnvVarFrom, InputEnv, InputEnvMapping } from "./types"
|
|
7
|
+
import { isValidEnvVarName } from "./validate-name"
|
|
8
|
+
|
|
9
|
+
type _EnvBuilderMap = MapOf<InputEnvMapping>
|
|
10
|
+
export class EnvBuilder {
|
|
11
|
+
constructor(private readonly _env: _EnvBuilderMap) {
|
|
12
|
+
for (const key of _env.keys()) {
|
|
13
|
+
if (!isValidEnvVarName(key)) {
|
|
14
|
+
throw new MakeError("Invalid environment variable name", {
|
|
15
|
+
key: key
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get values() {
|
|
22
|
+
return this._env
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private _envFromSecret(value: EnvVarFrom<api.v1_.Secret>): CDK.EnvVarSource {
|
|
26
|
+
return {
|
|
27
|
+
secretKeyRef: {
|
|
28
|
+
name: value.$ref.name,
|
|
29
|
+
key: value.key,
|
|
30
|
+
optional: value.optional
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private _envFromConfigMap(value: EnvVarFrom<api.v1_.ConfigMap>): CDK.EnvVarSource {
|
|
36
|
+
return {
|
|
37
|
+
configMapKeyRef: {
|
|
38
|
+
name: value.$ref.name,
|
|
39
|
+
key: value.key,
|
|
40
|
+
optional: value.optional
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
toEnvVars() {
|
|
46
|
+
return this.values
|
|
47
|
+
.map((value, key) => {
|
|
48
|
+
if (!isObject(value)) {
|
|
49
|
+
return {
|
|
50
|
+
name: key,
|
|
51
|
+
value: `${value}`
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const resourceValue = value as EnvVarFrom<api.v1_.Secret | api.v1_.ConfigMap>
|
|
55
|
+
switch (resourceValue.$ref.kind) {
|
|
56
|
+
case api.v1_.Secret:
|
|
57
|
+
return {
|
|
58
|
+
name: key,
|
|
59
|
+
valueFrom: this._envFromSecret(resourceValue as any)
|
|
60
|
+
}
|
|
61
|
+
case api.v1_.ConfigMap:
|
|
62
|
+
return {
|
|
63
|
+
name: key,
|
|
64
|
+
valueFrom: this._envFromConfigMap(resourceValue as any)
|
|
65
|
+
}
|
|
66
|
+
default:
|
|
67
|
+
throw new MakeError("Invalid environment variable reference", {
|
|
68
|
+
key: key,
|
|
69
|
+
value: value
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
.valueSeq()
|
|
74
|
+
.toArray()
|
|
75
|
+
}
|
|
76
|
+
private _withEnv(f: (env: _EnvBuilderMap) => _EnvBuilderMap) {
|
|
77
|
+
return new EnvBuilder(f(this._env))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
add(name: string, value: InputEnvMapping[string]): EnvBuilder
|
|
81
|
+
add(input: InputEnvMapping): EnvBuilder
|
|
82
|
+
add(a: any, b?: any) {
|
|
83
|
+
const pairs: [string, string][] = typeof a === "string" ? [[a, b]] : Object.entries(a)
|
|
84
|
+
const map = Map(pairs)
|
|
85
|
+
const existingKeys = map
|
|
86
|
+
.keySeq()
|
|
87
|
+
.filter(k => this._env.has(k))
|
|
88
|
+
.toList()
|
|
89
|
+
if (existingKeys.size > 0) {
|
|
90
|
+
throw new MakeError("Cannot overwrite existing keys using add", {
|
|
91
|
+
keys: existingKeys.toArray()
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
return this._withEnv(env => env.merge(map) as any)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
overwrite(name: string, value: string): EnvBuilder
|
|
98
|
+
overwrite(input: InputEnvMapping): EnvBuilder
|
|
99
|
+
overwrite(a: any, b?: any) {
|
|
100
|
+
if (typeof a === "string") {
|
|
101
|
+
return this._withEnv(env => env.set(a, b))
|
|
102
|
+
} else {
|
|
103
|
+
const map = Map(a as InputEnvMapping) as _EnvBuilderMap
|
|
104
|
+
return this._withEnv(env => env.merge(map) as any)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
toObject() {
|
|
109
|
+
return this._env
|
|
110
|
+
.filter(v => v != null)
|
|
111
|
+
.map(x => `${x}`)
|
|
112
|
+
.toObject()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static make(env?: InputEnv) {
|
|
116
|
+
if (!env) {
|
|
117
|
+
return new EnvBuilder(Map({}))
|
|
118
|
+
}
|
|
119
|
+
if (env instanceof EnvBuilder) {
|
|
120
|
+
return env
|
|
121
|
+
}
|
|
122
|
+
return new EnvBuilder(Map(env ?? {}).filter(v => v != null) as _EnvBuilderMap)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function Env(env?: InputEnvMapping) {
|
|
127
|
+
return EnvBuilder.make(env)
|
|
128
|
+
}
|
package/src/env/index.ts
ADDED
package/src/env/types.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Kind, Refable } from "@k8ts/instruments"
|
|
2
|
+
import type { EnvBuilder } from "./env"
|
|
3
|
+
|
|
4
|
+
export type InputEnvValue = string | null | number | boolean | bigint | undefined | EnvVarFrom
|
|
5
|
+
export type InputEnvMapping = Partial<Record<string, InputEnvValue>>
|
|
6
|
+
export interface EnvVarFrom<_Kind extends Kind = Kind> {
|
|
7
|
+
$ref: Refable<_Kind>
|
|
8
|
+
key: string
|
|
9
|
+
optional?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type InputEnv = EnvBuilder | InputEnvMapping
|
|
13
|
+
|
|
14
|
+
export type EnvFrom<_Kind extends Kind = Kind> = {
|
|
15
|
+
$ref: Refable<_Kind>
|
|
16
|
+
prefix?: string
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { anyCharOf, digit, letter } from "parjs"
|
|
2
|
+
import { many, or, stringify, then } from "parjs/combinators"
|
|
3
|
+
|
|
4
|
+
const pEnvVarStartChar = letter().pipe(or(anyCharOf("_")))
|
|
5
|
+
const pEnvVarChar = pEnvVarStartChar.pipe(or(digit()))
|
|
6
|
+
const pEnvVarName = pEnvVarStartChar.pipe(then(pEnvVarChar.pipe(many())), stringify())
|
|
7
|
+
|
|
8
|
+
export function isValidEnvVarName(x: string) {
|
|
9
|
+
return pEnvVarName.parse(x).isOk
|
|
10
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Env,
|
|
3
2
|
Kinded,
|
|
4
3
|
PortSet,
|
|
5
4
|
relations,
|
|
@@ -7,16 +6,16 @@ import {
|
|
|
7
6
|
Unit,
|
|
8
7
|
WritableDeep,
|
|
9
8
|
type CmdBuilder,
|
|
10
|
-
type InputEnvMapping,
|
|
11
9
|
type InputPortSetRecord,
|
|
12
10
|
type TaggedImage
|
|
13
11
|
} from "@k8ts/instruments"
|
|
14
12
|
import { Map } from "immutable"
|
|
15
13
|
import type { CDK } from "../../../_imports"
|
|
16
|
-
import { toContainerPorts
|
|
14
|
+
import { toContainerPorts } from "../../utils/adapters"
|
|
17
15
|
|
|
18
16
|
import { seq } from "doddle"
|
|
19
17
|
import { mapKeys, mapValues, omitBy } from "lodash"
|
|
18
|
+
import { Env, type InputEnvMapping } from "../../../env"
|
|
20
19
|
import { k8ts } from "../../../kind-map"
|
|
21
20
|
import { api } from "../../../kinds"
|
|
22
21
|
import type { ManifestResource } from "../../../node"
|
|
@@ -35,7 +34,6 @@ export namespace Container {
|
|
|
35
34
|
export type Mounts = {
|
|
36
35
|
[key: string]: SomeMount
|
|
37
36
|
}
|
|
38
|
-
|
|
39
37
|
interface K8tsPropsClean<Ports extends string = never> {
|
|
40
38
|
image: TaggedImage
|
|
41
39
|
ports?: InputPortSetRecord<Ports>
|
|
@@ -99,7 +97,7 @@ export namespace Container {
|
|
|
99
97
|
ports: $ports && toContainerPorts(PortSet.make($ports)).valueSeq().toArray(),
|
|
100
98
|
resources: self._resources()?.toObject(),
|
|
101
99
|
command: $command?.toArray(),
|
|
102
|
-
env:
|
|
100
|
+
env: Env($env).toEnvVars(),
|
|
103
101
|
...self._groupedMounts()
|
|
104
102
|
}
|
|
105
103
|
return container
|
|
@@ -64,6 +64,7 @@ export namespace Service {
|
|
|
64
64
|
private get backend() {
|
|
65
65
|
return this.props.$backend as Deployment<ExposedPorts>
|
|
66
66
|
}
|
|
67
|
+
// TODO: Ports force evaluates the backend which is not needed
|
|
67
68
|
get ports() {
|
|
68
69
|
const srcPorts = this.backend.ports.pull()
|
|
69
70
|
const knownPorts = Map(this.props.$ports)
|
|
@@ -86,7 +87,7 @@ export namespace Service {
|
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
private _getPortoPart(port: ExposedPorts, protocol: "http" | "https") {
|
|
89
|
-
const portNumber = this.ports
|
|
90
|
+
const portNumber = this.props.$ports[port]
|
|
90
91
|
if (portNumber === 80 && protocol === "http") {
|
|
91
92
|
return ""
|
|
92
93
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PortMap, PortMapEntry, PortSet, PortSetEntry } from "@k8ts/instruments"
|
|
2
2
|
import { CDK } from "../../_imports"
|
|
3
|
-
|
|
4
3
|
export function toContainerPort(entry: PortSetEntry): CDK.ContainerPort {
|
|
5
4
|
return {
|
|
6
5
|
containerPort: entry.port,
|
|
@@ -27,12 +26,3 @@ export function toServicePort(entry: PortMapEntry): CDK.ServicePort {
|
|
|
27
26
|
export function toServicePorts(ports: PortMap<any>) {
|
|
28
27
|
return ports.values.map(toServicePort).toList()
|
|
29
28
|
}
|
|
30
|
-
|
|
31
|
-
export function toEnvVars(env: EnvBuilder) {
|
|
32
|
-
return env.values.map((x, key) => {
|
|
33
|
-
return {
|
|
34
|
-
name: key,
|
|
35
|
-
value: `${x}`
|
|
36
|
-
} as CDK.EnvVar
|
|
37
|
-
})
|
|
38
|
-
}
|