Add deployment update
and deploy-webapp-from-registry
commands.
#676
@ -26,7 +26,8 @@ import click
|
||||
from stack_orchestrator.deploy.webapp import deploy_webapp
|
||||
from stack_orchestrator.deploy.webapp.util import (AttrDict, LaconicRegistryClient,
|
||||
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(
|
||||
@ -54,6 +55,26 @@ def process_app_deployment_request(
|
||||
container_tag = "%s:local" % app.attributes.name.replace("@", "")
|
||||
|
||||
# 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
|
||||
env_filename = None
|
||||
@ -109,34 +130,13 @@ def process_app_deployment_request(
|
||||
app,
|
||||
deployment_record,
|
||||
app_deployment_crn,
|
||||
dns_record,
|
||||
dns_crn,
|
||||
deployment_dir,
|
||||
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):
|
||||
if filename and os.path.exists(filename):
|
||||
return json.load(open(filename, "r"))
|
||||
|
@ -20,6 +20,8 @@ import random
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import uuid
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
@ -219,28 +221,84 @@ def deploy_to_k8s(deploy_record, deployment_dir):
|
||||
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:
|
||||
version = "0.0.1"
|
||||
deploy_ver = "0.0.1"
|
||||
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")))
|
||||
hostname = spec["network"]["http-proxy"][0]["host-name"]
|
||||
fqdn = spec["network"]["http-proxy"][0]["host-name"]
|
||||
|
||||
record = {
|
||||
uniq = uuid.uuid4()
|
||||
|
||||
new_dns_record = {
|
||||
"record": {
|
||||
"type": "ApplicationDeploymentRecord",
|
||||
"version": version,
|
||||
"url": f"https://{hostname}",
|
||||
"name": hostname,
|
||||
"application": app_record["id"],
|
||||
"type": "DnsRecord",
|
||||
"version": dns_ver,
|
||||
"name": fqdn,
|
||||
"resource_type": "A",
|
||||
"meta": {
|
||||
"config": file_hash(os.path.join(deployment_dir, "config.env"))
|
||||
"so": uniq.hex
|
||||
},
|
||||
}
|
||||
}
|
||||
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