From 82d61ae9e23c2ae1f722ed3b458a6e39721e71fd Mon Sep 17 00:00:00 2001 From: Michael Gugino Date: Thu, 31 Aug 2017 18:01:56 -0400 Subject: Refactor openshift_hosted plays and role Currently, openshift_hosted role duplicates some logic across separate task chains. This commit cleans up the openshift_hosted role and converts it to be primarily used with include_role to give better logic to the playbooks that utilize this role. This commit also refactors the playbook that calls various openshift_hosted roles into individual playbooks. This allows more granularity for advanced users. --- playbooks/common/openshift-cluster/cockpit-ui.yml | 6 + .../create_persistent_volumes.yml | 9 ++ .../openshift_default_storage_class.yml | 6 + .../common/openshift-cluster/openshift_hosted.yml | 73 ++------- .../openshift_hosted_create_projects.yml | 7 + .../openshift_hosted_registry.yml | 13 ++ .../openshift-cluster/openshift_hosted_router.yml | 13 ++ .../common/openshift-cluster/openshift_metrics.yml | 5 +- .../openshift-cluster/openshift_prometheus.yml | 9 +- roles/cockpit-ui/defaults/main.yml | 3 + roles/cockpit-ui/tasks/main.yml | 4 +- roles/openshift_hosted/defaults/main.yml | 72 +++++++-- roles/openshift_hosted/meta/main.yml | 1 - roles/openshift_hosted/tasks/create_projects.yml | 14 ++ roles/openshift_hosted/tasks/firewall.yml | 40 +++++ roles/openshift_hosted/tasks/main.yml | 20 +-- roles/openshift_hosted/tasks/registry.yml | 142 +++++++++++++++++ roles/openshift_hosted/tasks/registry/firewall.yml | 40 ----- roles/openshift_hosted/tasks/registry/registry.yml | 173 --------------------- roles/openshift_hosted/tasks/registry/secure.yml | 119 -------------- .../tasks/registry/secure/passthrough.yml | 45 ------ .../tasks/registry/secure/reencrypt.yml | 38 ----- .../tasks/registry/storage/glusterfs.yml | 92 ----------- .../tasks/registry/storage/object_storage.yml | 49 ------ .../tasks/registry/storage/registry_config.j2 | 1 - .../openshift_hosted/tasks/registry/storage/s3.yml | 45 ------ roles/openshift_hosted/tasks/router.yml | 105 +++++++++++++ roles/openshift_hosted/tasks/router/firewall.yml | 40 ----- roles/openshift_hosted/tasks/router/router.yml | 131 ---------------- roles/openshift_hosted/tasks/secure.yml | 119 ++++++++++++++ .../openshift_hosted/tasks/secure/passthrough.yml | 45 ++++++ roles/openshift_hosted/tasks/secure/reencrypt.yml | 38 +++++ roles/openshift_hosted/tasks/storage/glusterfs.yml | 92 +++++++++++ .../tasks/storage/object_storage.yml | 49 ++++++ .../tasks/storage/registry_config.j2 | 1 + roles/openshift_hosted/tasks/storage/s3.yml | 45 ++++++ roles/openshift_hosted/tasks/wait_for_pod.yml | 36 +++++ .../openshift_hosted/templates/registry_config.j2 | 4 +- roles/openshift_hosted/vars/main.yml | 11 -- 39 files changed, 879 insertions(+), 876 deletions(-) create mode 100644 playbooks/common/openshift-cluster/cockpit-ui.yml create mode 100644 playbooks/common/openshift-cluster/create_persistent_volumes.yml create mode 100644 playbooks/common/openshift-cluster/openshift_default_storage_class.yml create mode 100644 playbooks/common/openshift-cluster/openshift_hosted_create_projects.yml create mode 100644 playbooks/common/openshift-cluster/openshift_hosted_registry.yml create mode 100644 playbooks/common/openshift-cluster/openshift_hosted_router.yml create mode 100644 roles/cockpit-ui/defaults/main.yml create mode 100644 roles/openshift_hosted/tasks/create_projects.yml create mode 100644 roles/openshift_hosted/tasks/firewall.yml create mode 100644 roles/openshift_hosted/tasks/registry.yml delete mode 100644 roles/openshift_hosted/tasks/registry/firewall.yml delete mode 100644 roles/openshift_hosted/tasks/registry/registry.yml delete mode 100644 roles/openshift_hosted/tasks/registry/secure.yml delete mode 100644 roles/openshift_hosted/tasks/registry/secure/passthrough.yml delete mode 100644 roles/openshift_hosted/tasks/registry/secure/reencrypt.yml delete mode 100644 roles/openshift_hosted/tasks/registry/storage/glusterfs.yml delete mode 100644 roles/openshift_hosted/tasks/registry/storage/object_storage.yml delete mode 120000 roles/openshift_hosted/tasks/registry/storage/registry_config.j2 delete mode 100644 roles/openshift_hosted/tasks/registry/storage/s3.yml create mode 100644 roles/openshift_hosted/tasks/router.yml delete mode 100644 roles/openshift_hosted/tasks/router/firewall.yml delete mode 100644 roles/openshift_hosted/tasks/router/router.yml create mode 100644 roles/openshift_hosted/tasks/secure.yml create mode 100644 roles/openshift_hosted/tasks/secure/passthrough.yml create mode 100644 roles/openshift_hosted/tasks/secure/reencrypt.yml create mode 100644 roles/openshift_hosted/tasks/storage/glusterfs.yml create mode 100644 roles/openshift_hosted/tasks/storage/object_storage.yml create mode 120000 roles/openshift_hosted/tasks/storage/registry_config.j2 create mode 100644 roles/openshift_hosted/tasks/storage/s3.yml create mode 100644 roles/openshift_hosted/tasks/wait_for_pod.yml diff --git a/playbooks/common/openshift-cluster/cockpit-ui.yml b/playbooks/common/openshift-cluster/cockpit-ui.yml new file mode 100644 index 000000000..5ddafdb07 --- /dev/null +++ b/playbooks/common/openshift-cluster/cockpit-ui.yml @@ -0,0 +1,6 @@ +--- +- name: Create Hosted Resources - cockpit-ui + hosts: oo_first_master + roles: + - role: cockpit-ui + when: ( openshift.common.version_gte_3_3_or_1_3 | bool ) and ( openshift_hosted_manage_registry | default(true) | bool ) and not (openshift.docker.hosted_registry_insecure | default(false) | bool) diff --git a/playbooks/common/openshift-cluster/create_persistent_volumes.yml b/playbooks/common/openshift-cluster/create_persistent_volumes.yml new file mode 100644 index 000000000..8a60a30b8 --- /dev/null +++ b/playbooks/common/openshift-cluster/create_persistent_volumes.yml @@ -0,0 +1,9 @@ +--- +- name: Create Hosted Resources - persistent volumes + hosts: oo_first_master + vars: + persistent_volumes: "{{ hostvars[groups.oo_first_master.0] | oo_persistent_volumes(groups) }}" + persistent_volume_claims: "{{ hostvars[groups.oo_first_master.0] | oo_persistent_volume_claims }}" + roles: + - role: openshift_persistent_volumes + when: persistent_volumes | length > 0 or persistent_volume_claims | length > 0 diff --git a/playbooks/common/openshift-cluster/openshift_default_storage_class.yml b/playbooks/common/openshift-cluster/openshift_default_storage_class.yml new file mode 100644 index 000000000..4b4f19690 --- /dev/null +++ b/playbooks/common/openshift-cluster/openshift_default_storage_class.yml @@ -0,0 +1,6 @@ +--- +- name: Create Hosted Resources - openshift_default_storage_class + hosts: oo_first_master + roles: + - role: openshift_default_storage_class + when: openshift_cloudprovider_kind is defined and (openshift_cloudprovider_kind == 'aws' or openshift_cloudprovider_kind == 'gce') diff --git a/playbooks/common/openshift-cluster/openshift_hosted.yml b/playbooks/common/openshift-cluster/openshift_hosted.yml index 0e970f376..2cb404abe 100644 --- a/playbooks/common/openshift-cluster/openshift_hosted.yml +++ b/playbooks/common/openshift-cluster/openshift_hosted.yml @@ -1,57 +1,18 @@ --- -- name: Create persistent volumes - hosts: oo_first_master - tags: - - hosted - vars: - persistent_volumes: "{{ hostvars[groups.oo_first_master.0] | oo_persistent_volumes(groups) }}" - persistent_volume_claims: "{{ hostvars[groups.oo_first_master.0] | oo_persistent_volume_claims }}" - roles: - - role: openshift_persistent_volumes - when: persistent_volumes | length > 0 or persistent_volume_claims | length > 0 - -- name: Create Hosted Resources - hosts: oo_first_master - tags: - - hosted - pre_tasks: - - set_fact: - openshift_hosted_router_registryurl: "{{ hostvars[groups.oo_first_master.0].openshift.master.registry_url }}" - openshift_hosted_registry_registryurl: "{{ hostvars[groups.oo_first_master.0].openshift.master.registry_url }}" - when: "'master' in hostvars[groups.oo_first_master.0].openshift and 'registry_url' in hostvars[groups.oo_first_master.0].openshift.master" - - roles: - - role: openshift_default_storage_class - when: openshift_cloudprovider_kind is defined and (openshift_cloudprovider_kind == 'aws' or openshift_cloudprovider_kind == 'gce') - - role: openshift_hosted - - role: openshift_metrics - when: openshift_metrics_install_metrics | default(false) | bool - - role: openshift_logging - when: openshift_logging_install_logging | default(false) | bool - - - role: cockpit-ui - when: ( openshift.common.version_gte_3_3_or_1_3 | bool ) and ( openshift_hosted_manage_registry | default(true) | bool ) and not (openshift.docker.hosted_registry_insecure | default(false) | bool) - - - role: openshift_prometheus - when: openshift_hosted_prometheus_deploy | default(false) | bool - -- name: Update master-config for publicLoggingURL - hosts: oo_masters_to_config:!oo_first_master - tags: - - hosted - pre_tasks: - - set_fact: - openshift_metrics_hawkular_hostname: "{{ g_metrics_hostname | default('hawkular-metrics.' ~ (openshift_master_default_subdomain | default('router.default.svc.cluster.local', true))) }}" - tasks: - - - block: - - include_role: - name: openshift_logging - tasks_from: update_master_config - when: openshift_logging_install_logging | default(false) | bool - - - block: - - include_role: - name: openshift_metrics - tasks_from: update_master_config - when: openshift_metrics_install_metrics | default(false) | bool +- include: create_persistent_volumes.yml + +- include: openshift_default_storage_class.yml + +- include: openshift_hosted_create_projects.yml + +- include: openshift_hosted_router.yml + +- include: openshift_hosted_registry.yml + +- include: openshift_metrics.yml + +- include: openshift_logging.yml + +- include: cockpit-ui.yml + +- include: openshift_prometheus.yml diff --git a/playbooks/common/openshift-cluster/openshift_hosted_create_projects.yml b/playbooks/common/openshift-cluster/openshift_hosted_create_projects.yml new file mode 100644 index 000000000..d5ca5185c --- /dev/null +++ b/playbooks/common/openshift-cluster/openshift_hosted_create_projects.yml @@ -0,0 +1,7 @@ +--- +- name: Create Hosted Resources - openshift projects + hosts: oo_first_master + tasks: + - include_role: + name: openshift_hosted + tasks_from: create_projects.yml diff --git a/playbooks/common/openshift-cluster/openshift_hosted_registry.yml b/playbooks/common/openshift-cluster/openshift_hosted_registry.yml new file mode 100644 index 000000000..2a91a827c --- /dev/null +++ b/playbooks/common/openshift-cluster/openshift_hosted_registry.yml @@ -0,0 +1,13 @@ +--- +- name: Create Hosted Resources - registry + hosts: oo_first_master + tasks: + - set_fact: + openshift_hosted_registry_registryurl: "{{ hostvars[groups.oo_first_master.0].openshift.master.registry_url }}" + when: "'master' in hostvars[groups.oo_first_master.0].openshift and 'registry_url' in hostvars[groups.oo_first_master.0].openshift.master" + - include_role: + name: openshift_hosted + tasks_from: registry.yml + when: + - openshift_hosted_manage_registry | default(True) | bool + - openshift_hosted_registry_registryurl is defined diff --git a/playbooks/common/openshift-cluster/openshift_hosted_router.yml b/playbooks/common/openshift-cluster/openshift_hosted_router.yml new file mode 100644 index 000000000..bcb5a34a4 --- /dev/null +++ b/playbooks/common/openshift-cluster/openshift_hosted_router.yml @@ -0,0 +1,13 @@ +--- +- name: Create Hosted Resources - router + hosts: oo_first_master + tasks: + - set_fact: + openshift_hosted_router_registryurl: "{{ hostvars[groups.oo_first_master.0].openshift.master.registry_url }}" + when: "'master' in hostvars[groups.oo_first_master.0].openshift and 'registry_url' in hostvars[groups.oo_first_master.0].openshift.master" + - include_role: + name: openshift_hosted + tasks_from: router.yml + when: + - openshift_hosted_manage_router | default(True) | bool + - openshift_hosted_router_registryurl is defined diff --git a/playbooks/common/openshift-cluster/openshift_metrics.yml b/playbooks/common/openshift-cluster/openshift_metrics.yml index 1dc180c26..9cc98fe1e 100644 --- a/playbooks/common/openshift-cluster/openshift_metrics.yml +++ b/playbooks/common/openshift-cluster/openshift_metrics.yml @@ -2,7 +2,9 @@ - name: OpenShift Metrics hosts: oo_first_master roles: - - openshift_metrics + - role: openshift_metrics + when: openshift_metrics_install_metrics | default(false) | bool + - name: OpenShift Metrics hosts: oo_masters:!oo_first_master @@ -12,3 +14,4 @@ include_role: name: openshift_metrics tasks_from: update_master_config.yaml + when: openshift_metrics_install_metrics | default(false) | bool diff --git a/playbooks/common/openshift-cluster/openshift_prometheus.yml b/playbooks/common/openshift-cluster/openshift_prometheus.yml index a979c0c00..ed89d3bde 100644 --- a/playbooks/common/openshift-cluster/openshift_prometheus.yml +++ b/playbooks/common/openshift-cluster/openshift_prometheus.yml @@ -1,9 +1,6 @@ --- -- include: std_include.yml - -- name: OpenShift Prometheus +- name: Create Hosted Resources - openshift_prometheus hosts: oo_first_master roles: - - openshift_prometheus - vars: - openshift_prometheus_state: present + - role: openshift_prometheus + when: openshift_hosted_prometheus_deploy | default(False) | bool diff --git a/roles/cockpit-ui/defaults/main.yml b/roles/cockpit-ui/defaults/main.yml new file mode 100644 index 000000000..b1696f1b8 --- /dev/null +++ b/roles/cockpit-ui/defaults/main.yml @@ -0,0 +1,3 @@ +--- +openshift_config_base: "/etc/origin" +openshift_master_config_dir: "{{ openshift.common.config_base | default(openshift_config_base) }}/master" diff --git a/roles/cockpit-ui/tasks/main.yml b/roles/cockpit-ui/tasks/main.yml index 0114498f8..244e2cc41 100644 --- a/roles/cockpit-ui/tasks/main.yml +++ b/roles/cockpit-ui/tasks/main.yml @@ -50,7 +50,9 @@ -n default register: deploy_registry_console changed_when: "'already exists' not in deploy_registry_console.stderr" - failed_when: "'already exists' not in deploy_registry_console.stderr and deploy_registry_console.rc != 0" + failed_when: + - "'already exists' not in deploy_registry_console.stderr" + - "deploy_registry_console.rc != 0" - name: Delete temp directory file: diff --git a/roles/openshift_hosted/defaults/main.yml b/roles/openshift_hosted/defaults/main.yml index 712a2a591..c234c3740 100644 --- a/roles/openshift_hosted/defaults/main.yml +++ b/roles/openshift_hosted/defaults/main.yml @@ -1,14 +1,33 @@ --- +########## +# Common # +########## +openshift_hosted_infra_selector: "region=infra" +r_openshift_hosted_use_calico_default: "{{ openshift_use_calico | default(False) }}" +r_openshift_hosted_use_calico: "{{ r_openshift_hosted_use_calico_default }}" + +openshift_default_projects: + default: + default_node_selector: '' + logging: + default_node_selector: '' + openshift-infra: + default_node_selector: '' + +# openshift_additional_projects shares the same format as openshift_default_projects +openshift_additional_projects: {} + +openshift_config_base: "/etc/origin" +openshift_master_config_dir: "{{ openshift.common.config_base | default(openshift_config_base) }}/master" +openshift_cluster_domain: 'cluster.local' + +########## +# Router # +########## r_openshift_hosted_router_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" r_openshift_hosted_router_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" -r_openshift_hosted_registry_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" -r_openshift_hosted_registry_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" - openshift_hosted_router_wait: "{{ not (openshift_master_bootstrap_enabled | default(False)) }}" -openshift_hosted_registry_wait: "{{ not (openshift_master_bootstrap_enabled | default(False)) }}" - -registry_volume_claim: 'registry-claim' openshift_hosted_router_edits: - key: spec.strategy.rollingParams.intervalSeconds @@ -36,20 +55,49 @@ openshift_hosted_routers: certificate: "{{ openshift_hosted_router_certificate | default({}) }}" openshift_hosted_router_certificate: {} -openshift_hosted_registry_cert_expire_days: 730 openshift_hosted_router_create_certificate: True r_openshift_hosted_router_os_firewall_deny: [] r_openshift_hosted_router_os_firewall_allow: [] +############ +# Registry # +############ + +r_openshift_hosted_registry_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_openshift_hosted_registry_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" + +openshift_hosted_registry_name: docker-registry +openshift_hosted_registry_wait: "{{ not (openshift_master_bootstrap_enabled | default(False)) }}" +registry_volume_claim: 'registry-claim' +openshift_hosted_registry_cert_expire_days: 730 + r_openshift_hosted_registry_os_firewall_deny: [] r_openshift_hosted_registry_os_firewall_allow: - service: Docker Registry Port port: 5000/tcp cond: "{{ r_openshift_hosted_use_calico }}" -# NOTE -# r_openshift_hosted_use_calico_default may be defined external to this role. -# openshift_use_calico, if defined, may affect other roles or play behavior. -r_openshift_hosted_use_calico_default: "{{ openshift_use_calico | default(False) }}" -r_openshift_hosted_use_calico: "{{ r_openshift_hosted_use_calico_default }}" +openshift_hosted_registry_serviceaccount: registry +openshift_hosted_registry_volumes: [] +openshift_hosted_registry_env_vars: {} + +# These edits are being specified only to prevent 'changed' on rerun +openshift_hosted_registry_edits: +- key: spec.strategy.rollingParams + value: + intervalSeconds: 1 + maxSurge: "25%" + maxUnavailable: "25%" + timeoutSeconds: 600 + updatePeriodSeconds: 1 + action: put + +openshift_hosted_registry_force: +- False + +openshift_push_via_dns: False + +# NOTE: settting openshift_docker_hosted_registry_insecure may affect other roles +openshift_hosted_docker_registry_insecure_default: "{{ openshift_docker_hosted_registry_insecure | default(False) }}" +openshift_hosted_docker_registry_insecure: "{{ openshift_hosted_docker_registry_insecure_default }}" diff --git a/roles/openshift_hosted/meta/main.yml b/roles/openshift_hosted/meta/main.yml index 28fd396d6..1d70ef7eb 100644 --- a/roles/openshift_hosted/meta/main.yml +++ b/roles/openshift_hosted/meta/main.yml @@ -12,7 +12,6 @@ galaxy_info: categories: - cloud dependencies: -- role: openshift_cli - role: openshift_hosted_facts - role: lib_openshift - role: lib_os_firewall diff --git a/roles/openshift_hosted/tasks/create_projects.yml b/roles/openshift_hosted/tasks/create_projects.yml new file mode 100644 index 000000000..1b25d0c64 --- /dev/null +++ b/roles/openshift_hosted/tasks/create_projects.yml @@ -0,0 +1,14 @@ +--- +- name: Create default projects + oc_project: + name: "{{ item.key }}" + node_selector: + - "{{ item.value.default_node_selector }}" + with_dict: "{{ openshift_default_projects }}" + +- name: Create additional projects + oc_project: + name: "{{ item.key }}" + node_selector: + - "{{ item.value.default_node_selector }}" + with_dict: "{{ openshift_additional_projects }}" diff --git a/roles/openshift_hosted/tasks/firewall.yml b/roles/openshift_hosted/tasks/firewall.yml new file mode 100644 index 000000000..1eb2c92c8 --- /dev/null +++ b/roles/openshift_hosted/tasks/firewall.yml @@ -0,0 +1,40 @@ +--- +- when: r_openshift_hosted_router_firewall_enabled | bool and not r_openshift_hosted_router_use_firewalld | bool + block: + - name: Add iptables allow rules + os_firewall_manage_iptables: + name: "{{ item.service }}" + action: add + protocol: "{{ item.port.split('/')[1] }}" + port: "{{ item.port.split('/')[0] }}" + when: item.cond | default(True) + with_items: "{{ l_openshift_hosted_fw_allow }}" + + - name: Remove iptables rules + os_firewall_manage_iptables: + name: "{{ item.service }}" + action: remove + protocol: "{{ item.port.split('/')[1] }}" + port: "{{ item.port.split('/')[0] }}" + when: item.cond | default(True) + with_items: "{{ l_openshift_hosted_fw_deny }}" + +- when: l_openshift_hosted_firewall_enabled | bool and l_openshift_hosted_use_firewalld | bool + block: + - name: Add firewalld allow rules + firewalld: + port: "{{ item.port }}" + permanent: true + immediate: true + state: enabled + when: item.cond | default(True) + with_items: "{{ l_openshift_hosted_fw_allow }}" + + - name: Remove firewalld allow rules + firewalld: + port: "{{ item.port }}" + permanent: true + immediate: true + state: disabled + when: item.cond | default(True) + with_items: "{{ l_openshift_hosted_fw_deny }}" diff --git a/roles/openshift_hosted/tasks/main.yml b/roles/openshift_hosted/tasks/main.yml index 6efe2f63c..d306adf42 100644 --- a/roles/openshift_hosted/tasks/main.yml +++ b/roles/openshift_hosted/tasks/main.yml @@ -1,13 +1,9 @@ --- -- name: Create projects - oc_project: - name: "{{ item.key }}" - node_selector: - - "{{ item.value.default_node_selector }}" - with_dict: "{{ openshift_projects }}" - -- include: router/router.yml - when: openshift_hosted_manage_router | default(true) | bool - -- include: registry/registry.yml - when: openshift_hosted_manage_registry | default(true) | bool +# This role is intended to be used with include_role. +# include_role: +# name: openshift_hosted +# tasks_from: "{{ item }}" +# with_items: +# - create_projects.yml +# - router.yml +# - registry.yml diff --git a/roles/openshift_hosted/tasks/registry.yml b/roles/openshift_hosted/tasks/registry.yml new file mode 100644 index 000000000..f1aa9c5a8 --- /dev/null +++ b/roles/openshift_hosted/tasks/registry.yml @@ -0,0 +1,142 @@ +--- +- name: setup firewall + include: firewall.yml + vars: + l_openshift_hosted_firewall_enabled: "{{ r_openshift_hosted_registry_firewall_enabled }}" + l_openshift_hosted_use_firewalld: "{{ r_openshift_hosted_registry_use_firewalld }}" + l_openshift_hosted_fw_allow: "{{ r_openshift_hosted_registry_os_firewall_allow }}" + l_openshift_hosted_fw_deny: "{{ r_openshift_hosted_registry_os_firewall_deny }}" + +- when: openshift.hosted.registry.replicas | default(none) is none + block: + - name: Retrieve list of openshift nodes matching registry selector + oc_obj: + state: list + kind: node + selector: "{{ openshift.hosted.registry.selector | default(omit) }}" + register: registry_nodes + + - name: set_fact l_node_count to number of nodes matching registry selector + set_fact: + l_node_count: "{{ registry_nodes.results.results[0]['items'] | length }}" + + # Determine the default number of registry/router replicas to use if no count + # has been specified. + # If no registry nodes defined, the default should be 0. + - name: set_fact l_default_replicas when l_node_count == 0 + set_fact: + l_default_replicas: 0 + when: l_node_count | int == 0 + + # If registry nodes are defined and the registry storage kind is + # defined, default should be the number of registry nodes, otherwise + # just 1: + - name: set_fact l_default_replicas when l_node_count > 0 + set_fact: + l_default_replicas: "{{ l_node_count if openshift.hosted.registry.storage.kind | default(none) is not none else 1 }}" + when: l_node_count | int > 0 + + +- name: set openshift_hosted facts + set_fact: + openshift_hosted_registry_replicas: "{{ openshift.hosted.registry.replicas | default(l_default_replicas) }}" + openshift_hosted_registry_namespace: "{{ openshift.hosted.registry.namespace | default('default') }}" + openshift_hosted_registry_selector: "{{ openshift.hosted.registry.selector }}" + openshift_hosted_registry_images: "{{ openshift.hosted.registry.registryurl | default('openshift3/ose-${component}:${version}')}}" + +- name: Update registry environment variables when pushing via dns + set_fact: + openshift_hosted_registry_env_vars: "{{ openshift_hosted_registry_env_vars | combine({'OPENSHIFT_DEFAULT_REGISTRY':'docker-registry.default.svc:5000'}) }}" + when: openshift_push_via_dns | bool + +- name: Update registry proxy settings for dc/docker-registry + set_fact: + openshift_hosted_registry_env_vars: "{{ {'HTTPS_PROXY': (openshift.common.https_proxy | default('')), + 'HTTP_PROXY': (openshift.common.http_proxy | default('')), + 'NO_PROXY': (openshift.common.no_proxy | default(''))} + | combine(openshift_hosted_registry_env_vars) }}" + when: (openshift.common.https_proxy | default(False)) or (openshift.common.http_proxy | default('')) != '' + +- name: Create the registry service account + oc_serviceaccount: + name: "{{ openshift_hosted_registry_serviceaccount }}" + namespace: "{{ openshift_hosted_registry_namespace }}" + +- name: Grant the registry service account access to the appropriate scc + oc_adm_policy_user: + user: "system:serviceaccount:{{ openshift_hosted_registry_namespace }}:{{ openshift_hosted_registry_serviceaccount }}" + namespace: "{{ openshift_hosted_registry_namespace }}" + resource_kind: scc + resource_name: hostnetwork + +- name: oc adm policy add-cluster-role-to-user system:registry system:serviceaccount:default:registry + oc_adm_policy_user: + user: "system:serviceaccount:{{ openshift_hosted_registry_namespace }}:{{ openshift_hosted_registry_serviceaccount }}" + namespace: "{{ openshift_hosted_registry_namespace }}" + resource_kind: cluster-role + resource_name: system:registry + +- name: create the default registry service + oc_service: + namespace: "{{ openshift_hosted_registry_namespace }}" + name: "{{ openshift_hosted_registry_name }}" + ports: + - name: 5000-tcp + port: 5000 + protocol: TCP + targetPort: 5000 + selector: + docker-registry: default + session_affinity: ClientIP + service_type: ClusterIP + +- include: secure.yml + static: no + run_once: true + when: + - not (openshift.docker.hosted_registry_insecure | default(false) | bool) + +- include: storage/object_storage.yml + static: no + when: + - openshift.hosted.registry.storage.kind | default(none) == 'object' + +- name: Update openshift_hosted facts for persistent volumes + set_fact: + openshift_hosted_registry_volumes: "{{ openshift_hosted_registry_volumes | union(pvc_volume_mounts) }}" + vars: + pvc_volume_mounts: + - name: registry-storage + type: persistentVolumeClaim + claim_name: "{{ openshift.hosted.registry.storage.volume.name }}-claim" + when: + - openshift.hosted.registry.storage.kind | default(none) in ['nfs', 'openstack', 'glusterfs'] + +- name: Create OpenShift registry + oc_adm_registry: + name: "{{ openshift_hosted_registry_name }}" + namespace: "{{ openshift_hosted_registry_namespace }}" + selector: "{{ openshift_hosted_registry_selector }}" + replicas: "{{ openshift_hosted_registry_replicas }}" + service_account: "{{ openshift_hosted_registry_serviceaccount }}" + images: "{{ openshift_hosted_registry_images }}" + env_vars: "{{ openshift_hosted_registry_env_vars }}" + volume_mounts: "{{ openshift_hosted_registry_volumes }}" + edits: "{{ openshift_hosted_registry_edits }}" + force: "{{ True|bool in openshift_hosted_registry_force }}" + +- name: setup registry list + set_fact: + r_openshift_hosted_registry_list: + - name: "{{ openshift_hosted_registry_name }}" + namespace: "{{ openshift_hosted_registry_namespace }}" + +- name: Wait for pod (Registry) + include: wait_for_pod.yml + vars: + l_openshift_hosted_wait_for_pod: "{{ openshift_hosted_registry_wait }}" + l_openshift_hosted_wfp_items: "{{ r_openshift_hosted_registry_list }}" + +- include: storage/glusterfs.yml + when: + - openshift.hosted.registry.storage.kind | default(none) == 'glusterfs' or openshift.hosted.registry.storage.glusterfs.swap diff --git a/roles/openshift_hosted/tasks/registry/firewall.yml b/roles/openshift_hosted/tasks/registry/firewall.yml deleted file mode 100644 index 775b7d6d7..000000000 --- a/roles/openshift_hosted/tasks/registry/firewall.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- -- when: r_openshift_hosted_registry_firewall_enabled | bool and not r_openshift_hosted_registry_use_firewalld | bool - block: - - name: Add iptables allow rules - os_firewall_manage_iptables: - name: "{{ item.service }}" - action: add - protocol: "{{ item.port.split('/')[1] }}" - port: "{{ item.port.split('/')[0] }}" - when: item.cond | default(True) - with_items: "{{ r_openshift_hosted_registry_os_firewall_allow }}" - - - name: Remove iptables rules - os_firewall_manage_iptables: - name: "{{ item.service }}" - action: remove - protocol: "{{ item.port.split('/')[1] }}" - port: "{{ item.port.split('/')[0] }}" - when: item.cond | default(True) - with_items: "{{ r_openshift_hosted_registry_os_firewall_deny }}" - -- when: r_openshift_hosted_registry_firewall_enabled | bool and r_openshift_hosted_registry_use_firewalld | bool - block: - - name: Add firewalld allow rules - firewalld: - port: "{{ item.port }}" - permanent: true - immediate: true - state: enabled - when: item.cond | default(True) - with_items: "{{ r_openshift_hosted_registry_os_firewall_allow }}" - - - name: Remove firewalld allow rules - firewalld: - port: "{{ item.port }}" - permanent: true - immediate: true - state: disabled - when: item.cond | default(True) - with_items: "{{ r_openshift_hosted_registry_os_firewall_deny }}" diff --git a/roles/openshift_hosted/tasks/registry/registry.yml b/roles/openshift_hosted/tasks/registry/registry.yml deleted file mode 100644 index 48f53aef8..000000000 --- a/roles/openshift_hosted/tasks/registry/registry.yml +++ /dev/null @@ -1,173 +0,0 @@ ---- -- name: setup firewall - include: firewall.yml - static: yes - -- when: openshift.hosted.registry.replicas | default(none) is none - block: - - name: Retrieve list of openshift nodes matching registry selector - oc_obj: - state: list - kind: node - selector: "{{ openshift.hosted.registry.selector | default(omit) }}" - register: registry_nodes - - - name: set_fact l_node_count to number of nodes matching registry selector - set_fact: - l_node_count: "{{ registry_nodes.results.results[0]['items'] | length }}" - - # Determine the default number of registry/router replicas to use if no count - # has been specified. - # If no registry nodes defined, the default should be 0. - - name: set_fact l_default_replicas when l_node_count == 0 - set_fact: - l_default_replicas: 0 - when: l_node_count | int == 0 - - # If registry nodes are defined and the registry storage kind is - # defined, default should be the number of registry nodes, otherwise - # just 1: - - name: set_fact l_default_replicas when l_node_count > 0 - set_fact: - l_default_replicas: "{{ l_node_count if openshift.hosted.registry.storage.kind | default(none) is not none else 1 }}" - when: l_node_count | int > 0 - - -- name: set openshift_hosted facts - set_fact: - openshift_hosted_registry_replicas: "{{ openshift.hosted.registry.replicas | default(l_default_replicas) }}" - openshift_hosted_registry_name: docker-registry - openshift_hosted_registry_serviceaccount: registry - openshift_hosted_registry_namespace: "{{ openshift.hosted.registry.namespace | default('default') }}" - openshift_hosted_registry_selector: "{{ openshift.hosted.registry.selector }}" - openshift_hosted_registry_images: "{{ openshift.hosted.registry.registryurl | default('openshift3/ose-${component}:${version}')}}" - openshift_hosted_registry_volumes: [] - openshift_hosted_registry_env_vars: {} - openshift_hosted_registry_edits: - # These edits are being specified only to prevent 'changed' on rerun - - key: spec.strategy.rollingParams - value: - intervalSeconds: 1 - maxSurge: "25%" - maxUnavailable: "25%" - timeoutSeconds: 600 - updatePeriodSeconds: 1 - action: put - openshift_hosted_registry_force: - - False - -- name: Update registry environment variables when pushing via dns - set_fact: - openshift_hosted_registry_env_vars: "{{ openshift_hosted_registry_env_vars | combine({'OPENSHIFT_DEFAULT_REGISTRY':'docker-registry.default.svc:5000'}) }}" - when: openshift_push_via_dns | default(false) | bool - -- name: Update registry proxy settings for dc/docker-registry - set_fact: - openshift_hosted_registry_env_vars: "{{ {'HTTPS_PROXY': (openshift.common.https_proxy | default('')), - 'HTTP_PROXY': (openshift.common.http_proxy | default('')), - 'NO_PROXY': (openshift.common.no_proxy | default(''))} - | combine(openshift_hosted_registry_env_vars) }}" - when: (openshift.common.https_proxy | default(False)) or (openshift.common.http_proxy | default('')) != '' - -- name: Create the registry service account - oc_serviceaccount: - name: "{{ openshift_hosted_registry_serviceaccount }}" - namespace: "{{ openshift_hosted_registry_namespace }}" - -- name: Grant the registry service account access to the appropriate scc - oc_adm_policy_user: - user: "system:serviceaccount:{{ openshift_hosted_registry_namespace }}:{{ openshift_hosted_registry_serviceaccount }}" - namespace: "{{ openshift_hosted_registry_namespace }}" - resource_kind: scc - resource_name: hostnetwork - -- name: oc adm policy add-cluster-role-to-user system:registry system:serviceaccount:default:registry - oc_adm_policy_user: - user: "system:serviceaccount:{{ openshift_hosted_registry_namespace }}:{{ openshift_hosted_registry_serviceaccount }}" - namespace: "{{ openshift_hosted_registry_namespace }}" - resource_kind: cluster-role - resource_name: system:registry - -- name: create the default registry service - oc_service: - namespace: "{{ openshift_hosted_registry_namespace }}" - name: "{{ openshift_hosted_registry_name }}" - ports: - - name: 5000-tcp - port: 5000 - protocol: TCP - targetPort: 5000 - selector: - docker-registry: default - session_affinity: ClientIP - service_type: ClusterIP - -- include: secure.yml - static: no - run_once: true - when: - - not (openshift.docker.hosted_registry_insecure | default(false) | bool) - -- include: storage/object_storage.yml - static: no - when: - - openshift.hosted.registry.storage.kind | default(none) == 'object' - -- name: Update openshift_hosted facts for persistent volumes - set_fact: - openshift_hosted_registry_volumes: "{{ openshift_hosted_registry_volumes | union(pvc_volume_mounts) }}" - vars: - pvc_volume_mounts: - - name: registry-storage - type: persistentVolumeClaim - claim_name: "{{ openshift.hosted.registry.storage.volume.name }}-claim" - when: - - openshift.hosted.registry.storage.kind | default(none) in ['nfs', 'openstack', 'glusterfs'] - -- name: Create OpenShift registry - oc_adm_registry: - name: "{{ openshift_hosted_registry_name }}" - namespace: "{{ openshift_hosted_registry_namespace }}" - selector: "{{ openshift_hosted_registry_selector }}" - replicas: "{{ openshift_hosted_registry_replicas }}" - service_account: "{{ openshift_hosted_registry_serviceaccount }}" - images: "{{ openshift_hosted_registry_images }}" - env_vars: "{{ openshift_hosted_registry_env_vars }}" - volume_mounts: "{{ openshift_hosted_registry_volumes }}" - edits: "{{ openshift_hosted_registry_edits }}" - force: "{{ True|bool in openshift_hosted_registry_force }}" - -- when: openshift_hosted_registry_wait | bool - block: - - name: Ensure OpenShift registry correctly rolls out (best-effort today) - command: | - oc rollout status deploymentconfig {{ openshift_hosted_registry_name }} \ - --namespace {{ openshift_hosted_registry_namespace }} \ - --config {{ openshift.common.config_base }}/master/admin.kubeconfig - async: 600 - poll: 15 - failed_when: false - - - name: Determine the latest version of the OpenShift registry deployment - command: | - {{ openshift.common.client_binary }} get deploymentconfig {{ openshift_hosted_registry_name }} \ - --namespace {{ openshift_hosted_registry_namespace }} \ - --config {{ openshift.common.config_base }}/master/admin.kubeconfig \ - -o jsonpath='{ .status.latestVersion }' - register: openshift_hosted_registry_latest_version - - - name: Sanity-check that the OpenShift registry rolled out correctly - command: | - {{ openshift.common.client_binary }} get replicationcontroller {{ openshift_hosted_registry_name }}-{{ openshift_hosted_registry_latest_version.stdout }} \ - --namespace {{ openshift_hosted_registry_namespace }} \ - --config {{ openshift.common.config_base }}/master/admin.kubeconfig \ - -o jsonpath='{ .metadata.annotations.openshift\.io/deployment\.phase }' - register: openshift_hosted_registry_rc_phase - until: "'Running' not in openshift_hosted_registry_rc_phase.stdout" - delay: 15 - retries: 40 - failed_when: "'Failed' in openshift_hosted_registry_rc_phase.stdout" - -- include: storage/glusterfs.yml - when: - - openshift.hosted.registry.storage.kind | default(none) == 'glusterfs' or openshift.hosted.registry.storage.glusterfs.swap diff --git a/roles/openshift_hosted/tasks/registry/secure.yml b/roles/openshift_hosted/tasks/registry/secure.yml deleted file mode 100644 index 434b679df..000000000 --- a/roles/openshift_hosted/tasks/registry/secure.yml +++ /dev/null @@ -1,119 +0,0 @@ ---- -- name: Configure facts for docker-registry - set_fact: - openshift_hosted_registry_routecertificates: "{{ ('routecertificates' in openshift.hosted.registry.keys()) | ternary(openshift_hosted_registry_routecertificates, {}) }}" - openshift_hosted_registry_routehost: "{{ ('routehost' in openshift.hosted.registry.keys()) | ternary(openshift.hosted.registry.routehost, False) }}" - openshift_hosted_registry_routetermination: "{{ ('routetermination' in openshift.hosted.registry.keys()) | ternary(openshift.hosted.registry.routetermination, 'passthrough') }}" - -- name: Include reencrypt route configuration - include: secure/reencrypt.yml - static: no - when: openshift_hosted_registry_routetermination == 'reencrypt' - -- name: Include passthrough route configuration - include: secure/passthrough.yml - static: no - when: openshift_hosted_registry_routetermination == 'passthrough' - -- name: Fetch the docker-registry route - oc_route: - name: docker-registry - namespace: default - state: list - register: docker_registry_route - -- name: Retrieve registry service for the clusterip - oc_service: - namespace: "{{ openshift_hosted_registry_namespace }}" - name: docker-registry - state: list - register: docker_registry_service - -- name: Generate self-signed docker-registry 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_service.results.clusterip }}" - - "{{ docker_registry_route.results[0].spec.host }}" - - "{{ openshift_hosted_registry_name }}.default.svc" - - "{{ openshift_hosted_registry_name }}.default.svc.{{ openshift.common.dns_domain }}" - - "{{ openshift_hosted_registry_routehost }}" - cert: "{{ docker_registry_cert_path }}" - key: "{{ docker_registry_key_path }}" - expire_days: "{{ openshift_hosted_registry_cert_expire_days if openshift_version | oo_version_gte_3_5_or_1_5(openshift.common.deployment_type) | bool else omit }}" - register: registry_self_cert - when: docker_registry_self_signed - -# Setting up REGISTRY_HTTP_TLS_CLIENTCAS as the cacert doesn't seem to work. -# If we need to set up a cacert, bundle it with the cert. -- when: docker_registry_cacert_path is defined - block: - - name: Retrieve certificate files to generate certificate bundle - slurp: - src: "{{ item }}" - with_items: - - "{{ docker_registry_cert_path }}" - - "{{ docker_registry_cacert_path }}" - register: certificate_files - - - name: Generate certificate bundle - copy: - content: "{{ certificate_files.results | map(attribute='content') | map('b64decode') | join('') }}" - dest: "{{ openshift_master_config_dir }}/named_certificates/docker-registry.pem" - - - name: Reset the certificate path to use the bundle - set_fact: - docker_registry_cert_path: "{{ openshift_master_config_dir }}/named_certificates/docker-registry.pem" - -- name: Create the secret for the registry certificates - oc_secret: - name: registry-certificates - namespace: "{{ openshift_hosted_registry_namespace }}" - files: - - name: registry.crt - path: "{{ docker_registry_cert_path }}" - - name: registry.key - path: "{{ docker_registry_key_path }}" - register: create_registry_certificates_secret_out - -- name: Add the secret to the registry's pod service accounts - oc_serviceaccount_secret: - service_account: "{{ item }}" - secret: registry-certificates - namespace: "{{ openshift_hosted_registry_namespace }}" - with_items: - - registry - - default - -- name: Set facts for secure registry - set_fact: - registry_secure_volume_mounts: - - name: registry-certificates - path: /etc/secrets - type: secret - secret_name: registry-certificates - registry_secure_env_vars: - REGISTRY_HTTP_TLS_CERTIFICATE: /etc/secrets/registry.crt - REGISTRY_HTTP_TLS_KEY: /etc/secrets/registry.key - registry_secure_edits: - - key: spec.template.spec.containers[0].livenessProbe.httpGet.scheme - value: HTTPS - action: put - - key: spec.template.spec.containers[0].readinessProbe.httpGet.scheme - value: HTTPS - action: put - -- name: Detect if there has been certificate changes - set_fact: - registry_cert_changed: true - when: ( registry_self_cert is defined and registry_self_cert.changed ) or - create_registry_certificates_secret_out.changed - -- name: Update openshift_hosted facts with secure registry variables - set_fact: - openshift_hosted_registry_volumes: "{{ openshift_hosted_registry_volumes | union(registry_secure_volume_mounts) }}" - openshift_hosted_registry_env_vars: "{{ openshift_hosted_registry_env_vars | combine(registry_secure_env_vars) }}" - openshift_hosted_registry_edits: "{{ openshift_hosted_registry_edits | union(registry_secure_edits) }}" - openshift_hosted_registry_force: "{{ openshift_hosted_registry_force | union([registry_cert_changed | default(false)]) }}" diff --git a/roles/openshift_hosted/tasks/registry/secure/passthrough.yml b/roles/openshift_hosted/tasks/registry/secure/passthrough.yml deleted file mode 100644 index 5b44fda10..000000000 --- a/roles/openshift_hosted/tasks/registry/secure/passthrough.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- -# Generate a self-signed certificate when there is no user-supplied certificate -- name: Configure self-signed certificate file paths - set_fact: - docker_registry_cert_path: "{{ openshift_master_config_dir }}/registry.crt" - docker_registry_key_path: "{{ openshift_master_config_dir }}/registry.key" - docker_registry_cacert_path: "{{ openshift_master_config_dir }}/ca.crt" - docker_registry_self_signed: true - when: - - "'certfile' not in openshift_hosted_registry_routecertificates" - - "'keyfile' not in openshift_hosted_registry_routecertificates" - -# Retrieve user supplied certificate files if they are provided -- when: - - "'certfile' in openshift_hosted_registry_routecertificates" - - "'keyfile' in openshift_hosted_registry_routecertificates" - block: - - name: Configure provided certificate file paths - set_fact: - docker_registry_cert_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['certfile'] | basename }}" - docker_registry_key_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['keyfile'] | basename }}" - docker_registry_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_cacert_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['cafile'] | basename }}" - when: "'cafile' in openshift_hosted_registry_routecertificates" - - - name: Retrieve provided certificate files - copy: - backup: True - dest: "{{ openshift_master_config_dir }}/named_certificates/{{ item.value | basename }}" - src: "{{ item.value }}" - when: item.key in ['certfile', 'keyfile', 'cafile'] and item.value - with_dict: "{{ openshift_hosted_registry_routecertificates }}" - -- name: Configure a passthrough route for docker-registry - oc_route: - name: docker-registry - namespace: "{{ openshift_hosted_registry_namespace }}" - service_name: docker-registry - tls_termination: "{{ openshift_hosted_registry_routetermination }}" - host: "{{ openshift_hosted_registry_routehost | default(omit, true) }}" diff --git a/roles/openshift_hosted/tasks/registry/secure/reencrypt.yml b/roles/openshift_hosted/tasks/registry/secure/reencrypt.yml deleted file mode 100644 index 48e5b0fba..000000000 --- a/roles/openshift_hosted/tasks/registry/secure/reencrypt.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -- name: Validate route termination configuration - fail: - msg: > - When 'openshift_hosted_registry_routetermination' is 'reencrypt', you must - provide certificate files with 'openshift_hosted_registry_routecertificates' - when: ('certfile' not in openshift_hosted_registry_routecertificates) or - ('keyfile' not in openshift_hosted_registry_routecertificates) or - ('cafile' not in openshift_hosted_registry_routecertificates) - -- name: Configure self-signed certificate file paths - set_fact: - docker_registry_cert_path: "{{ openshift_master_config_dir }}/registry.crt" - docker_registry_key_path: "{{ openshift_master_config_dir }}/registry.key" - docker_registry_cacert_path: "{{ openshift_master_config_dir }}/ca.crt" - docker_registry_self_signed: true - -- name: Retrieve provided certificate files - copy: - backup: True - dest: "{{ openshift_master_config_dir }}/named_certificates/{{ item.value | basename }}" - src: "{{ item.value }}" - when: item.key in ['certfile', 'keyfile', 'cafile'] and item.value - with_dict: "{{ openshift_hosted_registry_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 docker-registry - oc_route: - name: docker-registry - namespace: "{{ openshift_hosted_registry_namespace }}" - service_name: docker-registry - tls_termination: "{{ openshift_hosted_registry_routetermination }}" - host: "{{ openshift_hosted_registry_routehost | default(omit, true) }}" - cert_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['certfile'] | basename }}" - key_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['keyfile'] | basename }}" - cacert_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['cafile'] | basename }}" - dest_cacert_path: "{{ openshift_master_config_dir }}/ca.crt" diff --git a/roles/openshift_hosted/tasks/registry/storage/glusterfs.yml b/roles/openshift_hosted/tasks/registry/storage/glusterfs.yml deleted file mode 100644 index c2954fde1..000000000 --- a/roles/openshift_hosted/tasks/registry/storage/glusterfs.yml +++ /dev/null @@ -1,92 +0,0 @@ ---- -- name: Get registry DeploymentConfig - oc_obj: - namespace: "{{ openshift_hosted_registry_namespace }}" - state: list - kind: dc - name: "{{ openshift_hosted_registry_name }}" - register: registry_dc - -- name: Wait for registry pods - oc_obj: - namespace: "{{ openshift_hosted_registry_namespace }}" - state: list - kind: pod - selector: "{% for label, value in registry_dc.results.results[0].spec.selector.iteritems() %}{{ label }}={{ value }}{% if not loop.last %},{% endif %}{% endfor %}" - register: registry_pods - until: - - "registry_pods.results.results[0]['items'] | count > 0" - # There must be as many matching pods with 'Ready' status True as there are expected replicas - - "registry_pods.results.results[0]['items'] | oo_collect(attribute='status.conditions') | oo_collect(attribute='status', filters={'type': 'Ready'}) | map('bool') | select | list | count == openshift_hosted_registry_replicas | int" - delay: 10 - retries: "{{ (600 / 10) | int }}" - -- name: Determine registry fsGroup - set_fact: - openshift_hosted_registry_fsgroup: "{{ registry_pods.results.results[0]['items'][0].spec.securityContext.fsGroup }}" - -- name: Create temp mount directory - command: mktemp -d /tmp/openshift-glusterfs-registry-XXXXXX - register: mktemp - changed_when: False - check_mode: no - -- name: Mount registry volume - mount: - state: mounted - fstype: glusterfs - src: "{% if 'glusterfs_registry' in groups %}{% set node = groups.glusterfs_registry[0] %}{% else %}{% set node = groups.glusterfs[0] %}{% endif %}{% if 'glusterfs_hostname' in hostvars[node] %}{{ hostvars[node].glusterfs_hostname }}{% elif 'openshift' in hostvars[node] %}{{ hostvars[node].openshift.node.nodename }}{% else %}{{ node }}{% endif %}:/{{ openshift.hosted.registry.storage.glusterfs.path }}" - name: "{{ mktemp.stdout }}" - -- name: Set registry volume permissions - file: - dest: "{{ mktemp.stdout }}" - state: directory - group: "{{ openshift_hosted_registry_fsgroup }}" - mode: "2775" - recurse: True - -- block: - - name: Activate registry maintenance mode - oc_env: - namespace: "{{ openshift_hosted_registry_namespace }}" - name: "{{ openshift_hosted_registry_name }}" - env_vars: - - REGISTRY_STORAGE_MAINTENANCE_READONLY_ENABLED: 'true' - - - name: Get first registry pod name - set_fact: - registry_pod_name: "{{ registry_pods.results.results[0]['items'][0].metadata.name }}" - - - name: Copy current registry contents to new GlusterFS volume - command: "oc rsync {{ registry_pod_name }}:/registry/ {{ mktemp.stdout }}/" - when: openshift.hosted.registry.storage.glusterfs.swapcopy - - - name: Swap new GlusterFS registry volume - oc_volume: - namespace: "{{ openshift_hosted_registry_namespace }}" - name: "{{ openshift_hosted_registry_name }}" - vol_name: registry-storage - mount_type: pvc - claim_name: "{{ openshift.hosted.registry.storage.volume.name }}-glusterfs-claim" - - - name: Deactivate registry maintenance mode - oc_env: - namespace: "{{ openshift_hosted_registry_namespace }}" - name: "{{ openshift_hosted_registry_name }}" - state: absent - env_vars: - - REGISTRY_STORAGE_MAINTENANCE_READONLY_ENABLED: 'true' - when: openshift.hosted.registry.storage.glusterfs.swap - -- name: Unmount registry volume - mount: - state: unmounted - name: "{{ mktemp.stdout }}" - -- name: Delete temp mount directory - file: - dest: "{{ mktemp.stdout }}" - state: absent - changed_when: False - check_mode: no diff --git a/roles/openshift_hosted/tasks/registry/storage/object_storage.yml b/roles/openshift_hosted/tasks/registry/storage/object_storage.yml deleted file mode 100644 index 8553a8098..000000000 --- a/roles/openshift_hosted/tasks/registry/storage/object_storage.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- -- include: s3.yml - when: openshift.hosted.registry.storage.provider == 's3' - -- name: Ensure the registry secret exists - oc_secret: - name: "{{ registry_config_secret_name }}" - state: present - contents: - - path: /tmp/config.yml - data: "{{ lookup('template', 'registry_config.j2') }}" - register: registry_config_out - when: openshift_hosted_registry_storage_gcs_keyfile is not defined - -- name: Ensure the registry secret exists for GCS - oc_secret: - name: "{{ registry_config_secret_name }}" - state: present - contents: - - path: /tmp/config.yml - data: "{{ lookup('template', 'registry_config.j2') }}" - - path: /tmp/gcs.json - data: "{{ lookup('file', openshift_hosted_registry_storage_gcs_keyfile) | string }}" - register: registry_config_out - when: openshift_hosted_registry_storage_gcs_keyfile is defined - -- name: Add secrets to registry service account - oc_serviceaccount_secret: - service_account: registry - secret: "{{ registry_config_secret_name }}" - namespace: "{{ openshift_hosted_registry_namespace }}" - state: present - register: svcac - -- name: Set facts for registry object storage - set_fact: - registry_obj_storage_volume_mounts: - - name: docker-config - path: /etc/registry - type: secret - secret_name: "{{ registry_config_secret_name }}" - registry_obj_storage_env_vars: - REGISTRY_CONFIGURATION_PATH: /etc/registry/config.yml - -- name: Update openshift_hosted registry facts for storage - set_fact: - openshift_hosted_registry_volumes: "{{ openshift_hosted_registry_volumes | union(registry_obj_storage_volume_mounts) }}" - openshift_hosted_registry_env_vars: "{{ openshift_hosted_registry_env_vars | combine(registry_obj_storage_env_vars) }}" - openshift_hosted_registry_force: "{{ openshift_hosted_registry_force | union([registry_config_out.changed]) | union([svcac.changed]) }}" diff --git a/roles/openshift_hosted/tasks/registry/storage/registry_config.j2 b/roles/openshift_hosted/tasks/registry/storage/registry_config.j2 deleted file mode 120000 index f3e82ad4f..000000000 --- a/roles/openshift_hosted/tasks/registry/storage/registry_config.j2 +++ /dev/null @@ -1 +0,0 @@ -../../../templates/registry_config.j2 \ No newline at end of file diff --git a/roles/openshift_hosted/tasks/registry/storage/s3.yml b/roles/openshift_hosted/tasks/registry/storage/s3.yml deleted file mode 100644 index 318969885..000000000 --- a/roles/openshift_hosted/tasks/registry/storage/s3.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- -- name: Assert that S3 variables are provided for registry_config template - assert: - that: - - openshift.hosted.registry.storage.s3.bucket | default(none) is not none - - openshift.hosted.registry.storage.s3.region | default(none) is not none - msg: | - When using S3 storage, the following variables are required: - openshift_hosted_registry_storage_s3_bucket - openshift_hosted_registry_storage_s3_region - -- name: If cloudfront is being used, assert that we have all the required variables - assert: - that: - - "openshift_hosted_registry_storage_s3_cloudfront_privatekeyfile | default(none) is not none" - - "openshift_hosted_registry_storage_s3_cloudfront_keypairid | default(none) is not none" - msg: | - When openshift_hosted_registry_storage_s3_cloudfront_baseurl is provided - openshift_hosted_registry_storage_s3_cloudfront_keypairid and - openshift_hosted_registry_storage_s3_cloudfront_privatekeyfile are required - when: openshift_hosted_registry_storage_s3_cloudfront_baseurl is defined - -# Inject the cloudfront private key as a secret when required -- block: - - - name: Create registry secret for cloudfront - oc_secret: - state: present - namespace: "{{ openshift_hosted_registry_namespace }}" - name: docker-registry-s3-cloudfront - contents: - - path: cloudfront.pem - data: "{{ lookup('file', openshift_hosted_registry_storage_s3_cloudfront_privatekeyfile) }}" - - - name: Append cloudfront secret registry volume to openshift_hosted_registry_volumes - set_fact: - openshift_hosted_registry_volumes: "{{ openshift_hosted_registry_volumes | union(s3_volume_mount) }}" - vars: - s3_volume_mount: - - name: cloudfront-vol - path: /etc/origin - type: secret - secret_name: docker-registry-s3-cloudfront - - when: openshift_hosted_registry_storage_s3_cloudfront_baseurl | default(none) is not none diff --git a/roles/openshift_hosted/tasks/router.yml b/roles/openshift_hosted/tasks/router.yml new file mode 100644 index 000000000..2aeecc943 --- /dev/null +++ b/roles/openshift_hosted/tasks/router.yml @@ -0,0 +1,105 @@ +--- +- name: setup firewall + include: firewall.yml + vars: + l_openshift_hosted_firewall_enabled: "{{ r_openshift_hosted_router_firewall_enabled }}" + l_openshift_hosted_use_firewalld: "{{ r_openshift_hosted_router_use_firewalld }}" + l_openshift_hosted_fw_allow: "{{ r_openshift_hosted_router_os_firewall_allow }}" + l_openshift_hosted_fw_deny: "{{ r_openshift_hosted_router_os_firewall_deny }}" + +- name: Retrieve list of openshift nodes matching router selector + oc_obj: + state: list + kind: node + namespace: "{{ openshift.hosted.router.namespace | default('default') }}" + selector: "{{ openshift.hosted.router.selector | default(omit) }}" + register: router_nodes + when: openshift.hosted.router.replicas | default(none) is none + +- name: set_fact replicas + set_fact: + replicas: "{{ openshift.hosted.router.replicas|default(None) | get_router_replicas(router_nodes) }}" + openshift_hosted_router_selector: "{{ openshift.hosted.router.selector | default(None) }}" + openshift_hosted_router_image: "{{ openshift.hosted.router.registryurl }}" + +- name: Get the certificate contents for router + copy: + backup: True + dest: "/etc/origin/master/{{ item | basename }}" + src: "{{ item }}" + with_items: "{{ openshift_hosted_routers | oo_collect(attribute='certificate') | + oo_select_keys_from_list(['keyfile', 'certfile', 'cafile']) }}" + when: ( not openshift_hosted_router_create_certificate | bool ) or openshift_hosted_router_certificate != {} + +# This is for when we desire a cluster signed cert +# The certificate is generated and placed in master_config_dir/ +- block: + - name: generate a default wildcard router certificate + 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: + - "{{ openshift_master_default_subdomain | default('router.default.svc.cluster.local') }}" + - "*.{{ openshift_master_default_subdomain | default('router.default.svc.cluster.local') }}" + cert: "{{ ('/etc/origin/master/' ~ (item.certificate.certfile | basename)) if 'certfile' in item.certificate else ((openshift_master_config_dir) ~ '/openshift-router.crt') }}" + key: "{{ ('/etc/origin/master/' ~ (item.certificate.keyfile | basename)) if 'keyfile' in item.certificate else ((openshift_master_config_dir) ~ '/openshift-router.key') }}" + with_items: "{{ openshift_hosted_routers }}" + + - name: set the openshift_hosted_router_certificate + set_fact: + openshift_hosted_router_certificate: + certfile: "{{ openshift_master_config_dir ~ '/openshift-router.crt' }}" + keyfile: "{{ openshift_master_config_dir ~ '/openshift-router.key' }}" + cafile: "{{ openshift_master_config_dir ~ '/ca.crt' }}" + + # End Block + when: ( openshift_hosted_router_create_certificate | bool ) and openshift_hosted_router_certificate == {} + +- name: Create the router service account(s) + oc_serviceaccount: + name: "{{ item.serviceaccount }}" + namespace: "{{ item.namespace }}" + state: present + with_items: "{{ openshift_hosted_routers }}" + +- name: Grant the router service account(s) access to the appropriate scc + oc_adm_policy_user: + user: "system:serviceaccount:{{ item.namespace }}:{{ item.serviceaccount }}" + namespace: "{{ item.namespace }}" + resource_kind: scc + resource_name: hostnetwork + with_items: "{{ openshift_hosted_routers }}" + +- name: Set additional permissions for router service account + oc_adm_policy_user: + user: "system:serviceaccount:{{ item.namespace }}:{{ item.serviceaccount }}" + namespace: "{{ item.namespace }}" + resource_kind: cluster-role + resource_name: cluster-reader + when: item.namespace == 'default' + with_items: "{{ openshift_hosted_routers }}" + +- name: Create OpenShift router + oc_adm_router: + name: "{{ item.name }}" + replicas: "{{ item.replicas }}" + namespace: "{{ item.namespace | default('default') }}" + # This option is not yet implemented + # force_subdomain: "{{ openshift_hosted_router_force_subdomain | default(none) }}" + service_account: "{{ item.serviceaccount | default('router') }}" + selector: "{{ item.selector | default(none) }}" + images: "{{ item.images | default(omit) }}" + cert_file: "{{ ('/etc/origin/master/' ~ (item.certificate.certfile | basename)) if 'certfile' in item.certificate else omit }}" + key_file: "{{ ('/etc/origin/master/' ~ (item.certificate.keyfile | basename)) if 'keyfile' in item.certificate else omit }}" + cacert_file: "{{ ('/etc/origin/master/' ~ (item.certificate.cafile | basename)) if 'cafile' in item.certificate else omit }}" + edits: "{{ openshift_hosted_router_edits | union(item.edits) }}" + ports: "{{ item.ports }}" + stats_port: "{{ item.stats_port }}" + with_items: "{{ openshift_hosted_routers }}" + +- name: Wait for pod (Routers) + include: wait_for_pod.yml + vars: + l_openshift_hosted_wait_for_pod: "{{ openshift_hosted_router_wait }}" + l_openshift_hosted_wfp_items: "{{ openshift_hosted_routers }}" diff --git a/roles/openshift_hosted/tasks/router/firewall.yml b/roles/openshift_hosted/tasks/router/firewall.yml deleted file mode 100644 index ff90f3372..000000000 --- a/roles/openshift_hosted/tasks/router/firewall.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- -- when: r_openshift_hosted_router_firewall_enabled | bool and not r_openshift_hosted_router_use_firewalld | bool - block: - - name: Add iptables allow rules - os_firewall_manage_iptables: - name: "{{ item.service }}" - action: add - protocol: "{{ item.port.split('/')[1] }}" - port: "{{ item.port.split('/')[0] }}" - when: item.cond | default(True) - with_items: "{{ r_openshift_hosted_router_os_firewall_allow }}" - - - name: Remove iptables rules - os_firewall_manage_iptables: - name: "{{ item.service }}" - action: remove - protocol: "{{ item.port.split('/')[1] }}" - port: "{{ item.port.split('/')[0] }}" - when: item.cond | default(True) - with_items: "{{ r_openshift_hosted_router_os_firewall_deny }}" - -- when: r_openshift_hosted_router_firewall_enabled | bool and r_openshift_hosted_router_use_firewalld | bool - block: - - name: Add firewalld allow rules - firewalld: - port: "{{ item.port }}" - permanent: true - immediate: true - state: enabled - when: item.cond | default(True) - with_items: "{{ r_openshift_hosted_router_os_firewall_allow }}" - - - name: Remove firewalld allow rules - firewalld: - port: "{{ item.port }}" - permanent: true - immediate: true - state: disabled - when: item.cond | default(True) - with_items: "{{ r_openshift_hosted_router_os_firewall_deny }}" diff --git a/roles/openshift_hosted/tasks/router/router.yml b/roles/openshift_hosted/tasks/router/router.yml deleted file mode 100644 index 2a42b5a7c..000000000 --- a/roles/openshift_hosted/tasks/router/router.yml +++ /dev/null @@ -1,131 +0,0 @@ ---- -- name: setup firewall - include: firewall.yml - static: yes - -- name: Retrieve list of openshift nodes matching router selector - oc_obj: - state: list - kind: node - namespace: "{{ openshift.hosted.router.namespace | default('default') }}" - selector: "{{ openshift.hosted.router.selector | default(omit) }}" - register: router_nodes - when: openshift.hosted.router.replicas | default(none) is none - -- name: set_fact replicas - set_fact: - replicas: "{{ openshift.hosted.router.replicas|default(None) | get_router_replicas(router_nodes) }}" - openshift_hosted_router_selector: "{{ openshift.hosted.router.selector | default(None) }}" - openshift_hosted_router_image: "{{ openshift.hosted.router.registryurl }}" - -- name: Get the certificate contents for router - copy: - backup: True - dest: "/etc/origin/master/{{ item | basename }}" - src: "{{ item }}" - with_items: "{{ openshift_hosted_routers | oo_collect(attribute='certificate') | - oo_select_keys_from_list(['keyfile', 'certfile', 'cafile']) }}" - when: ( not openshift_hosted_router_create_certificate | bool ) or openshift_hosted_router_certificate != {} - -# This is for when we desire a cluster signed cert -# The certificate is generated and placed in master_config_dir/ -- block: - - name: generate a default wildcard router certificate - 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: - - "{{ openshift_master_default_subdomain | default('router.default.svc.cluster.local') }}" - - "*.{{ openshift_master_default_subdomain | default('router.default.svc.cluster.local') }}" - cert: "{{ ('/etc/origin/master/' ~ (item.certificate.certfile | basename)) if 'certfile' in item.certificate else ((openshift_master_config_dir) ~ '/openshift-router.crt') }}" - key: "{{ ('/etc/origin/master/' ~ (item.certificate.keyfile | basename)) if 'keyfile' in item.certificate else ((openshift_master_config_dir) ~ '/openshift-router.key') }}" - with_items: "{{ openshift_hosted_routers }}" - - - name: set the openshift_hosted_router_certificate - set_fact: - openshift_hosted_router_certificate: - certfile: "{{ openshift_master_config_dir ~ '/openshift-router.crt' }}" - keyfile: "{{ openshift_master_config_dir ~ '/openshift-router.key' }}" - cafile: "{{ openshift_master_config_dir ~ '/ca.crt' }}" - - # End Block - when: ( openshift_hosted_router_create_certificate | bool ) and openshift_hosted_router_certificate == {} - -- name: Create the router service account(s) - oc_serviceaccount: - name: "{{ item.serviceaccount }}" - namespace: "{{ item.namespace }}" - state: present - with_items: "{{ openshift_hosted_routers }}" - -- name: Grant the router service account(s) access to the appropriate scc - oc_adm_policy_user: - user: "system:serviceaccount:{{ item.namespace }}:{{ item.serviceaccount }}" - namespace: "{{ item.namespace }}" - resource_kind: scc - resource_name: hostnetwork - with_items: "{{ openshift_hosted_routers }}" - -- name: Set additional permissions for router service account - oc_adm_policy_user: - user: "system:serviceaccount:{{ item.namespace }}:{{ item.serviceaccount }}" - namespace: "{{ item.namespace }}" - resource_kind: cluster-role - resource_name: cluster-reader - when: item.namespace == 'default' - with_items: "{{ openshift_hosted_routers }}" - -- name: Create OpenShift router - oc_adm_router: - name: "{{ item.name }}" - replicas: "{{ item.replicas }}" - namespace: "{{ item.namespace | default('default') }}" - # This option is not yet implemented - # force_subdomain: "{{ openshift.hosted.router.force_subdomain | default(none) }}" - service_account: "{{ item.serviceaccount | default('router') }}" - selector: "{{ item.selector | default(none) }}" - images: "{{ item.images | default(omit) }}" - cert_file: "{{ ('/etc/origin/master/' ~ (item.certificate.certfile | basename)) if 'certfile' in item.certificate else omit }}" - key_file: "{{ ('/etc/origin/master/' ~ (item.certificate.keyfile | basename)) if 'keyfile' in item.certificate else omit }}" - cacert_file: "{{ ('/etc/origin/master/' ~ (item.certificate.cafile | basename)) if 'cafile' in item.certificate else omit }}" - edits: "{{ openshift_hosted_router_edits | union(item.edits) }}" - ports: "{{ item.ports }}" - stats_port: "{{ item.stats_port }}" - with_items: "{{ openshift_hosted_routers }}" - -- when: openshift_hosted_router_wait | bool - block: - - name: Ensure OpenShift router correctly rolls out (best-effort today) - command: | - {{ openshift.common.client_binary }} rollout status deploymentconfig {{ item.name }} \ - --namespace {{ item.namespace | default('default') }} \ - --config {{ openshift.common.config_base }}/master/admin.kubeconfig - async: 600 - poll: 15 - with_items: "{{ openshift_hosted_routers }}" - failed_when: false - - - name: Determine the latest version of the OpenShift router deployment - command: | - {{ openshift.common.client_binary }} get deploymentconfig {{ item.name }} \ - --namespace {{ item.namespace }} \ - --config {{ openshift.common.config_base }}/master/admin.kubeconfig \ - -o jsonpath='{ .status.latestVersion }' - register: openshift_hosted_routers_latest_version - with_items: "{{ openshift_hosted_routers }}" - - - name: Poll for OpenShift router deployment success - command: | - {{ openshift.common.client_binary }} get replicationcontroller {{ item.0.name }}-{{ item.1.stdout }} \ - --namespace {{ item.0.namespace }} \ - --config {{ openshift.common.config_base }}/master/admin.kubeconfig \ - -o jsonpath='{ .metadata.annotations.openshift\.io/deployment\.phase }' - register: openshift_hosted_router_rc_phase - until: "'Running' not in openshift_hosted_router_rc_phase.stdout" - delay: 15 - retries: 40 - failed_when: "'Failed' in openshift_hosted_router_rc_phase.stdout" - with_together: - - "{{ openshift_hosted_routers }}" - - "{{ openshift_hosted_routers_latest_version.results }}" diff --git a/roles/openshift_hosted/tasks/secure.yml b/roles/openshift_hosted/tasks/secure.yml new file mode 100644 index 000000000..0da8ac8a7 --- /dev/null +++ b/roles/openshift_hosted/tasks/secure.yml @@ -0,0 +1,119 @@ +--- +- name: Configure facts for docker-registry + set_fact: + openshift_hosted_registry_routecertificates: "{{ ('routecertificates' in openshift.hosted.registry.keys()) | ternary(openshift_hosted_registry_routecertificates, {}) }}" + openshift_hosted_registry_routehost: "{{ ('routehost' in openshift.hosted.registry.keys()) | ternary(openshift.hosted.registry.routehost, False) }}" + openshift_hosted_registry_routetermination: "{{ ('routetermination' in openshift.hosted.registry.keys()) | ternary(openshift.hosted.registry.routetermination, 'passthrough') }}" + +- name: Include reencrypt route configuration + include: secure/reencrypt.yml + static: no + when: openshift_hosted_registry_routetermination == 'reencrypt' + +- name: Include passthrough route configuration + include: secure/passthrough.yml + static: no + when: openshift_hosted_registry_routetermination == 'passthrough' + +- name: Fetch the docker-registry route + oc_route: + name: docker-registry + namespace: default + state: list + register: docker_registry_route + +- name: Retrieve registry service for the clusterip + oc_service: + namespace: "{{ openshift_hosted_registry_namespace }}" + name: docker-registry + state: list + register: docker_registry_service + +- name: Generate self-signed docker-registry 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_service.results.clusterip }}" + - "{{ docker_registry_route.results[0].spec.host }}" + - "{{ openshift_hosted_registry_name }}.default.svc" + - "{{ openshift_hosted_registry_name }}.default.svc.{{ openshift_cluster_domain }}" + - "{{ openshift_hosted_registry_routehost }}" + cert: "{{ docker_registry_cert_path }}" + key: "{{ docker_registry_key_path }}" + expire_days: "{{ openshift_hosted_registry_cert_expire_days if openshift_version | oo_version_gte_3_5_or_1_5(openshift_deployment_type) | bool else omit }}" + register: registry_self_cert + when: docker_registry_self_signed + +# Setting up REGISTRY_HTTP_TLS_CLIENTCAS as the cacert doesn't seem to work. +# If we need to set up a cacert, bundle it with the cert. +- when: docker_registry_cacert_path is defined + block: + - name: Retrieve certificate files to generate certificate bundle + slurp: + src: "{{ item }}" + with_items: + - "{{ docker_registry_cert_path }}" + - "{{ docker_registry_cacert_path }}" + register: certificate_files + + - name: Generate certificate bundle + copy: + content: "{{ certificate_files.results | map(attribute='content') | map('b64decode') | join('') }}" + dest: "{{ openshift_master_config_dir }}/named_certificates/docker-registry.pem" + + - name: Reset the certificate path to use the bundle + set_fact: + docker_registry_cert_path: "{{ openshift_master_config_dir }}/named_certificates/docker-registry.pem" + +- name: Create the secret for the registry certificates + oc_secret: + name: registry-certificates + namespace: "{{ openshift_hosted_registry_namespace }}" + files: + - name: registry.crt + path: "{{ docker_registry_cert_path }}" + - name: registry.key + path: "{{ docker_registry_key_path }}" + register: create_registry_certificates_secret_out + +- name: Add the secret to the registry's pod service accounts + oc_serviceaccount_secret: + service_account: "{{ item }}" + secret: registry-certificates + namespace: "{{ openshift_hosted_registry_namespace }}" + with_items: + - registry + - default + +- name: Set facts for secure registry + set_fact: + registry_secure_volume_mounts: + - name: registry-certificates + path: /etc/secrets + type: secret + secret_name: registry-certificates + registry_secure_env_vars: + REGISTRY_HTTP_TLS_CERTIFICATE: /etc/secrets/registry.crt + REGISTRY_HTTP_TLS_KEY: /etc/secrets/registry.key + registry_secure_edits: + - key: spec.template.spec.containers[0].livenessProbe.httpGet.scheme + value: HTTPS + action: put + - key: spec.template.spec.containers[0].readinessProbe.httpGet.scheme + value: HTTPS + action: put + +- name: Detect if there has been certificate changes + set_fact: + registry_cert_changed: true + when: ( registry_self_cert is defined and registry_self_cert.changed ) or + create_registry_certificates_secret_out.changed + +- name: Update openshift_hosted facts with secure registry variables + set_fact: + openshift_hosted_registry_volumes: "{{ openshift_hosted_registry_volumes | union(registry_secure_volume_mounts) }}" + openshift_hosted_registry_env_vars: "{{ openshift_hosted_registry_env_vars | combine(registry_secure_env_vars) }}" + openshift_hosted_registry_edits: "{{ openshift_hosted_registry_edits | union(registry_secure_edits) }}" + openshift_hosted_registry_force: "{{ openshift_hosted_registry_force | union([registry_cert_changed | default(false)]) }}" diff --git a/roles/openshift_hosted/tasks/secure/passthrough.yml b/roles/openshift_hosted/tasks/secure/passthrough.yml new file mode 100644 index 000000000..5b44fda10 --- /dev/null +++ b/roles/openshift_hosted/tasks/secure/passthrough.yml @@ -0,0 +1,45 @@ +--- +# Generate a self-signed certificate when there is no user-supplied certificate +- name: Configure self-signed certificate file paths + set_fact: + docker_registry_cert_path: "{{ openshift_master_config_dir }}/registry.crt" + docker_registry_key_path: "{{ openshift_master_config_dir }}/registry.key" + docker_registry_cacert_path: "{{ openshift_master_config_dir }}/ca.crt" + docker_registry_self_signed: true + when: + - "'certfile' not in openshift_hosted_registry_routecertificates" + - "'keyfile' not in openshift_hosted_registry_routecertificates" + +# Retrieve user supplied certificate files if they are provided +- when: + - "'certfile' in openshift_hosted_registry_routecertificates" + - "'keyfile' in openshift_hosted_registry_routecertificates" + block: + - name: Configure provided certificate file paths + set_fact: + docker_registry_cert_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['certfile'] | basename }}" + docker_registry_key_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['keyfile'] | basename }}" + docker_registry_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_cacert_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['cafile'] | basename }}" + when: "'cafile' in openshift_hosted_registry_routecertificates" + + - name: Retrieve provided certificate files + copy: + backup: True + dest: "{{ openshift_master_config_dir }}/named_certificates/{{ item.value | basename }}" + src: "{{ item.value }}" + when: item.key in ['certfile', 'keyfile', 'cafile'] and item.value + with_dict: "{{ openshift_hosted_registry_routecertificates }}" + +- name: Configure a passthrough route for docker-registry + oc_route: + name: docker-registry + namespace: "{{ openshift_hosted_registry_namespace }}" + service_name: docker-registry + tls_termination: "{{ openshift_hosted_registry_routetermination }}" + host: "{{ openshift_hosted_registry_routehost | default(omit, true) }}" diff --git a/roles/openshift_hosted/tasks/secure/reencrypt.yml b/roles/openshift_hosted/tasks/secure/reencrypt.yml new file mode 100644 index 000000000..48e5b0fba --- /dev/null +++ b/roles/openshift_hosted/tasks/secure/reencrypt.yml @@ -0,0 +1,38 @@ +--- +- name: Validate route termination configuration + fail: + msg: > + When 'openshift_hosted_registry_routetermination' is 'reencrypt', you must + provide certificate files with 'openshift_hosted_registry_routecertificates' + when: ('certfile' not in openshift_hosted_registry_routecertificates) or + ('keyfile' not in openshift_hosted_registry_routecertificates) or + ('cafile' not in openshift_hosted_registry_routecertificates) + +- name: Configure self-signed certificate file paths + set_fact: + docker_registry_cert_path: "{{ openshift_master_config_dir }}/registry.crt" + docker_registry_key_path: "{{ openshift_master_config_dir }}/registry.key" + docker_registry_cacert_path: "{{ openshift_master_config_dir }}/ca.crt" + docker_registry_self_signed: true + +- name: Retrieve provided certificate files + copy: + backup: True + dest: "{{ openshift_master_config_dir }}/named_certificates/{{ item.value | basename }}" + src: "{{ item.value }}" + when: item.key in ['certfile', 'keyfile', 'cafile'] and item.value + with_dict: "{{ openshift_hosted_registry_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 docker-registry + oc_route: + name: docker-registry + namespace: "{{ openshift_hosted_registry_namespace }}" + service_name: docker-registry + tls_termination: "{{ openshift_hosted_registry_routetermination }}" + host: "{{ openshift_hosted_registry_routehost | default(omit, true) }}" + cert_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['certfile'] | basename }}" + key_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['keyfile'] | basename }}" + cacert_path: "{{ openshift_master_config_dir }}/named_certificates/{{ openshift_hosted_registry_routecertificates['cafile'] | basename }}" + dest_cacert_path: "{{ openshift_master_config_dir }}/ca.crt" diff --git a/roles/openshift_hosted/tasks/storage/glusterfs.yml b/roles/openshift_hosted/tasks/storage/glusterfs.yml new file mode 100644 index 000000000..c2954fde1 --- /dev/null +++ b/roles/openshift_hosted/tasks/storage/glusterfs.yml @@ -0,0 +1,92 @@ +--- +- name: Get registry DeploymentConfig + oc_obj: + namespace: "{{ openshift_hosted_registry_namespace }}" + state: list + kind: dc + name: "{{ openshift_hosted_registry_name }}" + register: registry_dc + +- name: Wait for registry pods + oc_obj: + namespace: "{{ openshift_hosted_registry_namespace }}" + state: list + kind: pod + selector: "{% for label, value in registry_dc.results.results[0].spec.selector.iteritems() %}{{ label }}={{ value }}{% if not loop.last %},{% endif %}{% endfor %}" + register: registry_pods + until: + - "registry_pods.results.results[0]['items'] | count > 0" + # There must be as many matching pods with 'Ready' status True as there are expected replicas + - "registry_pods.results.results[0]['items'] | oo_collect(attribute='status.conditions') | oo_collect(attribute='status', filters={'type': 'Ready'}) | map('bool') | select | list | count == openshift_hosted_registry_replicas | int" + delay: 10 + retries: "{{ (600 / 10) | int }}" + +- name: Determine registry fsGroup + set_fact: + openshift_hosted_registry_fsgroup: "{{ registry_pods.results.results[0]['items'][0].spec.securityContext.fsGroup }}" + +- name: Create temp mount directory + command: mktemp -d /tmp/openshift-glusterfs-registry-XXXXXX + register: mktemp + changed_when: False + check_mode: no + +- name: Mount registry volume + mount: + state: mounted + fstype: glusterfs + src: "{% if 'glusterfs_registry' in groups %}{% set node = groups.glusterfs_registry[0] %}{% else %}{% set node = groups.glusterfs[0] %}{% endif %}{% if 'glusterfs_hostname' in hostvars[node] %}{{ hostvars[node].glusterfs_hostname }}{% elif 'openshift' in hostvars[node] %}{{ hostvars[node].openshift.node.nodename }}{% else %}{{ node }}{% endif %}:/{{ openshift.hosted.registry.storage.glusterfs.path }}" + name: "{{ mktemp.stdout }}" + +- name: Set registry volume permissions + file: + dest: "{{ mktemp.stdout }}" + state: directory + group: "{{ openshift_hosted_registry_fsgroup }}" + mode: "2775" + recurse: True + +- block: + - name: Activate registry maintenance mode + oc_env: + namespace: "{{ openshift_hosted_registry_namespace }}" + name: "{{ openshift_hosted_registry_name }}" + env_vars: + - REGISTRY_STORAGE_MAINTENANCE_READONLY_ENABLED: 'true' + + - name: Get first registry pod name + set_fact: + registry_pod_name: "{{ registry_pods.results.results[0]['items'][0].metadata.name }}" + + - name: Copy current registry contents to new GlusterFS volume + command: "oc rsync {{ registry_pod_name }}:/registry/ {{ mktemp.stdout }}/" + when: openshift.hosted.registry.storage.glusterfs.swapcopy + + - name: Swap new GlusterFS registry volume + oc_volume: + namespace: "{{ openshift_hosted_registry_namespace }}" + name: "{{ openshift_hosted_registry_name }}" + vol_name: registry-storage + mount_type: pvc + claim_name: "{{ openshift.hosted.registry.storage.volume.name }}-glusterfs-claim" + + - name: Deactivate registry maintenance mode + oc_env: + namespace: "{{ openshift_hosted_registry_namespace }}" + name: "{{ openshift_hosted_registry_name }}" + state: absent + env_vars: + - REGISTRY_STORAGE_MAINTENANCE_READONLY_ENABLED: 'true' + when: openshift.hosted.registry.storage.glusterfs.swap + +- name: Unmount registry volume + mount: + state: unmounted + name: "{{ mktemp.stdout }}" + +- name: Delete temp mount directory + file: + dest: "{{ mktemp.stdout }}" + state: absent + changed_when: False + check_mode: no diff --git a/roles/openshift_hosted/tasks/storage/object_storage.yml b/roles/openshift_hosted/tasks/storage/object_storage.yml new file mode 100644 index 000000000..8553a8098 --- /dev/null +++ b/roles/openshift_hosted/tasks/storage/object_storage.yml @@ -0,0 +1,49 @@ +--- +- include: s3.yml + when: openshift.hosted.registry.storage.provider == 's3' + +- name: Ensure the registry secret exists + oc_secret: + name: "{{ registry_config_secret_name }}" + state: present + contents: + - path: /tmp/config.yml + data: "{{ lookup('template', 'registry_config.j2') }}" + register: registry_config_out + when: openshift_hosted_registry_storage_gcs_keyfile is not defined + +- name: Ensure the registry secret exists for GCS + oc_secret: + name: "{{ registry_config_secret_name }}" + state: present + contents: + - path: /tmp/config.yml + data: "{{ lookup('template', 'registry_config.j2') }}" + - path: /tmp/gcs.json + data: "{{ lookup('file', openshift_hosted_registry_storage_gcs_keyfile) | string }}" + register: registry_config_out + when: openshift_hosted_registry_storage_gcs_keyfile is defined + +- name: Add secrets to registry service account + oc_serviceaccount_secret: + service_account: registry + secret: "{{ registry_config_secret_name }}" + namespace: "{{ openshift_hosted_registry_namespace }}" + state: present + register: svcac + +- name: Set facts for registry object storage + set_fact: + registry_obj_storage_volume_mounts: + - name: docker-config + path: /etc/registry + type: secret + secret_name: "{{ registry_config_secret_name }}" + registry_obj_storage_env_vars: + REGISTRY_CONFIGURATION_PATH: /etc/registry/config.yml + +- name: Update openshift_hosted registry facts for storage + set_fact: + openshift_hosted_registry_volumes: "{{ openshift_hosted_registry_volumes | union(registry_obj_storage_volume_mounts) }}" + openshift_hosted_registry_env_vars: "{{ openshift_hosted_registry_env_vars | combine(registry_obj_storage_env_vars) }}" + openshift_hosted_registry_force: "{{ openshift_hosted_registry_force | union([registry_config_out.changed]) | union([svcac.changed]) }}" diff --git a/roles/openshift_hosted/tasks/storage/registry_config.j2 b/roles/openshift_hosted/tasks/storage/registry_config.j2 new file mode 120000 index 000000000..f3e82ad4f --- /dev/null +++ b/roles/openshift_hosted/tasks/storage/registry_config.j2 @@ -0,0 +1 @@ +../../../templates/registry_config.j2 \ No newline at end of file diff --git a/roles/openshift_hosted/tasks/storage/s3.yml b/roles/openshift_hosted/tasks/storage/s3.yml new file mode 100644 index 000000000..8e905d905 --- /dev/null +++ b/roles/openshift_hosted/tasks/storage/s3.yml @@ -0,0 +1,45 @@ +--- +- name: Assert that S3 variables are provided for registry_config template + assert: + that: + - openshift.hosted.registry.storage.s3.bucket | default(none) is not none + - openshift.hosted.registry.storage.s3.bucket | default(none) is not none + msg: | + When using S3 storage, the following variables are required: + openshift_hosted_registry_storage_s3_bucket + openshift_hosted_registry_storage_s3_region + +- name: If cloudfront is being used, assert that we have all the required variables + assert: + that: + - "openshift_hosted_registry_storage_s3_cloudfront_privatekeyfile | default(none) is not none" + - "openshift_hosted_registry_storage_s3_cloudfront_keypairid | default(none) is not none" + msg: | + When openshift_hosted_registry_storage_s3_cloudfront_baseurl is provided + openshift_hosted_registry_storage_s3_cloudfront_keypairid and + openshift_hosted_registry_storage_s3_cloudfront_privatekeyfile are required + when: openshift_hosted_registry_storage_s3_cloudfront_baseurl is defined + +# Inject the cloudfront private key as a secret when required +- block: + + - name: Create registry secret for cloudfront + oc_secret: + state: present + namespace: "{{ openshift_hosted_registry_namespace }}" + name: docker-registry-s3-cloudfront + contents: + - path: cloudfront.pem + data: "{{ lookup('file', openshift_hosted_registry_storage_s3_cloudfront_privatekeyfile) }}" + + - name: Append cloudfront secret registry volume to openshift_hosted_registry_volumes + set_fact: + openshift_hosted_registry_volumes: "{{ openshift_hosted_registry_volumes | union(s3_volume_mount) }}" + vars: + s3_volume_mount: + - name: cloudfront-vol + path: /etc/origin + type: secret + secret_name: docker-registry-s3-cloudfront + + when: openshift_hosted_registry_storage_s3_cloudfront_baseurl | default(none) is not none diff --git a/roles/openshift_hosted/tasks/wait_for_pod.yml b/roles/openshift_hosted/tasks/wait_for_pod.yml new file mode 100644 index 000000000..056c79334 --- /dev/null +++ b/roles/openshift_hosted/tasks/wait_for_pod.yml @@ -0,0 +1,36 @@ +--- +- when: l_openshift_hosted_wait_for_pod | default(False) | bool + block: + - name: Ensure OpenShift pod correctly rolls out (best-effort today) + command: | + {{ openshift.common.client_binary }} rollout status deploymentconfig {{ item.name }} \ + --namespace {{ item.namespace | default('default') }} \ + --config {{ openshift_master_config_dir }}/admin.kubeconfig + async: 600 + poll: 15 + with_items: "{{ l_openshift_hosted_wfp_items }}" + failed_when: false + + - name: Determine the latest version of the OpenShift pod deployment + command: | + {{ openshift.common.client_binary }} get deploymentconfig {{ item.name }} \ + --namespace {{ item.namespace }} \ + --config {{ openshift_master_config_dir }}/admin.kubeconfig \ + -o jsonpath='{ .status.latestVersion }' + register: l_openshift_hosted_wfp_latest_version + with_items: "{{ l_openshift_hosted_wfp_items }}" + + - name: Poll for OpenShift pod deployment success + command: | + {{ openshift.common.client_binary }} get replicationcontroller {{ item.0.name }}-{{ item.1.stdout }} \ + --namespace {{ item.0.namespace }} \ + --config {{ openshift_master_config_dir }}/admin.kubeconfig \ + -o jsonpath='{ .metadata.annotations.openshift\.io/deployment\.phase }' + register: openshift_hosted_wfp_rc_phase + until: "'Running' not in openshift_hosted_wfp_rc_phase.stdout" + delay: 15 + retries: 40 + failed_when: "'Failed' in openshift_hosted_wfp_rc_phase.stdout" + with_together: + - "{{ l_openshift_hosted_wfp_items }}" + - "{{ l_openshift_hosted_wfp_latest_version.results }}" diff --git a/roles/openshift_hosted/templates/registry_config.j2 b/roles/openshift_hosted/templates/registry_config.j2 index 61da452de..eae8b328e 100644 --- a/roles/openshift_hosted/templates/registry_config.j2 +++ b/roles/openshift_hosted/templates/registry_config.j2 @@ -70,10 +70,8 @@ auth: openshift: realm: openshift middleware: -{% if openshift.common.version_gte_3_3_or_1_3 | bool %} registry: - name: openshift -{% endif %} repository: - name: openshift options: @@ -87,7 +85,7 @@ middleware: baseurl: {{ openshift_hosted_registry_storage_s3_cloudfront_baseurl }} privatekey: /etc/origin/cloudfront.pem keypairid: {{ openshift_hosted_registry_storage_s3_cloudfront_keypairid }} -{% elif openshift.common.version_gte_3_3_or_1_3 | bool %} +{% else %} storage: - name: openshift {% endif -%} diff --git a/roles/openshift_hosted/vars/main.yml b/roles/openshift_hosted/vars/main.yml index 0821d0e7e..0e756d9e1 100644 --- a/roles/openshift_hosted/vars/main.yml +++ b/roles/openshift_hosted/vars/main.yml @@ -1,13 +1,2 @@ --- -openshift_master_config_dir: "{{ openshift.common.config_base }}/master" registry_config_secret_name: registry-config - -openshift_default_projects: - default: - default_node_selector: '' - logging: - default_node_selector: '' - openshift-infra: - default_node_selector: '' - -openshift_projects: "{{ openshift_additional_projects | default({}) | oo_merge_dicts(openshift_default_projects) }}" -- cgit v1.2.3