109 lines
3.7 KiB
Python

"""
Schémas Pydantic pour l'exécution Ansible.
"""
from datetime import datetime, timezone
from typing import Optional, List, Dict, Any, Literal
from pydantic import BaseModel, Field, field_validator
class AnsibleExecutionRequest(BaseModel):
"""Requête d'exécution de playbook Ansible."""
playbook: str = Field(..., description="Nom du playbook à exécuter")
target: str = Field(default="all", description="Hôte ou groupe cible")
extra_vars: Optional[Dict[str, Any]] = Field(default=None, description="Variables supplémentaires")
check_mode: bool = Field(default=False, description="Mode dry-run (--check)")
verbose: bool = Field(default=False, description="Mode verbeux")
class AdHocCommandRequest(BaseModel):
"""Requête pour exécuter une commande ad-hoc Ansible."""
target: str = Field(..., description="Hôte ou groupe cible")
command: str = Field(..., description="Commande shell à exécuter")
module: str = Field(default="shell", description="Module Ansible (shell, command, raw)")
become: bool = Field(default=False, description="Exécuter avec sudo")
timeout: int = Field(default=60, ge=5, le=600, description="Timeout en secondes")
category: Optional[str] = Field(default="default", description="Catégorie d'historique pour cette commande")
class AdHocCommandResult(BaseModel):
"""Résultat d'une commande ad-hoc."""
target: str
command: str
success: bool
return_code: int
stdout: str
stderr: Optional[str] = None
duration: float
hosts_results: Optional[Dict[str, Any]] = None
class AdHocHistoryEntry(BaseModel):
"""Entrée dans l'historique des commandes ad-hoc."""
id: str
command: str
target: str
module: str
become: bool
category: str = "default"
description: Optional[str] = None
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
last_used: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
use_count: int = 1
class AdHocHistoryCategory(BaseModel):
"""Catégorie pour organiser les commandes ad-hoc."""
name: str
description: Optional[str] = None
color: str = "#7c3aed"
icon: str = "fa-folder"
class PlaybookInfo(BaseModel):
"""Informations sur un playbook."""
name: str
filename: str
path: str
category: str = "general"
subcategory: str = "other"
hosts: str = "all"
size: int = 0
modified: Optional[str] = None
description: Optional[str] = None
class PlaybookContentRequest(BaseModel):
"""Requête pour sauvegarder le contenu d'un playbook."""
content: str = Field(..., description="Contenu YAML du playbook")
class PlaybooksListResponse(BaseModel):
"""Réponse API pour la liste des playbooks."""
playbooks: List[PlaybookInfo] = Field(default_factory=list)
categories: Dict[str, List[str]] = Field(default_factory=dict)
ansible_dir: str = ""
filter: Optional[str] = None
class BootstrapRequest(BaseModel):
"""Requête de bootstrap pour un hôte."""
host: str = Field(..., description="Adresse IP ou hostname de l'hôte")
root_password: str = Field(..., description="Mot de passe root pour la connexion initiale")
automation_user: str = Field(default="automation", description="Nom de l'utilisateur d'automatisation à créer")
class SSHConfigResponse(BaseModel):
"""Réponse de diagnostic de la configuration SSH."""
ssh_key_path: str
ssh_dir: str
ssh_dir_exists: bool
private_key_exists: bool
public_key_exists: bool
available_files: List[str] = Field(default_factory=list)
public_keys_found: List[str] = Field(default_factory=list)
active_private_key: Optional[str] = None
ssh_user: str
sshpass_available: bool