vault: implement bootstrap integration
This commit is contained in:
@@ -9,9 +9,10 @@ from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.table import Table
|
||||
|
||||
from generators import generate_host_files
|
||||
from manipulators import update_flake_nix, update_terraform_vms
|
||||
from generators import generate_host_files, generate_vault_terraform
|
||||
from manipulators import update_flake_nix, update_terraform_vms, add_wrapped_token_to_vm
|
||||
from models import HostConfig
|
||||
from vault_helper import generate_wrapped_token
|
||||
from validators import (
|
||||
validate_hostname_format,
|
||||
validate_hostname_unique,
|
||||
@@ -46,6 +47,8 @@ def main(
|
||||
disk: str = typer.Option("20G", "--disk", help="Disk size (e.g., 20G, 50G, 100G)"),
|
||||
dry_run: bool = typer.Option(False, "--dry-run", help="Preview changes without creating files"),
|
||||
force: bool = typer.Option(False, "--force", help="Overwrite existing host configuration"),
|
||||
skip_vault: bool = typer.Option(False, "--skip-vault", help="Skip Vault configuration and token generation"),
|
||||
regenerate_token: bool = typer.Option(False, "--regenerate-token", help="Only regenerate Vault wrapped token (no other changes)"),
|
||||
) -> None:
|
||||
"""
|
||||
Create a new NixOS host configuration.
|
||||
@@ -58,6 +61,51 @@ def main(
|
||||
ctx.get_help()
|
||||
sys.exit(1)
|
||||
|
||||
# Get repository root
|
||||
repo_root = get_repo_root()
|
||||
|
||||
# Handle token regeneration mode
|
||||
if regenerate_token:
|
||||
# Validate that incompatible options aren't used
|
||||
if force or dry_run or skip_vault:
|
||||
console.print("[bold red]Error:[/bold red] --regenerate-token cannot be used with --force, --dry-run, or --skip-vault\n")
|
||||
sys.exit(1)
|
||||
if ip or cpu != 2 or memory != 2048 or disk != "20G":
|
||||
console.print("[bold red]Error:[/bold red] --regenerate-token only regenerates the token. Other options (--ip, --cpu, --memory, --disk) are ignored.\n")
|
||||
console.print("[yellow]Tip:[/yellow] Use without those options, or use --force to update the entire configuration.\n")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
console.print(f"\n[bold blue]Regenerating Vault token for {hostname}...[/bold blue]")
|
||||
|
||||
# Validate hostname exists
|
||||
host_dir = repo_root / "hosts" / hostname
|
||||
if not host_dir.exists():
|
||||
console.print(f"[bold red]Error:[/bold red] Host {hostname} does not exist")
|
||||
console.print(f"Host directory not found: {host_dir}")
|
||||
sys.exit(1)
|
||||
|
||||
# Generate new wrapped token
|
||||
wrapped_token = generate_wrapped_token(hostname, repo_root)
|
||||
|
||||
# Update only the wrapped token in vms.tf
|
||||
add_wrapped_token_to_vm(hostname, wrapped_token, repo_root)
|
||||
console.print("[green]✓[/green] Regenerated and updated wrapped token in terraform/vms.tf")
|
||||
|
||||
console.print("\n[bold green]✓ Token regenerated successfully![/bold green]")
|
||||
console.print(f"\n[yellow]⚠️[/yellow] Token expires in 24 hours")
|
||||
console.print(f"[yellow]⚠️[/yellow] Deploy the VM within 24h or regenerate token again\n")
|
||||
|
||||
console.print("[bold cyan]Next steps:[/bold cyan]")
|
||||
console.print(f" cd terraform && tofu apply")
|
||||
console.print(f" # Then redeploy VM to pick up new token\n")
|
||||
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
console.print(f"\n[bold red]Error regenerating token:[/bold red] {e}\n")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
# Build configuration
|
||||
config = HostConfig(
|
||||
@@ -68,9 +116,6 @@ def main(
|
||||
disk=disk,
|
||||
)
|
||||
|
||||
# Get repository root
|
||||
repo_root = get_repo_root()
|
||||
|
||||
# Validate configuration
|
||||
console.print("\n[bold blue]Validating configuration...[/bold blue]")
|
||||
|
||||
@@ -116,11 +161,34 @@ def main(
|
||||
update_terraform_vms(config, repo_root, force=force)
|
||||
console.print("[green]✓[/green] Updated terraform/vms.tf")
|
||||
|
||||
# Generate Vault configuration if not skipped
|
||||
if not skip_vault:
|
||||
console.print("\n[bold blue]Configuring Vault integration...[/bold blue]")
|
||||
|
||||
try:
|
||||
# Generate Vault Terraform configuration
|
||||
generate_vault_terraform(hostname, repo_root)
|
||||
console.print("[green]✓[/green] Updated terraform/vault/hosts-generated.tf")
|
||||
|
||||
# Generate wrapped token
|
||||
wrapped_token = generate_wrapped_token(hostname, repo_root)
|
||||
|
||||
# Add wrapped token to VM configuration
|
||||
add_wrapped_token_to_vm(hostname, wrapped_token, repo_root)
|
||||
console.print("[green]✓[/green] Added wrapped token to terraform/vms.tf")
|
||||
|
||||
except Exception as e:
|
||||
console.print(f"\n[yellow]⚠️ Vault configuration failed: {e}[/yellow]")
|
||||
console.print("[yellow]Host configuration created without Vault integration[/yellow]")
|
||||
console.print("[yellow]You can add Vault support later by re-running with --force[/yellow]\n")
|
||||
else:
|
||||
console.print("\n[yellow]Skipped Vault configuration (--skip-vault)[/yellow]")
|
||||
|
||||
# Success message
|
||||
console.print("\n[bold green]✓ Host configuration generated successfully![/bold green]\n")
|
||||
|
||||
# Display next steps
|
||||
display_next_steps(hostname)
|
||||
display_next_steps(hostname, skip_vault=skip_vault)
|
||||
|
||||
except ValueError as e:
|
||||
console.print(f"\n[bold red]Error:[/bold red] {e}\n", style="red")
|
||||
@@ -164,8 +232,18 @@ def display_dry_run_summary(config: HostConfig, repo_root: Path) -> None:
|
||||
console.print(f" • {repo_root}/terraform/vms.tf (add VM definition)")
|
||||
|
||||
|
||||
def display_next_steps(hostname: str) -> None:
|
||||
def display_next_steps(hostname: str, skip_vault: bool = False) -> None:
|
||||
"""Display next steps after successful generation."""
|
||||
vault_files = "" if skip_vault else " terraform/vault/hosts-generated.tf"
|
||||
vault_apply = ""
|
||||
|
||||
if not skip_vault:
|
||||
vault_apply = """
|
||||
4a. Apply Vault configuration:
|
||||
[white]cd terraform/vault
|
||||
tofu apply[/white]
|
||||
"""
|
||||
|
||||
next_steps = f"""[bold cyan]Next Steps:[/bold cyan]
|
||||
|
||||
1. Review changes:
|
||||
@@ -181,14 +259,16 @@ def display_next_steps(hostname: str) -> None:
|
||||
tofu plan[/white]
|
||||
|
||||
4. Commit changes:
|
||||
[white]git add hosts/{hostname} flake.nix terraform/vms.tf
|
||||
[white]git add hosts/{hostname} flake.nix terraform/vms.tf{vault_files}
|
||||
git commit -m "hosts: add {hostname} configuration"[/white]
|
||||
|
||||
5. Deploy VM (after merging to master):
|
||||
{vault_apply}
|
||||
5. Deploy VM (after merging to master or within 24h of token generation):
|
||||
[white]cd terraform
|
||||
tofu apply[/white]
|
||||
|
||||
6. Bootstrap the host (see Phase 3 of deployment pipeline)
|
||||
6. Host will bootstrap automatically on first boot
|
||||
- Wrapped token expires in 24 hours
|
||||
- If expired, re-run: create-host --hostname {hostname} --force
|
||||
"""
|
||||
console.print(Panel(next_steps, border_style="cyan"))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user