#!/bin/bash # ============================================================================== # validate-service-descriptors.sh - Validacion de service descriptors # ============================================================================== # Uso: ./validate-service-descriptors.sh [directorio-proyecto] # ============================================================================== set -e # Colores RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # Rutas SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONTROL_PLANE="${SCRIPT_DIR}/../../.." PORTS_REGISTRY="${CONTROL_PLANE}/registries/ports.registry.yml" DOMAINS_REGISTRY="${CONTROL_PLANE}/registries/domains.registry.yml" DATABASES_REGISTRY="${CONTROL_PLANE}/registries/databases.registry.yml" echo -e "${YELLOW}=== Validando Service Descriptors ===${NC}" # Directorio a validar PROJECT_DIR="${1:-.}" if [ ! -d "$PROJECT_DIR" ]; then echo -e "${RED}ERROR: Directorio no existe: $PROJECT_DIR${NC}" exit 1 fi echo "Directorio: $PROJECT_DIR" # Buscar todos los service.descriptor.yml DESCRIPTORS=$(find "$PROJECT_DIR" -name "service.descriptor.yml" 2>/dev/null || true) if [ -z "$DESCRIPTORS" ]; then echo -e "${YELLOW}WARN: No se encontraron service descriptors${NC}" exit 0 fi ERRORS=0 VALIDATED=0 for descriptor in $DESCRIPTORS; do echo "" echo -e "${YELLOW}Validando: $descriptor${NC}" # 1. Verificar YAML valido if ! python3 -c "import yaml; yaml.safe_load(open('$descriptor'))" 2>/dev/null; then echo -e " ${RED}[ERROR]${NC} YAML invalido" ERRORS=$((ERRORS + 1)) continue fi echo -e " ${GREEN}[OK]${NC} YAML valido" # 2. Validar campos obligatorios y referencias python3 << EOF import yaml import sys descriptor_path = "$descriptor" ports_registry_path = "$PORTS_REGISTRY" databases_registry_path = "$DATABASES_REGISTRY" errors = [] # Cargar descriptor with open(descriptor_path, 'r') as f: desc = yaml.safe_load(f) # Campos obligatorios en service required_service = ['name', 'type', 'runtime', 'owner_agent'] for field in required_service: if field not in desc.get('service', {}): errors.append(f"Campo obligatorio faltante: service.{field}") # Campos obligatorios en repository required_repo = ['name', 'path'] for field in required_repo: if field not in desc.get('repository', {}): errors.append(f"Campo obligatorio faltante: repository.{field}") # Campos obligatorios en ports if 'ports' in desc: if 'internal' not in desc['ports']: errors.append("Campo obligatorio faltante: ports.internal") if 'registry_ref' not in desc['ports']: errors.append("Campo obligatorio faltante: ports.registry_ref") # Validar referencia a ports registry if desc.get('ports', {}).get('registry_ref'): try: with open(ports_registry_path, 'r') as f: ports_reg = yaml.safe_load(f) ref = desc['ports']['registry_ref'] # Formato esperado: "projects.gamilit.api" parts = ref.split('.') if len(parts) >= 3 and parts[0] == 'projects': project = parts[1] service = parts[2] if project not in ports_reg.get('projects', {}): errors.append(f"ports.registry_ref: proyecto '{project}' no existe en registry") elif service not in ports_reg['projects'][project].get('services', {}): errors.append(f"ports.registry_ref: servicio '{service}' no existe en registry") else: # Verificar que el puerto coincide reg_port = ports_reg['projects'][project]['services'][service].get('internal') desc_port = desc['ports'].get('internal') if reg_port != desc_port: errors.append(f"Puerto no coincide: descriptor={desc_port}, registry={reg_port}") except Exception as e: errors.append(f"No se pudo validar ports.registry_ref: {e}") # Validar referencia a database registry if desc.get('database', {}).get('registry_ref'): try: with open(databases_registry_path, 'r') as f: db_reg = yaml.safe_load(f) ref = desc['database']['registry_ref'] if ref not in db_reg.get('databases', {}): errors.append(f"database.registry_ref: '{ref}' no existe en registry") except Exception as e: errors.append(f"No se pudo validar database.registry_ref: {e}") # Imprimir resultados if errors: for err in errors: print(f" \033[0;31m[ERROR]\033[0m {err}") sys.exit(1) else: print(f" \033[0;32m[OK]\033[0m Todos los campos obligatorios presentes") print(f" \033[0;32m[OK]\033[0m Referencias a registries validas") sys.exit(0) EOF if [ $? -eq 0 ]; then VALIDATED=$((VALIDATED + 1)) else ERRORS=$((ERRORS + 1)) fi done # Resultado final echo "" echo "========================================" echo "Descriptors validados: $VALIDATED" echo "Errores: $ERRORS" echo "========================================" if [ $ERRORS -eq 0 ]; then echo -e "${GREEN}=== Validacion exitosa ===${NC}" exit 0 else echo -e "${RED}=== Validacion fallida ===${NC}" exit 1 fi