Skip to content

Commit

Permalink
Refactor registry-console setup and add support for SSL
Browse files Browse the repository at this point in the history
This is a refactor to significantly improve the configurability
of the registry console service and route in order to bring it
in line with the way we configure docker-registry.

Effectively, this adds the ability to select a hostname for the
registry console and adds support for securing the registry-console
route with a provided SSL certificate either with passthrough or
reencrypt termination.

We maintain backwards compatibility by keeping the same default
which provides a default registry-console hostname and self-signed
certificates on a passthrough route.
  • Loading branch information
David Moreau-Simard committed Oct 24, 2017
1 parent abb5b1c commit 06ee306
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 34 deletions.
1 change: 1 addition & 0 deletions roles/cockpit-ui/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
openshift_config_base: "/etc/origin"
openshift_master_config_dir: "{{ openshift.common.config_base | default(openshift_config_base) }}/master"
openshift_hosted_registry_console_cert_expire_days: 730
123 changes: 89 additions & 34 deletions roles/cockpit-ui/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,41 +1,47 @@
---
- block:
- name: Configure facts for registry-console
set_fact:
openshift_hosted_registry_console_namespace: "{{ ('namespace' in openshift.hosted.registry.console.keys()) | ternary(openshift.hosted.registry.console.namespace, 'default') }}"
openshift_hosted_registry_console_routecertificates: "{{ ('routecertificates' in openshift.hosted.registry.console.keys()) | ternary(openshift.hosted.registry.console.routecertificates, {}) }}"
openshift_hosted_registry_console_routehost: "{{ ('routehost' in openshift.hosted.registry.console.keys()) | ternary(openshift.hosted.registry.console.routehost, False) }}"
openshift_hosted_registry_console_routetermination: "{{ ('routetermination' in openshift.hosted.registry.console.keys()) | ternary(openshift.hosted.registry.console.routetermination, 'passthrough') }}"

- name: Create directory for registry-console certificates
file:
path: "{{ openshift_master_config_dir }}/registry_console_certificates"
state: directory
owner: root
group: root
mode: 0700

- name: Include reencrypt route configuration
include: route/reencrypt.yml
static: no
when: openshift_hosted_registry_console_routetermination == 'reencrypt'

- name: Include passthrough route configuration
include: route/passthrough.yml
static: no
when: openshift_hosted_registry_console_routetermination == 'passthrough'

# When openshift_hosted_manage_registry=true the openshift_hosted
# role will create the appropriate route for the docker-registry.
# When openshift_hosted_manage_registry=false then this code will
# not be run.
- name: fetch the docker-registry route
- name: Fetch the docker-registry route
oc_route:
kubeconfig: "{{ openshift_master_config_dir }}/admin.kubeconfig"
name: docker-registry
namespace: default
state: list
register: docker_registry_route

- name: Create passthrough route for registry-console
- name: Fetch the registry-console route
oc_route:
kubeconfig: "{{ openshift_master_config_dir }}/admin.kubeconfig"
name: registry-console
namespace: default
service_name: registry-console
state: present
tls_termination: passthrough
register: registry_console_cockpit_kube

# XXX: Required for items still using command
- name: Create temp directory for kubeconfig
command: mktemp -d /tmp/openshift-ansible-XXXXXX
register: mktemp
changed_when: False

- set_fact:
openshift_hosted_kubeconfig: "{{ mktemp.stdout }}/admin.kubeconfig"

- name: Copy the admin client config(s)
command: >
cp {{ openshift_master_config_dir }}/admin.kubeconfig {{ openshift_hosted_kubeconfig }}
changed_when: False
state: list
register: registry_console_route

# TODO: Need to fix the origin and enterprise templates so that they both respect IMAGE_PREFIX
- name: Deploy registry-console
Expand All @@ -45,19 +51,68 @@
{% if openshift_cockpit_deployer_version is defined %}-p IMAGE_VERSION="{{ openshift_cockpit_deployer_version }}"{% endif %}
-p OPENSHIFT_OAUTH_PROVIDER_URL="{{ openshift.master.public_api_url }}"
-p REGISTRY_HOST="{{ docker_registry_route.results[0].spec.host }}"
-p COCKPIT_KUBE_URL="https://{{ registry_console_cockpit_kube.results.results[0].spec.host }}"
--config={{ openshift_hosted_kubeconfig }}
-n default
-p COCKPIT_KUBE_URL="https://{{ registry_console_route.results[0].spec.host }}"
--config={{ openshift_master_config_dir }}/admin.kubeconfig
-n {{ openshift_hosted_registry_console_namespace }}
register: deploy_registry_console
changed_when: "'already exists' not in deploy_registry_console.stderr"
failed_when:
- "'already exists' not in deploy_registry_console.stderr"
- "deploy_registry_console.rc != 0"
failed_when: "'already exists' not in deploy_registry_console.stderr and deploy_registry_console.rc != 0"

- name: Delete temp directory
file:
name: "{{ mktemp.stdout }}"
state: absent
changed_when: False
# XXX: End required for items still using command
- name: Retrieve registry-console service for the clusterip
oc_service:
namespace: "{{ openshift_hosted_registry_console_namespace }}"
name: registry-console
state: list
register: docker_registry_console_service

- name: Generate self-signed registry-console certificates
oc_adm_ca_server_cert:
signer_cert: "{{ openshift_master_config_dir }}/ca.crt"
signer_key: "{{ openshift_master_config_dir }}/ca.key"
signer_serial: "{{ openshift_master_config_dir }}/ca.serial.txt"
hostnames:
- "{{ docker_registry_console_service.results.clusterip }}"
- "{{ registry_console_route.results[0].spec.host }}"
cert: "{{ docker_registry_console_cert_path }}"
key: "{{ docker_registry_console_key_path }}"
expire_days: "{{ openshift_hosted_registry_console_cert_expire_days if openshift_version | oo_version_gte_3_5_or_1_5(openshift.common.deployment_type) | bool else omit }}"
when: docker_registry_console_self_signed

# The certificate file expected inside the registry-console service is
# in .pem format that bundles the certificate(s) and the private key.
- name: Retrieve certificate files to generate certificate bundle
slurp:
src: "{{ item }}"
with_items: >
{%- set files = [ docker_registry_console_cert_path ] %}
{%- if docker_registry_console_cacert is defined %}
{%- set _ = files.append(docker_registry_console_cacert) %}
{%- endif %}
{%- set _ = files.append(docker_registry_console_key_path) %}
{{- files -}}
register: certificate_files

- name: Generate certificate bundle
copy:
content: "{{ certificate_files.results | map(attribute='content') | map('b64decode') | join('') }}"
dest: "{{ openshift_master_config_dir }}/registry_console_certificates/registry-console.pem"

- name: Create the secret for the registry-console certificate
oc_secret:
name: registry-console-certificate
namespace: "{{ openshift_hosted_registry_console_namespace }}"
files:
- name: registry-console.cert
path: "{{ openshift_master_config_dir }}/registry_console_certificates/registry-console.pem"

- name: Mount secret registry console certificates volume
oc_volume:
state: present
namespace: "{{ openshift_hosted_registry_console_namespace }}"
kind: dc
name: registry-console
mount_type: secret
mount_path: "/etc/cockpit/ws-certs.d"
secret_name: registry-console-certificate
vol_name: registry-console-certificate
run_once: true
46 changes: 46 additions & 0 deletions roles/cockpit-ui/tasks/route/passthrough.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
# We'll generate a self-signed certificate when there is no user-supplied
# certificate
- name: Configure self-signed certificate file paths
set_fact:
docker_registry_console_cert_path: "{{ openshift_master_config_dir }}/registry-console.crt"
docker_registry_console_key_path: "{{ openshift_master_config_dir }}/registry-console.key"
docker_registry_console_cacert_path: "{{ openshift_master_config_dir }}/ca.crt"
docker_registry_console_self_signed: true
when:
- "'certfile' not in openshift_hosted_registry_console_routecertificates"
- "'keyfile' not in openshift_hosted_registry_console_routecertificates"

# Retrieve user supplied certificate files if they are provided
- when:
- "'certfile' in openshift_hosted_registry_console_routecertificates"
- "'keyfile' in openshift_hosted_registry_console_routecertificates"
block:
- name: Configure provided certificate file paths
set_fact:
docker_registry_console_cert_path: "{{ openshift_master_config_dir }}/registry_console_certificates/{{ openshift_hosted_registry_console_routecertificates['certfile'] | basename }}"
docker_registry_console_key_path: "{{ openshift_master_config_dir }}/registry_console_certificates/{{ openshift_hosted_registry_console_routecertificates['keyfile'] | basename }}"
docker_registry_console_self_signed: false

# Since we end up bundling the cert, cacert and key in a .pem file, the 'cafile'
# is optional
- name: Configure provided ca certificate file path
set_fact:
docker_registry_console_cacert_path: "{{ openshift_master_config_dir }}/registry_console_certificates/{{ openshift_hosted_registry_console_routecertificates['cafile'] | basename }}"
when: "'cafile' in openshift_hosted_registry_console_routecertificates"

- name: Retrieve provided certificate files
copy:
backup: True
dest: "{{ openshift_master_config_dir }}/registry_console_certificates/{{ item.value | basename }}"
src: "{{ item.value }}"
when: item.key in ['certfile', 'keyfile', 'cafile'] and item.value
with_dict: "{{ openshift_hosted_registry_console_routecertificates }}"

- name: Configure a passthrough route for registry-console
oc_route:
name: registry-console
namespace: "{{ openshift_hosted_registry_console_namespace }}"
service_name: registry-console
tls_termination: "{{ openshift_hosted_registry_console_routetermination }}"
host: "{{ openshift_hosted_registry_console_routehost | default(omit, true) }}"
38 changes: 38 additions & 0 deletions roles/cockpit-ui/tasks/route/reencrypt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
- name: Validate route termination configuration
fail:
msg: >
When 'openshift_hosted_registry_console_routetermination' is 'reencrypt', you must
provide certificate files with 'openshift_hosted_registry_console_routecertificates'
when: ('certfile' not in openshift_hosted_registry_console_routecertificates) or
('keyfile' not in openshift_hosted_registry_console_routecertificates) or
('cafile' not in openshift_hosted_registry_console_routecertificates)

- name: Configure self-signed certificate file paths
set_fact:
docker_registry_console_cert_path: "{{ openshift_master_config_dir }}/registry-console.crt"
docker_registry_console_key_path: "{{ openshift_master_config_dir }}/registry-console.key"
docker_registry_console_cacert_path: "{{ openshift_master_config_dir }}/ca.crt"
docker_registry_console_self_signed: true

- name: Retrieve provided certificate files
copy:
backup: True
dest: "{{ openshift_master_config_dir }}/registry_console_certificates/{{ item.value | basename }}"
src: "{{ item.value }}"
when: item.key in ['certfile', 'keyfile', 'cafile'] and item.value
with_dict: "{{ openshift_hosted_registry_console_routecertificates }}"

# Encrypt with the provided certificate and provide the dest_cacert for the
# self-signed certificate at the endpoint
- name: Configure a reencrypt route for registry-console
oc_route:
name: registry-console
namespace: "{{ openshift_hosted_registry_console_namespace }}"
service_name: registry-console
tls_termination: "{{ openshift_hosted_registry_console_routetermination }}"
host: "{{ openshift_hosted_registry_console_routehost | default(omit, true) }}"
cert_path: "{{ openshift_master_config_dir }}/registry_console_certificates/{{ openshift_hosted_registry_console_routecertificates['certfile'] | basename }}"
key_path: "{{ openshift_master_config_dir }}/registry_console_certificates/{{ openshift_hosted_registry_console_routecertificates['keyfile'] | basename }}"
cacert_path: "{{ openshift_master_config_dir }}/registry_console_certificates/{{ openshift_hosted_registry_console_routecertificates['cafile'] | basename }}"
dest_cacert_path: "{{ openshift_master_config_dir }}/ca.crt"

0 comments on commit 06ee306

Please sign in to comment.