#!/usr/bin/env python3 """ Configuration Converter Converts between .env and values.yaml formats """ import os import sys import argparse from pathlib import Path from typing import Dict, Any import yaml def parse_env_file(env_file: Path) -> Dict[str, str]: """Parse .env file and return dictionary of variables.""" env_vars = {} with open(env_file, 'r') as f: for line in f: line = line.strip() # Skip comments and empty lines if not line or line.startswith('#'): continue # Parse KEY=VALUE if '=' in line: key, value = line.split('=', 1) env_vars[key.strip()] = value.strip() return env_vars def env_to_values(env_vars: Dict[str, str]) -> Dict[str, Any]: """Convert environment variables to values.yaml structure.""" values = { 'mongodb': { 'auth': { 'rootUsername': env_vars.get('MONGO_ROOT_USER', 'admin'), 'rootPassword': env_vars.get('MONGO_ROOT_PASSWORD', 'changeme'), 'database': env_vars.get('MONGODB_DATABASE', 'datacenter_docs'), }, 'url': env_vars.get('MONGODB_URL', 'mongodb://admin:changeme@mongodb:27017'), }, 'redis': { 'auth': { 'password': env_vars.get('REDIS_PASSWORD', 'changeme'), }, 'url': env_vars.get('REDIS_URL', 'redis://redis:6379/0'), }, 'mcp': { 'server': { 'url': env_vars.get('MCP_SERVER_URL', 'https://mcp.company.local'), 'apiKey': env_vars.get('MCP_API_KEY', 'your_mcp_api_key_here'), }, }, 'proxmox': { 'host': env_vars.get('PROXMOX_HOST', 'proxmox.example.com'), 'port': int(env_vars.get('PROXMOX_PORT', '8006')), 'auth': { 'user': env_vars.get('PROXMOX_USER', 'root@pam'), 'password': env_vars.get('PROXMOX_PASSWORD', 'your-password-here'), }, 'ssl': { 'verify': env_vars.get('PROXMOX_VERIFY_SSL', 'false').lower() == 'true', }, 'timeout': int(env_vars.get('PROXMOX_TIMEOUT', '30')), }, 'llm': { 'baseUrl': env_vars.get('LLM_BASE_URL', 'https://api.openai.com/v1'), 'apiKey': env_vars.get('LLM_API_KEY', 'sk-your-openai-api-key-here'), 'model': env_vars.get('LLM_MODEL', 'gpt-4-turbo-preview'), 'generation': { 'temperature': float(env_vars.get('LLM_TEMPERATURE', '0.3')), 'maxTokens': int(env_vars.get('LLM_MAX_TOKENS', '4096')), }, }, 'api': { 'host': env_vars.get('API_HOST', '0.0.0.0'), 'port': int(env_vars.get('API_PORT', '8000')), 'workers': int(env_vars.get('WORKERS', '4')), }, 'cors': { 'origins': env_vars.get('CORS_ORIGINS', 'http://localhost:3000').split(','), }, 'application': { 'logging': { 'level': env_vars.get('LOG_LEVEL', 'INFO'), }, 'debug': env_vars.get('DEBUG', 'false').lower() == 'true', }, 'celery': { 'broker': { 'url': env_vars.get('CELERY_BROKER_URL', 'redis://redis:6379/0'), }, 'result': { 'backend': env_vars.get('CELERY_RESULT_BACKEND', 'redis://redis:6379/0'), }, }, 'vectorStore': { 'chroma': { 'path': env_vars.get('VECTOR_STORE_PATH', './data/chroma_db'), }, 'embedding': { 'model': env_vars.get('EMBEDDING_MODEL', 'sentence-transformers/all-MiniLM-L6-v2'), }, }, } return values def values_to_env(values: Dict[str, Any]) -> Dict[str, str]: """Convert values.yaml structure to environment variables.""" env_vars = {} # MongoDB if 'mongodb' in values: mongo = values['mongodb'] if 'auth' in mongo: env_vars['MONGO_ROOT_USER'] = mongo['auth'].get('rootUsername', 'admin') env_vars['MONGO_ROOT_PASSWORD'] = mongo['auth'].get('rootPassword', 'changeme') env_vars['MONGODB_DATABASE'] = mongo['auth'].get('database', 'datacenter_docs') env_vars['MONGODB_URL'] = mongo.get('url', 'mongodb://admin:changeme@mongodb:27017') # Redis if 'redis' in values: redis = values['redis'] if 'auth' in redis: env_vars['REDIS_PASSWORD'] = redis['auth'].get('password', 'changeme') env_vars['REDIS_URL'] = redis.get('url', 'redis://redis:6379/0') # MCP if 'mcp' in values and 'server' in values['mcp']: mcp = values['mcp']['server'] env_vars['MCP_SERVER_URL'] = mcp.get('url', 'https://mcp.company.local') env_vars['MCP_API_KEY'] = mcp.get('apiKey', 'your_mcp_api_key_here') # Proxmox if 'proxmox' in values: px = values['proxmox'] env_vars['PROXMOX_HOST'] = px.get('host', 'proxmox.example.com') env_vars['PROXMOX_PORT'] = str(px.get('port', 8006)) if 'auth' in px: env_vars['PROXMOX_USER'] = px['auth'].get('user', 'root@pam') env_vars['PROXMOX_PASSWORD'] = px['auth'].get('password', 'your-password-here') if 'ssl' in px: env_vars['PROXMOX_VERIFY_SSL'] = str(px['ssl'].get('verify', False)).lower() env_vars['PROXMOX_TIMEOUT'] = str(px.get('timeout', 30)) # LLM if 'llm' in values: llm = values['llm'] env_vars['LLM_BASE_URL'] = llm.get('baseUrl', 'https://api.openai.com/v1') env_vars['LLM_API_KEY'] = llm.get('apiKey', 'sk-your-openai-api-key-here') env_vars['LLM_MODEL'] = llm.get('model', 'gpt-4-turbo-preview') if 'generation' in llm: env_vars['LLM_TEMPERATURE'] = str(llm['generation'].get('temperature', 0.3)) env_vars['LLM_MAX_TOKENS'] = str(llm['generation'].get('maxTokens', 4096)) # API if 'api' in values: api = values['api'] env_vars['API_HOST'] = api.get('host', '0.0.0.0') env_vars['API_PORT'] = str(api.get('port', 8000)) env_vars['WORKERS'] = str(api.get('workers', 4)) # CORS if 'cors' in values: origins = values['cors'].get('origins', ['http://localhost:3000']) env_vars['CORS_ORIGINS'] = ','.join(origins) # Application if 'application' in values: app = values['application'] if 'logging' in app: env_vars['LOG_LEVEL'] = app['logging'].get('level', 'INFO') env_vars['DEBUG'] = str(app.get('debug', False)).lower() # Celery if 'celery' in values: celery = values['celery'] if 'broker' in celery: env_vars['CELERY_BROKER_URL'] = celery['broker'].get('url', 'redis://redis:6379/0') if 'result' in celery: env_vars['CELERY_RESULT_BACKEND'] = celery['result'].get('backend', 'redis://redis:6379/0') # Vector Store if 'vectorStore' in values: vs = values['vectorStore'] if 'chroma' in vs: env_vars['VECTOR_STORE_PATH'] = vs['chroma'].get('path', './data/chroma_db') if 'embedding' in vs: env_vars['EMBEDDING_MODEL'] = vs['embedding'].get('model', 'sentence-transformers/all-MiniLM-L6-v2') return env_vars def write_env_file(env_vars: Dict[str, str], output_file: Path): """Write environment variables to .env file.""" with open(output_file, 'w') as f: f.write("# =============================================================================\n") f.write("# Datacenter Documentation System - Configuration\n") f.write("# Generated from values.yaml\n") f.write("# =============================================================================\n\n") # Group by section sections = { 'MongoDB': ['MONGO_ROOT_USER', 'MONGO_ROOT_PASSWORD', 'MONGODB_URL', 'MONGODB_DATABASE'], 'Redis': ['REDIS_PASSWORD', 'REDIS_URL'], 'MCP': ['MCP_SERVER_URL', 'MCP_API_KEY'], 'Proxmox': ['PROXMOX_HOST', 'PROXMOX_PORT', 'PROXMOX_USER', 'PROXMOX_PASSWORD', 'PROXMOX_VERIFY_SSL', 'PROXMOX_TIMEOUT'], 'LLM': ['LLM_BASE_URL', 'LLM_API_KEY', 'LLM_MODEL', 'LLM_TEMPERATURE', 'LLM_MAX_TOKENS'], 'API': ['API_HOST', 'API_PORT', 'WORKERS'], 'CORS': ['CORS_ORIGINS'], 'Application': ['LOG_LEVEL', 'DEBUG'], 'Celery': ['CELERY_BROKER_URL', 'CELERY_RESULT_BACKEND'], 'Vector Store': ['VECTOR_STORE_PATH', 'EMBEDDING_MODEL'], } for section, keys in sections.items(): f.write(f"# {section}\n") for key in keys: if key in env_vars: f.write(f"{key}={env_vars[key]}\n") f.write("\n") def main(): parser = argparse.ArgumentParser( description='Convert between .env and values.yaml configuration formats' ) parser.add_argument( 'mode', choices=['env-to-yaml', 'yaml-to-env'], help='Conversion mode' ) parser.add_argument( 'input', type=Path, help='Input file path' ) parser.add_argument( 'output', type=Path, help='Output file path' ) args = parser.parse_args() # Check input file exists if not args.input.exists(): print(f"Error: Input file not found: {args.input}", file=sys.stderr) sys.exit(1) try: if args.mode == 'env-to-yaml': # Convert .env to values.yaml print(f"Reading .env file: {args.input}") env_vars = parse_env_file(args.input) print("Converting to values.yaml format...") values = env_to_values(env_vars) print(f"Writing values.yaml: {args.output}") with open(args.output, 'w') as f: yaml.dump(values, f, default_flow_style=False, sort_keys=False, indent=2) print("✓ Conversion completed successfully!") else: # yaml-to-env # Convert values.yaml to .env print(f"Reading values.yaml file: {args.input}") with open(args.input, 'r') as f: values = yaml.safe_load(f) print("Converting to .env format...") env_vars = values_to_env(values) print(f"Writing .env file: {args.output}") write_env_file(env_vars, args.output) print("✓ Conversion completed successfully!") print(f"\nOutput written to: {args.output}") except Exception as e: print(f"Error during conversion: {e}", file=sys.stderr) sys.exit(1) if __name__ == '__main__': main()