137 lines
4.6 KiB
Python
Executable File
137 lines
4.6 KiB
Python
Executable File
#!/usr/bin/python3
|
|
#
|
|
# For a usage examples, see README.md
|
|
#
|
|
# TODO
|
|
#
|
|
# - make the action idempotent (i.e. if you run it multiple times, the first
|
|
# run will create/delete the registry, and the reset will be a no-op and won't
|
|
# error out)
|
|
#
|
|
# - take only a plain authentication file, and create the encrypted version in
|
|
# the action
|
|
#
|
|
# - validate the parameters (make sure tlscert is a certificate, that tlskey is a
|
|
# proper key, etc)
|
|
#
|
|
# - when https://bugs.launchpad.net/juju/+bug/1661015 is fixed, handle the
|
|
# base64 encoding the parameters in the action itself
|
|
|
|
import os
|
|
import sys
|
|
|
|
from base64 import b64encode
|
|
|
|
from charmhelpers.core.hookenv import action_get
|
|
from charmhelpers.core.hookenv import action_set
|
|
from charms.templating.jinja2 import render
|
|
from subprocess import call
|
|
|
|
os.environ['PATH'] += os.pathsep + os.path.join(os.sep, 'snap', 'bin')
|
|
|
|
deletion = action_get('delete')
|
|
|
|
context = {}
|
|
|
|
# These config options must be defined in the case of a creation
|
|
param_error = False
|
|
for param in ('tlscert', 'tlskey', 'domain', 'htpasswd', 'htpasswd-plain'):
|
|
value = action_get(param)
|
|
if not value and not deletion:
|
|
key = "registry-create-parameter-{}".format(param)
|
|
error = "failure, parameter {} is required".format(param)
|
|
action_set({key: error})
|
|
param_error = True
|
|
|
|
context[param] = value
|
|
|
|
# Create the dockercfg template variable
|
|
dockercfg = '{"%s": {"auth": "%s", "email": "root@localhost"}}' % \
|
|
(context['domain'], context['htpasswd-plain'])
|
|
context['dockercfg'] = b64encode(dockercfg.encode()).decode('ASCII')
|
|
|
|
if param_error:
|
|
sys.exit(0)
|
|
|
|
# This one is either true or false, no need to check if it has a "good" value.
|
|
context['ingress'] = action_get('ingress')
|
|
|
|
# Declare a kubectl template when invoking kubectl
|
|
kubectl = ['kubectl', '--kubeconfig=/root/cdk/kubeconfig']
|
|
|
|
# Remove deployment if requested
|
|
if deletion:
|
|
resources = ['svc/kube-registry', 'rc/kube-registry-v0', 'secrets/registry-tls-data',
|
|
'secrets/registry-auth-data', 'secrets/registry-access']
|
|
|
|
if action_get('ingress'):
|
|
resources.append('ing/registry-ing')
|
|
|
|
delete_command = kubectl + ['delete', '--ignore-not-found=true'] + resources
|
|
delete_response = call(delete_command)
|
|
if delete_response == 0:
|
|
action_set({'registry-delete': 'success'})
|
|
else:
|
|
action_set({'registry-delete': 'failure'})
|
|
|
|
sys.exit(0)
|
|
|
|
# Creation request
|
|
render('registry.yaml', '/root/cdk/addons/registry.yaml',
|
|
context)
|
|
|
|
create_command = kubectl + ['create', '-f',
|
|
'/root/cdk/addons/registry.yaml']
|
|
|
|
create_response = call(create_command)
|
|
|
|
if create_response == 0:
|
|
action_set({'registry-create': 'success'})
|
|
|
|
# Create a ConfigMap if it doesn't exist yet, else patch it.
|
|
# A ConfigMap is needed to change the default value for nginx' client_max_body_size.
|
|
# The default is 1MB, and this is the maximum size of images that can be
|
|
# pushed on the registry. 1MB images aren't useful, so we bump this value to 1024MB.
|
|
cm_name = 'nginx-load-balancer-conf'
|
|
check_cm_command = kubectl + ['get', 'cm', cm_name]
|
|
check_cm_response = call(check_cm_command)
|
|
|
|
if check_cm_response == 0:
|
|
# There is an existing ConfigMap, patch it
|
|
patch = '{"data":{"body-size":"1024m"}}'
|
|
patch_cm_command = kubectl + ['patch', 'cm', cm_name, '-p', patch]
|
|
patch_cm_response = call(patch_cm_command)
|
|
|
|
if patch_cm_response == 0:
|
|
action_set({'configmap-patch': 'success'})
|
|
else:
|
|
action_set({'configmap-patch': 'failure'})
|
|
|
|
else:
|
|
# No existing ConfigMap, create it
|
|
render('registry-configmap.yaml', '/root/cdk/addons/registry-configmap.yaml',
|
|
context)
|
|
create_cm_command = kubectl + ['create', '-f', '/root/cdk/addons/registry-configmap.yaml']
|
|
create_cm_response = call(create_cm_command)
|
|
|
|
if create_cm_response == 0:
|
|
action_set({'configmap-create': 'success'})
|
|
else:
|
|
action_set({'configmap-create': 'failure'})
|
|
|
|
# Patch the "default" serviceaccount with an imagePullSecret.
|
|
# This will allow the docker daemons to authenticate to our private
|
|
# registry automatically
|
|
patch = '{"imagePullSecrets":[{"name":"registry-access"}]}'
|
|
patch_sa_command = kubectl + ['patch', 'sa', 'default', '-p', patch]
|
|
patch_sa_response = call(patch_sa_command)
|
|
|
|
if patch_sa_response == 0:
|
|
action_set({'serviceaccount-patch': 'success'})
|
|
else:
|
|
action_set({'serviceaccount-patch': 'failure'})
|
|
|
|
|
|
else:
|
|
action_set({'registry-create': 'failure'})
|