UNPKG

@cdklib/argo-synth

Version:

Manage ArgoCD structure with cdk8s

175 lines (168 loc) 5.93 kB
'use strict'; var path3 = require('path'); var cdk8s = require('cdk8s'); var promises = require('fs/promises'); var child_process = require('child_process'); var util = require('util'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var path3__default = /*#__PURE__*/_interopDefault(path3); // src/paths.ts var SYNTH_PATH_KEY = "@cdklib/argocd/synthPath"; var addSynthPath = (scope, ...suffixes) => { let currentPath = ""; try { currentPath = getSynthPath(scope); } catch { } const basePath = currentPath ? [currentPath] : []; scope.node.setContext(SYNTH_PATH_KEY, path3__default.default.join(...basePath, ...suffixes)); }; var getSynthPath = (scope) => { try { return scope.node.getContext(SYNTH_PATH_KEY); } catch (e) { if (e instanceof Error && e.message.includes("No context value")) { throw new Error("No synth path found - call addSynthPath first"); } throw e; } }; var GitOpsHelmChart = class extends cdk8s.Chart { name; version; repository; values; constructor(scope, { name, values, synthPath, version, repository }) { super(scope, name, {}); this.name = name; this.version = version; this.values = values; this.repository = repository; const pathParts = Array.isArray(synthPath) ? synthPath : [synthPath]; addSynthPath(this, ...pathParts); } }; var wipeDirectory = async (dirname) => { await util.promisify(child_process.exec)(`rm -rf ${dirname}`); await promises.mkdir(dirname, { recursive: true }); }; var ensureDirectory = async (dirname) => { await promises.mkdir(dirname, { recursive: true }); }; // src/synth/api-object.ts var getApiObjects = (...scopes) => scopes.flatMap( (s) => s.node.findAll().map((s2) => { if (s2 instanceof cdk8s.ApiObject) return { apiObject: s2, outputPath: getSynthPath(s2) }; const apiObject = s2.apiObject; if (apiObject) return { apiObject, outputPath: getSynthPath(s2) }; return void 0; }).filter(Boolean) ); var synthApiObjects = async (outputPath, scope, suffix) => { const apiObjects = getApiObjects(scope); if (!apiObjects.length) return; const uniqueSubPaths = new Set(apiObjects.map(({ outputPath: outputPath2 }) => outputPath2)); await Promise.all( Array.from(uniqueSubPaths).map( (subPath) => ensureDirectory(path3__default.default.join(outputPath, subPath, ...suffix ? [suffix] : [])) ) ); await Promise.all( apiObjects.map(({ apiObject, outputPath: subPath }) => { return promises.writeFile( path3__default.default.join( outputPath, subPath, ...suffix ? [suffix] : [], `${apiObject.kind}.${apiObject.name}.yaml` ), cdk8s.Yaml.stringify(apiObject.toJson()) ); }) ); }; var HELM_TEMPLATES_PATH = "templates"; var synthHelmChart = async (outputPath, helmChart) => { const { name, version, repository, values } = helmChart; const chartOutputPath = path3__default.default.join(outputPath, getSynthPath(helmChart)); await ensureDirectory(chartOutputPath); const apiObjects = helmChart.apiObjects; let apiObjectsPromise = Promise.resolve(); if (apiObjects.length > 0) { const templatesOutputPath = path3__default.default.join(chartOutputPath, HELM_TEMPLATES_PATH); await ensureDirectory(templatesOutputPath); apiObjectsPromise = synthApiObjects(outputPath, helmChart, HELM_TEMPLATES_PATH); } const chartYaml = { apiVersion: "v2", name, version, description: `${name} cluster addon, managed by CDK8S.`, dependencies: [{ name, repository, version }] }; const chartYamlPromise = promises.writeFile( path3__default.default.join(chartOutputPath, "Chart.yaml"), cdk8s.Yaml.stringify(chartYaml) ); const chartValues = { [name]: values }; const valuesPromise = promises.writeFile( path3__default.default.join(chartOutputPath, "values.yaml"), cdk8s.Yaml.stringify(chartValues) ); await Promise.all([apiObjectsPromise, chartYamlPromise, valuesPromise]); }; var execAsync = util.promisify(child_process.exec); var synthApp = async (outputPath, app) => { const helmCharts = []; const otherCharts = []; app.charts.forEach((o) => { if (o instanceof GitOpsHelmChart && "repository" in o) { helmCharts.push(o); } else { otherCharts.push(o); } }); const appSynthPromises = otherCharts.map(async (chart) => { await synthApiObjects(outputPath, chart); }); await Promise.all([ ...helmCharts.map((helmChart) => synthHelmChart(outputPath, helmChart)), ...appSynthPromises ]); }; var createFileTree = async (outputPath) => { try { const { stdout } = await execAsync(`tree ${outputPath} -I "node_modules"`); return stdout; } catch { try { const { stdout } = await execAsync(`find ${outputPath} -type f | sort`); return stdout.split("\n").filter(Boolean).join("\n"); } catch { return `Could not generate file listing for ${outputPath}. Please check the directory manually.`; } } }; var synthApps = async (outputPath, apps, { clean = false, summary = true } = {}) => { if (clean) await wipeDirectory(outputPath); const allSynthesizedFiles = await Promise.all(apps.map((app) => synthApp(outputPath, app))); const flattenedFiles = allSynthesizedFiles.flat(); if (summary && flattenedFiles.length > 0) { const treeOutput = await createFileTree(outputPath); console.log(treeOutput); } }; // src/index.ts var ArgoSynth = class { /** Synthesizes multiple applications with regards to ArgoCD paths */ static synth = synthApps; /** Adds a suffix to the synthesized path for ArgoCD apps */ static addPath = addSynthPath; /** Gets the synth path for the cdk8s App / Chart */ static getPath = getSynthPath; }; exports.ArgoSynth = ArgoSynth; exports.GitOpsHelmChart = GitOpsHelmChart; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map