diff --git a/docs/vault-bootstrap-testing.md b/docs/vault-bootstrap-testing.md index ed2eb45..b564c3f 100644 --- a/docs/vault-bootstrap-testing.md +++ b/docs/vault-bootstrap-testing.md @@ -307,13 +307,24 @@ tofu apply ``` ❌ **Expected**: Bootstrap fails with message about expired token -**Fix:** +**Fix (Option 1 - Regenerate token only):** ```bash +# Only regenerates the wrapped token, preserves all other configuration +nix run .#create-host -- --hostname vaulttest01 --regenerate-token +cd terraform +tofu apply +``` + +**Fix (Option 2 - Full regeneration with --force):** +```bash +# Overwrites entire host configuration (including any manual changes) nix run .#create-host -- --hostname vaulttest01 --force cd terraform tofu apply ``` +**Recommendation**: Use `--regenerate-token` to avoid losing manual configuration changes. + ### Scenario 6: Already-Used Wrapped Token Try to deploy the same VM twice without regenerating token. diff --git a/scripts/create-host/create_host.py b/scripts/create-host/create_host.py index 8e0612f..a86f86e 100644 --- a/scripts/create-host/create_host.py +++ b/scripts/create-host/create_host.py @@ -48,6 +48,7 @@ def main( 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. @@ -60,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( @@ -70,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]")