UNPKG

k8ts

Version:

Powerful framework for building Kubernetes manifests in TypeScript.

129 lines (118 loc) 4.09 kB
import { Map, type MapOf } from "immutable" import { isObject } from "what-are-you" import type { CDK } from "../_imports" import { MakeError } from "../error" import { api } from "../kinds" import type { EnvVarFrom, InputEnv, InputEnvMapping } from "./types" import { isValidEnvVarName } from "./validate-name" type _EnvBuilderMap = MapOf<InputEnvMapping> export class EnvBuilder { constructor(private readonly _env: _EnvBuilderMap) { for (const key of _env.keys()) { if (!isValidEnvVarName(key)) { throw new MakeError("Invalid environment variable name", { key: key }) } } } get values() { return this._env } private _envFromSecret(value: EnvVarFrom<api.v1_.Secret>): CDK.EnvVarSource { return { secretKeyRef: { name: value.$ref.name, key: value.key, optional: value.optional } } } private _envFromConfigMap(value: EnvVarFrom<api.v1_.ConfigMap>): CDK.EnvVarSource { return { configMapKeyRef: { name: value.$ref.name, key: value.key, optional: value.optional } } } toEnvVars() { return this.values .map((value, key) => { if (!isObject(value)) { return { name: key, value: `${value}` } } const resourceValue = value as EnvVarFrom<api.v1_.Secret | api.v1_.ConfigMap> switch (resourceValue.$ref.kind) { case api.v1_.Secret: return { name: key, valueFrom: this._envFromSecret(resourceValue as any) } case api.v1_.ConfigMap: return { name: key, valueFrom: this._envFromConfigMap(resourceValue as any) } default: throw new MakeError("Invalid environment variable reference", { key: key, value: value }) } }) .valueSeq() .toArray() } private _withEnv(f: (env: _EnvBuilderMap) => _EnvBuilderMap) { return new EnvBuilder(f(this._env)) } add(name: string, value: InputEnvMapping[string]): EnvBuilder add(input: InputEnvMapping): EnvBuilder add(a: any, b?: any) { const pairs: [string, string][] = typeof a === "string" ? [[a, b]] : Object.entries(a) const map = Map(pairs) const existingKeys = map .keySeq() .filter(k => this._env.has(k)) .toList() if (existingKeys.size > 0) { throw new MakeError("Cannot overwrite existing keys using add", { keys: existingKeys.toArray() }) } return this._withEnv(env => env.merge(map) as any) } overwrite(name: string, value: string): EnvBuilder overwrite(input: InputEnvMapping): EnvBuilder overwrite(a: any, b?: any) { if (typeof a === "string") { return this._withEnv(env => env.set(a, b)) } else { const map = Map(a as InputEnvMapping) as _EnvBuilderMap return this._withEnv(env => env.merge(map) as any) } } toObject() { return this._env .filter(v => v != null) .map(x => `${x}`) .toObject() } static make(env?: InputEnv) { if (!env) { return new EnvBuilder(Map({})) } if (env instanceof EnvBuilder) { return env } return new EnvBuilder(Map(env ?? {}).filter(v => v != null) as _EnvBuilderMap) } } export function Env(env?: InputEnvMapping) { return EnvBuilder.make(env) }