diff --git a/machine/subcommands/create.py b/machine/subcommands/create.py index 77dcf3e..5324d79 100644 --- a/machine/subcommands/create.py +++ b/machine/subcommands/create.py @@ -12,6 +12,13 @@ from machine.types import TAG_MACHINE_SESSION_PREFIX +def _validate_dns_zone(provider, dns_zone): + available_zones = provider.list_domains() + if dns_zone not in available_zones: + zones_str = ", ".join(available_zones) if available_zones else "none" + fatal_error(f"Error: DNS zone '{dns_zone}' not found in {provider.provider_name}. Available zones: {zones_str}") + + @click.command(help="Create a machine") @click.option("--name", "-n", required=True, metavar="", help="Name for new machine") @click.option("--tag", "-t", metavar="", help="tag to be applied to new machine") @@ -34,6 +41,9 @@ def command(context, name, tag, type, region, machine_size, image, wait_for_ip, if update_dns and not config.dns_zone: fatal_error("Error: DNS update requested but no zone configured") + if update_dns and config.dns_zone: + _validate_dns_zone(provider, config.dns_zone) + user_data = None if initialize: if not type: diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 176559d..bd94947 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -255,6 +255,31 @@ def instance(config_file, session_id): # --------------------------------------------------------------------------- +class TestDnsZonePreFlight: + """Verify that create fails fast when the configured DNS zone does not exist.""" + + def test_create_fails_for_nonexistent_dns_zone(self, tmp_path, session_id): + bogus_zone = f"bogus-{uuid.uuid4().hex[:8]}.example" + cfg_path = tmp_path / "config.yml" + _write_config(cfg_path, **{"dns-zone": bogus_zone}) + + result = run_machine( + "create", + "--name", + _unique_name(), + "--type", + "e2e-basic", + "--no-initialize", + "--update-dns", + config_file=cfg_path, + session_id=session_id, + ) + assert result.returncode != 0, "Expected create to fail for nonexistent DNS zone" + combined = result.stdout + result.stderr + assert bogus_zone in combined, f"Error should mention the bogus zone '{bogus_zone}'" + assert "not found" in combined.lower(), "Error should indicate zone was not found" + + class TestInstanceLifecycle: """Create one instance with all features and verify each aspect independently.