scripts: add create-host tool for automated host configuration generation
Implements Phase 2 of the automated deployment pipeline. This commit adds a Python CLI tool that automates the creation of NixOS host configurations, eliminating manual boilerplate and reducing errors. Features: - Python CLI using typer framework with rich terminal UI - Comprehensive validation (hostname format/uniqueness, IP subnet/uniqueness) - Jinja2 templates for NixOS configurations - Automatic updates to flake.nix and terraform/vms.tf - Support for both static IP and DHCP configurations - Dry-run mode for safe previews - Packaged as Nix derivation and added to devShell Usage: create-host --hostname myhost --ip 10.69.13.50/24 The tool generates: - hosts/<hostname>/default.nix - hosts/<hostname>/configuration.nix - Updates flake.nix with new nixosConfigurations entry - Updates terraform/vms.tf with new VM definition All generated configurations include full system imports (monitoring, SOPS, autoupgrade, etc.) and are validated with nix flake check and tofu validate. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
100
scripts/create-host/manipulators.py
Normal file
100
scripts/create-host/manipulators.py
Normal file
@@ -0,0 +1,100 @@
|
||||
"""Text manipulation for flake.nix and Terraform files."""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from models import HostConfig
|
||||
|
||||
|
||||
def update_flake_nix(config: HostConfig, repo_root: Path) -> None:
|
||||
"""
|
||||
Add new host entry to flake.nix nixosConfigurations.
|
||||
|
||||
Args:
|
||||
config: Host configuration
|
||||
repo_root: Path to repository root
|
||||
"""
|
||||
flake_path = repo_root / "flake.nix"
|
||||
content = flake_path.read_text()
|
||||
|
||||
# Find the closing of nixosConfigurations block
|
||||
# Pattern: " };\n packages ="
|
||||
pattern = r"( \};)\n( packages =)"
|
||||
|
||||
# Create new entry
|
||||
new_entry = f""" {config.hostname} = nixpkgs.lib.nixosSystem {{
|
||||
inherit system;
|
||||
specialArgs = {{
|
||||
inherit inputs self sops-nix;
|
||||
}};
|
||||
modules = [
|
||||
(
|
||||
{{ config, pkgs, ... }}:
|
||||
{{
|
||||
nixpkgs.overlays = commonOverlays;
|
||||
}}
|
||||
)
|
||||
./hosts/{config.hostname}
|
||||
sops-nix.nixosModules.sops
|
||||
];
|
||||
}};
|
||||
"""
|
||||
|
||||
# Insert new entry before closing brace
|
||||
replacement = rf"\g<1>\n{new_entry}\g<2>"
|
||||
|
||||
new_content, count = re.subn(pattern, replacement, content)
|
||||
|
||||
if count == 0:
|
||||
raise ValueError(
|
||||
"Could not find insertion point in flake.nix. "
|
||||
"Looking for pattern: ' };\\n devShells ='"
|
||||
)
|
||||
|
||||
flake_path.write_text(new_content)
|
||||
|
||||
|
||||
def update_terraform_vms(config: HostConfig, repo_root: Path) -> None:
|
||||
"""
|
||||
Add new VM entry to terraform/vms.tf locals.vms map.
|
||||
|
||||
Args:
|
||||
config: Host configuration
|
||||
repo_root: Path to repository root
|
||||
"""
|
||||
terraform_path = repo_root / "terraform" / "vms.tf"
|
||||
content = terraform_path.read_text()
|
||||
|
||||
# Find the closing of locals.vms block
|
||||
# Pattern: " }\n\n # Compute VM configurations"
|
||||
pattern = r"( \})\n\n( # Compute VM configurations)"
|
||||
|
||||
# Create new entry based on whether we have static IP or DHCP
|
||||
if config.is_static_ip:
|
||||
new_entry = f''' "{config.hostname}" = {{
|
||||
ip = "{config.ip}"
|
||||
cpu_cores = {config.cpu}
|
||||
memory = {config.memory}
|
||||
disk_size = "{config.disk}"
|
||||
}}
|
||||
'''
|
||||
else:
|
||||
new_entry = f''' "{config.hostname}" = {{
|
||||
cpu_cores = {config.cpu}
|
||||
memory = {config.memory}
|
||||
disk_size = "{config.disk}"
|
||||
}}
|
||||
'''
|
||||
|
||||
# Insert new entry before closing brace
|
||||
replacement = rf"{new_entry}\g<1>\n\n\g<2>"
|
||||
|
||||
new_content, count = re.subn(pattern, replacement, content)
|
||||
|
||||
if count == 0:
|
||||
raise ValueError(
|
||||
"Could not find insertion point in terraform/vms.tf. "
|
||||
"Looking for pattern: ' }\\n\\n # Compute VM configurations'"
|
||||
)
|
||||
|
||||
terraform_path.write_text(new_content)
|
||||
Reference in New Issue
Block a user