UNPKG

kubricate

Version:

A TypeScript framework for building reusable, type-safe Kubernetes infrastructure — without the YAML mess.

146 lines (124 loc) 5.07 kB
import path from 'node:path'; import c from 'ansis'; import { type BaseLogger } from '@kubricate/core'; import { getConfig, getMatchConfigFile } from '../internal/load-config.js'; import type { GlobalConfigOptions } from '../internal/types.js'; import { validateId, verboseCliConfig, type Subcommand } from '../internal/utils.js'; import { SecretsOrchestrator } from '../secret/index.js'; import type { KubricateConfig } from '../types.js'; interface InitializeOptions<CommandOptions> { subject: Subcommand; commandOptions: CommandOptions; processConfig?: (config: KubricateConfig, commandOptions: CommandOptions, logger: BaseLogger) => BaseLogger; } export class ConfigLoader { constructor( protected options: GlobalConfigOptions, protected logger: BaseLogger ) {} /** * Initialize everything needed to run the command */ // public async initialize<CommandOptions extends Record<string, unknown>>(options: InitializeOptions<CommandOptions>) { // const { subject, commandOptions, processConfig } = options; // verboseCliConfig(commandOptions, this.logger, subject); // const config = await this.load(); // let logger = commandOptions.logger as BaseLogger | undefined ?? new ConsoleLogger(); // console.log(`this.logger Level: ${this.logger.level}`); // console.log(`logger Level: ${logger.level}`); // if (processConfig) { // logger = processConfig(config, commandOptions, logger); // } // this.setLogger(logger); // console.log(`this.logger Level: ${this.logger.level}`); // console.log(`logger Level: ${logger.level}`); // this.showVersion(); // const orchestrator = await this.prepare(config); // return { // config, // orchestrator, // } // } public async initialize<CommandOptions extends Record<string, unknown>>(options: InitializeOptions<CommandOptions>) { const { subject, commandOptions } = options; verboseCliConfig(commandOptions, this.logger, subject); const config = await this.load(); this.showVersion(); const orchestrator = await this.prepare(config); return { config, orchestrator, }; } public showVersion() { this.logger.log('\n' + c.bold(c.blue`kubricate`) + ` v${this.options.version}\n`); } public setLogger(logger: BaseLogger) { this.logger = logger; } protected injectLogger(config: KubricateConfig) { for (const stack of Object.values(config.stacks ?? {})) { stack.injectLogger(this.logger); } } private validateStackId(config: KubricateConfig | undefined) { if (!config) return; for (const stackId of Object.keys(config.stacks ?? {})) { validateId(stackId, 'stackId'); } } protected handleDeprecatedOptions(config: KubricateConfig | undefined): KubricateConfig { if (!config) return {}; if (!config.secret) return config; const { secret } = config; if (secret.manager && secret.registry) { throw new Error(`[config.secret] Cannot define both "manager" and "registry". Use "secretSpec" instead.`); } if (secret.manager || secret.registry) { this.logger.warn(`[config.secret] 'manager' and 'registry' are deprecated. Please use 'secretSpec' instead.`); } if (secret.manager) { config.secret = { ...secret, secretSpec: secret.manager }; } else if (secret.registry) { config.secret = { ...secret, secretSpec: secret.registry }; } delete config.secret.manager; delete config.secret.registry; return config; } public async load(): Promise<KubricateConfig> { const logger = this.logger; logger.debug('Initializing secrets orchestrator...'); let config: KubricateConfig | undefined; logger.debug('Loading configuration...'); config = await getConfig(this.options); config = this.handleDeprecatedOptions(config); if (!config) { logger.error(`No config file found matching '${getMatchConfigFile()}'`); logger.error(`Please ensure a config file exists in the root directory:\n ${this.options.root}`); logger.error(`If your config is located elsewhere, specify it using:\n --root <dir>`); logger.error(`Or specify a config file using:\n --config <file>`); logger.error(`Exiting...`); throw new Error('No config file found'); } this.validateStackId(config); logger.debug('Validated Stack Ids'); logger.debug('Configuration loaded: ' + JSON.stringify(config, null, 2)); return config; } public async prepare(config: KubricateConfig) { const logger = this.logger; logger.debug('Injecting logger into stacks...'); this.injectLogger(config); logger.debug('Injected logger into stacks.'); logger.debug('Creating secrets orchestrator...'); const workingDir = this.options.root ? path.resolve(this.options.root) : undefined; const orchestrator = SecretsOrchestrator.create({ config, logger, effectOptions: { workingDir }, }); logger.debug('Secrets orchestrator created.'); return orchestrator; } }