- 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
175 lines
3.8 KiB
TypeScript
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()
|
|
|