added aim
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from aim.exceptions import ExternalCommandFailed
|
||||
from aim.external import command_available, run_external
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PlaybookSpec:
|
||||
key: str
|
||||
name: str
|
||||
filename: str
|
||||
category: str
|
||||
platforms: tuple[str, ...]
|
||||
extra_vars: tuple[str, ...] = ()
|
||||
customer_specific: bool = False
|
||||
ask_pass: bool = False
|
||||
require_vault: bool = False
|
||||
|
||||
|
||||
PLAYBOOKS: tuple[PlaybookSpec, ...] = (
|
||||
PlaybookSpec("checkmk_cleanup", "Cleanup CheckMK", "checkmk_cleanup.yml", "CheckMK", ("linux", "windows"), ("checkmk_cleanup_enabled=true",)),
|
||||
PlaybookSpec("checkmk_install_agent", "Install CheckMK Agent", "checkmk_install_agent.yml", "CheckMK", ("linux", "windows")),
|
||||
PlaybookSpec("checkmk_update_config", "Update CheckMK Config", "checkmk_update_config.yml", "CheckMK", ("linux", "windows")),
|
||||
PlaybookSpec("debug_ping", "Ping", "debug_ping.yml", "Debug", ("linux", "windows")),
|
||||
PlaybookSpec("debug_server_role_selection", "Server Role Selection", "debug_server_role_selection.yml", "Debug", ("linux", "windows")),
|
||||
PlaybookSpec("debug_disk_usage", "Disk Usage", "debug_disk_usage.yml", "Debug", ("windows",)),
|
||||
PlaybookSpec("patch_os", "Patch OS", "patch_os.yml", "Maintenance", ("linux", "windows")),
|
||||
PlaybookSpec("reboot_system", "Reboot System", "reboot_system.yml", "Maintenance", ("linux", "windows")),
|
||||
PlaybookSpec("backup_eventlog", "Backup Event Log", "backup_eventlog.yml", "Maintenance", ("windows",)),
|
||||
PlaybookSpec("start_stopped_services", "Start Stopped Services", "start_stopped_services.yml", "Maintenance", ("windows",)),
|
||||
PlaybookSpec("configure_sophos_initial", "Initial Bitformer Config", "configure_sophos_initial_bitformer_config.yml", "Sophos XGS", ("sophosxgs",), ask_pass=True, require_vault=True),
|
||||
PlaybookSpec("configure_sophosxgs", "Configure Sophos XGS", "configure_sophosxgs.yml", "Sophos XGS", ("sophosxgs",), customer_specific=True, ask_pass=True, require_vault=True),
|
||||
)
|
||||
|
||||
CATEGORY_ORDER = ("CheckMK", "Debug", "Maintenance", "Sophos XGS")
|
||||
|
||||
|
||||
class PlaybookManager:
|
||||
def __init__(self, customers, config):
|
||||
self.customers = customers
|
||||
self.config = config
|
||||
|
||||
@property
|
||||
def root(self) -> Path:
|
||||
return self.config.root_dir / "playbooks"
|
||||
|
||||
def categories(self) -> list[str]:
|
||||
return list(CATEGORY_ORDER)
|
||||
|
||||
def specs_for_category(self, category: str) -> list[PlaybookSpec]:
|
||||
return [spec for spec in PLAYBOOKS if spec.category == category]
|
||||
|
||||
def path(self, spec: PlaybookSpec, customer: str | None = None) -> Path:
|
||||
if spec.customer_specific:
|
||||
if not customer:
|
||||
raise ValueError(f"Customer is required for playbook {spec.name}")
|
||||
return self.root / "customers" / customer / spec.filename
|
||||
return self.root / spec.filename
|
||||
|
||||
def available(self, spec: PlaybookSpec, customer: str | None = None) -> bool:
|
||||
return self.path(spec, customer).is_file()
|
||||
|
||||
def run(self, customer: str, inventory: Path, spec: PlaybookSpec, *, limit: str | None = None) -> None:
|
||||
playbook = self.path(spec, customer)
|
||||
if not playbook.is_file():
|
||||
raise FileNotFoundError(playbook)
|
||||
if not inventory.is_file():
|
||||
raise FileNotFoundError(inventory)
|
||||
if not command_available("ansible-playbook"):
|
||||
raise ExternalCommandFailed("Required command not found: ansible-playbook")
|
||||
|
||||
args = ["ansible-playbook", "-i", str(inventory), str(playbook)]
|
||||
vault = inventory.parent / "group_vars" / "all" / "vault.yml"
|
||||
if spec.require_vault and not vault.is_file():
|
||||
raise FileNotFoundError(f"Required customer vault not found: {vault}")
|
||||
if vault.is_file():
|
||||
args.extend(["--vault-id", f"{customer}@prompt"])
|
||||
if spec.ask_pass:
|
||||
args.append("--ask-pass")
|
||||
if limit:
|
||||
args.extend(["--limit", limit])
|
||||
for extra_var in spec.extra_vars:
|
||||
args.extend(["-e", extra_var])
|
||||
|
||||
result = run_external(args, cwd=self.config.root_dir)
|
||||
if result.returncode:
|
||||
raise ExternalCommandFailed(f"Playbook failed with exit code {result.returncode}")
|
||||
Reference in New Issue
Block a user