UNPKG

kubricate

Version:

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

97 lines 3.19 kB
import path from 'node:path'; import c from 'ansis'; import { cloneDeep, merge } from 'lodash-es'; import { stringify as yamlStringify } from 'yaml'; import { getClassName } from '../../internal/utils.js'; import { version } from '../../version.js'; import { MetadataInjector } from '../MetadataInjector.js'; const defaultMetadata = { inject: true, injectManagedAt: true, injectResourceHash: true, injectVersion: true }; export class Renderer { logger; metadata; constructor(globalOptions, logger) { this.logger = logger; this.metadata = merge({}, defaultMetadata, globalOptions.metadata); } injectMetadata(resources, options) { const createInjector = resourceId => new MetadataInjector({ type: 'stack', kubricateVersion: version, managedAt: new Date().toISOString(), stackId: options.stackId, stackName: options.stackName, resourceId, inject: { managedAt: this.metadata.injectManagedAt, resourceHash: this.metadata.injectResourceHash, version: this.metadata.injectVersion } }); const output = {}; for (const [resourceId, resource] of Object.entries(resources)) { const clone = cloneDeep(resource); if (clone && typeof clone !== 'object') { this.logger.warn(c.yellow('Warning: Resource is not an object, skipping metadata injection.')); continue; } const injector = createInjector(resourceId); injector.inject(clone); output[resourceId] = clone; } return output; } renderStacks(config) { const output = []; if (!config.stacks || Object.keys(config.stacks ?? {}).length === 0) { throw new Error('No stacks found in config'); } for (const [stackId, stack] of Object.entries(config.stacks)) { let builtResources = {}; const stackName = stack.getName() ?? getClassName(stack) ?? 'unknown'; if (this.metadata.inject === true) { builtResources = this.injectMetadata(stack.build(), { stackId, stackName }); } else { builtResources = stack.build(); this.logger.debug(`Warning: Metadata injection is disabled, skipping metadata injection`); } for (const [resourceId, resource] of Object.entries(builtResources)) { const kind = resource?.kind || 'UnknownKind'; const name = resource?.metadata?.name || 'unnamed'; const content = yamlStringify(resource) + '---\n'; output.push({ stackName, kind, name, content, id: resourceId, stackId }); } } return output; } resolveOutputPath(resource, mode, stdout) { if (stdout) { // Create canonical name for the resource groped by stackId and resourceId return `${resource.stackId}.${resource.id}`; } switch (mode) { case 'flat': return 'stacks.yml'; case 'stack': return `${resource.stackId}.yml`; case 'resource': return path.join(resource.stackId, `${resource.kind}_${resource.id}.yml`); } throw new Error(`Unknown output mode: ${mode}`); } } //# sourceMappingURL=Renderer.js.map