|
| 1 | +import * as k8s from '@kubernetes/client-node'; |
| 2 | +import * as fs from 'fs'; |
| 3 | +import * as yaml from 'js-yaml'; |
| 4 | +import { promisify } from 'util'; |
| 5 | + |
| 6 | +/** |
| 7 | + * Replicate the functionality of `kubectl apply`. That is, create the resources defined in the `specFile` if they do |
| 8 | + * not exist, patch them if they do exist. |
| 9 | + * |
| 10 | + * @param specPath File system path to a YAML Kubernetes spec. |
| 11 | + * @return Array of resources created |
| 12 | + */ |
| 13 | +export async function apply(specPath: string): Promise<k8s.KubernetesObject[]> { |
| 14 | + const kc = new k8s.KubeConfig(); |
| 15 | + kc.loadFromDefault(); |
| 16 | + const client = k8s.KubernetesObjectApi.makeApiClient(kc); |
| 17 | + const fsReadFileP = promisify(fs.readFile); |
| 18 | + const specString = await fsReadFileP(specPath, 'utf8'); |
| 19 | + const specs: k8s.KubernetesObject[] = yaml.safeLoadAll(specString); |
| 20 | + const validSpecs = specs.filter((s) => s && s.kind && s.metadata); |
| 21 | + const created: k8s.KubernetesObject[] = []; |
| 22 | + for (const spec of validSpecs) { |
| 23 | + // this is to convince the old version of TypeScript that metadata exists even though we already filtered specs |
| 24 | + // without metadata out |
| 25 | + spec.metadata = spec.metadata || {}; |
| 26 | + spec.metadata.annotations = spec.metadata.annotations || {}; |
| 27 | + delete spec.metadata.annotations['kubectl.kubernetes.io/last-applied-configuration']; |
| 28 | + spec.metadata.annotations['kubectl.kubernetes.io/last-applied-configuration'] = JSON.stringify(spec); |
| 29 | + try { |
| 30 | + // try to get the resource, if it does not exist an error will be thrown and we will end up in the catch |
| 31 | + // block. |
| 32 | + await client.read(spec); |
| 33 | + // we got the resource, so it exists, so patch it |
| 34 | + const response = await client.patch(spec); |
| 35 | + created.push(response.body); |
| 36 | + } catch (e) { |
| 37 | + // we did not get the resource, so it does not exist, so create it |
| 38 | + const response = await client.create(spec); |
| 39 | + created.push(response.body); |
| 40 | + } |
| 41 | + } |
| 42 | + return created; |
| 43 | +} |
0 commit comments