Add --fqdn-policy option to deploy-webapp-from-registry. (#802)
Some checks failed
Fixturenet-Eth-Plugeth-Arm-Test / Run an Ethereum plugeth fixturenet test (push) Failing after 1s
K8s Deploy Test / Run deploy test suite on kind/k8s (push) Successful in 9m38s
Fixturenet-Eth-Plugeth-Test / Run an Ethereum plugeth fixturenet test (push) Failing after 3h10m0s
Database Test / Run database hosting test on kind/k8s (push) Successful in 10m11s
Lint Checks / Run linter (push) Successful in 57s
Publish / Build and publish (push) Successful in 1m34s
Webapp Test / Run webapp test suite (push) Successful in 5m8s
Deploy Test / Run deploy test suite (push) Successful in 6m20s
Smoke Test / Run basic test suite (push) Successful in 5m30s
Fixturenet-Laconicd-Test / Run Laconicd fixturenet and Laconic CLI tests (push) Successful in 14m49s

This add a new option `--fqdn-policy` to the `deploy-webapp-from-registry`.

The default policy, `prohibit` means that `ApplicationDeploymentRequests` which specify a FQDN will be rejected.  The `allow` policy will cause them to be processed.  The `preexisting` policy will only process them if an existing `DnsRecord` exists in the registry with the correct ownership.

The latter would be useful in conjunction with a pre-checking scheme in the UI (eg, that the DNS entry is properly configured, the domain is under the control of the requestor, etc.)  Only after all the checks were successful would the `DnsRecord` be created, allowing for `ApplicationDeploymentRequests` to use it.

Reviewed-on: #802
Reviewed-by: David Boreham <dboreham@noreply.git.vdb.to>
Co-authored-by: Thomas E Lackey <telackey@bozemanpass.com>
Co-committed-by: Thomas E Lackey <telackey@bozemanpass.com>
This commit is contained in:
Thomas E Lackey 2024-04-15 12:20:35 +00:00 committed by David Boreham
parent 345d200873
commit 4126f2fc43

View File

@ -39,11 +39,12 @@ def process_app_deployment_request(
app_deployment_request, app_deployment_request,
deployment_record_namespace, deployment_record_namespace,
dns_record_namespace, dns_record_namespace,
dns_suffix, default_dns_suffix,
deployment_parent_dir, deployment_parent_dir,
kube_config, kube_config,
image_registry, image_registry,
force_rebuild, force_rebuild,
fqdn_policy,
logger logger
): ):
logger.log("BEGIN - process_app_deployment_request") logger.log("BEGIN - process_app_deployment_request")
@ -56,14 +57,15 @@ def process_app_deployment_request(
requested_name = hostname_for_deployment_request(app_deployment_request, laconic) requested_name = hostname_for_deployment_request(app_deployment_request, laconic)
logger.log(f"Determined requested name: {requested_name}") logger.log(f"Determined requested name: {requested_name}")
# HACK
if "." in requested_name: if "." in requested_name:
raise Exception("Only unqualified hostnames allowed at this time.") if "allow" == fqdn_policy or "preexisting" == fqdn_policy:
fqdn = requested_name
fqdn = f"{requested_name}.{dns_suffix}" else:
raise Exception(f"{requested_name} is invalid: only unqualified hostnames are allowed.")
else:
fqdn = f"{requested_name}.{default_dns_suffix}"
# 3. check ownership of existing dnsrecord vs this request # 3. check ownership of existing dnsrecord vs this request
# TODO: Support foreign DNS
dns_crn = f"{dns_record_namespace}/{fqdn}" dns_crn = f"{dns_record_namespace}/{fqdn}"
dns_record = laconic.get_record(dns_crn) dns_record = laconic.get_record(dns_crn)
if dns_record: if dns_record:
@ -75,7 +77,9 @@ def process_app_deployment_request(
logger.log(f"Matched DnsRecord ownership: {matched_owner}") logger.log(f"Matched DnsRecord ownership: {matched_owner}")
else: else:
raise Exception("Unable to confirm ownership of DnsRecord %s for request %s" % raise Exception("Unable to confirm ownership of DnsRecord %s for request %s" %
(dns_record.id, app_deployment_request.id)) (dns_crn, app_deployment_request.id))
elif "preexisting" == fqdn_policy:
raise Exception(f"No pre-existing DnsRecord {dns_crn} could be found for request {app_deployment_request.id}.")
# 4. get build and runtime config from request # 4. get build and runtime config from request
env_filename = None env_filename = None
@ -191,6 +195,7 @@ def dump_known_requests(filename, requests, status="SEEN"):
@click.option("--state-file", help="File to store state about previously seen requests.") @click.option("--state-file", help="File to store state about previously seen requests.")
@click.option("--only-update-state", help="Only update the state file, don't process any requests anything.", is_flag=True) @click.option("--only-update-state", help="Only update the state file, don't process any requests anything.", is_flag=True)
@click.option("--dns-suffix", help="DNS domain to use eg, laconic.servesthe.world") @click.option("--dns-suffix", help="DNS domain to use eg, laconic.servesthe.world")
@click.option("--fqdn-policy", help="How to handle requests with an FQDN: prohibit, allow, preexisting", default="prohibit")
@click.option("--record-namespace-dns", help="eg, crn://laconic/dns") @click.option("--record-namespace-dns", help="eg, crn://laconic/dns")
@click.option("--record-namespace-deployments", help="eg, crn://laconic/deployments") @click.option("--record-namespace-deployments", help="eg, crn://laconic/deployments")
@click.option("--dry-run", help="Don't do anything, just report what would be done.", is_flag=True) @click.option("--dry-run", help="Don't do anything, just report what would be done.", is_flag=True)
@ -201,7 +206,7 @@ def dump_known_requests(filename, requests, status="SEEN"):
@click.pass_context @click.pass_context
def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_dir, # noqa: C901 def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_dir, # noqa: C901
request_id, discover, state_file, only_update_state, request_id, discover, state_file, only_update_state,
dns_suffix, record_namespace_dns, record_namespace_deployments, dry_run, dns_suffix, fqdn_policy, record_namespace_dns, record_namespace_deployments, dry_run,
include_tags, exclude_tags, force_rebuild, log_dir): include_tags, exclude_tags, force_rebuild, log_dir):
if request_id and discover: if request_id and discover:
print("Cannot specify both --request-id and --discover", file=sys.stderr) print("Cannot specify both --request-id and --discover", file=sys.stderr)
@ -220,6 +225,10 @@ def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_
print("--dns-suffix, --record-namespace-dns, and --record-namespace-deployments are all required", file=sys.stderr) print("--dns-suffix, --record-namespace-dns, and --record-namespace-deployments are all required", file=sys.stderr)
sys.exit(2) sys.exit(2)
if fqdn_policy not in ["prohibit", "allow", "preexisting"]:
print("--fqdn-policy must be one of 'prohibit', 'allow', or 'preexisting'", file=sys.stderr)
sys.exit(2)
# Split CSV and clean up values. # Split CSV and clean up values.
include_tags = [tag.strip() for tag in include_tags.split(",") if tag] include_tags = [tag.strip() for tag in include_tags.split(",") if tag]
exclude_tags = [tag.strip() for tag in exclude_tags.split(",") if tag] exclude_tags = [tag.strip() for tag in exclude_tags.split(",") if tag]
@ -334,6 +343,7 @@ def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_
kube_config, kube_config,
image_registry, image_registry,
force_rebuild, force_rebuild,
fqdn_policy,
logger logger
) )
status = "DEPLOYED" status = "DEPLOYED"