UNPKG

@atomist/sdm

Version:

Atomist Software Delivery Machine SDK

161 lines 5.67 kB
"use strict"; /* * Copyright © 2020 Atomist, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.specStringSnippet = exports.specSnippet = exports.specSlug = exports.parseKubernetesSpecs = exports.kubernetesSpecStringify = exports.kubernetesSpecFileBasename = void 0; const yaml = require("js-yaml"); const stableStringify = require("json-stable-stringify"); const stringify = require("json-stringify-safe"); const secret_1 = require("./secret"); /** * Create a suitable basename for the spec file for `resource`. The * form of the file name is "NN-NAMESPACE-NAME-KIND", where "NN" is a * numeric prefix so the resources are created in the proper order, * "NAMESPACE-" is omitted if resource is not namespaced, the kind is * converted from PascalCase to kebab-case, and the whole name is * lowercased. * * @param resource Kubernetes resource spec * @return Base file name for resource spec */ function kubernetesSpecFileBasename(resource) { let prefix; switch (resource.kind) { case "Namespace": prefix = "10"; break; case "PersistentVolume": case "StorageClass": prefix = "15"; break; case "ServiceAccount": prefix = "20"; break; case "ClusterRole": case "Role": prefix = "25"; break; case "ClusterRoleBinding": case "RoleBinding": prefix = "30"; break; case "NetworkPolicy": case "PersistentVolumeClaim": case "PodSecurityPolicy": prefix = "40"; break; case "Service": prefix = "50"; break; case "ConfigMap": case "Secret": prefix = "60"; break; case "CronJob": case "DaemonSet": case "Deployment": case "StatefulSet": prefix = "70"; break; case "HorizontalPodAutoscaler": case "Ingress": case "PodDisruptionBudget": prefix = "80"; break; default: prefix = "90"; break; } const ns = (resource.metadata.namespace) ? `${resource.metadata.namespace}_` : ""; const kebabKind = resource.kind.replace(/([a-z])([A-Z])/g, "$1-$2"); return `${prefix}_${ns}${resource.metadata.name}_${kebabKind}`.toLowerCase(); } exports.kubernetesSpecFileBasename = kubernetesSpecFileBasename; /** * Convert a Kubernetes resource spec into a stable string suitable * for writing to a file or comparisons. * * @param resource Kubernetes resource to stringify * @param options Options for serializing the resource spec * @return Stable string representation of the resource spec */ async function kubernetesSpecStringify(spec, options = {}) { let resource = spec; if (resource.kind === "Secret" && options.secretKey) { resource = await secret_1.encryptSecret(resource, options.secretKey); } if (options.format === "yaml") { return yaml.safeDump(resource, { sortKeys: true }); } else { return stableStringify(resource, { space: 2 }) + "\n"; } } exports.kubernetesSpecStringify = kubernetesSpecStringify; /** * Parses content of string as Kubernetes JSON or YAML specs. It * parses the file as YAML, since JSON is valid YAML, and returns an * array of [[k8s.KubernetesObject]]s, since a YAML file can contain multiple * documents. It validates that each document parsed looks something * like a Kubernetes spec. If it does not, it is filtered out of the * returned specs. * * @param specString String representation of Kubernetes spec(s) * @return Parsed and filtered Kubernetes spec objects */ function parseKubernetesSpecs(specString) { if (!specString) { return []; } try { const specs = yaml.safeLoadAll(specString); return specs.filter(s => s && s.apiVersion && s.kind && s.metadata && s.metadata.name); } catch (e) { e.spec = specString; e.message = `Failed to parse Kubernetes spec '${specStringSnippet(specString)}': ${e.message}`; throw e; } } exports.parseKubernetesSpecs = parseKubernetesSpecs; /** Return unique string for spec. */ function specSlug(spec) { const parts = [spec.apiVersion]; if (spec.metadata && spec.metadata.namespace) { parts.push(spec.metadata.namespace); } const plural = spec.kind.toLowerCase().replace(/s$/, "se").replace(/y$/, "ie") + "s"; parts.push(plural, spec.metadata.name); return parts.join("/"); } exports.specSlug = specSlug; /** Convert spec to string and shorten it if necessary. */ function specSnippet(spec) { return specStringSnippet(stringify(spec)); } exports.specSnippet = specSnippet; /** Return beginning snippet from spec string. */ function specStringSnippet(spec) { const max = 200; if (spec.length > max) { return spec.substring(0, max - 4) + "...}"; } else { return spec; } } exports.specStringSnippet = specStringSnippet; //# sourceMappingURL=spec.js.map