UNPKG

@catladder/cli

Version:

Panter cli tool for cloud CI/CD and DevOps

193 lines (172 loc) • 4.83 kB
import type { Config, EnvironmentEnvVars, VariableValue, } from "@catladder/pipeline"; import { readConfig, getAllEnvs, getEnvironment as _getEnvironment, createComponentContext, getSecretVarName, } from "@catladder/pipeline"; import type { IO } from "../core/types"; import { getAllVariables, getVariableValueByRawName } from "../utils/gitlab"; import { getGitRoot } from "../utils/projects"; export { parseChoice } from "./parseChoice"; let currentConfig: Config | null = null; const loadConfig = async () => { const gitRoot = await getGitRoot(); if (!gitRoot) { return; } const result = await readConfig(gitRoot); if (!result) { return; } currentConfig = result.config; }; export const getProjectConfig = async () => { if (!currentConfig) { await loadConfig(); } return currentConfig as Config; }; export const getProjectComponents = async () => { const config = await getProjectConfig(); if (!config) return []; return Object.keys(config.components); }; export const getPipelineContextByChoice = async ( env: string, componentName: string, ) => { const config = await getProjectConfig(); return await createComponentContext({ config, componentName, env, }); }; export const getAllComponentsWithAllEnvsFlat = async (): Promise< Array<{ env: string; componentName: string }> > => { const config = await getProjectConfig(); if (!config) { return []; } return getAllComponentsWithAllEnvsFlatFromConfig(config); }; export const getAllComponentsWithAllEnvsHierarchical = async (): Promise<{ [componentName: string]: string[]; }> => { const config = await getProjectConfig(); if (!config) { return {}; } return Object.fromEntries( Object.keys(config.components).map((componentName) => [ componentName, getAllEnvs(config, componentName), ]), ); }; export const getAllPipelineContexts = async ( onlyComponent?: string | string[], { includeLocal = false }: { includeLocal?: boolean } = {}, ) => { const onlyComponentsArray = onlyComponent ? Array.isArray(onlyComponent) ? onlyComponent : [onlyComponent] : null; return Promise.all( (await getAllComponentsWithAllEnvsFlat()) .filter((c) => includeLocal || c.env !== "local") .filter( (c) => !onlyComponentsArray || onlyComponentsArray.includes(c.componentName), ) .map(({ env, componentName }) => getPipelineContextByChoice(env, componentName), ), ); }; export const getEnvironment = async (env: string, componentName: string) => { const config = await getProjectConfig(); return _getEnvironment({ config, componentName, env }); }; export const getGitlabVar = async ( io: IO, env: string, componentName: string, variableName: string, ) => { const rawVariableName = getSecretVarName(env, componentName, variableName); return await getVariableValueByRawName(io, rawVariableName); }; const resolveSecrets = async ( io: IO | null, varSets: EnvironmentEnvVars[], ): Promise<Record<string, string>> => { const allVariablesInGitlab = await getAllVariables(io); return Object.fromEntries( varSets.flatMap(({ envVars, secretEnvVarKeys }) => Object.entries(envVars) .filter( ([key, value]) => value !== undefined && value !== null && !secretEnvVarKeys.find((k) => k.key === key)?.hidden, ) .map(([key, value]) => [ key, allVariablesInGitlab.reduce( (acc, curr) => acc.replace(new RegExp("\\$" + curr.key, "g"), curr.value), `${value}`, ), ]), ), ); }; export const getEnvVarsResolved = async ( io: IO | null, env: string, componentName: string | null, ) => { if (!componentName) { return {}; } const envionment = await getEnvironment(env, componentName); // in the pipeline the secrets alreadyy exists and bash will expand them // but here we need to manually load them return resolveSecrets(io, [ { envVars: envionment.envVars, secretEnvVarKeys: envionment.secretEnvVarKeys, }, ]); }; /** * * is used to get job only vars that should also be editable locally with catladder. */ export const getJobOnlyEnvVarsResolved = async ( io: IO, env: string, componentName: string, ) => { const envionment = await getEnvironment(env, componentName); return resolveSecrets(io, [ envionment.jobOnlyVars.build, envionment.jobOnlyVars.deploy, ]); }; function getAllComponentsWithAllEnvsFlatFromConfig( config: Config, ): { env: string; componentName: string }[] { return Object.keys(config.components).flatMap((componentName) => getAllEnvs(config, componentName).map((env) => ({ env, componentName })), ); }