Files
Sankofa/api/src/lib/helm-executor.ts
defiQUG 9daf1fd378 Apply Composer changes: comprehensive API updates, migrations, middleware, and infrastructure improvements
- Add comprehensive database migrations (001-024) for schema evolution
- Enhance API schema with expanded type definitions and resolvers
- Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth
- Implement new services: AI optimization, billing, blockchain, compliance, marketplace
- Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage)
- Update Crossplane provider with enhanced VM management capabilities
- Add comprehensive test suite for API endpoints and services
- Update frontend components with improved GraphQL subscriptions and real-time updates
- Enhance security configurations and headers (CSP, CORS, etc.)
- Update documentation and configuration files
- Add new CI/CD workflows and validation scripts
- Implement design system improvements and UI enhancements
2025-12-12 18:01:35 -08:00

175 lines
3.8 KiB
TypeScript

/**
* Helm Executor
* Wraps Helm CLI operations
*/
import { exec } from 'child_process'
import { promisify } from 'util'
import { logger } from './logger.js'
const execAsync = promisify(exec)
export interface HelmInstallOptions {
releaseName: string
chart: string
namespace?: string
valuesFile?: string
values?: Record<string, any>
version?: string
wait?: boolean
timeout?: string
}
export interface HelmUpgradeOptions extends HelmInstallOptions {
reuseValues?: boolean
}
export class HelmExecutor {
/**
* Check if Helm is available
*/
async checkHelmInstalled(): Promise<boolean> {
try {
await execAsync('helm version')
return true
} catch {
return false
}
}
/**
* Install Helm chart
*/
async install(options: HelmInstallOptions): Promise<{ stdout: string; stderr: string }> {
const args: string[] = [
'install',
options.releaseName,
options.chart,
]
if (options.namespace) {
args.push('--namespace', options.namespace)
}
if (options.valuesFile) {
args.push('--values', options.valuesFile)
}
if (options.version) {
args.push('--version', options.version)
}
if (options.wait) {
args.push('--wait')
}
if (options.timeout) {
args.push('--timeout', options.timeout)
}
if (options.values) {
// Write values to temp file and use --set-file or --set
// For now, we'll use --set for simple values
for (const [key, value] of Object.entries(options.values)) {
args.push('--set', `${key}=${JSON.stringify(value)}`)
}
}
logger.info('Executing Helm install', { args })
return execAsync(`helm ${args.join(' ')}`)
}
/**
* Upgrade Helm release
*/
async upgrade(options: HelmUpgradeOptions): Promise<{ stdout: string; stderr: string }> {
const args: string[] = [
'upgrade',
options.releaseName,
options.chart,
]
if (options.namespace) {
args.push('--namespace', options.namespace)
}
if (options.valuesFile) {
args.push('--values', options.valuesFile)
}
if (options.version) {
args.push('--version', options.version)
}
if (options.wait) {
args.push('--wait')
}
if (options.timeout) {
args.push('--timeout', options.timeout)
}
if (options.reuseValues) {
args.push('--reuse-values')
}
logger.info('Executing Helm upgrade', { args })
return execAsync(`helm ${args.join(' ')}`)
}
/**
* Uninstall Helm release
*/
async uninstall(releaseName: string, namespace?: string): Promise<{ stdout: string; stderr: string }> {
const args: string[] = ['uninstall', releaseName]
if (namespace) {
args.push('--namespace', namespace)
}
logger.info('Executing Helm uninstall', { args })
return execAsync(`helm ${args.join(' ')}`)
}
/**
* Get release status
*/
async status(releaseName: string, namespace?: string): Promise<any> {
const args: string[] = ['status', releaseName, '--output', 'json']
if (namespace) {
args.push('--namespace', namespace)
}
try {
const { stdout } = await execAsync(`helm ${args.join(' ')}`)
return JSON.parse(stdout)
} catch (error) {
logger.error('Failed to get Helm status', { error })
throw error
}
}
/**
* List releases
*/
async list(namespace?: string): Promise<any[]> {
const args: string[] = ['list', '--output', 'json']
if (namespace) {
args.push('--namespace', namespace)
}
try {
const { stdout } = await execAsync(`helm ${args.join(' ')}`)
return JSON.parse(stdout)
} catch (error) {
logger.error('Failed to list Helm releases', { error })
throw error
}
}
}
export const helmExecutor = new HelmExecutor()