summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.tito/packages/openshift-ansible2
-rw-r--r--openshift-ansible.spec13
-rw-r--r--playbooks/common/openshift-cluster/config.yml25
-rw-r--r--playbooks/common/openshift-cluster/initialize_oo_option_facts.yml27
-rw-r--r--playbooks/common/openshift-cluster/openshift_provisioners.yml5
-rw-r--r--playbooks/common/openshift-cluster/redeploy-certificates/ca.yml6
-rw-r--r--playbooks/common/openshift-cluster/upgrades/init.yml22
-rw-r--r--playbooks/common/openshift-cluster/upgrades/post_control_plane.yml40
-rw-r--r--playbooks/common/openshift-master/restart.yml6
-rw-r--r--roles/lib_openshift/library/oc_adm_ca_server_cert.py2
-rw-r--r--roles/lib_openshift/src/class/oc_adm_ca_server_cert.py2
-rwxr-xr-xroles/openshift_health_checker/library/aos_version.py214
-rw-r--r--roles/openshift_health_checker/meta/main.yml1
-rw-r--r--roles/openshift_health_checker/openshift_checks/package_availability.py4
-rw-r--r--roles/openshift_health_checker/openshift_checks/package_version.py8
-rw-r--r--roles/openshift_health_checker/test/aos_version_test.py120
-rw-r--r--roles/openshift_health_checker/test/conftest.py3
-rw-r--r--roles/openshift_health_checker/test/package_availability_test.py14
-rw-r--r--roles/openshift_health_checker/test/package_version_test.py13
-rw-r--r--roles/openshift_provisioners/README.md29
-rw-r--r--roles/openshift_provisioners/defaults/main.yaml12
-rw-r--r--roles/openshift_provisioners/meta/main.yaml16
-rw-r--r--roles/openshift_provisioners/tasks/generate_clusterrolebindings.yaml19
-rw-r--r--roles/openshift_provisioners/tasks/generate_secrets.yaml14
-rw-r--r--roles/openshift_provisioners/tasks/generate_serviceaccounts.yaml12
-rw-r--r--roles/openshift_provisioners/tasks/install_efs.yaml70
-rw-r--r--roles/openshift_provisioners/tasks/install_provisioners.yaml55
-rw-r--r--roles/openshift_provisioners/tasks/install_support.yaml24
-rw-r--r--roles/openshift_provisioners/tasks/main.yaml27
-rw-r--r--roles/openshift_provisioners/tasks/oc_apply.yaml51
-rw-r--r--roles/openshift_provisioners/tasks/start_cluster.yaml20
-rw-r--r--roles/openshift_provisioners/tasks/stop_cluster.yaml20
-rw-r--r--roles/openshift_provisioners/tasks/uninstall_provisioners.yaml43
-rw-r--r--roles/openshift_provisioners/templates/clusterrolebinding.j230
-rw-r--r--roles/openshift_provisioners/templates/efs.j258
-rw-r--r--roles/openshift_provisioners/templates/pv.j232
-rw-r--r--roles/openshift_provisioners/templates/pvc.j226
-rw-r--r--roles/openshift_provisioners/templates/secret.j215
-rw-r--r--roles/openshift_provisioners/templates/serviceaccount.j216
-rw-r--r--roles/openshift_sanitize_inventory/tasks/main.yml13
40 files changed, 991 insertions, 138 deletions
diff --git a/.tito/packages/openshift-ansible b/.tito/packages/openshift-ansible
index 49ecde422..13ff44567 100644
--- a/.tito/packages/openshift-ansible
+++ b/.tito/packages/openshift-ansible
@@ -1 +1 @@
-3.6.21-1 ./
+3.6.22-1 ./
diff --git a/openshift-ansible.spec b/openshift-ansible.spec
index 4a69537fe..166d21918 100644
--- a/openshift-ansible.spec
+++ b/openshift-ansible.spec
@@ -9,7 +9,7 @@
%global __requires_exclude ^/usr/bin/ansible-playbook$
Name: openshift-ansible
-Version: 3.6.21
+Version: 3.6.22
Release: 1%{?dist}
Summary: Openshift and Atomic Enterprise Ansible
License: ASL 2.0
@@ -270,6 +270,17 @@ Atomic OpenShift Utilities includes
%changelog
+* Wed Apr 12 2017 Jenkins CD Merge Bot <tdawson@redhat.com> 3.6.22-1
+- Fixed spelling mistake. (kwoodson@redhat.com)
+- Remove unnecessary folder refs (rteague@redhat.com)
+- Switching commands for modules during upgrade of router and registry.
+ (kwoodson@redhat.com)
+- Fixing a compatibility issue with python 2.7 to 3.5 when reading from
+ subprocess. (kwoodson@redhat.com)
+- Refactor use of initialize_oo_option_facts.yml (rteague@redhat.com)
+- preflight checks: refactor and fix aos_version (lmeyer@redhat.com)
+- Add external provisioners playbook starting with aws efs (mawong@redhat.com)
+
* Tue Apr 11 2017 Jenkins CD Merge Bot <tdawson@redhat.com> 3.6.21-1
- Adding a query for the existing docker-registry route. (kwoodson@redhat.com)
- Removing docker-registry route from cockpit-ui. (kwoodson@redhat.com)
diff --git a/playbooks/common/openshift-cluster/config.yml b/playbooks/common/openshift-cluster/config.yml
index 1b967b7f1..3c70db6a9 100644
--- a/playbooks/common/openshift-cluster/config.yml
+++ b/playbooks/common/openshift-cluster/config.yml
@@ -1,30 +1,7 @@
---
-- name: Set oo_option facts
- hosts: oo_all_hosts
+- include: initialize_oo_option_facts.yml
tags:
- always
- tasks:
- - set_fact:
- openshift_docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries') }}"
- when: openshift_docker_additional_registries is not defined
- - set_fact:
- openshift_docker_insecure_registries: "{{ lookup('oo_option', 'docker_insecure_registries') }}"
- when: openshift_docker_insecure_registries is not defined
- - set_fact:
- openshift_docker_blocked_registries: "{{ lookup('oo_option', 'docker_blocked_registries') }}"
- when: openshift_docker_blocked_registries is not defined
- - set_fact:
- openshift_docker_options: "{{ lookup('oo_option', 'docker_options') }}"
- when: openshift_docker_options is not defined
- - set_fact:
- openshift_docker_log_driver: "{{ lookup('oo_option', 'docker_log_driver') }}"
- when: openshift_docker_log_driver is not defined
- - set_fact:
- openshift_docker_log_options: "{{ lookup('oo_option', 'docker_log_options') }}"
- when: openshift_docker_log_options is not defined
- - set_fact:
- openshift_docker_selinux_enabled: "{{ lookup('oo_option', 'docker_selinux_enabled') }}"
- when: openshift_docker_selinux_enabled is not defined
- include: disable_excluder.yml
tags:
diff --git a/playbooks/common/openshift-cluster/initialize_oo_option_facts.yml b/playbooks/common/openshift-cluster/initialize_oo_option_facts.yml
new file mode 100644
index 000000000..ac3c702a0
--- /dev/null
+++ b/playbooks/common/openshift-cluster/initialize_oo_option_facts.yml
@@ -0,0 +1,27 @@
+---
+- name: Set oo_option facts
+ hosts: oo_all_hosts
+ tags:
+ - always
+ tasks:
+ - set_fact:
+ openshift_docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries') }}"
+ when: openshift_docker_additional_registries is not defined
+ - set_fact:
+ openshift_docker_insecure_registries: "{{ lookup('oo_option', 'docker_insecure_registries') }}"
+ when: openshift_docker_insecure_registries is not defined
+ - set_fact:
+ openshift_docker_blocked_registries: "{{ lookup('oo_option', 'docker_blocked_registries') }}"
+ when: openshift_docker_blocked_registries is not defined
+ - set_fact:
+ openshift_docker_options: "{{ lookup('oo_option', 'docker_options') }}"
+ when: openshift_docker_options is not defined
+ - set_fact:
+ openshift_docker_log_driver: "{{ lookup('oo_option', 'docker_log_driver') }}"
+ when: openshift_docker_log_driver is not defined
+ - set_fact:
+ openshift_docker_log_options: "{{ lookup('oo_option', 'docker_log_options') }}"
+ when: openshift_docker_log_options is not defined
+ - set_fact:
+ openshift_docker_selinux_enabled: "{{ lookup('oo_option', 'docker_selinux_enabled') }}"
+ when: openshift_docker_selinux_enabled is not defined
diff --git a/playbooks/common/openshift-cluster/openshift_provisioners.yml b/playbooks/common/openshift-cluster/openshift_provisioners.yml
new file mode 100644
index 000000000..b1ca6f606
--- /dev/null
+++ b/playbooks/common/openshift-cluster/openshift_provisioners.yml
@@ -0,0 +1,5 @@
+---
+- name: OpenShift Provisioners
+ hosts: oo_first_master
+ roles:
+ - openshift_provisioners
diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/ca.yml b/playbooks/common/openshift-cluster/redeploy-certificates/ca.yml
index cbb4a2434..3b26abcc7 100644
--- a/playbooks/common/openshift-cluster/redeploy-certificates/ca.yml
+++ b/playbooks/common/openshift-cluster/redeploy-certificates/ca.yml
@@ -130,7 +130,7 @@
state: absent
changed_when: false
-- include: ../../../common/openshift-etcd/restart.yml
+- include: ../openshift-etcd/restart.yml
# Update master config when ca-bundle not referenced. Services will be
# restarted below after new CA certificate has been distributed.
@@ -322,7 +322,7 @@
group: "{{ 'root' if item == 'root' else _ansible_ssh_user_gid.stdout }}"
with_items: "{{ client_users }}"
-- include: ../../../common/openshift-master/restart.yml
+- include: ../openshift-master/restart.yml
- name: Distribute OpenShift CA certificate to nodes
hosts: oo_nodes_to_config
@@ -371,4 +371,4 @@
state: absent
changed_when: false
-- include: ../../../common/openshift-node/restart.yml
+- include: ../openshift-node/restart.yml
diff --git a/playbooks/common/openshift-cluster/upgrades/init.yml b/playbooks/common/openshift-cluster/upgrades/init.yml
index 01d151eb9..cc1fa5a0a 100644
--- a/playbooks/common/openshift-cluster/upgrades/init.yml
+++ b/playbooks/common/openshift-cluster/upgrades/init.yml
@@ -30,27 +30,7 @@
g_new_node_hosts: []
openshift_cluster_id: "{{ cluster_id | default('default') }}"
-- name: Set oo_options
- hosts: oo_all_hosts
- tasks:
- - set_fact:
- openshift_docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries') }}"
- when: openshift_docker_additional_registries is not defined
- - set_fact:
- openshift_docker_insecure_registries: "{{ lookup('oo_option', 'docker_insecure_registries') }}"
- when: openshift_docker_insecure_registries is not defined
- - set_fact:
- openshift_docker_blocked_registries: "{{ lookup('oo_option', 'docker_blocked_registries') }}"
- when: openshift_docker_blocked_registries is not defined
- - set_fact:
- openshift_docker_options: "{{ lookup('oo_option', 'docker_options') }}"
- when: openshift_docker_options is not defined
- - set_fact:
- openshift_docker_log_driver: "{{ lookup('oo_option', 'docker_log_driver') }}"
- when: openshift_docker_log_driver is not defined
- - set_fact:
- openshift_docker_log_options: "{{ lookup('oo_option', 'docker_log_options') }}"
- when: openshift_docker_log_options is not defined
+- include: ../initialize_oo_option_facts.yml
- include: ../initialize_facts.yml
diff --git a/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml
index c00795a8d..0d7cdb227 100644
--- a/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml
+++ b/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml
@@ -5,9 +5,10 @@
- name: Upgrade default router and default registry
hosts: oo_first_master
vars:
- registry_image: "{{ openshift.master.registry_url | replace( '${component}', 'docker-registry' ) | replace ( '${version}', openshift_image_tag ) }}"
- router_image: "{{ openshift.master.registry_url | replace( '${component}', 'haproxy-router' ) | replace ( '${version}', openshift_image_tag ) }}"
- oc_cmd: "{{ openshift.common.client_binary }} --config={{ openshift.common.config_base }}/master/admin.kubeconfig"
+ registry_image: "{{ openshift.master.registry_url | replace( '${component}', 'docker-registry' ) |
+ replace ( '${version}', openshift_image_tag ) }}"
+ router_image: "{{ openshift.master.registry_url | replace( '${component}', 'haproxy-router' ) |
+ replace ( '${version}', openshift_image_tag ) }}"
pre_tasks:
- name: Load lib_openshift modules
@@ -21,7 +22,10 @@
selector: 'router'
register: all_routers
- - set_fact: haproxy_routers="{{ all_routers.results.results[0]['items'] | oo_pods_match_component(openshift_deployment_type, 'haproxy-router') | oo_select_keys_from_list(['metadata']) }}"
+ - set_fact:
+ haproxy_routers: "{{ all_routers.results.results[0]['items'] |
+ oo_pods_match_component(openshift_deployment_type, 'haproxy-router') |
+ oo_select_keys_from_list(['metadata']) }}"
when:
- all_routers.results.returncode == 0
@@ -30,16 +34,15 @@
- all_routers.results.returncode != 0
- name: Update router image to current version
+ oc_edit:
+ kind: dc
+ name: "{{ item['labels']['deploymentconfig'] }}"
+ namespace: "{{ item['namespace'] }}"
+ content:
+ spec.template.spec.containers[0].image: "{{ router_image }}"
+ with_items: "{{ haproxy_routers }}"
when:
- all_routers.results.returncode == 0
- command: >
- {{ oc_cmd }} patch dc/{{ item['labels']['deploymentconfig'] }} -n {{ item['namespace'] }} -p
- '{"spec":{"template":{"spec":{"containers":[{"name":"router","image":"{{ router_image }}","livenessProbe":{"tcpSocket":null,"httpGet":{"path": "/healthz", "port": 1936, "host": "localhost", "scheme": "HTTP"},"initialDelaySeconds":10,"timeoutSeconds":1}}]}}}}'
- --api-version=v1
- with_items: "{{ haproxy_routers }}"
- # AUDIT:changed_when_note: `false` not being set here. What we
- # need to do is check the current router image version and see if
- # this task needs to be ran.
- name: Check for default registry
oc_obj:
@@ -49,15 +52,14 @@
register: _default_registry
- name: Update registry image to current version
+ oc_edit:
+ kind: dc
+ name: docker-registry
+ namespace: default
+ content:
+ spec.template.spec.containers[0].image: "{{ registry_image }}"
when:
- _default_registry.results.results[0] != {}
- command: >
- {{ oc_cmd }} patch dc/docker-registry -n default -p
- '{"spec":{"template":{"spec":{"containers":[{"name":"registry","image":"{{ registry_image }}"}]}}}}'
- --api-version=v1
- # AUDIT:changed_when_note: `false` not being set here. What we
- # need to do is check the current registry image version and see
- # if this task needs to be ran.
roles:
- openshift_manageiq
diff --git a/playbooks/common/openshift-master/restart.yml b/playbooks/common/openshift-master/restart.yml
index b35368bf1..6fec346c3 100644
--- a/playbooks/common/openshift-master/restart.yml
+++ b/playbooks/common/openshift-master/restart.yml
@@ -1,5 +1,5 @@
---
-- include: ../../common/openshift-master/validate_restart.yml
+- include: validate_restart.yml
- name: Restart masters
hosts: oo_masters_to_config
@@ -12,8 +12,8 @@
roles:
- openshift_facts
post_tasks:
- - include: ../../common/openshift-master/restart_hosts.yml
+ - include: restart_hosts.yml
when: openshift_rolling_restart_mode | default('services') == 'system'
- - include: ../../common/openshift-master/restart_services.yml
+ - include: restart_services.yml
when: openshift_rolling_restart_mode | default('services') == 'services'
diff --git a/roles/lib_openshift/library/oc_adm_ca_server_cert.py b/roles/lib_openshift/library/oc_adm_ca_server_cert.py
index c69f5deda..4d083c4d5 100644
--- a/roles/lib_openshift/library/oc_adm_ca_server_cert.py
+++ b/roles/lib_openshift/library/oc_adm_ca_server_cert.py
@@ -1508,7 +1508,7 @@ class CAServerCert(OpenShiftCLI):
x509output, _ = proc.communicate()
if proc.returncode == 0:
regex = re.compile(r"^\s*X509v3 Subject Alternative Name:\s*?\n\s*(.*)\s*\n", re.MULTILINE)
- match = regex.search(x509output) # E501
+ match = regex.search(x509output.decode()) # E501
if not match:
return False
diff --git a/roles/lib_openshift/src/class/oc_adm_ca_server_cert.py b/roles/lib_openshift/src/class/oc_adm_ca_server_cert.py
index f954f40ef..cf99a6584 100644
--- a/roles/lib_openshift/src/class/oc_adm_ca_server_cert.py
+++ b/roles/lib_openshift/src/class/oc_adm_ca_server_cert.py
@@ -77,7 +77,7 @@ class CAServerCert(OpenShiftCLI):
x509output, _ = proc.communicate()
if proc.returncode == 0:
regex = re.compile(r"^\s*X509v3 Subject Alternative Name:\s*?\n\s*(.*)\s*\n", re.MULTILINE)
- match = regex.search(x509output) # E501
+ match = regex.search(x509output.decode()) # E501
if not match:
return False
diff --git a/roles/openshift_health_checker/library/aos_version.py b/roles/openshift_health_checker/library/aos_version.py
index 191a4b107..a46589443 100755
--- a/roles/openshift_health_checker/library/aos_version.py
+++ b/roles/openshift_health_checker/library/aos_version.py
@@ -1,91 +1,199 @@
#!/usr/bin/python
# vim: expandtab:tabstop=4:shiftwidth=4
'''
-Ansible module for determining if multiple versions of an OpenShift package are
-available, and if the version requested is available down to the given
-precision.
-
-Multiple versions available suggest that multiple repos are enabled for the
-different versions, which may cause installation problems.
+Ansible module for yum-based systems determining if multiple releases
+of an OpenShift package are available, and if the release requested
+(if any) is available down to the given precision.
+
+For Enterprise, multiple releases available suggest that multiple repos
+are enabled for the different releases, which may cause installation
+problems. With Origin, however, this is a normal state of affairs as
+all the releases are provided in a single repo with the expectation that
+only the latest can be installed.
+
+Code in the openshift_version role contains a lot of logic to pin down
+the exact package and image version to use and so does some validation
+of release availability already. Without duplicating all that, we would
+like the user to have a helpful error message if we detect things will
+not work out right. Note that if openshift_release is not specified in
+the inventory, the version comparison checks just pass.
+
+TODO: fail gracefully on non-yum systems (dnf in Fedora)
'''
-import yum # pylint: disable=import-error
-
from ansible.module_utils.basic import AnsibleModule
+IMPORT_EXCEPTION = None
+try:
+ import yum # pylint: disable=import-error
+except ImportError as err:
+ IMPORT_EXCEPTION = err # in tox test env, yum import fails
+
-def main(): # pylint: disable=missing-docstring,too-many-branches
+class AosVersionException(Exception):
+ '''Base exception class for package version problems'''
+ def __init__(self, message, problem_pkgs=None):
+ Exception.__init__(self, message)
+ self.problem_pkgs = problem_pkgs
+
+
+def main():
+ '''Entrypoint for this Ansible module'''
module = AnsibleModule(
argument_spec=dict(
- prefix=dict(required=True), # atomic-openshift, origin, ...
- version=dict(required=True),
+ requested_openshift_release=dict(type="str", default=''),
+ openshift_deployment_type=dict(required=True),
+ rpm_prefix=dict(required=True), # atomic-openshift, origin, ...?
),
supports_check_mode=True
)
- def bail(error): # pylint: disable=missing-docstring
- module.fail_json(msg=error)
-
- rpm_prefix = module.params['prefix']
+ if IMPORT_EXCEPTION:
+ module.fail_json(msg="aos_version module could not import yum: %s" % IMPORT_EXCEPTION)
+ # determine the packages we will look for
+ rpm_prefix = module.params['rpm_prefix']
if not rpm_prefix:
- bail("prefix must not be empty")
-
- yb = yum.YumBase() # pylint: disable=invalid-name
- yb.conf.disable_excludes = ["all"] # assume the openshift excluder will be managed, ignore current state
-
- # search for package versions available for aos pkgs
- expected_pkgs = [
+ module.fail_json(msg="rpm_prefix must not be empty")
+ expected_pkgs = set([
rpm_prefix,
rpm_prefix + '-master',
rpm_prefix + '-node',
- ]
+ ])
+
+ # determine what level of precision the user specified for the openshift version.
+ # should look like a version string with possibly many segments e.g. "3.4.1":
+ requested_openshift_release = module.params['requested_openshift_release']
+
+ # get the list of packages available and complain if anything is wrong
+ try:
+ pkgs = _retrieve_available_packages(expected_pkgs)
+ if requested_openshift_release:
+ _check_precise_version_found(pkgs, expected_pkgs, requested_openshift_release)
+ _check_higher_version_found(pkgs, expected_pkgs, requested_openshift_release)
+ if module.params['openshift_deployment_type'] in ['openshift-enterprise']:
+ _check_multi_minor_release(pkgs, expected_pkgs)
+ except AosVersionException as excinfo:
+ module.fail_json(msg=str(excinfo))
+ module.exit_json(changed=False)
+
+
+def _retrieve_available_packages(expected_pkgs):
+ # search for package versions available for openshift pkgs
+ yb = yum.YumBase() # pylint: disable=invalid-name
+
+ # The openshift excluder prevents unintended updates to openshift
+ # packages by setting yum excludes on those packages. See:
+ # https://wiki.centos.org/SpecialInterestGroup/PaaS/OpenShift-Origin-Control-Updates
+ # Excludes are then disabled during an install or upgrade, but
+ # this check will most likely be running outside either. When we
+ # attempt to determine what packages are available via yum they may
+ # be excluded. So, for our purposes here, disable excludes to see
+ # what will really be available during an install or upgrade.
+ yb.conf.disable_excludes = ['all']
+
try:
pkgs = yb.pkgSack.returnPackages(patterns=expected_pkgs)
- except yum.Errors.PackageSackError as e: # pylint: disable=invalid-name
+ except yum.Errors.PackageSackError as excinfo:
# you only hit this if *none* of the packages are available
- bail('Unable to find any OpenShift packages.\nCheck your subscription and repo settings.\n%s' % e)
+ raise AosVersionException('\n'.join([
+ 'Unable to find any OpenShift packages.',
+ 'Check your subscription and repo settings.',
+ str(excinfo),
+ ]))
+ return pkgs
- # determine what level of precision we're expecting for the version
- expected_version = module.params['version']
- if expected_version.startswith('v'): # v3.3 => 3.3
- expected_version = expected_version[1:]
- num_dots = expected_version.count('.')
- pkgs_by_name_version = {}
+class PreciseVersionNotFound(AosVersionException):
+ '''Exception for reporting packages not available at given release'''
+ def __init__(self, requested_release, not_found):
+ msg = ['Not all of the required packages are available at requested version %s:' % requested_release]
+ msg += [' ' + name for name in not_found]
+ msg += ['Please check your subscriptions and enabled repositories.']
+ AosVersionException.__init__(self, '\n'.join(msg), not_found)
+
+
+def _check_precise_version_found(pkgs, expected_pkgs, requested_openshift_release):
+ # see if any packages couldn't be found at requested release version
+ # we would like to verify that the latest available pkgs have however specific a version is given.
+ # so e.g. if there is a package version 3.4.1.5 the check passes; if only 3.4.0, it fails.
+
pkgs_precise_version_found = {}
for pkg in pkgs:
- # get expected version precision
- match_version = '.'.join(pkg.version.split('.')[:num_dots + 1])
- if match_version == expected_version:
+ if pkg.name not in expected_pkgs:
+ continue
+ # does the version match, to the precision requested?
+ # and, is it strictly greater, at the precision requested?
+ match_version = '.'.join(pkg.version.split('.')[:requested_openshift_release.count('.') + 1])
+ if match_version == requested_openshift_release:
pkgs_precise_version_found[pkg.name] = True
- # get x.y version precision
- minor_version = '.'.join(pkg.version.split('.')[:2])
- if pkg.name not in pkgs_by_name_version:
- pkgs_by_name_version[pkg.name] = {}
- pkgs_by_name_version[pkg.name][minor_version] = True
- # see if any packages couldn't be found at requested version
- # see if any packages are available in more than one minor version
not_found = []
- multi_found = []
for name in expected_pkgs:
if name not in pkgs_precise_version_found:
not_found.append(name)
+
+ if not_found:
+ raise PreciseVersionNotFound(requested_openshift_release, not_found)
+
+
+class FoundHigherVersion(AosVersionException):
+ '''Exception for reporting that a higher version than requested is available'''
+ def __init__(self, requested_release, higher_found):
+ msg = ['Some required package(s) are available at a version',
+ 'that is higher than requested %s:' % requested_release]
+ msg += [' ' + name for name in higher_found]
+ msg += ['This will prevent installing the version you requested.']
+ msg += ['Please check your enabled repositories or adjust openshift_release.']
+ AosVersionException.__init__(self, '\n'.join(msg), higher_found)
+
+
+def _check_higher_version_found(pkgs, expected_pkgs, requested_openshift_release):
+ req_release_arr = [int(segment) for segment in requested_openshift_release.split(".")]
+ # see if any packages are available in a version higher than requested
+ higher_version_for_pkg = {}
+ for pkg in pkgs:
+ if pkg.name not in expected_pkgs:
+ continue
+ version = [int(segment) for segment in pkg.version.split(".")]
+ too_high = version[:len(req_release_arr)] > req_release_arr
+ higher_than_seen = version > higher_version_for_pkg.get(pkg.name, [])
+ if too_high and higher_than_seen:
+ higher_version_for_pkg[pkg.name] = version
+
+ if higher_version_for_pkg:
+ higher_found = []
+ for name, version in higher_version_for_pkg.items():
+ higher_found.append(name + '-' + '.'.join(str(segment) for segment in version))
+ raise FoundHigherVersion(requested_openshift_release, higher_found)
+
+
+class FoundMultiRelease(AosVersionException):
+ '''Exception for reporting multiple minor releases found for same package'''
+ def __init__(self, multi_found):
+ msg = ['Multiple minor versions of these packages are available']
+ msg += [' ' + name for name in multi_found]
+ msg += ["There should only be one OpenShift release repository enabled at a time."]
+ AosVersionException.__init__(self, '\n'.join(msg), multi_found)
+
+
+def _check_multi_minor_release(pkgs, expected_pkgs):
+ # see if any packages are available in more than one minor version
+ pkgs_by_name_version = {}
+ for pkg in pkgs:
+ # keep track of x.y (minor release) versions seen
+ minor_release = '.'.join(pkg.version.split('.')[:2])
+ if pkg.name not in pkgs_by_name_version:
+ pkgs_by_name_version[pkg.name] = {}
+ pkgs_by_name_version[pkg.name][minor_release] = True
+
+ multi_found = []
+ for name in expected_pkgs:
if name in pkgs_by_name_version and len(pkgs_by_name_version[name]) > 1:
multi_found.append(name)
- if not_found:
- msg = 'Not all of the required packages are available at requested version %s:\n' % expected_version
- for name in not_found:
- msg += ' %s\n' % name
- bail(msg + 'Please check your subscriptions and enabled repositories.')
- if multi_found:
- msg = 'Multiple minor versions of these packages are available\n'
- for name in multi_found:
- msg += ' %s\n' % name
- bail(msg + "There should only be one OpenShift version's repository enabled at a time.")
- module.exit_json(changed=False)
+ if multi_found:
+ raise FoundMultiRelease(multi_found)
if __name__ == '__main__':
diff --git a/roles/openshift_health_checker/meta/main.yml b/roles/openshift_health_checker/meta/main.yml
index 0bbeadd34..cd9b55902 100644
--- a/roles/openshift_health_checker/meta/main.yml
+++ b/roles/openshift_health_checker/meta/main.yml
@@ -1,3 +1,4 @@
---
dependencies:
- role: openshift_facts
+ - role: openshift_repos
diff --git a/roles/openshift_health_checker/openshift_checks/package_availability.py b/roles/openshift_health_checker/openshift_checks/package_availability.py
index 9891972a6..a7eb720fd 100644
--- a/roles/openshift_health_checker/openshift_checks/package_availability.py
+++ b/roles/openshift_health_checker/openshift_checks/package_availability.py
@@ -9,6 +9,10 @@ class PackageAvailability(NotContainerizedMixin, OpenShiftCheck):
name = "package_availability"
tags = ["preflight"]
+ @classmethod
+ def is_active(cls, task_vars):
+ return super(PackageAvailability, cls).is_active(task_vars) and task_vars["ansible_pkg_mgr"] == "yum"
+
def run(self, tmp, task_vars):
rpm_prefix = get_var(task_vars, "openshift", "common", "service_type")
group_names = get_var(task_vars, "group_names", default=[])
diff --git a/roles/openshift_health_checker/openshift_checks/package_version.py b/roles/openshift_health_checker/openshift_checks/package_version.py
index 42193a1c6..cca2d8b75 100644
--- a/roles/openshift_health_checker/openshift_checks/package_version.py
+++ b/roles/openshift_health_checker/openshift_checks/package_version.py
@@ -10,11 +10,9 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck):
tags = ["preflight"]
def run(self, tmp, task_vars):
- rpm_prefix = get_var(task_vars, "openshift", "common", "service_type")
- openshift_release = get_var(task_vars, "openshift_release")
-
args = {
- "prefix": rpm_prefix,
- "version": openshift_release,
+ "requested_openshift_release": get_var(task_vars, "openshift_release", default=''),
+ "openshift_deployment_type": get_var(task_vars, "openshift_deployment_type"),
+ "rpm_prefix": get_var(task_vars, "openshift", "common", "service_type"),
}
return self.execute_module("aos_version", args, tmp, task_vars)
diff --git a/roles/openshift_health_checker/test/aos_version_test.py b/roles/openshift_health_checker/test/aos_version_test.py
new file mode 100644
index 000000000..39c86067a
--- /dev/null
+++ b/roles/openshift_health_checker/test/aos_version_test.py
@@ -0,0 +1,120 @@
+import pytest
+import aos_version
+
+from collections import namedtuple
+Package = namedtuple('Package', ['name', 'version'])
+
+expected_pkgs = set(['spam', 'eggs'])
+
+
+@pytest.mark.parametrize('pkgs, requested_release, expect_not_found', [
+ (
+ [],
+ '3.2.1',
+ expected_pkgs, # none found
+ ),
+ (
+ [Package('spam', '3.2.1')],
+ '3.2',
+ ['eggs'], # completely missing
+ ),
+ (
+ [Package('spam', '3.2.1'), Package('eggs', '3.3.2')],
+ '3.2',
+ ['eggs'], # not the right version
+ ),
+ (
+ [Package('spam', '3.2.1'), Package('eggs', '3.2.1')],
+ '3.2',
+ [], # all found
+ ),
+ (
+ [Package('spam', '3.2.1'), Package('eggs', '3.2.1.5')],
+ '3.2.1',
+ [], # found with more specific version
+ ),
+ (
+ [Package('eggs', '1.2.3'), Package('eggs', '3.2.1.5')],
+ '3.2.1',
+ ['spam'], # eggs found with multiple versions
+ ),
+])
+def test_check_pkgs_for_precise_version(pkgs, requested_release, expect_not_found):
+ if expect_not_found:
+ with pytest.raises(aos_version.PreciseVersionNotFound) as e:
+ aos_version._check_precise_version_found(pkgs, expected_pkgs, requested_release)
+ assert set(expect_not_found) == set(e.value.problem_pkgs)
+ else:
+ aos_version._check_precise_version_found(pkgs, expected_pkgs, requested_release)
+
+
+@pytest.mark.parametrize('pkgs, requested_release, expect_higher', [
+ (
+ [],
+ '3.2.1',
+ [],
+ ),
+ (
+ [Package('spam', '3.2.1')],
+ '3.2',
+ [], # more precise but not strictly higher
+ ),
+ (
+ [Package('spam', '3.3')],
+ '3.2.1',
+ ['spam-3.3'], # lower precision, but higher
+ ),
+ (
+ [Package('spam', '3.2.1'), Package('eggs', '3.3.2')],
+ '3.2',
+ ['eggs-3.3.2'], # one too high
+ ),
+ (
+ [Package('eggs', '1.2.3'), Package('eggs', '3.2.1.5'), Package('eggs', '3.4')],
+ '3.2.1',
+ ['eggs-3.4'], # multiple versions, one is higher
+ ),
+ (
+ [Package('eggs', '3.2.1'), Package('eggs', '3.4'), Package('eggs', '3.3')],
+ '3.2.1',
+ ['eggs-3.4'], # multiple versions, two are higher
+ ),
+])
+def test_check_pkgs_for_greater_version(pkgs, requested_release, expect_higher):
+ if expect_higher:
+ with pytest.raises(aos_version.FoundHigherVersion) as e:
+ aos_version._check_higher_version_found(pkgs, expected_pkgs, requested_release)
+ assert set(expect_higher) == set(e.value.problem_pkgs)
+ else:
+ aos_version._check_higher_version_found(pkgs, expected_pkgs, requested_release)
+
+
+@pytest.mark.parametrize('pkgs, expect_to_flag_pkgs', [
+ (
+ [],
+ [],
+ ),
+ (
+ [Package('spam', '3.2.1')],
+ [],
+ ),
+ (
+ [Package('spam', '3.2.1'), Package('eggs', '3.2.2')],
+ [],
+ ),
+ (
+ [Package('spam', '3.2.1'), Package('spam', '3.3.2')],
+ ['spam'],
+ ),
+ (
+ [Package('eggs', '1.2.3'), Package('eggs', '3.2.1.5'), Package('eggs', '3.4')],
+ ['eggs'],
+ ),
+])
+def test_check_pkgs_for_multi_release(pkgs, expect_to_flag_pkgs):
+ if expect_to_flag_pkgs:
+ with pytest.raises(aos_version.FoundMultiRelease) as e:
+ aos_version._check_multi_minor_release(pkgs, expected_pkgs)
+ assert set(expect_to_flag_pkgs) == set(e.value.problem_pkgs)
+ else:
+ aos_version._check_multi_minor_release(pkgs, expected_pkgs)
diff --git a/roles/openshift_health_checker/test/conftest.py b/roles/openshift_health_checker/test/conftest.py
index d16401260..3cbd65507 100644
--- a/roles/openshift_health_checker/test/conftest.py
+++ b/roles/openshift_health_checker/test/conftest.py
@@ -6,5 +6,6 @@ import sys
openshift_health_checker_path = os.path.dirname(os.path.dirname(__file__))
sys.path[1:1] = [
openshift_health_checker_path,
- os.path.join(openshift_health_checker_path, 'action_plugins')
+ os.path.join(openshift_health_checker_path, 'action_plugins'),
+ os.path.join(openshift_health_checker_path, 'library'),
]
diff --git a/roles/openshift_health_checker/test/package_availability_test.py b/roles/openshift_health_checker/test/package_availability_test.py
index 25385339a..f7e916a46 100644
--- a/roles/openshift_health_checker/test/package_availability_test.py
+++ b/roles/openshift_health_checker/test/package_availability_test.py
@@ -3,6 +3,20 @@ import pytest
from openshift_checks.package_availability import PackageAvailability
+@pytest.mark.parametrize('pkg_mgr,is_containerized,is_active', [
+ ('yum', False, True),
+ ('yum', True, False),
+ ('dnf', True, False),
+ ('dnf', False, False),
+])
+def test_is_active(pkg_mgr, is_containerized, is_active):
+ task_vars = dict(
+ ansible_pkg_mgr=pkg_mgr,
+ openshift=dict(common=dict(is_containerized=is_containerized)),
+ )
+ assert PackageAvailability.is_active(task_vars=task_vars) == is_active
+
+
@pytest.mark.parametrize('task_vars,must_have_packages,must_not_have_packages', [
(
dict(openshift=dict(common=dict(service_type='openshift'))),
diff --git a/roles/openshift_health_checker/test/package_version_test.py b/roles/openshift_health_checker/test/package_version_test.py
index cc1d263bc..c6889ee9b 100644
--- a/roles/openshift_health_checker/test/package_version_test.py
+++ b/roles/openshift_health_checker/test/package_version_test.py
@@ -4,16 +4,19 @@ from openshift_checks.package_version import PackageVersion
def test_package_version():
task_vars = dict(
openshift=dict(common=dict(service_type='origin')),
- openshift_release='v3.5',
+ openshift_release='3.5',
+ openshift_deployment_type='origin',
)
return_value = object()
def execute_module(module_name=None, module_args=None, tmp=None, task_vars=None):
assert module_name == 'aos_version'
- assert 'prefix' in module_args
- assert 'version' in module_args
- assert module_args['prefix'] == task_vars['openshift']['common']['service_type']
- assert module_args['version'] == task_vars['openshift_release']
+ assert 'requested_openshift_release' in module_args
+ assert 'openshift_deployment_type' in module_args
+ assert 'rpm_prefix' in module_args
+ assert module_args['requested_openshift_release'] == task_vars['openshift_release']
+ assert module_args['openshift_deployment_type'] == task_vars['openshift_deployment_type']
+ assert module_args['rpm_prefix'] == task_vars['openshift']['common']['service_type']
return return_value
check = PackageVersion(execute_module=execute_module)
diff --git a/roles/openshift_provisioners/README.md b/roles/openshift_provisioners/README.md
new file mode 100644
index 000000000..7449073e6
--- /dev/null
+++ b/roles/openshift_provisioners/README.md
@@ -0,0 +1,29 @@
+# OpenShift External Dynamic Provisioners
+
+## Required Vars
+* `openshift_provisioners_install_provisioners`: When `True` the openshift_provisioners role will install provisioners that have their "master" var (e.g. `openshift_provisioners_efs`) set `True`. When `False` will uninstall provisioners that have their var set `True`.
+
+## Optional Vars
+* `openshift_provisioners_image_prefix`: The prefix for the provisioner images to use. Defaults to 'docker.io/openshift/origin-'.
+* `openshift_provisioners_image_version`: The image version for the provisioner images to use. Defaults to 'latest'.
+* `openshift_provisioners_project`: The namespace that provisioners will be installed in. Defaults to 'openshift-infra'.
+
+## AWS EFS
+
+### Prerequisites
+* An IAM user assigned the AmazonElasticFileSystemReadOnlyAccess policy (or better)
+* An EFS file system in your cluster's region
+* [Mount targets](http://docs.aws.amazon.com/efs/latest/ug/accessing-fs.html) and [security groups](http://docs.aws.amazon.com/efs/latest/ug/accessing-fs-create-security-groups.html) such that any node (in any zone in the cluster's region) can mount the EFS file system by its [File system DNS name](http://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html)
+
+### Required Vars
+* `openshift_provisioners_efs_fsid`: The [File system ID](http://docs.aws.amazon.com/efs/latest/ug/gs-step-two-create-efs-resources.html) of the EFS file system, e.g. fs-47a2c22e.
+* `openshift_provisioners_efs_region`: The Amazon EC2 region of the EFS file system.
+* `openshift_provisioners_efs_aws_access_key_id`: The AWS access key of the IAM user, used to check that the EFS file system specified actually exists.
+* `openshift_provisioners_efs_aws_secret_access_key`: The AWS secret access key of the IAM user, used to check that the EFS file system specified actually exists.
+
+### Optional Vars
+* `openshift_provisioners_efs`: When `True` the AWS EFS provisioner will be installed or uninstalled according to whether `openshift_provisioners_install_provisioners` is `True` or `False`, respectively. Defaults to `False`.
+* `openshift_provisioners_efs_path`: The path of the directory in the EFS file system in which the EFS provisioner will create a directory to back each PV it creates. It must exist and be mountable by the EFS provisioner. Defaults to '/persistentvolumes'.
+* `openshift_provisioners_efs_name`: The `provisioner` name that `StorageClasses` specify. Defaults to 'openshift.org/aws-efs'.
+* `openshift_provisioners_efs_nodeselector`: A map of labels (e.g. {"node":"infra","region":"west"} to select the nodes where the pod will land.
+* `openshift_provisioners_efs_supplementalgroup`: The supplemental group to give the pod in case it is needed for permission to write to the EFS file system. Defaults to '65534'.
diff --git a/roles/openshift_provisioners/defaults/main.yaml b/roles/openshift_provisioners/defaults/main.yaml
new file mode 100644
index 000000000..a6f040831
--- /dev/null
+++ b/roles/openshift_provisioners/defaults/main.yaml
@@ -0,0 +1,12 @@
+---
+openshift_provisioners_install_provisioners: True
+openshift_provisioners_image_prefix: docker.io/openshift/origin-
+openshift_provisioners_image_version: latest
+
+openshift_provisioners_efs: False
+openshift_provisioners_efs_path: /persistentvolumes
+openshift_provisioners_efs_name: openshift.org/aws-efs
+openshift_provisioners_efs_nodeselector: ""
+openshift_provisioners_efs_supplementalgroup: '65534'
+
+openshift_provisioners_project: openshift-infra
diff --git a/roles/openshift_provisioners/meta/main.yaml b/roles/openshift_provisioners/meta/main.yaml
new file mode 100644
index 000000000..cb9278eb7
--- /dev/null
+++ b/roles/openshift_provisioners/meta/main.yaml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+ author: OpenShift Red Hat
+ description: OpenShift Provisioners
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 2.2
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+dependencies:
+- role: lib_openshift
+- role: openshift_facts
diff --git a/roles/openshift_provisioners/tasks/generate_clusterrolebindings.yaml b/roles/openshift_provisioners/tasks/generate_clusterrolebindings.yaml
new file mode 100644
index 000000000..ac21a5e37
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/generate_clusterrolebindings.yaml
@@ -0,0 +1,19 @@
+---
+- name: Generate ClusterRoleBindings
+ template: src=clusterrolebinding.j2 dest={{mktemp.stdout}}/templates/{{obj_name}}-clusterrolebinding.yaml
+ vars:
+ acct_name: provisioners-{{item}}
+ obj_name: run-provisioners-{{item}}
+ labels:
+ provisioners-infra: support
+ crb_usernames: ["system:serviceaccount:{{openshift_provisioners_project}}:{{acct_name}}"]
+ subjects:
+ - kind: ServiceAccount
+ name: "{{acct_name}}"
+ namespace: "{{openshift_provisioners_project}}"
+ cr_name: "system:persistent-volume-provisioner"
+ with_items:
+ # TODO
+ - efs
+ check_mode: no
+ changed_when: no
diff --git a/roles/openshift_provisioners/tasks/generate_secrets.yaml b/roles/openshift_provisioners/tasks/generate_secrets.yaml
new file mode 100644
index 000000000..e6cbb1bbf
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/generate_secrets.yaml
@@ -0,0 +1,14 @@
+---
+- name: Generate secret for efs
+ template: src=secret.j2 dest={{mktemp.stdout}}/templates/{{obj_name}}-secret.yaml
+ vars:
+ name: efs
+ obj_name: "provisioners-efs"
+ labels:
+ provisioners-infra: support
+ secrets:
+ - {key: aws-access-key-id, value: "{{openshift_provisioners_efs_aws_access_key_id}}"}
+ - {key: aws-secret-access-key, value: "{{openshift_provisioners_efs_aws_secret_access_key}}"}
+ check_mode: no
+ changed_when: no
+ when: openshift_provisioners_efs | bool
diff --git a/roles/openshift_provisioners/tasks/generate_serviceaccounts.yaml b/roles/openshift_provisioners/tasks/generate_serviceaccounts.yaml
new file mode 100644
index 000000000..4fe0583ee
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/generate_serviceaccounts.yaml
@@ -0,0 +1,12 @@
+---
+- name: Generating serviceaccounts
+ template: src=serviceaccount.j2 dest={{mktemp.stdout}}/templates/{{obj_name}}-sa.yaml
+ vars:
+ obj_name: provisioners-{{item}}
+ labels:
+ provisioners-infra: support
+ with_items:
+ # TODO
+ - efs
+ check_mode: no
+ changed_when: no
diff --git a/roles/openshift_provisioners/tasks/install_efs.yaml b/roles/openshift_provisioners/tasks/install_efs.yaml
new file mode 100644
index 000000000..57279c665
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/install_efs.yaml
@@ -0,0 +1,70 @@
+---
+- name: Check efs current replica count
+ command: >
+ {{ openshift.common.client_binary }} --config={{ mktemp.stdout }}/admin.kubeconfig get dc provisioners-efs
+ -o jsonpath='{.spec.replicas}' -n {{openshift_provisioners_project}}
+ register: efs_replica_count
+ when: not ansible_check_mode
+ ignore_errors: yes
+ changed_when: no
+
+- name: Generate efs PersistentVolumeClaim
+ template: src=pvc.j2 dest={{mktemp.stdout}}/templates/{{obj_name}}-pvc.yaml
+ vars:
+ obj_name: "provisioners-efs"
+ size: "1Mi"
+ access_modes:
+ - "ReadWriteMany"
+ pv_selector:
+ provisioners-efs: efs
+ check_mode: no
+ changed_when: no
+
+- name: Generate efs PersistentVolume
+ template: src=pv.j2 dest={{mktemp.stdout}}/templates/{{obj_name}}-pv.yaml
+ vars:
+ obj_name: "provisioners-efs"
+ size: "1Mi"
+ access_modes:
+ - "ReadWriteMany"
+ labels:
+ provisioners-efs: efs
+ volume_plugin: "nfs"
+ volume_source:
+ - {key: "server", value: "{{openshift_provisioners_efs_fsid}}.efs.{{openshift_provisioners_efs_region}}.amazonaws.com"}
+ - {key: "path", value: "{{openshift_provisioners_efs_path}}"}
+ claim_name: "provisioners-efs"
+ check_mode: no
+ changed_when: no
+
+- name: Generate efs DeploymentConfig
+ template:
+ src: efs.j2
+ dest: "{{ mktemp.stdout }}/templates/{{deploy_name}}-dc.yaml"
+ vars:
+ name: efs
+ deploy_name: "provisioners-efs"
+ deploy_serviceAccount: "provisioners-efs"
+ replica_count: "{{efs_replica_count.stdout | default(0)}}"
+ node_selector: "{{openshift_provisioners_efs_nodeselector | default('') }}"
+ claim_name: "provisioners-efs"
+ check_mode: no
+ changed_when: false
+
+# anyuid in order to run as root & chgrp shares with allocated gids
+- name: "Check efs anyuid permissions"
+ command: >
+ {{ openshift.common.client_binary }} --config={{ mktemp.stdout }}/admin.kubeconfig
+ get scc/anyuid -o jsonpath='{.users}'
+ register: efs_anyuid
+ check_mode: no
+ changed_when: no
+
+- name: "Set anyuid permissions for efs"
+ command: >
+ {{ openshift.common.admin_binary}} --config={{ mktemp.stdout }}/admin.kubeconfig policy
+ add-scc-to-user anyuid system:serviceaccount:{{openshift_provisioners_project}}:provisioners-efs
+ register: efs_output
+ failed_when: "efs_output.rc == 1 and 'exists' not in efs_output.stderr"
+ check_mode: no
+ when: efs_anyuid.stdout.find("system:serviceaccount:{{openshift_provisioners_project}}:provisioners-efs") == -1
diff --git a/roles/openshift_provisioners/tasks/install_provisioners.yaml b/roles/openshift_provisioners/tasks/install_provisioners.yaml
new file mode 100644
index 000000000..324fdcc82
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/install_provisioners.yaml
@@ -0,0 +1,55 @@
+---
+- name: Check that EFS File System ID is set
+ fail: msg='the openshift_provisioners_efs_fsid variable is required'
+ when: (openshift_provisioners_efs | bool) and openshift_provisioners_efs_fsid is not defined
+
+- name: Check that EFS region is set
+ fail: msg='the openshift_provisioners_efs_region variable is required'
+ when: (openshift_provisioners_efs | bool) and openshift_provisioners_efs_region is not defined
+
+- name: Check that EFS AWS access key id is set
+ fail: msg='the openshift_provisioners_efs_aws_access_key_id variable is required'
+ when: (openshift_provisioners_efs | bool) and openshift_provisioners_efs_aws_access_key_id is not defined
+
+- name: Check that EFS AWS secret access key is set
+ fail: msg='the openshift_provisioners_efs_aws_secret_access_key variable is required'
+ when: (openshift_provisioners_efs | bool) and openshift_provisioners_efs_aws_secret_access_key is not defined
+
+- name: Install support
+ include: install_support.yaml
+
+- name: Install EFS
+ include: install_efs.yaml
+ when: openshift_provisioners_efs | bool
+
+- find: paths={{ mktemp.stdout }}/templates patterns=*.yaml
+ register: object_def_files
+ changed_when: no
+
+- slurp: src={{item}}
+ register: object_defs
+ with_items: "{{object_def_files.files | map(attribute='path') | list | sort}}"
+ changed_when: no
+
+- name: Create objects
+ include: oc_apply.yaml
+ vars:
+ - kubeconfig: "{{ mktemp.stdout }}/admin.kubeconfig"
+ - namespace: "{{ openshift_provisioners_project }}"
+ - file_name: "{{ file.source }}"
+ - file_content: "{{ file.content | b64decode | from_yaml }}"
+ with_items: "{{ object_defs.results }}"
+ loop_control:
+ loop_var: file
+ when: not ansible_check_mode
+
+- name: Printing out objects to create
+ debug: msg={{file.content | b64decode }}
+ with_items: "{{ object_defs.results }}"
+ loop_control:
+ loop_var: file
+ when: ansible_check_mode
+
+- name: Scaling up cluster
+ include: start_cluster.yaml
+ when: start_cluster | default(true) | bool
diff --git a/roles/openshift_provisioners/tasks/install_support.yaml b/roles/openshift_provisioners/tasks/install_support.yaml
new file mode 100644
index 000000000..ba472f1c9
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/install_support.yaml
@@ -0,0 +1,24 @@
+---
+- name: Check for provisioners project already exists
+ command: >
+ {{ openshift.common.client_binary }} --config={{ mktemp.stdout }}/admin.kubeconfig get project {{openshift_provisioners_project}} --no-headers
+ register: provisioners_project_result
+ ignore_errors: yes
+ when: not ansible_check_mode
+ changed_when: no
+
+- name: Create provisioners project
+ command: >
+ {{ openshift.common.admin_binary }} --config={{ mktemp.stdout }}/admin.kubeconfig new-project {{openshift_provisioners_project}}
+ when: not ansible_check_mode and "not found" in provisioners_project_result.stderr
+
+- name: Create temp directory for all our templates
+ file: path={{mktemp.stdout}}/templates state=directory mode=0755
+ changed_when: False
+ check_mode: no
+
+- include: generate_secrets.yaml
+
+- include: generate_clusterrolebindings.yaml
+
+- include: generate_serviceaccounts.yaml
diff --git a/roles/openshift_provisioners/tasks/main.yaml b/roles/openshift_provisioners/tasks/main.yaml
new file mode 100644
index 000000000..a50c78c97
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/main.yaml
@@ -0,0 +1,27 @@
+---
+- name: Create temp directory for doing work in
+ command: mktemp -td openshift-provisioners-ansible-XXXXXX
+ register: mktemp
+ changed_when: False
+ check_mode: no
+
+- name: Copy the admin client config(s)
+ command: >
+ cp {{ openshift.common.config_base}}/master/admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig
+ changed_when: False
+ check_mode: no
+ tags: provisioners_init
+
+- include: "{{ role_path }}/tasks/install_provisioners.yaml"
+ when: openshift_provisioners_install_provisioners | default(false) | bool
+
+- include: "{{ role_path }}/tasks/uninstall_provisioners.yaml"
+ when: not openshift_provisioners_install_provisioners | default(false) | bool
+
+- name: Delete temp directory
+ file:
+ name: "{{ mktemp.stdout }}"
+ state: absent
+ tags: provisioners_cleanup
+ changed_when: False
+ check_mode: no
diff --git a/roles/openshift_provisioners/tasks/oc_apply.yaml b/roles/openshift_provisioners/tasks/oc_apply.yaml
new file mode 100644
index 000000000..49d03f203
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/oc_apply.yaml
@@ -0,0 +1,51 @@
+---
+- name: Checking generation of {{file_content.kind}} {{file_content.metadata.name}}
+ command: >
+ {{ openshift.common.client_binary }} --config={{ kubeconfig }}
+ get {{file_content.kind}} {{file_content.metadata.name}}
+ -o jsonpath='{.metadata.resourceVersion}'
+ -n {{namespace}}
+ register: generation_init
+ failed_when: "'not found' not in generation_init.stderr and generation_init.stdout == ''"
+ changed_when: no
+
+- name: Applying {{file_name}}
+ command: >
+ {{ openshift.common.client_binary }} --config={{ kubeconfig }}
+ apply -f {{ file_name }}
+ -n {{ namespace }}
+ register: generation_apply
+ failed_when: "'error' in generation_apply.stderr"
+ changed_when: no
+
+- name: Determine change status of {{file_content.kind}} {{file_content.metadata.name}}
+ command: >
+ {{ openshift.common.client_binary }} --config={{ kubeconfig }}
+ get {{file_content.kind}} {{file_content.metadata.name}}
+ -o jsonpath='{.metadata.resourceVersion}'
+ -n {{namespace}}
+ register: generation_changed
+ failed_when: "'not found' not in generation_changed.stderr and generation_changed.stdout == ''"
+ changed_when: generation_changed.stdout | default (0) | int > generation_init.stdout | default(0) | int
+ when:
+ - "'field is immutable' not in generation_apply.stderr"
+
+- name: Removing previous {{file_name}}
+ command: >
+ {{ openshift.common.client_binary }} --config={{ kubeconfig }}
+ delete -f {{ file_name }}
+ -n {{ namespace }}
+ register: generation_delete
+ failed_when: "'error' in generation_delete.stderr"
+ changed_when: generation_delete.rc == 0
+ when: generation_apply.rc != 0
+
+- name: Recreating {{file_name}}
+ command: >
+ {{ openshift.common.client_binary }} --config={{ kubeconfig }}
+ apply -f {{ file_name }}
+ -n {{ namespace }}
+ register: generation_apply
+ failed_when: "'error' in generation_apply.stderr"
+ changed_when: generation_apply.rc == 0
+ when: generation_apply.rc != 0
diff --git a/roles/openshift_provisioners/tasks/start_cluster.yaml b/roles/openshift_provisioners/tasks/start_cluster.yaml
new file mode 100644
index 000000000..ee7f545a9
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/start_cluster.yaml
@@ -0,0 +1,20 @@
+---
+- name: Retrieve efs
+ oc_obj:
+ state: list
+ kind: dc
+ selector: "provisioners-infra=efs"
+ namespace: "{{openshift_provisioners_project}}"
+ register: efs_dc
+ when: openshift_provisioners_efs | bool
+
+- name: start efs
+ oc_scale:
+ kind: dc
+ name: "{{ object }}"
+ namespace: "{{openshift_provisioners_project}}"
+ replicas: 1
+ with_items: "{{ efs_dc.results.results[0]['items'] | map(attribute='metadata.name') | list }}"
+ loop_control:
+ loop_var: object
+ when: openshift_provisioners_efs | bool
diff --git a/roles/openshift_provisioners/tasks/stop_cluster.yaml b/roles/openshift_provisioners/tasks/stop_cluster.yaml
new file mode 100644
index 000000000..30b6b12c8
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/stop_cluster.yaml
@@ -0,0 +1,20 @@
+---
+- name: Retrieve efs
+ oc_obj:
+ state: list
+ kind: dc
+ selector: "provisioners-infra=efs"
+ namespace: "{{openshift_provisioners_project}}"
+ register: efs_dc
+ when: openshift_provisioners_efs | bool
+
+- name: stop efs
+ oc_scale:
+ kind: dc
+ name: "{{ object }}"
+ namespace: "{{openshift_provisioners_project}}"
+ replicas: 0
+ with_items: "{{ efs_dc.results.results[0]['items'] | map(attribute='metadata.name') | list }}"
+ loop_control:
+ loop_var: object
+ when: openshift_provisioners_efs | bool
diff --git a/roles/openshift_provisioners/tasks/uninstall_provisioners.yaml b/roles/openshift_provisioners/tasks/uninstall_provisioners.yaml
new file mode 100644
index 000000000..0be4bc7d2
--- /dev/null
+++ b/roles/openshift_provisioners/tasks/uninstall_provisioners.yaml
@@ -0,0 +1,43 @@
+---
+- name: stop provisioners
+ include: stop_cluster.yaml
+
+# delete the deployment objects that we had created
+- name: delete provisioner api objects
+ command: >
+ {{ openshift.common.client_binary }} --config={{ mktemp.stdout }}/admin.kubeconfig
+ delete {{ item }} --selector provisioners-infra -n {{ openshift_provisioners_project }} --ignore-not-found=true
+ with_items:
+ - dc
+ register: delete_result
+ changed_when: delete_result.stdout.find("deleted") != -1 and delete_result.rc == 0
+
+# delete our old secrets
+- name: delete provisioner secrets
+ command: >
+ {{ openshift.common.client_binary }} --config={{ mktemp.stdout }}/admin.kubeconfig
+ delete secret {{ item }} -n {{ openshift_provisioners_project }} --ignore-not-found=true
+ with_items:
+ - provisioners-efs
+ ignore_errors: yes
+ register: delete_result
+ changed_when: delete_result.stdout.find("deleted") != -1 and delete_result.rc == 0
+
+# delete cluster role bindings
+- name: delete cluster role bindings
+ command: >
+ {{ openshift.common.client_binary }} --config={{ mktemp.stdout }}/admin.kubeconfig
+ delete clusterrolebindings {{ item }} -n {{ openshift_provisioners_project }} --ignore-not-found=true
+ with_items:
+ - run-provisioners-efs
+ register: delete_result
+ changed_when: delete_result.stdout.find("deleted") != -1 and delete_result.rc == 0
+
+# delete our service accounts
+- name: delete service accounts
+ oc_serviceaccount:
+ name: "{{ item }}"
+ namespace: "{{ openshift_provisioners_project }}"
+ state: absent
+ with_items:
+ - provisioners-efs
diff --git a/roles/openshift_provisioners/templates/clusterrolebinding.j2 b/roles/openshift_provisioners/templates/clusterrolebinding.j2
new file mode 100644
index 000000000..994afa32d
--- /dev/null
+++ b/roles/openshift_provisioners/templates/clusterrolebinding.j2
@@ -0,0 +1,30 @@
+apiVersion: v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{obj_name}}
+{% if labels is defined%}
+ labels:
+{% for key, value in labels.iteritems() %}
+ {{key}}: {{value}}
+{% endfor %}
+{% endif %}
+{% if crb_usernames is defined %}
+userNames:
+{% for name in crb_usernames %}
+ - {{ name }}
+{% endfor %}
+{% endif %}
+{% if crb_groupnames is defined %}
+groupNames:
+{% for name in crb_groupnames %}
+ - {{ name }}
+{% endfor %}
+{% endif %}
+subjects:
+{% for sub in subjects %}
+ - kind: {{ sub.kind }}
+ name: {{ sub.name }}
+ namespace: {{sub.namespace}}
+{% endfor %}
+roleRef:
+ name: {{cr_name}}
diff --git a/roles/openshift_provisioners/templates/efs.j2 b/roles/openshift_provisioners/templates/efs.j2
new file mode 100644
index 000000000..81b9ccca5
--- /dev/null
+++ b/roles/openshift_provisioners/templates/efs.j2
@@ -0,0 +1,58 @@
+kind: DeploymentConfig
+apiVersion: v1
+metadata:
+ name: "{{deploy_name}}"
+ labels:
+ provisioners-infra: "{{name}}"
+ name: "{{name}}"
+spec:
+ replicas: {{replica_count}}
+ selector:
+ provisioners-infra: "{{name}}"
+ name: "{{name}}"
+ strategy:
+ type: Recreate
+ template:
+ metadata:
+ name: "{{deploy_name}}"
+ labels:
+ provisioners-infra: "{{name}}"
+ name: "{{name}}"
+ spec:
+ serviceAccountName: "{{deploy_serviceAccount}}"
+{% if node_selector is iterable and node_selector | length > 0 %}
+ nodeSelector:
+{% for key, value in node_selector.iteritems() %}
+ {{key}}: "{{value}}"
+{% endfor %}
+{% endif %}
+ containers:
+ - name: efs-provisioner
+ image: {{openshift_provisioners_image_prefix}}efs-provisioner:{{openshift_provisioners_image_version}}
+ env:
+ - name: AWS_ACCESS_KEY_ID
+ valueFrom:
+ secretKeyRef:
+ name: provisioners-efs
+ key: aws-access-key-id
+ - name: AWS_SECRET_ACCESS_KEY
+ valueFrom:
+ secretKeyRef:
+ name: provisioners-efs
+ key: aws-secret-access-key
+ - name: FILE_SYSTEM_ID
+ value: "{{openshift_provisioners_efs_fsid}}"
+ - name: AWS_REGION
+ value: "{{openshift_provisioners_efs_region}}"
+ - name: PROVISIONER_NAME
+ value: "{{openshift_provisioners_efs_name}}"
+ volumeMounts:
+ - name: pv-volume
+ mountPath: /persistentvolumes
+ securityContext:
+ supplementalGroups:
+ - {{openshift_provisioners_efs_supplementalgroup}}
+ volumes:
+ - name: pv-volume
+ persistentVolumeClaim:
+ claimName: "{{claim_name}}"
diff --git a/roles/openshift_provisioners/templates/pv.j2 b/roles/openshift_provisioners/templates/pv.j2
new file mode 100644
index 000000000..f4128f9f0
--- /dev/null
+++ b/roles/openshift_provisioners/templates/pv.j2
@@ -0,0 +1,32 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: {{obj_name}}
+{% if annotations is defined %}
+ annotations:
+{% for key,value in annotations.iteritems() %}
+ {{key}}: {{value}}
+{% endfor %}
+{% endif %}
+{% if labels is defined%}
+ labels:
+{% for key, value in labels.iteritems() %}
+ {{key}}: {{value}}
+{% endfor %}
+{% endif %}
+spec:
+ capacity:
+ storage: {{size}}
+ accessModes:
+{% for mode in access_modes %}
+ - {{mode}}
+{% endfor %}
+ {{volume_plugin}}:
+{% for s in volume_source %}
+ {{s.key}}: {{s.value}}
+{% endfor %}
+{% if claim_name is defined%}
+ claimRef:
+ name: {{claim_name}}
+ namespace: {{openshift_provisioners_project}}
+{% endif %}
diff --git a/roles/openshift_provisioners/templates/pvc.j2 b/roles/openshift_provisioners/templates/pvc.j2
new file mode 100644
index 000000000..83d503056
--- /dev/null
+++ b/roles/openshift_provisioners/templates/pvc.j2
@@ -0,0 +1,26 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: {{obj_name}}
+{% if annotations is defined %}
+ annotations:
+{% for key,value in annotations.iteritems() %}
+ {{key}}: {{value}}
+{% endfor %}
+{% endif %}
+spec:
+{% if pv_selector is defined and pv_selector is mapping %}
+ selector:
+ matchLabels:
+{% for key,value in pv_selector.iteritems() %}
+ {{key}}: {{value}}
+{% endfor %}
+{% endif %}
+ accessModes:
+{% for mode in access_modes %}
+ - {{mode}}
+{% endfor %}
+ resources:
+ requests:
+ storage: {{size}}
+
diff --git a/roles/openshift_provisioners/templates/secret.j2 b/roles/openshift_provisioners/templates/secret.j2
new file mode 100644
index 000000000..78824095b
--- /dev/null
+++ b/roles/openshift_provisioners/templates/secret.j2
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{obj_name}}
+{% if labels is defined%}
+ labels:
+{% for key, value in labels.iteritems() %}
+ {{key}}: {{value}}
+{% endfor %}
+{% endif %}
+type: Opaque
+data:
+{% for s in secrets %}
+ "{{s.key}}" : "{{s.value | b64encode}}"
+{% endfor %}
diff --git a/roles/openshift_provisioners/templates/serviceaccount.j2 b/roles/openshift_provisioners/templates/serviceaccount.j2
new file mode 100644
index 000000000..b22acc594
--- /dev/null
+++ b/roles/openshift_provisioners/templates/serviceaccount.j2
@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{obj_name}}
+{% if labels is defined%}
+ labels:
+{% for key, value in labels.iteritems() %}
+ {{key}}: {{value}}
+{% endfor %}
+{% endif %}
+{% if secrets is defined %}
+secrets:
+{% for name in secrets %}
+- name: {{ name }}
+{% endfor %}
+{% endif %}
diff --git a/roles/openshift_sanitize_inventory/tasks/main.yml b/roles/openshift_sanitize_inventory/tasks/main.yml
index b944c8991..f15dc16d1 100644
--- a/roles/openshift_sanitize_inventory/tasks/main.yml
+++ b/roles/openshift_sanitize_inventory/tasks/main.yml
@@ -1,4 +1,17 @@
---
+- name: Abort when conflicting deployment type variables are set
+ when:
+ - deployment_type is defined
+ - openshift_deployment_type is defined
+ - openshift_deployment_type != deployment_type
+ fail:
+ msg: |-
+ openshift_deployment_type is set to "{{ openshift_deployment_type }}".
+ deployment_type is set to "{{ deployment_type }}".
+ To avoid unexpected results, this conflict is not allowed.
+ deployment_type is deprecated in favor of openshift_deployment_type.
+ Please specify only openshift_deployment_type, or make both the same.
+
- name: Standardize on latest variable names
set_fact:
# goal is to deprecate deployment_type in favor of openshift_deployment_type.