Some checks failed
Build / Code Quality Checks (push) Successful in 15m11s
Build / Build & Push Docker Images (worker) (push) Successful in 13m44s
Build / Build & Push Docker Images (frontend) (push) Successful in 5m8s
Build / Build & Push Docker Images (chat) (push) Failing after 30m7s
Build / Build & Push Docker Images (api) (push) Failing after 21m39s
299 lines
11 KiB
Python
Executable File
299 lines
11 KiB
Python
Executable File
#!/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()
|