Check DNS owner
This commit is contained in:
parent
d991ebed09
commit
a6e4b6c62d
@ -26,7 +26,8 @@ import click
|
|||||||
from stack_orchestrator.deploy.webapp import deploy_webapp
|
from stack_orchestrator.deploy.webapp import deploy_webapp
|
||||||
from stack_orchestrator.deploy.webapp.util import (AttrDict, LaconicRegistryClient,
|
from stack_orchestrator.deploy.webapp.util import (AttrDict, LaconicRegistryClient,
|
||||||
build_container_image, push_container_image,
|
build_container_image, push_container_image,
|
||||||
file_hash, deploy_to_k8s, publish_deployment)
|
file_hash, deploy_to_k8s, publish_deployment,
|
||||||
|
hostname_for_deployment_request, generate_hostname_for_app)
|
||||||
|
|
||||||
|
|
||||||
def process_app_deployment_request(
|
def process_app_deployment_request(
|
||||||
@ -54,6 +55,26 @@ def process_app_deployment_request(
|
|||||||
container_tag = "%s:local" % app.attributes.name.replace("@", "")
|
container_tag = "%s:local" % app.attributes.name.replace("@", "")
|
||||||
|
|
||||||
# 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_record = laconic.get_record(dns_crn)
|
||||||
|
if dns_record:
|
||||||
|
dns_record_owners = dns_record.owners
|
||||||
|
dns_request_owners = []
|
||||||
|
if dns_record.request:
|
||||||
|
prev_request = laconic.get_record(dns_record.request, require=True)
|
||||||
|
dns_request_owners = prev_request.owners
|
||||||
|
|
||||||
|
owner_match = None
|
||||||
|
|
||||||
|
for owner in app_deployment_request.owners:
|
||||||
|
if owner in dns_request_owners or owner in dns_record_owners:
|
||||||
|
owner_match = owner
|
||||||
|
if owner_match:
|
||||||
|
print("Matched DnsRecord ownership to", owner)
|
||||||
|
else:
|
||||||
|
raise Exception("Unable to confirm ownership of DnsRecord %s for request %s" %
|
||||||
|
(dns_record.id, 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
|
||||||
@ -109,34 +130,13 @@ def process_app_deployment_request(
|
|||||||
app,
|
app,
|
||||||
deployment_record,
|
deployment_record,
|
||||||
app_deployment_crn,
|
app_deployment_crn,
|
||||||
|
dns_record,
|
||||||
|
dns_crn,
|
||||||
deployment_dir,
|
deployment_dir,
|
||||||
app_deployment_request
|
app_deployment_request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def hostname_for_deployment_request(app_deployment_request, laconic):
|
|
||||||
dns_name = app_deployment_request.attributes.dns
|
|
||||||
if not dns_name:
|
|
||||||
app = laconic.get_record(app_deployment_request.attributes.application, require=True)
|
|
||||||
dns_name = generate_hostname_for_app(app)
|
|
||||||
elif dns_name.startswith("crn://"):
|
|
||||||
record = laconic.get_record(dns_name, require=True)
|
|
||||||
dns_name = record.attributes.name
|
|
||||||
return dns_name
|
|
||||||
|
|
||||||
|
|
||||||
def generate_hostname_for_app(app):
|
|
||||||
last_part = app.attributes.name.split("/")[-1]
|
|
||||||
m = hashlib.sha256()
|
|
||||||
m.update(app.attributes.name.encode())
|
|
||||||
m.update(b"|")
|
|
||||||
if isinstance(app.attributes.repository, list):
|
|
||||||
m.update(app.attributes.repository[0].encode())
|
|
||||||
else:
|
|
||||||
m.update(app.attributes.repository.encode())
|
|
||||||
return "%s-%s" % (last_part, m.hexdigest()[0:10])
|
|
||||||
|
|
||||||
|
|
||||||
def load_known_requests(filename):
|
def load_known_requests(filename):
|
||||||
if filename and os.path.exists(filename):
|
if filename and os.path.exists(filename):
|
||||||
return json.load(open(filename, "r"))
|
return json.load(open(filename, "r"))
|
||||||
|
@ -20,6 +20,8 @@ import random
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import uuid
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
@ -219,28 +221,84 @@ def deploy_to_k8s(deploy_record, deployment_dir):
|
|||||||
result.check_returncode()
|
result.check_returncode()
|
||||||
|
|
||||||
|
|
||||||
def publish_deployment(laconic: LaconicRegistryClient, app_record, deploy_record, deployment_crn, deployment_dir, app_deployment_request=None):
|
def publish_deployment(laconic: LaconicRegistryClient,
|
||||||
|
app_record,
|
||||||
|
deploy_record,
|
||||||
|
deployment_crn,
|
||||||
|
dns_record,
|
||||||
|
dns_crn,
|
||||||
|
deployment_dir,
|
||||||
|
app_deployment_request=None):
|
||||||
if not deploy_record:
|
if not deploy_record:
|
||||||
version = "0.0.1"
|
deploy_ver = "0.0.1"
|
||||||
else:
|
else:
|
||||||
version = "0.0.%d" % (int(deploy_record["attributes"]["version"].split(".")[-1]) + 1)
|
deploy_ver = "0.0.%d" % (int(deploy_record.attributes.version.split(".")[-1]) + 1)
|
||||||
|
|
||||||
|
if not dns_record:
|
||||||
|
dns_ver = "0.0.1"
|
||||||
|
else:
|
||||||
|
dns_ver = "0.0.%d" % (int(dns_record.attributes.version.split(".")[-1]) + 1)
|
||||||
|
|
||||||
spec = yaml.full_load(open(os.path.join(deployment_dir, "spec.yml")))
|
spec = yaml.full_load(open(os.path.join(deployment_dir, "spec.yml")))
|
||||||
hostname = spec["network"]["http-proxy"][0]["host-name"]
|
fqdn = spec["network"]["http-proxy"][0]["host-name"]
|
||||||
|
|
||||||
record = {
|
uniq = uuid.uuid4()
|
||||||
|
|
||||||
|
new_dns_record = {
|
||||||
"record": {
|
"record": {
|
||||||
"type": "ApplicationDeploymentRecord",
|
"type": "DnsRecord",
|
||||||
"version": version,
|
"version": dns_ver,
|
||||||
"url": f"https://{hostname}",
|
"name": fqdn,
|
||||||
"name": hostname,
|
"resource_type": "A",
|
||||||
"application": app_record["id"],
|
|
||||||
"meta": {
|
"meta": {
|
||||||
"config": file_hash(os.path.join(deployment_dir, "config.env"))
|
"so": uniq.hex
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if app_deployment_request:
|
if app_deployment_request:
|
||||||
record["record"]["request"] = app_deployment_request.id
|
new_dns_record["record"]["request"] = app_deployment_request.id
|
||||||
|
|
||||||
return laconic.publish(record, [deployment_crn])
|
dns_id = laconic.publish(new_dns_record, [dns_crn])
|
||||||
|
|
||||||
|
new_deployment_record = {
|
||||||
|
"record": {
|
||||||
|
"type": "ApplicationDeploymentRecord",
|
||||||
|
"version": deploy_ver,
|
||||||
|
"url": f"https://{fqdn}",
|
||||||
|
"name": app_record.attributes.name,
|
||||||
|
"application": app_record.id,
|
||||||
|
"dns": dns_id,
|
||||||
|
"meta": {
|
||||||
|
"config": file_hash(os.path.join(deployment_dir, "config.env")),
|
||||||
|
"so": uniq.hex
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if app_deployment_request:
|
||||||
|
new_deployment_record["record"]["request"] = app_deployment_request.id
|
||||||
|
|
||||||
|
deployment_id = laconic.publish(new_deployment_record, [deployment_crn])
|
||||||
|
return {"dns": dns_id, "deployment": deployment_id}
|
||||||
|
|
||||||
|
|
||||||
|
def hostname_for_deployment_request(app_deployment_request, laconic):
|
||||||
|
dns_name = app_deployment_request.attributes.dns
|
||||||
|
if not dns_name:
|
||||||
|
app = laconic.get_record(app_deployment_request.attributes.application, require=True)
|
||||||
|
dns_name = generate_hostname_for_app(app)
|
||||||
|
elif dns_name.startswith("crn://"):
|
||||||
|
record = laconic.get_record(dns_name, require=True)
|
||||||
|
dns_name = record.attributes.name
|
||||||
|
return dns_name
|
||||||
|
|
||||||
|
|
||||||
|
def generate_hostname_for_app(app):
|
||||||
|
last_part = app.attributes.name.split("/")[-1]
|
||||||
|
m = hashlib.sha256()
|
||||||
|
m.update(app.attributes.name.encode())
|
||||||
|
m.update(b"|")
|
||||||
|
if isinstance(app.attributes.repository, list):
|
||||||
|
m.update(app.attributes.repository[0].encode())
|
||||||
|
else:
|
||||||
|
m.update(app.attributes.repository.encode())
|
||||||
|
return "%s-%s" % (last_part, m.hexdigest()[0:10])
|
||||||
|
Loading…
Reference in New Issue
Block a user