diff options
89 files changed, 1593 insertions, 419 deletions
diff --git a/playbooks/cluster-operator/aws/components.yml b/playbooks/cluster-operator/aws/components.yml new file mode 100644 index 000000000..8587aac45 --- /dev/null +++ b/playbooks/cluster-operator/aws/components.yml @@ -0,0 +1,24 @@ +--- +- name: Alert user to variables needed + hosts: localhost + tasks: + - name: Alert user to variables needed - clusterid + debug: + msg: "openshift_aws_clusterid={{ openshift_aws_clusterid | default('default') }}" + + - name: Alert user to variables needed - region + debug: + msg: "openshift_aws_region={{ openshift_aws_region | default('us-east-1') }}" + +- name: Setup the master node group + hosts: localhost + tasks: + - import_role: + name: openshift_aws + tasks_from: setup_master_group.yml + +- name: run the init + import_playbook: ../../init/main.yml + +- name: Include the components playbook to finish the hosted configuration + import_playbook: ../../common/private/components.yml diff --git a/playbooks/common/openshift-cluster/upgrades/docker/docker_upgrade.yml b/playbooks/common/openshift-cluster/upgrades/docker/docker_upgrade.yml index 8392e21ee..094c70b46 100644 --- a/playbooks/common/openshift-cluster/upgrades/docker/docker_upgrade.yml +++ b/playbooks/common/openshift-cluster/upgrades/docker/docker_upgrade.yml @@ -19,7 +19,7 @@ - import_role: name: container_runtime tasks_from: docker_upgrade_check.yml - when: docker_upgrade is not defined or docker_upgrade | bool + when: docker_upgrade | default(True) | bool # If a node fails, halt everything, the admin will need to clean up and we diff --git a/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml index 86cde2844..3144e9ef5 100644 --- a/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml +++ b/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml @@ -130,7 +130,7 @@ # Step 2: Set a fact to be used to determine if we should run the redeploy of registry certs - name: set a fact to include the registry certs playbook if needed set_fact: - openshift_hosted_rollout_certs_and_registry: "{{ cert_output.rc == 0 }}" + openshift_hosted_rollout_certs_and_registry: "{{ cert_output.rc != 0 }}" # Run the redeploy certs based upon the certificates. Defaults to False for insecure registries - when: (hostvars[groups.oo_first_master.0].openshift_hosted_rollout_certs_and_registry | default(False)) | bool @@ -165,3 +165,10 @@ msg: "WARNING the shared-resource-viewer role could not be upgraded to 3.6 spec because it's marked protected, please see https://bugzilla.redhat.com/show_bug.cgi?id=1493213" when: - __shared_resource_viewer_protected | default(false) + +- name: Upgrade Service Catalog + hosts: oo_first_master + roles: + - role: openshift_service_catalog + when: + - openshift_enable_service_catalog | default(true) | bool diff --git a/playbooks/common/openshift-cluster/upgrades/pre/config.yml b/playbooks/common/openshift-cluster/upgrades/pre/config.yml index 44af37b2d..7bf1496cb 100644 --- a/playbooks/common/openshift-cluster/upgrades/pre/config.yml +++ b/playbooks/common/openshift-cluster/upgrades/pre/config.yml @@ -51,6 +51,10 @@ # l_openshift_version_set_hosts is passed via upgrade_control_plane.yml # l_openshift_version_check_hosts is passed via upgrade_control_plane.yml +# version_override will set various version-related variables during a double upgrade. +- import_playbook: version_override.yml + when: l_double_upgrade_cp | default(False) + - import_playbook: verify_cluster.yml # If we're only upgrading nodes, we need to ensure masters are already upgraded @@ -79,3 +83,4 @@ - import_role: name: container_runtime tasks_from: docker_upgrade_check.yml + when: docker_upgrade | default(True) | bool diff --git a/playbooks/common/openshift-cluster/upgrades/pre/version_override.yml b/playbooks/common/openshift-cluster/upgrades/pre/version_override.yml new file mode 100644 index 000000000..b2954397f --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/pre/version_override.yml @@ -0,0 +1,29 @@ +--- +# This playbook overrides normal version setting during double upgrades. + +- name: Set proper version values for upgrade + hosts: "{{ l_version_override_hosts | default('all:!all') }}" + tasks: + - set_fact: + # All of these will either have been set by openshift_version or + # provided by the user; we need to save these for later. + l_double_upgrade_saved_version: "{{ openshift_version }}" + l_double_upgrade_saved_release: "{{ openshift_release | default(openshift_upgrade_target) }}" + l_double_upgrade_saved_tag: "{{ openshift_image_tag }}" + l_double_upgrade_saved_pkgv: "{{ openshift_pkg_version }}" + - set_fact: + # We already ran openshift_version for the second of two upgrades; + # here we need to set some variables to enable the first upgrade. + # openshift_version, openshift_image_tag, and openshift_pkg_version + # will be modified by openshift_version; we want to ensure these + # are initially set to first versions to ensure no accidental usage of + # second versions (eg, 3.8 and 3.9 respectively) are used. + l_double_upgrade_cp_reset_version: True + openshift_version: "{{ l_double_upgrade_first_version }}" + openshift_release: "{{ l_double_upgrade_first_release }}" + openshift_upgrade_target: '3.8' + openshift_upgrade_min: '3.7' + +# Now that we have force-set a different version, we need to update a few things +# to ensure we have settings that actually match what's in repos/registries. +- import_playbook: ../../../../init/version.yml diff --git a/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_control_plane.yml index 9c7677f1b..c21862dea 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_control_plane.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_control_plane.yml @@ -17,32 +17,32 @@ l_init_fact_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" l_base_packages_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" -## Check to see if they're running 3.7 and if so upgrade them to 3.8 on control plan -## If they've specified pkg_version or image_tag preserve that for later use -- name: Configure the upgrade target for the common upgrade tasks 3.8 +- name: Configure the initial upgrade target for the common upgrade tasks hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config tasks: - set_fact: - openshift_upgrade_target: '3.8' + # We use 3.9 here so when we run openshift_version we can get + # correct values for 3.9, 3.8 we will hard-code the values in + # ../pre/version_override.yml, if necessary. + openshift_upgrade_target: '3.9' openshift_upgrade_min: '3.7' - openshift_release: '3.8' - _requested_pkg_version: "{{ openshift_pkg_version if openshift_pkg_version is defined else omit }}" - openshift_pkg_version: '' - _requested_image_tag: "{{ openshift_image_tag if openshift_image_tag is defined else omit }}" + +## Check to see if we need to double upgrade (3.7 -> 3.8 -> 3.9) +- name: Configure variables for double upgrade + hosts: oo_masters_to_config:oo_etcd_to_config + tasks: + - set_fact: l_double_upgrade_cp: True + l_version_override_hosts: "oo_masters_to_config:oo_etcd_to_config" + l_double_upgrade_first_version: "3.8" + l_double_upgrade_first_release: "3.8" when: hostvars[groups.oo_first_master.0].openshift_currently_installed_version | version_compare('3.8','<') - - name: set l_force_image_tag_to_version = True - set_fact: - # Need to set this during 3.8 upgrade to ensure image_tag is set correctly - # to match 3.8 version - l_force_image_tag_to_version: True - when: _requested_image_tag is defined - - import_playbook: ../pre/config.yml # These vars a meant to exclude oo_nodes from plays that would otherwise include # them by default. vars: + l_version_override_hosts: "oo_masters_to_config:oo_etcd_to_config" l_openshift_version_set_hosts: "oo_etcd_to_config:oo_masters_to_config:!oo_first_master" l_openshift_version_check_hosts: "oo_masters_to_config:!oo_first_master" l_upgrade_repo_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" @@ -52,46 +52,48 @@ l_upgrade_docker_target_hosts: "oo_masters_to_config:oo_etcd_to_config" l_upgrade_excluder_hosts: "oo_masters_to_config" openshift_protect_installed_version: False - when: hostvars[groups.oo_first_master.0].openshift_currently_installed_version | version_compare('3.8','<') + when: l_double_upgrade_cp | default(False) - name: Flag pre-upgrade checks complete for hosts without errors 3.8 hosts: oo_masters_to_config:oo_etcd_to_config tasks: - set_fact: pre_upgrade_complete: True - when: hostvars[groups.oo_first_master.0].openshift_currently_installed_version | version_compare('3.8','<') + when: l_double_upgrade_cp | default(False) # Pre-upgrade completed - name: Intermediate 3.8 Upgrade import_playbook: ../upgrade_control_plane.yml - when: hostvars[groups.oo_first_master.0].openshift_currently_installed_version | version_compare('3.8','<') + when: l_double_upgrade_cp | default(False) + +- name: Restore 3.9 version variables + hosts: oo_masters_to_config:oo_etcd_to_config + tasks: + - set_fact: + # all:!all == 0 hosts + l_version_override_hosts: "all:!all" + openshift_version: "{{ l_double_upgrade_saved_version }}" + openshift_release: "{{ l_double_upgrade_saved_release }}" + openshift_image_tag: "{{ l_double_upgrade_saved_tag }}" + openshift_pkg_version: "{{ l_double_upgrade_saved_pkgv }}" + when: l_double_upgrade_cp | default(False) ## 3.8 upgrade complete we should now be able to upgrade to 3.9 +- name: Clear some values now that we're done with double upgrades. + hosts: oo_masters_to_config:oo_etcd_to_config + tasks: + - set_fact: + l_double_upgrade_cp: False + l_double_upgrade_cp_reset_version: False -- name: Configure the upgrade target for the common upgrade tasks 3.9 +# We should be on 3.8 at this point, need to set upgrade_target to 3.9 +- name: Configure the upgrade target for second upgrade hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config tasks: - - meta: clear_facts - set_fact: openshift_upgrade_target: '3.9' openshift_upgrade_min: '3.8' - openshift_release: '3.9' - openshift_pkg_version: "{{ _requested_pkg_version if _requested_pkg_version is defined else '' }}" - # Set the user's specified image_tag for 3.9 upgrade if it was provided. - - set_fact: - openshift_image_tag: "{{ _requested_image_tag }}" - l_force_image_tag_to_version: False - when: _requested_image_tag is defined - # If the user didn't specify an image_tag, we need to force update image_tag - # because it will have already been set during 3.8. If we aren't running - # a double upgrade, then we can preserve image_tag because it will still - # be the user provided value. - - set_fact: - l_force_image_tag_to_version: True - when: - - l_double_upgrade_cp is defined and l_double_upgrade_cp - - _requested_image_tag is not defined - import_playbook: ../pre/config.yml # These vars a meant to exclude oo_nodes from plays that would otherwise include @@ -106,7 +108,6 @@ l_upgrade_docker_target_hosts: "oo_masters_to_config:oo_etcd_to_config" l_upgrade_excluder_hosts: "oo_masters_to_config" openshift_protect_installed_version: False - openshift_version_reinit: True - name: Flag pre-upgrade checks complete for hosts without errors hosts: oo_masters_to_config:oo_etcd_to_config diff --git a/playbooks/common/private/components.yml b/playbooks/common/private/components.yml index 089645d07..739be93c5 100644 --- a/playbooks/common/private/components.yml +++ b/playbooks/common/private/components.yml @@ -20,7 +20,9 @@ - import_playbook: ../../openshift-hosted/private/config.yml - import_playbook: ../../openshift-web-console/private/config.yml - when: openshift_web_console_install | default(true) | bool + when: + - openshift_web_console_install | default(true) | bool + - openshift.common.version_gte_3_9 - import_playbook: ../../openshift-metrics/private/config.yml when: openshift_metrics_install_metrics | default(false) | bool diff --git a/playbooks/openshift-etcd/scaleup.yml b/playbooks/openshift-etcd/scaleup.yml index 3e2fca8d4..1b2229baa 100644 --- a/playbooks/openshift-etcd/scaleup.yml +++ b/playbooks/openshift-etcd/scaleup.yml @@ -45,6 +45,7 @@ vars: skip_version: True l_init_fact_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config:oo_new_etcd_to_config" + l_sanity_check_hosts: "{{ groups['oo_new_etcd_to_config'] | union(groups['oo_masters_to_config']) | union(groups['oo_etcd_to_config']) }}" l_openshift_version_set_hosts: "all:!all" l_openshift_version_check_hosts: "all:!all" when: diff --git a/playbooks/openshift-glusterfs/private/uninstall.yml b/playbooks/openshift-glusterfs/private/uninstall.yml new file mode 100644 index 000000000..40f178f4c --- /dev/null +++ b/playbooks/openshift-glusterfs/private/uninstall.yml @@ -0,0 +1,8 @@ +--- +- name: Uninstall GlusterFS + hosts: oo_first_master + tasks: + - name: Run glusterfs uninstall role + include_role: + name: openshift_storage_glusterfs + tasks_from: uninstall.yml diff --git a/playbooks/openshift-glusterfs/uninstall.yml b/playbooks/openshift-glusterfs/uninstall.yml new file mode 100644 index 000000000..77bf75c23 --- /dev/null +++ b/playbooks/openshift-glusterfs/uninstall.yml @@ -0,0 +1,4 @@ +--- +- import_playbook: ../init/main.yml + +- import_playbook: private/uninstall.yml diff --git a/playbooks/openshift-master/private/validate_restart.yml b/playbooks/openshift-master/private/validate_restart.yml index 60b0e5bb6..40aaa653c 100644 --- a/playbooks/openshift-master/private/validate_restart.yml +++ b/playbooks/openshift-master/private/validate_restart.yml @@ -33,6 +33,7 @@ - stat: path="{{ hostvars.localhost.mktemp.stdout }}" register: exists changed_when: false + when: "'stdout' in hostvars.localhost.mktemp" - name: Cleanup temp file on localhost hosts: localhost @@ -41,6 +42,7 @@ tasks: - file: path="{{ hostvars.localhost.mktemp.stdout }}" state=absent changed_when: false + when: "'stdout' in hostvars.localhost.mktemp" - name: Warn if restarting the system where ansible is running hosts: oo_masters_to_config @@ -54,7 +56,9 @@ must be verified manually. To only restart services, set openshift_master_rolling_restart_mode=services in host inventory and relaunch the playbook. - when: exists.stat.exists and openshift.common.rolling_restart_mode == 'system' + when: + - "'stat' in exists" + - exists.stat.exists and openshift.common.rolling_restart_mode == 'system' - set_fact: current_host: "{{ exists.stat.exists }}" when: openshift.common.rolling_restart_mode == 'system' diff --git a/playbooks/openstack/advanced-configuration.md b/playbooks/openstack/advanced-configuration.md index e8f4cfc32..8df3c40b0 100644 --- a/playbooks/openstack/advanced-configuration.md +++ b/playbooks/openstack/advanced-configuration.md @@ -273,6 +273,38 @@ openshift_openstack_cluster_node_labels: mylabel: myvalue ``` +`openshift_openstack_provision_user_commands` allows users to execute +shell commands via cloud-init for all of the created Nova servers in +the Heat stack, before they are available for SSH connections. +Note that you should use custom ansible playbooks whenever +possible, like this `provision_install_custom.yml` example playbook: +``` +- import_playbook: openshift-ansible/playbooks/openstack/openshift-cluster/provision.yml + +- name: My custom actions + hosts: cluster_hosts + tasks: + - do whatever you want here + +- import_playbook: openshift-ansible/playbooks/openstack/openshift-cluster/install.yml +``` +The playbook leverages a two existing provider interfaces: `provision.yml` and +`install.yml`. For some cases, like SSH keys configuration and coordinated reboots of +servers, the cloud-init runcmd directive may be a better choice though. User specified +shell commands for cloud-init need to be either strings or lists, for example: +``` +- openshift_openstack_provision_user_commands: + - set -vx + - systemctl stop sshd # fences off ansible playbooks as we want to reboot later + - ['echo', 'foo', '>', '/tmp/foo'] + - [ ls, /tmp/foo, '||', true ] + - reboot # unfences ansible playbooks to continue after reboot +``` + +**Note** To protect Nova servers from recreating when the user-data changes via +`openshift_openstack_provision_user_commands`, the +`user_data_update_policy` parameter configured to `IGNORE` for Heat resources. + The `openshift_openstack_nodes_to_remove` allows you to specify the numerical indexes of App nodes that should be removed; for example, ['0', '2'], diff --git a/playbooks/openstack/inventory.py b/playbooks/openstack/inventory.py index d5a8c3e24..c16a9e228 100755 --- a/playbooks/openstack/inventory.py +++ b/playbooks/openstack/inventory.py @@ -89,7 +89,7 @@ def build_inventory(): for server in cluster_hosts: if 'group' in server.metadata: - group = server.metadata.group + group = server.metadata.get('group') if group not in inventory: inventory[group] = {'hosts': []} inventory[group]['hosts'].append(server.name) diff --git a/playbooks/openstack/openshift-cluster/install.yml b/playbooks/openstack/openshift-cluster/install.yml index 2ab7d14a0..cb6bf4d11 100644 --- a/playbooks/openstack/openshift-cluster/install.yml +++ b/playbooks/openstack/openshift-cluster/install.yml @@ -8,8 +8,7 @@ # values here. We do it in the OSEv3 group vars. Do we need to add # some logic here? -- name: run the cluster deploy - import_playbook: ../../prerequisites.yml +- import_playbook: ../../prerequisites.yml - name: run the cluster deploy import_playbook: ../../deploy_cluster.yml diff --git a/playbooks/openstack/openshift-cluster/provision.yml b/playbooks/openstack/openshift-cluster/provision.yml index 73c1926a0..44e3d00c0 100644 --- a/playbooks/openstack/openshift-cluster/provision.yml +++ b/playbooks/openstack/openshift-cluster/provision.yml @@ -26,9 +26,6 @@ - name: Gather facts for the new nodes setup: -- import_playbook: ../../init/basic_facts.yml -- import_playbook: ../../init/cluster_facts.yml - # TODO(shadower): consider splitting this up so people can stop here # and configure their DNS if they have to. @@ -43,7 +40,10 @@ - openshift_openstack_external_nsupdate_keys is defined - openshift_openstack_external_nsupdate_keys.private is defined or openshift_openstack_external_nsupdate_keys.public is defined -- name: Prepare the Nodes in the cluster for installation + +- import_playbook: ../../init/basic_facts.yml + +- name: Optionally subscribe the RHEL nodes hosts: oo_all_hosts become: yes gather_facts: yes @@ -63,6 +63,12 @@ - ansible_distribution == "RedHat" - rh_subscribed is defined + +- name: Prepare the Nodes in the cluster for installation + hosts: oo_all_hosts + become: yes + gather_facts: yes + tasks: - name: Install dependencies import_role: name: openshift_openstack diff --git a/roles/container_runtime/defaults/main.yml b/roles/container_runtime/defaults/main.yml index 01540776f..77cf86b0a 100644 --- a/roles/container_runtime/defaults/main.yml +++ b/roles/container_runtime/defaults/main.yml @@ -87,6 +87,8 @@ openshift_use_crio_only: False l_openshift_image_tag_default: "{{ openshift_release | default('latest') }}" l_openshift_image_tag: "{{ openshift_image_tag | default(l_openshift_image_tag_default) | string}}" +l_required_docker_version: '1.12' + # --------------------- # # systemcontainers_crio # # --------------------- # diff --git a/roles/container_runtime/tasks/docker_upgrade_check.yml b/roles/container_runtime/tasks/docker_upgrade_check.yml index 8dd916e79..4a341b744 100644 --- a/roles/container_runtime/tasks/docker_upgrade_check.yml +++ b/roles/container_runtime/tasks/docker_upgrade_check.yml @@ -36,14 +36,16 @@ failed_when: false changed_when: false -- fail: - msg: This playbook requires access to Docker 1.12 or later +- name: Required docker version not available (non-atomic) + fail: + msg: "This playbook requires access to Docker {{ l_required_docker_version }} or later" # Disable the 1.12 requirement if the user set a specific Docker version when: - not openshift_is_atomic | bool - docker_version is not defined - - docker_upgrade is not defined or docker_upgrade | bool == True - - (pkg_check.rc == 0 and (avail_docker_version.stdout == "" or avail_docker_version.stdout is version_compare('1.12','<'))) + - docker_upgrade | bool + - pkg_check.rc == 0 + - avail_docker_version.stdout == "" or avail_docker_version.stdout is version_compare(l_required_docker_version,'<') # Default l_docker_upgrade to False, we'll set to True if an upgrade is required: - set_fact: @@ -54,7 +56,8 @@ docker_version: "{{ avail_docker_version.stdout }}" when: - not openshift_is_atomic | bool - - pkg_check.rc == 0 and docker_version is not defined + - pkg_check.rc == 0 + - docker_version is not defined - name: Flag for Docker upgrade if necessary set_fact: @@ -74,8 +77,9 @@ l_docker_version: "{{ g_atomic_docker_version_result.stdout | from_yaml }}" when: openshift_is_atomic | bool -- fail: - msg: This playbook requires access to Docker 1.12 or later +- name: Required docker version is unavailable (atomic) + fail: + msg: "This playbook requires access to Docker {{ l_required_docker_version }} or later" when: - openshift_is_atomic | bool - - l_docker_version.avail_version | default(l_docker_version.curr_version, true) is version_compare('1.12','<') + - l_docker_version.avail_version | default(l_docker_version.curr_version, true) is version_compare(l_required_docker_version,'<') diff --git a/roles/kuryr/tasks/master.yaml b/roles/kuryr/tasks/master.yaml index 1cc6d2375..4f9dd82de 100644 --- a/roles/kuryr/tasks/master.yaml +++ b/roles/kuryr/tasks/master.yaml @@ -1,6 +1,7 @@ --- - name: Perform OpenShift ServiceAccount config include_tasks: serviceaccount.yaml + run_once: true - name: Create kuryr manifests tempdir command: mktemp -d @@ -32,6 +33,7 @@ namespace: "{{ kuryr_namespace }}" files: - "{{ manifests_tmpdir.stdout }}/configmap.yaml" + run_once: true - name: Apply Controller Deployment manifest oc_obj: @@ -41,6 +43,7 @@ namespace: "{{ kuryr_namespace }}" files: - "{{ manifests_tmpdir.stdout }}/controller-deployment.yaml" + run_once: true - name: Apply kuryr-cni DaemonSet manifest oc_obj: @@ -50,3 +53,4 @@ namespace: "{{ kuryr_namespace }}" files: - "{{ manifests_tmpdir.stdout }}/cni-daemonset.yaml" + run_once: true 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 bfed58011..379d9a83e 100644 --- a/roles/lib_openshift/library/oc_adm_ca_server_cert.py +++ b/roles/lib_openshift/library/oc_adm_ca_server_cert.py @@ -362,10 +362,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -413,7 +419,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -658,7 +664,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -727,6 +738,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_adm_csr.py b/roles/lib_openshift/library/oc_adm_csr.py index c78e379d5..30e8991cd 100644 --- a/roles/lib_openshift/library/oc_adm_csr.py +++ b/roles/lib_openshift/library/oc_adm_csr.py @@ -340,10 +340,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -391,7 +397,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -636,7 +642,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -705,6 +716,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] @@ -1639,6 +1651,7 @@ def main(): timeout=dict(default=30, type='int'), approve_all=dict(default=False, type='bool'), service_account=dict(default='node-bootstrapper', type='str'), + fail_on_timeout=dict(default=False, type='bool'), ), supports_check_mode=True, mutually_exclusive=[['approve_all', 'nodes']], @@ -1649,6 +1662,12 @@ def main(): rval = OCcsr.run_ansible(module.params, module.check_mode) + # If we timed out then we weren't finished. Fail if user requested to fail. + if (module.params['timeout'] > 0 and + module.params['fail_on_timeout'] and + rval['timeout']): + return module.fail_json(msg='Timed out accepting certificate signing requests. Failing as requested.', **rval) + if 'failed' in rval: return module.fail_json(**rval) diff --git a/roles/lib_openshift/library/oc_adm_manage_node.py b/roles/lib_openshift/library/oc_adm_manage_node.py index b1b2cb5b5..1cf5b4953 100644 --- a/roles/lib_openshift/library/oc_adm_manage_node.py +++ b/roles/lib_openshift/library/oc_adm_manage_node.py @@ -348,10 +348,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -399,7 +405,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -644,7 +650,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -713,6 +724,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_adm_policy_group.py b/roles/lib_openshift/library/oc_adm_policy_group.py index 2773201d7..70a82aaf6 100644 --- a/roles/lib_openshift/library/oc_adm_policy_group.py +++ b/roles/lib_openshift/library/oc_adm_policy_group.py @@ -334,10 +334,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -385,7 +391,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -630,7 +636,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -699,6 +710,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_adm_policy_user.py b/roles/lib_openshift/library/oc_adm_policy_user.py index 25cbed8b7..6796d7475 100644 --- a/roles/lib_openshift/library/oc_adm_policy_user.py +++ b/roles/lib_openshift/library/oc_adm_policy_user.py @@ -348,10 +348,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -399,7 +405,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -644,7 +650,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -713,6 +724,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_adm_registry.py b/roles/lib_openshift/library/oc_adm_registry.py index e26214316..8b1e9e04f 100644 --- a/roles/lib_openshift/library/oc_adm_registry.py +++ b/roles/lib_openshift/library/oc_adm_registry.py @@ -452,10 +452,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -503,7 +509,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -748,7 +754,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -817,6 +828,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_adm_router.py b/roles/lib_openshift/library/oc_adm_router.py index 62fca19e5..c1d19ff88 100644 --- a/roles/lib_openshift/library/oc_adm_router.py +++ b/roles/lib_openshift/library/oc_adm_router.py @@ -477,10 +477,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -528,7 +534,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -773,7 +779,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -842,6 +853,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_clusterrole.py b/roles/lib_openshift/library/oc_clusterrole.py index 0c4bfa01f..884ed706f 100644 --- a/roles/lib_openshift/library/oc_clusterrole.py +++ b/roles/lib_openshift/library/oc_clusterrole.py @@ -326,10 +326,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -377,7 +383,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -622,7 +628,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -691,6 +702,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_configmap.py b/roles/lib_openshift/library/oc_configmap.py index 36e6111eb..f188ed2fe 100644 --- a/roles/lib_openshift/library/oc_configmap.py +++ b/roles/lib_openshift/library/oc_configmap.py @@ -332,10 +332,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -383,7 +389,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -628,7 +634,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -697,6 +708,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_edit.py b/roles/lib_openshift/library/oc_edit.py index ab4f153c7..bfb7c5908 100644 --- a/roles/lib_openshift/library/oc_edit.py +++ b/roles/lib_openshift/library/oc_edit.py @@ -376,10 +376,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -427,7 +433,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -672,7 +678,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -741,6 +752,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_env.py b/roles/lib_openshift/library/oc_env.py index f334ddaa4..d57bea625 100644 --- a/roles/lib_openshift/library/oc_env.py +++ b/roles/lib_openshift/library/oc_env.py @@ -343,10 +343,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -394,7 +400,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -639,7 +645,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -708,6 +719,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_group.py b/roles/lib_openshift/library/oc_group.py index 7e9078339..ef01d01d7 100644 --- a/roles/lib_openshift/library/oc_group.py +++ b/roles/lib_openshift/library/oc_group.py @@ -316,10 +316,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -367,7 +373,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -612,7 +618,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -681,6 +692,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_image.py b/roles/lib_openshift/library/oc_image.py index e71e2eb5c..b479857ad 100644 --- a/roles/lib_openshift/library/oc_image.py +++ b/roles/lib_openshift/library/oc_image.py @@ -335,10 +335,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -386,7 +392,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -631,7 +637,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -700,6 +711,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_label.py b/roles/lib_openshift/library/oc_label.py index ac3279ef8..93c11970e 100644 --- a/roles/lib_openshift/library/oc_label.py +++ b/roles/lib_openshift/library/oc_label.py @@ -352,10 +352,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -403,7 +409,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -648,7 +654,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -717,6 +728,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_obj.py b/roles/lib_openshift/library/oc_obj.py index ca53c4c97..0512cd34e 100644 --- a/roles/lib_openshift/library/oc_obj.py +++ b/roles/lib_openshift/library/oc_obj.py @@ -355,10 +355,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -406,7 +412,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -651,7 +657,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -720,6 +731,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_objectvalidator.py b/roles/lib_openshift/library/oc_objectvalidator.py index 877c78d93..24da3e639 100644 --- a/roles/lib_openshift/library/oc_objectvalidator.py +++ b/roles/lib_openshift/library/oc_objectvalidator.py @@ -287,10 +287,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -338,7 +344,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -583,7 +589,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -652,6 +663,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_process.py b/roles/lib_openshift/library/oc_process.py index 507170424..30b60ebc5 100644 --- a/roles/lib_openshift/library/oc_process.py +++ b/roles/lib_openshift/library/oc_process.py @@ -344,10 +344,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -395,7 +401,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -640,7 +646,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -709,6 +720,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_project.py b/roles/lib_openshift/library/oc_project.py index 347e879ca..7b8ca4a59 100644 --- a/roles/lib_openshift/library/oc_project.py +++ b/roles/lib_openshift/library/oc_project.py @@ -341,10 +341,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -392,7 +398,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -637,7 +643,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -706,6 +717,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_pvc.py b/roles/lib_openshift/library/oc_pvc.py index 93c96b817..342865048 100644 --- a/roles/lib_openshift/library/oc_pvc.py +++ b/roles/lib_openshift/library/oc_pvc.py @@ -348,10 +348,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -399,7 +405,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -644,7 +650,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -713,6 +724,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_route.py b/roles/lib_openshift/library/oc_route.py index 3369cf134..5106925b4 100644 --- a/roles/lib_openshift/library/oc_route.py +++ b/roles/lib_openshift/library/oc_route.py @@ -392,10 +392,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -443,7 +449,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -688,7 +694,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -757,6 +768,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_scale.py b/roles/lib_openshift/library/oc_scale.py index 1b6202a26..d07c0fc2e 100644 --- a/roles/lib_openshift/library/oc_scale.py +++ b/roles/lib_openshift/library/oc_scale.py @@ -330,10 +330,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -381,7 +387,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -626,7 +632,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -695,6 +706,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_secret.py b/roles/lib_openshift/library/oc_secret.py index 732299e48..998daae1a 100644 --- a/roles/lib_openshift/library/oc_secret.py +++ b/roles/lib_openshift/library/oc_secret.py @@ -388,10 +388,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -439,7 +445,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -684,7 +690,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -753,6 +764,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_service.py b/roles/lib_openshift/library/oc_service.py index a6cf764ff..81977b590 100644 --- a/roles/lib_openshift/library/oc_service.py +++ b/roles/lib_openshift/library/oc_service.py @@ -395,10 +395,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -446,7 +452,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -691,7 +697,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -760,6 +771,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_serviceaccount.py b/roles/lib_openshift/library/oc_serviceaccount.py index 90d514292..db997ef9c 100644 --- a/roles/lib_openshift/library/oc_serviceaccount.py +++ b/roles/lib_openshift/library/oc_serviceaccount.py @@ -328,10 +328,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -379,7 +385,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -624,7 +630,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -693,6 +704,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_serviceaccount_secret.py b/roles/lib_openshift/library/oc_serviceaccount_secret.py index 0d9acac0e..7ad380631 100644 --- a/roles/lib_openshift/library/oc_serviceaccount_secret.py +++ b/roles/lib_openshift/library/oc_serviceaccount_secret.py @@ -328,10 +328,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -379,7 +385,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -624,7 +630,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -693,6 +704,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_storageclass.py b/roles/lib_openshift/library/oc_storageclass.py index 6fb5a94e9..401572536 100644 --- a/roles/lib_openshift/library/oc_storageclass.py +++ b/roles/lib_openshift/library/oc_storageclass.py @@ -346,10 +346,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -397,7 +403,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -642,7 +648,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -711,6 +722,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_user.py b/roles/lib_openshift/library/oc_user.py index feb69348b..4e653fc47 100644 --- a/roles/lib_openshift/library/oc_user.py +++ b/roles/lib_openshift/library/oc_user.py @@ -388,10 +388,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -439,7 +445,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -684,7 +690,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -753,6 +764,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_version.py b/roles/lib_openshift/library/oc_version.py index 0f024c048..b918f180c 100644 --- a/roles/lib_openshift/library/oc_version.py +++ b/roles/lib_openshift/library/oc_version.py @@ -300,10 +300,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -351,7 +357,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -596,7 +602,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -665,6 +676,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/library/oc_volume.py b/roles/lib_openshift/library/oc_volume.py index 6f409f979..f20546969 100644 --- a/roles/lib_openshift/library/oc_volume.py +++ b/roles/lib_openshift/library/oc_volume.py @@ -377,10 +377,16 @@ class Yedit(object): # pragma: no cover pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -428,7 +434,7 @@ class Yedit(object): # pragma: no cover # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -673,7 +679,12 @@ class Yedit(object): # pragma: no cover curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -742,6 +753,7 @@ class Yedit(object): # pragma: no cover '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/lib_openshift/src/ansible/oc_adm_csr.py b/roles/lib_openshift/src/ansible/oc_adm_csr.py index 9e43a810b..7b5e245d4 100644 --- a/roles/lib_openshift/src/ansible/oc_adm_csr.py +++ b/roles/lib_openshift/src/ansible/oc_adm_csr.py @@ -16,6 +16,7 @@ def main(): timeout=dict(default=30, type='int'), approve_all=dict(default=False, type='bool'), service_account=dict(default='node-bootstrapper', type='str'), + fail_on_timeout=dict(default=False, type='bool'), ), supports_check_mode=True, mutually_exclusive=[['approve_all', 'nodes']], @@ -26,6 +27,12 @@ def main(): rval = OCcsr.run_ansible(module.params, module.check_mode) + # If we timed out then we weren't finished. Fail if user requested to fail. + if (module.params['timeout'] > 0 and + module.params['fail_on_timeout'] and + rval['timeout']): + return module.fail_json(msg='Timed out accepting certificate signing requests. Failing as requested.', **rval) + if 'failed' in rval: return module.fail_json(**rval) diff --git a/roles/lib_utils/action_plugins/generate_pv_pvcs_list.py b/roles/lib_utils/action_plugins/generate_pv_pvcs_list.py index eb13a58ba..c60742dd3 100644 --- a/roles/lib_utils/action_plugins/generate_pv_pvcs_list.py +++ b/roles/lib_utils/action_plugins/generate_pv_pvcs_list.py @@ -118,10 +118,16 @@ class ActionModule(ActionBase): create_pvc = self._templar.template(create_pvc) if kind != 'object' and create_pv and create_pvc: volume, size, _, access_modes = self.build_common(varname=varname) + storageclass = self.task_vars.get(str(varname) + '_storageclass') + if storageclass: + storageclass = self._templar.template(storageclass) + elif storageclass is None and kind != 'dynamic': + storageclass = '' return dict( name="{0}-claim".format(volume), capacity=size, - access_modes=access_modes) + access_modes=access_modes, + storageclass=storageclass) return None def run(self, tmp=None, task_vars=None): diff --git a/roles/lib_utils/action_plugins/sanity_checks.py b/roles/lib_utils/action_plugins/sanity_checks.py index 09ce55e8f..ce54debc2 100644 --- a/roles/lib_utils/action_plugins/sanity_checks.py +++ b/roles/lib_utils/action_plugins/sanity_checks.py @@ -54,6 +54,12 @@ class ActionModule(ActionBase): def template_var(self, hostvars, host, varname): """Retrieve a variable from hostvars and template it. If undefined, return None type.""" + # We will set the current host and variable checked for easy debugging + # if there are any unhandled exceptions. + # pylint: disable=W0201 + self.last_checked_var = varname + # pylint: disable=W0201 + self.last_checked_host = host res = hostvars[host].get(varname) if res is None: return None @@ -156,6 +162,11 @@ class ActionModule(ActionBase): # pylint: disable=W0201 self.task_vars = task_vars or {} + # pylint: disable=W0201 + self.last_checked_host = "none" + # pylint: disable=W0201 + self.last_checked_var = "none" + # self._task.args holds task parameters. # check_hosts is a parameter to this plugin, and should provide # a list of hosts. @@ -172,7 +183,13 @@ class ActionModule(ActionBase): # We loop through each host in the provided list check_hosts for host in check_hosts: - self.run_checks(hostvars, host) + try: + self.run_checks(hostvars, host) + except Exception as uncaught_e: + msg = "last_checked_host: {}, last_checked_var: {};" + msg = msg.format(self.last_checked_host, self.last_checked_var) + msg += str(uncaught_e) + raise errors.AnsibleModuleError(msg) result["changed"] = False result["failed"] = False diff --git a/roles/lib_utils/library/yedit.py b/roles/lib_utils/library/yedit.py index cf5c2e423..4bd5171a7 100644 --- a/roles/lib_utils/library/yedit.py +++ b/roles/lib_utils/library/yedit.py @@ -410,10 +410,16 @@ class Yedit(object): pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -461,7 +467,7 @@ class Yedit(object): # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -706,7 +712,12 @@ class Yedit(object): curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -775,6 +786,7 @@ class Yedit(object): '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] @@ -885,7 +897,7 @@ def main(): debug=dict(default=False, type='bool'), src=dict(default=None, type='str'), content=dict(default=None), - content_type=dict(default='dict', choices=['dict']), + content_type=dict(default='yaml', choices=['yaml', 'json']), key=dict(default='', type='str'), value=dict(), value_type=dict(default='', type='str'), diff --git a/roles/lib_utils/src/ansible/yedit.py b/roles/lib_utils/src/ansible/yedit.py index c4b818cf1..c2ae08654 100644 --- a/roles/lib_utils/src/ansible/yedit.py +++ b/roles/lib_utils/src/ansible/yedit.py @@ -13,7 +13,7 @@ def main(): debug=dict(default=False, type='bool'), src=dict(default=None, type='str'), content=dict(default=None), - content_type=dict(default='dict', choices=['dict']), + content_type=dict(default='yaml', choices=['yaml', 'json']), key=dict(default='', type='str'), value=dict(), value_type=dict(default='', type='str'), diff --git a/roles/lib_utils/src/class/yedit.py b/roles/lib_utils/src/class/yedit.py index 0a4fbe07a..5f69d797c 100644 --- a/roles/lib_utils/src/class/yedit.py +++ b/roles/lib_utils/src/class/yedit.py @@ -207,10 +207,16 @@ class Yedit(object): pass # Try to use RoundTripDumper if supported. - try: - Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) - except AttributeError: - Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + if self.content_type == 'yaml': + try: + Yedit._write(self.filename, yaml.dump(self.yaml_dict, Dumper=yaml.RoundTripDumper)) + except AttributeError: + Yedit._write(self.filename, yaml.safe_dump(self.yaml_dict, default_flow_style=False)) + elif self.content_type == 'json': + Yedit._write(self.filename, json.dumps(self.yaml_dict, indent=4, sort_keys=True)) + else: + raise YeditException('Unsupported content_type: {}.'.format(self.content_type) + + 'Please specify a content_type of yaml or json.') return (True, self.yaml_dict) @@ -258,7 +264,7 @@ class Yedit(object): # Try to use RoundTripLoader if supported. try: - self.yaml_dict = yaml.safe_load(contents, yaml.RoundTripLoader) + self.yaml_dict = yaml.load(contents, yaml.RoundTripLoader) except AttributeError: self.yaml_dict = yaml.safe_load(contents) @@ -503,7 +509,12 @@ class Yedit(object): curr_value = invalue if val_type == 'yaml': - curr_value = yaml.load(invalue) + try: + # AUDIT:maybe-no-member makes sense due to different yaml libraries + # pylint: disable=maybe-no-member + curr_value = yaml.safe_load(invalue, Loader=yaml.RoundTripLoader) + except AttributeError: + curr_value = yaml.safe_load(invalue) elif val_type == 'json': curr_value = json.loads(invalue) @@ -572,6 +583,7 @@ class Yedit(object): '''perform the idempotent crud operations''' yamlfile = Yedit(filename=params['src'], backup=params['backup'], + content_type=params['content_type'], separator=params['separator']) state = params['state'] diff --git a/roles/openshift_aws/tasks/accept_nodes.yml b/roles/openshift_aws/tasks/accept_nodes.yml index db30fe5c9..cc0cdcb0b 100644 --- a/roles/openshift_aws/tasks/accept_nodes.yml +++ b/roles/openshift_aws/tasks/accept_nodes.yml @@ -37,5 +37,6 @@ #approve_all: True nodes: "{{ instancesout.instances|map(attribute='private_dns_name') | list }}" timeout: 60 + fail_on_timeout: "{{ openshift_aws_node_accept_fail_on_timeout | default(false) | bool }}" register: nodeout delegate_to: "{{ groups.masters.0 }}" diff --git a/roles/openshift_cloud_provider/defaults/main.yml b/roles/openshift_cloud_provider/defaults/main.yml index 37cbf5603..cda6acd90 100644 --- a/roles/openshift_cloud_provider/defaults/main.yml +++ b/roles/openshift_cloud_provider/defaults/main.yml @@ -2,3 +2,4 @@ openshift_gcp_project: '' openshift_gcp_prefix: '' openshift_gcp_network_name: "{{ openshift_gcp_prefix }}network" +openshift_gcp_multizone: False diff --git a/roles/openshift_cloud_provider/tasks/gce.yml b/roles/openshift_cloud_provider/tasks/gce.yml index 9e1c31b1d..8b9c1b42a 100644 --- a/roles/openshift_cloud_provider/tasks/gce.yml +++ b/roles/openshift_cloud_provider/tasks/gce.yml @@ -1,11 +1,13 @@ --- - name: check variables are passed fail: - msg: "Ensure correct variables are defined for gcp. {{ item }}" - when: item == '' + msg: "Ensure correct variables are defined for gcp. {{ item.name }}" + when: item.value == '' with_items: - - "{{ openshift_gcp_project }}" - - "{{ openshift_gcp_prefix }}" + - name: openshift_gcp_project + value: "{{ openshift_gcp_project }}" + - name: openshift_gcp_prefix + value: "{{ openshift_gcp_prefix }}" # Work around ini_file create option in 2.2 which defaults to no - name: Create cloud config file @@ -28,4 +30,4 @@ - { key: 'network-name', value: '{{ openshift_gcp_network_name }}' } - { key: 'node-tags', value: '{{ openshift_gcp_prefix }}ocp' } - { key: 'node-instance-prefix', value: '{{ openshift_gcp_prefix }}' } - - { key: 'multizone', value: 'false' } + - { key: 'multizone', value: '{{ openshift_gcp_multizone | string }}' } diff --git a/roles/openshift_etcd_facts/tasks/set_etcd_ca_host.yml b/roles/openshift_etcd_facts/tasks/set_etcd_ca_host.yml index bf8d28a9b..624ad714e 100644 --- a/roles/openshift_etcd_facts/tasks/set_etcd_ca_host.yml +++ b/roles/openshift_etcd_facts/tasks/set_etcd_ca_host.yml @@ -14,10 +14,10 @@ # and /etc/etcd/generated_certs directories. - set_fact: __etcd_ca_dir_hosts: "{{ __etcd_ca_host_stat.results - | lib_utils_oo_collect('_ansible_delegated_vars.ansible_host', + | lib_utils_oo_collect('_ansible_delegated_vars.inventory_hostname', filters={'stat.path':'/etc/etcd/ca','stat.exists':True}) }}" __etcd_generated_certs_dir_hosts: "{{ __etcd_ca_host_stat.results - | lib_utils_oo_collect('_ansible_delegated_vars.ansible_host', + | lib_utils_oo_collect('_ansible_delegated_vars.inventory_hostname', filters={'stat.path':'/etc/etcd/generated_certs','stat.exists':True}) }}" run_once: true diff --git a/roles/openshift_gcp/defaults/main.yml b/roles/openshift_gcp/defaults/main.yml index 18fc453b2..f0cbb2f32 100644 --- a/roles/openshift_gcp/defaults/main.yml +++ b/roles/openshift_gcp/defaults/main.yml @@ -56,3 +56,5 @@ openshift_gcp_node_group_config: openshift_gcp_startup_script_file: '' openshift_gcp_user_data_file: '' + +openshift_gcp_multizone: False diff --git a/roles/openshift_gcp/tasks/node_cloud_config.yml b/roles/openshift_gcp/tasks/node_cloud_config.yml index 4e982f497..c38a052ea 100644 --- a/roles/openshift_gcp/tasks/node_cloud_config.yml +++ b/roles/openshift_gcp/tasks/node_cloud_config.yml @@ -9,4 +9,4 @@ - { key: 'network-name', value: '{{ openshift_gcp_network_name }}' } - { key: 'node-tags', value: '{{ openshift_gcp_prefix }}ocp' } - { key: 'node-instance-prefix', value: '{{ openshift_gcp_prefix }}' } - - { key: 'multizone', value: 'false' } + - { key: 'multizone', value: '{{ openshift_gcp_multizone | string }}' } diff --git a/roles/openshift_logging_eventrouter/templates/2.x/eventrouter-template.j2 b/roles/openshift_logging_eventrouter/templates/2.x/eventrouter-template.j2 new file mode 100644 index 000000000..3bd29163b --- /dev/null +++ b/roles/openshift_logging_eventrouter/templates/2.x/eventrouter-template.j2 @@ -0,0 +1,109 @@ +# this jinja2 template should always match (except nodeSelector) openshift template in +# ../files/eventrouter-template.yaml +kind: Template +apiVersion: v1 +metadata: + name: eventrouter-template + annotations: + description: "A pod forwarding kubernetes events to EFK aggregated logging stack." + tags: "events,EFK,logging" +objects: + - kind: ServiceAccount + apiVersion: v1 + metadata: + name: aggregated-logging-eventrouter + - kind: ClusterRole + apiVersion: v1 + metadata: + name: event-reader + rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "watch", "list"] + - kind: ConfigMap + apiVersion: v1 + metadata: + name: logging-eventrouter + data: + config.json: |- + { + "sink": "${SINK}" + } + - kind: DeploymentConfig + apiVersion: v1 + metadata: + name: logging-eventrouter + labels: + component: eventrouter + logging-infra: eventrouter + provider: openshift + spec: + selector: + component: eventrouter + logging-infra: eventrouter + provider: openshift + replicas: "${{ '{{' }}REPLICAS{{ '}}' }}" + template: + metadata: + labels: + component: eventrouter + logging-infra: eventrouter + provider: openshift + name: logging-eventrouter + spec: + serviceAccount: aggregated-logging-eventrouter + serviceAccountName: aggregated-logging-eventrouter +{% if node_selector is iterable and node_selector | length > 0 %} + nodeSelector: +{% for key, value in node_selector.items() %} + {{ key }}: "{{ value }}" +{% endfor %} +{% endif %} + containers: + - name: kube-eventrouter + image: ${IMAGE} + imagePullPolicy: IfNotPresent + resources: + limits: + memory: ${MEMORY} + requires: + cpu: ${CPU} + memory: ${MEMORY} + volumeMounts: + - name: config-volume + mountPath: /etc/eventrouter + volumes: + - name: config-volume + configMap: + name: logging-eventrouter + - kind: ClusterRoleBinding + apiVersion: v1 + metadata: + name: event-reader-binding + subjects: + - kind: ServiceAccount + name: aggregated-logging-eventrouter + namespace: ${NAMESPACE} + roleRef: + kind: ClusterRole + name: event-reader + +parameters: + - name: SINK + displayName: Sink + value: stdout + - name: REPLICAS + displayName: Replicas + value: "1" + - name: IMAGE + displayName: Image + value: "docker.io/openshift/origin-logging-eventrouter:latest" + - name: MEMORY + displayName: Memory + value: "128Mi" + - name: CPU + displayName: CPU + value: "100m" + - name: NAMESPACE + displayName: Namespace + value: default diff --git a/roles/openshift_node/README.md b/roles/openshift_node/README.md index 87ceb8103..c61742bc2 100644 --- a/roles/openshift_node/README.md +++ b/roles/openshift_node/README.md @@ -15,10 +15,17 @@ Role Variables -------------- From this role: -| Name | Default value | | -|----------------------------|-----------------------|----------------------------------------------------------| -| oreg_url | UNDEF (Optional) | Default docker registry to use | -| oreg_url_node | UNDEF (Optional) | Default docker registry to use, specifically on the node | +| Name | Default value | | +|------------------------------|-----------------------|----------------------------------------------------------| +| openshift_node_start_options | UNDEF (Optional) | Options to pass to node start cmdline | +| oreg_url | UNDEF (Optional) | Default docker registry to use | +| oreg_url_node | UNDEF (Optional) | Default docker registry to use, specifically on the node | + +openshift_node_start_options can be used for passing any start node option, e.g.: + +--enable=kubelet,plugins + +Which would have a node running without kube-proxy and dns. Dependencies ------------ diff --git a/roles/openshift_node/defaults/main.yml b/roles/openshift_node/defaults/main.yml index 64ab07bb5..9f887891b 100644 --- a/roles/openshift_node/defaults/main.yml +++ b/roles/openshift_node/defaults/main.yml @@ -112,7 +112,7 @@ l_is_openvswitch_system_container: "{{ (openshift_use_openvswitch_system_contain openshift_image_tag: '' default_r_openshift_node_image_prep_packages: -#- "{{ openshift_service_type }}-master" +- "{{ openshift_service_type }}-master" - "{{ openshift_service_type }}-node" - "{{ openshift_service_type }}-docker-excluder" - "{{ openshift_service_type }}-sdn-ovs" diff --git a/roles/openshift_node/files/networkmanager/99-origin-dns.sh b/roles/openshift_node/files/networkmanager/99-origin-dns.sh index f4e48b5b7..acf3e2f38 100755 --- a/roles/openshift_node/files/networkmanager/99-origin-dns.sh +++ b/roles/openshift_node/files/networkmanager/99-origin-dns.sh @@ -116,8 +116,9 @@ EOF echo "nameserver "${def_route_ip}"" >> ${NEW_RESOLV_CONF} if ! grep -qw search ${NEW_RESOLV_CONF}; then echo 'search cluster.local' >> ${NEW_RESOLV_CONF} - elif ! grep -q 'search.*cluster.local' ${NEW_RESOLV_CONF}; then - sed -i '/^search/ s/$/ cluster.local/' ${NEW_RESOLV_CONF} + elif ! grep -q 'search cluster.local' ${NEW_RESOLV_CONF}; then + # cluster.local should be in first three DNS names so that glibc resolver would work + sed -i -e 's/^search \(.\+\)\( cluster\.local\)\{0,1\}$/search cluster.local \1/' ${NEW_RESOLV_CONF} fi cp -Z ${NEW_RESOLV_CONF} /etc/resolv.conf fi diff --git a/roles/openshift_node/tasks/bootstrap.yml b/roles/openshift_node/tasks/bootstrap.yml index f9f042eeb..4abd060c4 100644 --- a/roles/openshift_node/tasks/bootstrap.yml +++ b/roles/openshift_node/tasks/bootstrap.yml @@ -1,11 +1,7 @@ --- -- name: install needed rpm(s) - package: - name: "{{ item }}" - state: present - with_items: "{{ r_openshift_node_image_prep_packages }}" - register: result - until: result is succeeded +- name: include package installs + import_tasks: install_rpms.yml + when: not (openshift_is_atomic | default(False) | bool) - name: create the directory for node file: diff --git a/roles/openshift_node/tasks/config/configure-node-settings.yml b/roles/openshift_node/tasks/config/configure-node-settings.yml index ebc1426d3..dcdbeb220 100644 --- a/roles/openshift_node/tasks/config/configure-node-settings.yml +++ b/roles/openshift_node/tasks/config/configure-node-settings.yml @@ -7,7 +7,7 @@ create: true with_items: - regex: '^OPTIONS=' - line: "OPTIONS=--loglevel={{ openshift_node_debug_level }}" + line: "OPTIONS=--loglevel={{ openshift_node_debug_level }} {{ openshift_node_start_options | default('') }}" - regex: '^CONFIG_FILE=' line: "CONFIG_FILE={{ openshift.common.config_base }}/node/node-config.yaml" - regex: '^IMAGE_VERSION=' diff --git a/roles/openshift_node/tasks/install_rpms.yml b/roles/openshift_node/tasks/install_rpms.yml new file mode 100644 index 000000000..c96e9cdaf --- /dev/null +++ b/roles/openshift_node/tasks/install_rpms.yml @@ -0,0 +1,9 @@ +--- +- name: install needed rpm(s) + package: + name: "{{ item }}" + state: present + with_items: "{{ r_openshift_node_image_prep_packages }}" + register: result + until: result is succeeded + when: not (openshift_is_atomic | default(False) | bool) diff --git a/roles/openshift_openstack/defaults/main.yml b/roles/openshift_openstack/defaults/main.yml index 75bed96f0..6c7e5b543 100644 --- a/roles/openshift_openstack/defaults/main.yml +++ b/roles/openshift_openstack/defaults/main.yml @@ -21,16 +21,15 @@ openshift_openstack_cluster_node_labels: openshift_openstack_install_debug_packages: false openshift_openstack_required_packages: - - docker - NetworkManager - - wget - - git - - net-tools - - bind-utils - - bridge-utils openshift_openstack_debug_packages: - bash-completion + - bind-utils + - bridge-utils + - git + - net-tools - vim-enhanced + - wget # container-storage-setup openshift_openstack_container_storage_setup: @@ -96,6 +95,8 @@ openshift_openstack_etcd_volume_size: 2 openshift_openstack_lb_volume_size: 5 openshift_openstack_ephemeral_volumes: false +# User commands for cloud-init executed on all Nova servers provisioned +openshift_openstack_provision_user_commands: [] # cloud-config openshift_openstack_disable_root: true diff --git a/roles/openshift_openstack/templates/user_data.j2 b/roles/openshift_openstack/templates/user_data.j2 index ccaa5d464..1ca87a429 100644 --- a/roles/openshift_openstack/templates/user_data.j2 +++ b/roles/openshift_openstack/templates/user_data.j2 @@ -11,3 +11,19 @@ write_files: permissions: 440 content: | Defaults:openshift !requiretty + +{% if openshift_openstack_provision_user_commands %} + - path: /root/ansible_install.sh + permissions: '0544' + content: | +{% for cmd in openshift_openstack_provision_user_commands %} +{% if cmd is string %} + {{ cmd }} +{% elif cmd is iterable %} + {{ cmd|join(' ') }} +{% endif %} +{% endfor %} + +runcmd: + - /root/ansible_install.sh +{% endif %} diff --git a/roles/openshift_persistent_volumes/templates/persistent-volume-claim.yml.j2 b/roles/openshift_persistent_volumes/templates/persistent-volume-claim.yml.j2 index fac589a92..ca8b747ee 100644 --- a/roles/openshift_persistent_volumes/templates/persistent-volume-claim.yml.j2 +++ b/roles/openshift_persistent_volumes/templates/persistent-volume-claim.yml.j2 @@ -12,4 +12,7 @@ items: resources: requests: storage: "{{ claim.capacity }}" +{% if claim.storageclass is not None %} + storageClassName: "{{ claim.storageclass }}" +{% endif %} {% endfor %} diff --git a/roles/openshift_storage_glusterfs/files/v3.6/deploy-heketi-template.yml b/roles/openshift_storage_glusterfs/files/v3.6/deploy-heketi-template.yml index 7b705c2d4..34af652c2 100644 --- a/roles/openshift_storage_glusterfs/files/v3.6/deploy-heketi-template.yml +++ b/roles/openshift_storage_glusterfs/files/v3.6/deploy-heketi-template.yml @@ -73,13 +73,11 @@ objects: - name: HEKETI_EXECUTOR value: ${HEKETI_EXECUTOR} - name: HEKETI_FSTAB - value: /var/lib/heketi/fstab + value: ${HEKETI_FSTAB} - name: HEKETI_SNAPSHOT_LIMIT value: '14' - name: HEKETI_KUBE_GLUSTER_DAEMONSET value: '1' - - name: HEKETI_KUBE_NAMESPACE - value: ${HEKETI_KUBE_NAMESPACE} ports: - containerPort: 8080 volumeMounts: @@ -115,10 +113,10 @@ parameters: displayName: heketi executor type description: Set the executor type, kubernetes or ssh value: kubernetes -- name: HEKETI_KUBE_NAMESPACE - displayName: Namespace - description: Set the namespace where the GlusterFS pods reside - value: default +- name: HEKETI_FSTAB + displayName: heketi fstab path + description: Set the fstab path, file that is populated with bricks that heketi creates + value: /var/lib/heketi/fstab - name: HEKETI_ROUTE displayName: heketi route name description: Set the hostname for the route URL diff --git a/roles/openshift_storage_glusterfs/files/v3.6/gluster-s3-pvcs-template.yml b/roles/openshift_storage_glusterfs/files/v3.6/gluster-s3-pvcs-template.yml new file mode 100644 index 000000000..064b51473 --- /dev/null +++ b/roles/openshift_storage_glusterfs/files/v3.6/gluster-s3-pvcs-template.yml @@ -0,0 +1,67 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: gluster-s3-pvcs + labels: + glusterfs: s3-pvcs-template + gluster-s3: pvcs-template + annotations: + description: Gluster S3 service template + tags: glusterfs,heketi,gluster-s3 +objects: +- kind: PersistentVolumeClaim + apiVersion: v1 + metadata: + name: "${PVC}" + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-storage + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-pvc + annotations: + volume.beta.kubernetes.io/storage-class: "glusterfs-${CLUSTER_NAME}" + spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: "${PVC_SIZE}" +- kind: PersistentVolumeClaim + apiVersion: v1 + metadata: + name: "${META_PVC}" + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-storage + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-meta-pvc + annotations: + volume.beta.kubernetes.io/storage-class: "glusterfs-${CLUSTER_NAME}" + spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: "${META_PVC_SIZE}" +parameters: +- name: S3_ACCOUNT + displayName: S3 Account Name + description: S3 storage account which will provide storage on GlusterFS volumes + required: true +- name: PVC + displayName: Primary GlusterFS-backed PVC + description: GlusterFS-backed PVC for object storage + required: true +- name: PVC_SIZE + displayName: Primary GlusterFS-backed PVC capacity + description: Capacity for GlusterFS-backed PVC for object storage + value: 2Gi +- name: META_PVC + displayName: Metadata GlusterFS-backed PVC + description: GlusterFS-backed PVC for object storage metadata + required: true +- name: META_PVC_SIZE + displayName: Metadata GlusterFS-backed PVC capacity + description: Capacity for GlusterFS-backed PVC for object storage metadata + value: 1Gi +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances + value: storage diff --git a/roles/openshift_storage_glusterfs/files/v3.6/gluster-s3-template.yml b/roles/openshift_storage_glusterfs/files/v3.6/gluster-s3-template.yml new file mode 100644 index 000000000..896a1b226 --- /dev/null +++ b/roles/openshift_storage_glusterfs/files/v3.6/gluster-s3-template.yml @@ -0,0 +1,140 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: gluster-s3 + labels: + glusterfs: s3-template + gluster-s3: template + annotations: + description: Gluster S3 service template + tags: glusterfs,heketi,gluster-s3 +objects: +- kind: Service + apiVersion: v1 + metadata: + name: gluster-s3-${CLUSTER_NAME}-${S3_ACCOUNT}-service + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-service + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-service + spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + selector: + glusterfs: s3-pod + type: ClusterIP + sessionAffinity: None + status: + loadBalancer: {} +- kind: Route + apiVersion: v1 + metadata: + name: gluster-s3-${CLUSTER_NAME}-${S3_ACCOUNT}-route + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-route + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-route + spec: + to: + kind: Service + name: gluster-s3-${CLUSTER_NAME}-${S3_ACCOUNT}-service +- kind: DeploymentConfig + apiVersion: v1 + metadata: + name: gluster-s3-${CLUSTER_NAME}-${S3_ACCOUNT}-dc + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-dc + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-dc + annotations: + openshift.io/scc: privileged + description: Defines how to deploy gluster s3 object storage + spec: + replicas: 1 + selector: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-pod + template: + metadata: + name: gluster-${CLUSTER_NAME}-${S3_ACCOUNT}-s3 + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-pod + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-pod + spec: + containers: + - name: gluster-s3 + image: ${IMAGE_NAME}:${IMAGE_VERSION} + imagePullPolicy: IfNotPresent + ports: + - name: gluster + containerPort: 8080 + protocol: TCP + env: + - name: S3_ACCOUNT + value: "${S3_ACCOUNT}" + - name: S3_USER + value: "${S3_USER}" + - name: S3_PASSWORD + value: "${S3_PASSWORD}" + resources: {} + volumeMounts: + - name: gluster-vol1 + mountPath: "/mnt/gluster-object/${S3_ACCOUNT}" + - name: gluster-vol2 + mountPath: "/mnt/gluster-object/gsmetadata" + - name: glusterfs-cgroup + readOnly: true + mountPath: "/sys/fs/cgroup" + terminationMessagePath: "/dev/termination-log" + securityContext: + privileged: true + volumes: + - name: glusterfs-cgroup + hostPath: + path: "/sys/fs/cgroup" + - name: gluster-vol1 + persistentVolumeClaim: + claimName: ${PVC} + - name: gluster-vol2 + persistentVolumeClaim: + claimName: ${META_PVC} + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + securityContext: {} +parameters: +- name: IMAGE_NAME + displayName: glusterblock provisioner container image name + required: True +- name: IMAGE_VERSION + displayName: glusterblock provisioner container image version + required: True +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances + value: storage +- name: S3_ACCOUNT + displayName: S3 Account Name + description: S3 storage account which will provide storage on GlusterFS volumes + required: true +- name: S3_USER + displayName: S3 User + description: S3 user who can access the S3 storage account + required: true +- name: S3_PASSWORD + displayName: S3 User Password + description: Password for the S3 user + required: true +- name: PVC + displayName: Primary GlusterFS-backed PVC + description: GlusterFS-backed PVC for object storage + value: gluster-s3-claim +- name: META_PVC + displayName: Metadata GlusterFS-backed PVC + description: GlusterFS-backed PVC for object storage metadata + value: gluster-s3-meta-claim +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances + value: storage diff --git a/roles/openshift_storage_glusterfs/files/v3.6/glusterblock-provisioner.yml b/roles/openshift_storage_glusterfs/files/v3.6/glusterblock-provisioner.yml new file mode 100644 index 000000000..63dd5cce6 --- /dev/null +++ b/roles/openshift_storage_glusterfs/files/v3.6/glusterblock-provisioner.yml @@ -0,0 +1,104 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: glusterblock-provisioner + labels: + glusterfs: block-template + glusterblock: template + annotations: + description: glusterblock provisioner template + tags: glusterfs +objects: +- kind: ClusterRole + apiVersion: v1 + metadata: + name: glusterblock-provisioner-runner + labels: + glusterfs: block-provisioner-runner-clusterrole + glusterblock: provisioner-runner-clusterrole + rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["services"] + verbs: ["get"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create", "delete"] + - apiGroups: [""] + resources: ["routes"] + verbs: ["get", "list"] +- apiVersion: v1 + kind: ServiceAccount + metadata: + name: glusterblock-${CLUSTER_NAME}-provisioner + labels: + glusterfs: block-${CLUSTER_NAME}-provisioner-sa + glusterblock: ${CLUSTER_NAME}-provisioner-sa +- apiVersion: v1 + kind: ClusterRoleBinding + metadata: + name: glusterblock-${CLUSTER_NAME}-provisioner + roleRef: + name: glusterblock-provisioner-runner + subjects: + - kind: ServiceAccount + name: glusterblock-${CLUSTER_NAME}-provisioner + namespace: ${NAMESPACE} +- kind: DeploymentConfig + apiVersion: v1 + metadata: + name: glusterblock-${CLUSTER_NAME}-provisioner-dc + labels: + glusterfs: block-${CLUSTER_NAME}-provisioner-dc + glusterblock: ${CLUSTER_NAME}-provisioner-dc + annotations: + description: Defines how to deploy the glusterblock provisioner pod. + spec: + replicas: 1 + selector: + glusterfs: block-${CLUSTER_NAME}-provisioner-pod + triggers: + - type: ConfigChange + strategy: + type: Recreate + template: + metadata: + name: glusterblock-provisioner + labels: + glusterfs: block-${CLUSTER_NAME}-provisioner-pod + spec: + serviceAccountName: glusterblock-${CLUSTER_NAME}-provisioner + containers: + - name: glusterblock-provisioner + image: ${IMAGE_NAME}:${IMAGE_VERSION} + imagePullPolicy: IfNotPresent + env: + - name: PROVISIONER_NAME + value: gluster.org/glusterblock +parameters: +- name: IMAGE_NAME + displayName: glusterblock provisioner container image name + required: True +- name: IMAGE_VERSION + displayName: glusterblock provisioner container image version + required: True +- name: NAMESPACE + displayName: glusterblock provisioner namespace + description: The namespace in which these resources are being created + required: True +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances + value: storage diff --git a/roles/openshift_storage_glusterfs/files/v3.6/glusterfs-template.yml b/roles/openshift_storage_glusterfs/files/v3.6/glusterfs-template.yml index 8c5e1ded3..09850a2c2 100644 --- a/roles/openshift_storage_glusterfs/files/v3.6/glusterfs-template.yml +++ b/roles/openshift_storage_glusterfs/files/v3.6/glusterfs-template.yml @@ -35,6 +35,15 @@ objects: - name: glusterfs image: ${IMAGE_NAME}:${IMAGE_VERSION} imagePullPolicy: IfNotPresent + env: + - name: GB_GLFS_LRU_COUNT + value: "${GB_GLFS_LRU_COUNT}" + - name: TCMU_LOGDIR + value: "${TCMU_LOGDIR}" + resources: + requests: + memory: 100Mi + cpu: 100m volumeMounts: - name: glusterfs-heketi mountPath: "/var/lib/heketi" @@ -83,7 +92,6 @@ objects: periodSeconds: 25 successThreshold: 1 failureThreshold: 15 - resources: {} terminationMessagePath: "/dev/termination-log" volumes: - name: glusterfs-heketi @@ -134,3 +142,13 @@ parameters: displayName: GlusterFS cluster name description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances value: storage +- name: GB_GLFS_LRU_COUNT + displayName: Maximum number of block hosting volumes + description: This value is to set maximum number of block hosting volumes. + value: "15" + required: true +- name: TCMU_LOGDIR + displayName: Tcmu runner log directory + description: This value is to set tcmu runner log directory + value: "/var/log/glusterfs/gluster-block" + required: true diff --git a/roles/openshift_storage_glusterfs/files/v3.6/heketi-template.yml b/roles/openshift_storage_glusterfs/files/v3.6/heketi-template.yml index 61b6a8c13..28cdb2982 100644 --- a/roles/openshift_storage_glusterfs/files/v3.6/heketi-template.yml +++ b/roles/openshift_storage_glusterfs/files/v3.6/heketi-template.yml @@ -15,6 +15,7 @@ objects: name: heketi-${CLUSTER_NAME} labels: glusterfs: heketi-${CLUSTER_NAME}-service + heketi: ${CLUSTER_NAME}-service annotations: description: Exposes Heketi service spec: @@ -30,6 +31,7 @@ objects: name: ${HEKETI_ROUTE} labels: glusterfs: heketi-${CLUSTER_NAME}-route + heketi: ${CLUSTER_NAME}-route spec: to: kind: Service @@ -40,6 +42,7 @@ objects: name: heketi-${CLUSTER_NAME} labels: glusterfs: heketi-${CLUSTER_NAME}-dc + heketi: ${CLUSTER_NAME}-dc annotations: description: Defines how to deploy Heketi spec: @@ -55,6 +58,7 @@ objects: name: heketi-${CLUSTER_NAME} labels: glusterfs: heketi-${CLUSTER_NAME}-pod + heketi: ${CLUSTER_NAME}-pod spec: serviceAccountName: heketi-${CLUSTER_NAME}-service-account containers: @@ -69,13 +73,11 @@ objects: - name: HEKETI_EXECUTOR value: ${HEKETI_EXECUTOR} - name: HEKETI_FSTAB - value: /var/lib/heketi/fstab + value: ${HEKETI_FSTAB} - name: HEKETI_SNAPSHOT_LIMIT value: '14' - name: HEKETI_KUBE_GLUSTER_DAEMONSET value: '1' - - name: HEKETI_KUBE_NAMESPACE - value: ${HEKETI_KUBE_NAMESPACE} ports: - containerPort: 8080 volumeMounts: @@ -114,10 +116,10 @@ parameters: displayName: heketi executor type description: Set the executor type, kubernetes or ssh value: kubernetes -- name: HEKETI_KUBE_NAMESPACE - displayName: Namespace - description: Set the namespace where the GlusterFS pods reside - value: default +- name: HEKETI_FSTAB + displayName: heketi fstab path + description: Set the fstab path, file that is populated with bricks that heketi creates + value: /var/lib/heketi/fstab - name: HEKETI_ROUTE displayName: heketi route name description: Set the hostname for the route URL diff --git a/roles/openshift_storage_glusterfs/tasks/glusterfs_config.yml b/roles/openshift_storage_glusterfs/tasks/glusterfs_config.yml index 92de1b64d..b50050956 100644 --- a/roles/openshift_storage_glusterfs/tasks/glusterfs_config.yml +++ b/roles/openshift_storage_glusterfs/tasks/glusterfs_config.yml @@ -1,53 +1,3 @@ --- -- set_fact: - glusterfs_timeout: "{{ openshift_storage_glusterfs_timeout }}" - glusterfs_namespace: "{{ openshift_storage_glusterfs_namespace }}" - glusterfs_is_native: "{{ openshift_storage_glusterfs_is_native | bool }}" - glusterfs_name: "{{ openshift_storage_glusterfs_name }}" - # map_from_pairs is a custom filter plugin in role lib_utils - glusterfs_nodeselector: "{{ openshift_storage_glusterfs_nodeselector | default(['storagenode', openshift_storage_glusterfs_name] | join('=')) | map_from_pairs }}" - glusterfs_use_default_selector: "{{ openshift_storage_glusterfs_use_default_selector }}" - glusterfs_storageclass: "{{ openshift_storage_glusterfs_storageclass }}" - glusterfs_storageclass_default: "{{ openshift_storage_glusterfs_storageclass_default | bool }}" - glusterfs_image: "{{ openshift_storage_glusterfs_image }}" - glusterfs_version: "{{ openshift_storage_glusterfs_version }}" - glusterfs_block_deploy: "{{ openshift_storage_glusterfs_block_deploy | bool }}" - glusterfs_block_image: "{{ openshift_storage_glusterfs_block_image }}" - glusterfs_block_version: "{{ openshift_storage_glusterfs_block_version }}" - glusterfs_block_host_vol_create: "{{ openshift_storage_glusterfs_block_host_vol_create }}" - glusterfs_block_host_vol_size: "{{ openshift_storage_glusterfs_block_host_vol_size }}" - glusterfs_block_host_vol_max: "{{ openshift_storage_glusterfs_block_host_vol_max }}" - glusterfs_block_storageclass: "{{ openshift_storage_glusterfs_block_storageclass | bool }}" - glusterfs_block_storageclass_default: "{{ openshift_storage_glusterfs_block_storageclass_default | bool }}" - glusterfs_s3_deploy: "{{ openshift_storage_glusterfs_s3_deploy | bool }}" - glusterfs_s3_image: "{{ openshift_storage_glusterfs_s3_image }}" - glusterfs_s3_version: "{{ openshift_storage_glusterfs_s3_version }}" - glusterfs_s3_account: "{{ openshift_storage_glusterfs_s3_account }}" - glusterfs_s3_user: "{{ openshift_storage_glusterfs_s3_user }}" - glusterfs_s3_password: "{{ openshift_storage_glusterfs_s3_password }}" - glusterfs_s3_pvc: "{{ openshift_storage_glusterfs_s3_pvc }}" - glusterfs_s3_pvc_size: "{{ openshift_storage_glusterfs_s3_pvc_size }}" - glusterfs_s3_meta_pvc: "{{ openshift_storage_glusterfs_s3_meta_pvc }}" - glusterfs_s3_meta_pvc_size: "{{ openshift_storage_glusterfs_s3_meta_pvc_size }}" - glusterfs_wipe: "{{ openshift_storage_glusterfs_wipe | bool }}" - glusterfs_heketi_is_native: "{{ openshift_storage_glusterfs_heketi_is_native | bool }}" - glusterfs_heketi_is_missing: "{{ openshift_storage_glusterfs_heketi_is_missing | bool }}" - glusterfs_heketi_deploy_is_missing: "{{ openshift_storage_glusterfs_heketi_deploy_is_missing | bool }}" - glusterfs_heketi_cli: "{{ openshift_storage_glusterfs_heketi_cli }}" - glusterfs_heketi_image: "{{ openshift_storage_glusterfs_heketi_image }}" - glusterfs_heketi_version: "{{ openshift_storage_glusterfs_heketi_version }}" - glusterfs_heketi_admin_key: "{{ openshift_storage_glusterfs_heketi_admin_key }}" - glusterfs_heketi_user_key: "{{ openshift_storage_glusterfs_heketi_user_key }}" - glusterfs_heketi_topology_load: "{{ openshift_storage_glusterfs_heketi_topology_load | bool }}" - glusterfs_heketi_wipe: "{{ openshift_storage_glusterfs_heketi_wipe | bool }}" - glusterfs_heketi_url: "{{ openshift_storage_glusterfs_heketi_url }}" - glusterfs_heketi_port: "{{ openshift_storage_glusterfs_heketi_port }}" - glusterfs_heketi_executor: "{{ openshift_storage_glusterfs_heketi_executor }}" - glusterfs_heketi_ssh_port: "{{ openshift_storage_glusterfs_heketi_ssh_port }}" - glusterfs_heketi_ssh_user: "{{ openshift_storage_glusterfs_heketi_ssh_user }}" - glusterfs_heketi_ssh_sudo: "{{ openshift_storage_glusterfs_heketi_ssh_sudo | bool }}" - glusterfs_heketi_ssh_keyfile: "{{ openshift_storage_glusterfs_heketi_ssh_keyfile }}" - glusterfs_heketi_fstab: "{{ openshift_storage_glusterfs_heketi_fstab }}" - glusterfs_nodes: "{{ groups.glusterfs | default([]) }}" - +- include_tasks: glusterfs_config_facts.yml - include_tasks: glusterfs_common.yml diff --git a/roles/openshift_storage_glusterfs/tasks/glusterfs_config_facts.yml b/roles/openshift_storage_glusterfs/tasks/glusterfs_config_facts.yml new file mode 100644 index 000000000..67d30bf25 --- /dev/null +++ b/roles/openshift_storage_glusterfs/tasks/glusterfs_config_facts.yml @@ -0,0 +1,51 @@ +--- +- set_fact: + glusterfs_timeout: "{{ openshift_storage_glusterfs_timeout }}" + glusterfs_namespace: "{{ openshift_storage_glusterfs_namespace }}" + glusterfs_is_native: "{{ openshift_storage_glusterfs_is_native | bool }}" + glusterfs_name: "{{ openshift_storage_glusterfs_name }}" + # map_from_pairs is a custom filter plugin in role lib_utils + glusterfs_nodeselector: "{{ openshift_storage_glusterfs_nodeselector | default(['storagenode', openshift_storage_glusterfs_name] | join('=')) | map_from_pairs }}" + glusterfs_use_default_selector: "{{ openshift_storage_glusterfs_use_default_selector }}" + glusterfs_storageclass: "{{ openshift_storage_glusterfs_storageclass }}" + glusterfs_storageclass_default: "{{ openshift_storage_glusterfs_storageclass_default | bool }}" + glusterfs_image: "{{ openshift_storage_glusterfs_image }}" + glusterfs_version: "{{ openshift_storage_glusterfs_version }}" + glusterfs_block_deploy: "{{ openshift_storage_glusterfs_block_deploy | bool }}" + glusterfs_block_image: "{{ openshift_storage_glusterfs_block_image }}" + glusterfs_block_version: "{{ openshift_storage_glusterfs_block_version }}" + glusterfs_block_host_vol_create: "{{ openshift_storage_glusterfs_block_host_vol_create }}" + glusterfs_block_host_vol_size: "{{ openshift_storage_glusterfs_block_host_vol_size }}" + glusterfs_block_host_vol_max: "{{ openshift_storage_glusterfs_block_host_vol_max }}" + glusterfs_block_storageclass: "{{ openshift_storage_glusterfs_block_storageclass | bool }}" + glusterfs_block_storageclass_default: "{{ openshift_storage_glusterfs_block_storageclass_default | bool }}" + glusterfs_s3_deploy: "{{ openshift_storage_glusterfs_s3_deploy | bool }}" + glusterfs_s3_image: "{{ openshift_storage_glusterfs_s3_image }}" + glusterfs_s3_version: "{{ openshift_storage_glusterfs_s3_version }}" + glusterfs_s3_account: "{{ openshift_storage_glusterfs_s3_account }}" + glusterfs_s3_user: "{{ openshift_storage_glusterfs_s3_user }}" + glusterfs_s3_password: "{{ openshift_storage_glusterfs_s3_password }}" + glusterfs_s3_pvc: "{{ openshift_storage_glusterfs_s3_pvc }}" + glusterfs_s3_pvc_size: "{{ openshift_storage_glusterfs_s3_pvc_size }}" + glusterfs_s3_meta_pvc: "{{ openshift_storage_glusterfs_s3_meta_pvc }}" + glusterfs_s3_meta_pvc_size: "{{ openshift_storage_glusterfs_s3_meta_pvc_size }}" + glusterfs_wipe: "{{ openshift_storage_glusterfs_wipe | bool }}" + glusterfs_heketi_is_native: "{{ openshift_storage_glusterfs_heketi_is_native | bool }}" + glusterfs_heketi_is_missing: "{{ openshift_storage_glusterfs_heketi_is_missing | bool }}" + glusterfs_heketi_deploy_is_missing: "{{ openshift_storage_glusterfs_heketi_deploy_is_missing | bool }}" + glusterfs_heketi_cli: "{{ openshift_storage_glusterfs_heketi_cli }}" + glusterfs_heketi_image: "{{ openshift_storage_glusterfs_heketi_image }}" + glusterfs_heketi_version: "{{ openshift_storage_glusterfs_heketi_version }}" + glusterfs_heketi_admin_key: "{{ openshift_storage_glusterfs_heketi_admin_key }}" + glusterfs_heketi_user_key: "{{ openshift_storage_glusterfs_heketi_user_key }}" + glusterfs_heketi_topology_load: "{{ openshift_storage_glusterfs_heketi_topology_load | bool }}" + glusterfs_heketi_wipe: "{{ openshift_storage_glusterfs_heketi_wipe | bool }}" + glusterfs_heketi_url: "{{ openshift_storage_glusterfs_heketi_url }}" + glusterfs_heketi_port: "{{ openshift_storage_glusterfs_heketi_port }}" + glusterfs_heketi_executor: "{{ openshift_storage_glusterfs_heketi_executor }}" + glusterfs_heketi_ssh_port: "{{ openshift_storage_glusterfs_heketi_ssh_port }}" + glusterfs_heketi_ssh_user: "{{ openshift_storage_glusterfs_heketi_ssh_user }}" + glusterfs_heketi_ssh_sudo: "{{ openshift_storage_glusterfs_heketi_ssh_sudo | bool }}" + glusterfs_heketi_ssh_keyfile: "{{ openshift_storage_glusterfs_heketi_ssh_keyfile }}" + glusterfs_heketi_fstab: "{{ openshift_storage_glusterfs_heketi_fstab }}" + glusterfs_nodes: "{{ groups.glusterfs | default([]) }}" diff --git a/roles/openshift_storage_glusterfs/tasks/glusterfs_registry.yml b/roles/openshift_storage_glusterfs/tasks/glusterfs_registry.yml index 10c29fd37..e91e13033 100644 --- a/roles/openshift_storage_glusterfs/tasks/glusterfs_registry.yml +++ b/roles/openshift_storage_glusterfs/tasks/glusterfs_registry.yml @@ -1,54 +1,5 @@ --- -- set_fact: - glusterfs_timeout: "{{ openshift_storage_glusterfs_registry_timeout }}" - glusterfs_namespace: "{{ openshift_storage_glusterfs_registry_namespace }}" - glusterfs_is_native: "{{ openshift_storage_glusterfs_registry_is_native | bool }}" - glusterfs_name: "{{ openshift_storage_glusterfs_registry_name }}" - # map_from_pairs is a custom filter plugin in role lib_utils - glusterfs_nodeselector: "{{ openshift_storage_glusterfs_registry_nodeselector | default(['storagenode', openshift_storage_glusterfs_registry_name] | join('=')) | map_from_pairs }}" - glusterfs_use_default_selector: "{{ openshift_storage_glusterfs_registry_use_default_selector }}" - glusterfs_storageclass: "{{ openshift_storage_glusterfs_registry_storageclass }}" - glusterfs_storageclass_default: "{{ openshift_storage_glusterfs_registry_storageclass_default | bool }}" - glusterfs_image: "{{ openshift_storage_glusterfs_registry_image }}" - glusterfs_version: "{{ openshift_storage_glusterfs_registry_version }}" - glusterfs_block_deploy: "{{ openshift_storage_glusterfs_registry_block_deploy | bool }}" - glusterfs_block_image: "{{ openshift_storage_glusterfs_registry_block_image }}" - glusterfs_block_version: "{{ openshift_storage_glusterfs_registry_block_version }}" - glusterfs_block_host_vol_create: "{{ openshift_storage_glusterfs_registry_block_host_vol_create }}" - glusterfs_block_host_vol_size: "{{ openshift_storage_glusterfs_registry_block_host_vol_size }}" - glusterfs_block_host_vol_max: "{{ openshift_storage_glusterfs_registry_block_host_vol_max }}" - glusterfs_block_storageclass: "{{ openshift_storage_glusterfs_registry_block_storageclass | bool }}" - glusterfs_block_storageclass_default: "{{ openshift_storage_glusterfs_registry_block_storageclass_default | bool }}" - glusterfs_s3_deploy: "{{ openshift_storage_glusterfs_registry_s3_deploy | bool }}" - glusterfs_s3_image: "{{ openshift_storage_glusterfs_registry_s3_image }}" - glusterfs_s3_version: "{{ openshift_storage_glusterfs_registry_s3_version }}" - glusterfs_s3_account: "{{ openshift_storage_glusterfs_registry_s3_account }}" - glusterfs_s3_user: "{{ openshift_storage_glusterfs_registry_s3_user }}" - glusterfs_s3_password: "{{ openshift_storage_glusterfs_registry_s3_password }}" - glusterfs_s3_pvc: "{{ openshift_storage_glusterfs_registry_s3_pvc }}" - glusterfs_s3_pvc_size: "{{ openshift_storage_glusterfs_registry_s3_pvc_size }}" - glusterfs_s3_meta_pvc: "{{ openshift_storage_glusterfs_registry_s3_meta_pvc }}" - glusterfs_s3_meta_pvc_size: "{{ openshift_storage_glusterfs_registry_s3_meta_pvc_size }}" - glusterfs_wipe: "{{ openshift_storage_glusterfs_registry_wipe | bool }}" - glusterfs_heketi_is_native: "{{ openshift_storage_glusterfs_registry_heketi_is_native | bool }}" - glusterfs_heketi_is_missing: "{{ openshift_storage_glusterfs_registry_heketi_is_missing | bool }}" - glusterfs_heketi_deploy_is_missing: "{{ openshift_storage_glusterfs_registry_heketi_deploy_is_missing | bool }}" - glusterfs_heketi_cli: "{{ openshift_storage_glusterfs_registry_heketi_cli }}" - glusterfs_heketi_image: "{{ openshift_storage_glusterfs_registry_heketi_image }}" - glusterfs_heketi_version: "{{ openshift_storage_glusterfs_registry_heketi_version }}" - glusterfs_heketi_admin_key: "{{ openshift_storage_glusterfs_registry_heketi_admin_key }}" - glusterfs_heketi_user_key: "{{ openshift_storage_glusterfs_registry_heketi_user_key }}" - glusterfs_heketi_topology_load: "{{ openshift_storage_glusterfs_registry_heketi_topology_load | bool }}" - glusterfs_heketi_wipe: "{{ openshift_storage_glusterfs_registry_heketi_wipe | bool }}" - glusterfs_heketi_url: "{{ openshift_storage_glusterfs_registry_heketi_url }}" - glusterfs_heketi_port: "{{ openshift_storage_glusterfs_registry_heketi_port }}" - glusterfs_heketi_executor: "{{ openshift_storage_glusterfs_registry_heketi_executor }}" - glusterfs_heketi_ssh_port: "{{ openshift_storage_glusterfs_registry_heketi_ssh_port }}" - glusterfs_heketi_ssh_user: "{{ openshift_storage_glusterfs_registry_heketi_ssh_user }}" - glusterfs_heketi_ssh_sudo: "{{ openshift_storage_glusterfs_registry_heketi_ssh_sudo | bool }}" - glusterfs_heketi_ssh_keyfile: "{{ openshift_storage_glusterfs_registry_heketi_ssh_keyfile }}" - glusterfs_heketi_fstab: "{{ openshift_storage_glusterfs_registry_heketi_fstab }}" - glusterfs_nodes: "{% if groups.glusterfs_registry is defined and groups['glusterfs_registry'] | length > 0 %}{% set nodes = groups.glusterfs_registry %}{% elif 'groups.glusterfs' is defined and groups['glusterfs'] | length > 0 %}{% set nodes = groups.glusterfs %}{% else %}{% set nodes = '[]' %}{% endif %}{{ nodes }}" +- include_tasks: glusterfs_registry_facts.yml - include_tasks: glusterfs_common.yml when: diff --git a/roles/openshift_storage_glusterfs/tasks/glusterfs_registry_facts.yml b/roles/openshift_storage_glusterfs/tasks/glusterfs_registry_facts.yml new file mode 100644 index 000000000..5fa5f0895 --- /dev/null +++ b/roles/openshift_storage_glusterfs/tasks/glusterfs_registry_facts.yml @@ -0,0 +1,51 @@ +--- +- set_fact: + glusterfs_timeout: "{{ openshift_storage_glusterfs_registry_timeout }}" + glusterfs_namespace: "{{ openshift_storage_glusterfs_registry_namespace }}" + glusterfs_is_native: "{{ openshift_storage_glusterfs_registry_is_native | bool }}" + glusterfs_name: "{{ openshift_storage_glusterfs_registry_name }}" + # map_from_pairs is a custom filter plugin in role lib_utils + glusterfs_nodeselector: "{{ openshift_storage_glusterfs_registry_nodeselector | default(['storagenode', openshift_storage_glusterfs_registry_name] | join('=')) | map_from_pairs }}" + glusterfs_use_default_selector: "{{ openshift_storage_glusterfs_registry_use_default_selector }}" + glusterfs_storageclass: "{{ openshift_storage_glusterfs_registry_storageclass }}" + glusterfs_storageclass_default: "{{ openshift_storage_glusterfs_registry_storageclass_default | bool }}" + glusterfs_image: "{{ openshift_storage_glusterfs_registry_image }}" + glusterfs_version: "{{ openshift_storage_glusterfs_registry_version }}" + glusterfs_block_deploy: "{{ openshift_storage_glusterfs_registry_block_deploy | bool }}" + glusterfs_block_image: "{{ openshift_storage_glusterfs_registry_block_image }}" + glusterfs_block_version: "{{ openshift_storage_glusterfs_registry_block_version }}" + glusterfs_block_host_vol_create: "{{ openshift_storage_glusterfs_registry_block_host_vol_create }}" + glusterfs_block_host_vol_size: "{{ openshift_storage_glusterfs_registry_block_host_vol_size }}" + glusterfs_block_host_vol_max: "{{ openshift_storage_glusterfs_registry_block_host_vol_max }}" + glusterfs_block_storageclass: "{{ openshift_storage_glusterfs_registry_block_storageclass | bool }}" + glusterfs_block_storageclass_default: "{{ openshift_storage_glusterfs_registry_block_storageclass_default | bool }}" + glusterfs_s3_deploy: "{{ openshift_storage_glusterfs_registry_s3_deploy | bool }}" + glusterfs_s3_image: "{{ openshift_storage_glusterfs_registry_s3_image }}" + glusterfs_s3_version: "{{ openshift_storage_glusterfs_registry_s3_version }}" + glusterfs_s3_account: "{{ openshift_storage_glusterfs_registry_s3_account }}" + glusterfs_s3_user: "{{ openshift_storage_glusterfs_registry_s3_user }}" + glusterfs_s3_password: "{{ openshift_storage_glusterfs_registry_s3_password }}" + glusterfs_s3_pvc: "{{ openshift_storage_glusterfs_registry_s3_pvc }}" + glusterfs_s3_pvc_size: "{{ openshift_storage_glusterfs_registry_s3_pvc_size }}" + glusterfs_s3_meta_pvc: "{{ openshift_storage_glusterfs_registry_s3_meta_pvc }}" + glusterfs_s3_meta_pvc_size: "{{ openshift_storage_glusterfs_registry_s3_meta_pvc_size }}" + glusterfs_wipe: "{{ openshift_storage_glusterfs_registry_wipe | bool }}" + glusterfs_heketi_is_native: "{{ openshift_storage_glusterfs_registry_heketi_is_native | bool }}" + glusterfs_heketi_is_missing: "{{ openshift_storage_glusterfs_registry_heketi_is_missing | bool }}" + glusterfs_heketi_deploy_is_missing: "{{ openshift_storage_glusterfs_registry_heketi_deploy_is_missing | bool }}" + glusterfs_heketi_cli: "{{ openshift_storage_glusterfs_registry_heketi_cli }}" + glusterfs_heketi_image: "{{ openshift_storage_glusterfs_registry_heketi_image }}" + glusterfs_heketi_version: "{{ openshift_storage_glusterfs_registry_heketi_version }}" + glusterfs_heketi_admin_key: "{{ openshift_storage_glusterfs_registry_heketi_admin_key }}" + glusterfs_heketi_user_key: "{{ openshift_storage_glusterfs_registry_heketi_user_key }}" + glusterfs_heketi_topology_load: "{{ openshift_storage_glusterfs_registry_heketi_topology_load | bool }}" + glusterfs_heketi_wipe: "{{ openshift_storage_glusterfs_registry_heketi_wipe | bool }}" + glusterfs_heketi_url: "{{ openshift_storage_glusterfs_registry_heketi_url }}" + glusterfs_heketi_port: "{{ openshift_storage_glusterfs_registry_heketi_port }}" + glusterfs_heketi_executor: "{{ openshift_storage_glusterfs_registry_heketi_executor }}" + glusterfs_heketi_ssh_port: "{{ openshift_storage_glusterfs_registry_heketi_ssh_port }}" + glusterfs_heketi_ssh_user: "{{ openshift_storage_glusterfs_registry_heketi_ssh_user }}" + glusterfs_heketi_ssh_sudo: "{{ openshift_storage_glusterfs_registry_heketi_ssh_sudo | bool }}" + glusterfs_heketi_ssh_keyfile: "{{ openshift_storage_glusterfs_registry_heketi_ssh_keyfile }}" + glusterfs_heketi_fstab: "{{ openshift_storage_glusterfs_registry_heketi_fstab }}" + glusterfs_nodes: "{% if groups.glusterfs_registry is defined and groups['glusterfs_registry'] | length > 0 %}{% set nodes = groups.glusterfs_registry %}{% elif 'groups.glusterfs' is defined and groups['glusterfs'] | length > 0 %}{% set nodes = groups.glusterfs %}{% else %}{% set nodes = '[]' %}{% endif %}{{ nodes }}" diff --git a/roles/openshift_storage_glusterfs/tasks/glusterfs_uninstall.yml b/roles/openshift_storage_glusterfs/tasks/glusterfs_uninstall.yml new file mode 100644 index 000000000..a5774cc75 --- /dev/null +++ b/roles/openshift_storage_glusterfs/tasks/glusterfs_uninstall.yml @@ -0,0 +1,116 @@ +--- + +- name: Delete pre-existing heketi resources + oc_obj: + namespace: "{{ glusterfs_namespace }}" + kind: "{{ item.kind }}" + name: "{{ item.name | default(omit) }}" + selector: "{{ item.selector | default(omit) }}" + state: absent + with_items: + - kind: "template,route,service,dc,jobs,secret" + selector: "deploy-heketi" + - kind: "svc" + name: "heketi-storage-endpoints" + - kind: "svc" + name: "heketi-storage" + - kind: "secret" + name: "heketi-{{ glusterfs_name }}-topology-secret" + - kind: "template,route,service,dc" + name: "heketi-{{ glusterfs_name }}" + - kind: "svc" + name: "heketi-db-{{ glusterfs_name }}-endpoints" + - kind: "sa" + name: "heketi-{{ glusterfs_name }}-service-account" + - kind: "secret" + name: "heketi-{{ glusterfs_name }}-admin-secret" + - kind: "secret" + name: "heketi-{{ glusterfs_name }}-config-secret" + failed_when: False + +- name: Delete pre-existing GlusterFS resources + oc_obj: + namespace: "{{ glusterfs_namespace }}" + kind: "{{ item.kind }}" + name: "{{ item.name }}" + state: absent + with_items: + - kind: template + name: glusterfs + - kind: daemonset + name: "glusterfs-{{ glusterfs_name }}" + - kind: storageclass + name: "glusterfs-{{ glusterfs_name }}" + +- name: Unlabel any existing GlusterFS nodes + oc_label: + name: "{{ hostvars[item].openshift.node.nodename }}" + kind: node + state: absent + labels: "{{ glusterfs_nodeselector | lib_utils_oo_dict_to_list_of_dict }}" + with_items: "{{ groups.all }}" + +- name: Delete pre-existing GlusterFS config + file: + path: /var/lib/glusterd + state: absent + delegate_to: "{{ item }}" + with_items: "{{ glusterfs_nodes | default([]) }}" + +- name: Delete pre-existing additional GlusterFS config + file: + path: /etc/glusterfs + state: absent + delegate_to: "{{ item }}" + with_items: "{{ glusterfs_nodes | default([]) }}" + +- name: Delete pre-existing Heketi config + file: + path: /var/lib/heketi + state: absent + delegate_to: "{{ item }}" + with_items: "{{ glusterfs_nodes | default([]) }}" + +- name: Delete Glusterfs logs + file: + path: /var/log/glusterfs + state: absent + delegate_to: "{{ item }}" + with_items: "{{ glusterfs_nodes | default([]) }}" + +- name: Delete deploy resources + oc_obj: + namespace: "{{ glusterfs_namespace }}" + kind: "{{ item.kind }}" + name: "{{ item.name | default(omit) }}" + selector: "{{ item.selector | default(omit) }}" + state: absent + with_items: + - kind: "template,route,service,jobs,dc,secret" + selector: "deploy-heketi" + - kind: "svc" + name: "heketi-storage-endpoints" + - kind: "secret" + name: "heketi-{{ glusterfs_name }}-topology-secret" + +- name: Get GlusterFS storage devices state + command: "pvdisplay -C --noheadings -o pv_name,vg_name {% for device in hostvars[item].glusterfs_devices %}{{ device }} {% endfor %}" + register: devices_info + delegate_to: "{{ item }}" + with_items: "{{ glusterfs_nodes | default([]) }}" + failed_when: False + when: glusterfs_wipe + + # Runs "lvremove -ff <vg>; vgremove -fy <vg>; pvremove -fy <pv>" for every device found to be a physical volume. +- name: Clear GlusterFS storage device contents + shell: "{% for line in item.stdout_lines %}{% set fields = line.split() %}{% if fields | count > 1 %}lvremove -ff {{ fields[1] }}; vgremove -fy {{ fields[1] }}; {% endif %}pvremove -fy {{ fields[0] }}; {% endfor %}" + delegate_to: "{{ item.item }}" + with_items: "{{ devices_info.results }}" + register: clear_devices + until: + - "'contains a filesystem in use' not in clear_devices.stderr" + delay: 1 + retries: 30 + when: + - glusterfs_wipe + - item.stdout_lines | count > 0 diff --git a/roles/openshift_storage_glusterfs/tasks/uninstall.yml b/roles/openshift_storage_glusterfs/tasks/uninstall.yml new file mode 100644 index 000000000..dcf0c9357 --- /dev/null +++ b/roles/openshift_storage_glusterfs/tasks/uninstall.yml @@ -0,0 +1,12 @@ +--- +- name: uninstall glusterfs + block: + - include_tasks: glusterfs_config_facts.yml + - include_tasks: glusterfs_uninstall.yml + when: "'glusterfs' in groups and groups['glusterfs'] | length > 0" + +- name: uninstall glusterfs registry + block: + - include_tasks: glusterfs_registry_facts.yml + - include_tasks: glusterfs_uninstall.yml + when: "'glusterfs_registry' in groups and groups['glusterfs_registry'] | length > 0" diff --git a/roles/openshift_storage_glusterfs/templates/v3.6/gluster-block-storageclass.yml.j2 b/roles/openshift_storage_glusterfs/templates/v3.6/gluster-block-storageclass.yml.j2 new file mode 100644 index 000000000..02ed8fa8d --- /dev/null +++ b/roles/openshift_storage_glusterfs/templates/v3.6/gluster-block-storageclass.yml.j2 @@ -0,0 +1,19 @@ +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: glusterfs-{{ glusterfs_name }}-block +{% if glusterfs_block_storageclass_default is defined and glusterfs_block_storageclass_default %} + annotations: + storageclass.kubernetes.io/is-default-class: "true" +{% endif %} +provisioner: gluster.org/glusterblock +parameters: + resturl: "http://{% if glusterfs_heketi_is_native %}{{ glusterfs_heketi_route }}{% else %}{{ glusterfs_heketi_url }}:{{ glusterfs_heketi_port }}{% endif %}" + restuser: "admin" + chapauthenabled: "true" + hacount: "3" +{% if glusterfs_heketi_admin_key is defined %} + restsecretnamespace: "{{ glusterfs_namespace }}" + restsecretname: "heketi-{{ glusterfs_name }}-admin-secret-block" +{%- endif -%} diff --git a/roles/openshift_storage_glusterfs/templates/v3.6/glusterfs-storageclass.yml.j2 b/roles/openshift_storage_glusterfs/templates/v3.6/glusterfs-storageclass.yml.j2 index ca87807fe..095fb780f 100644 --- a/roles/openshift_storage_glusterfs/templates/v3.6/glusterfs-storageclass.yml.j2 +++ b/roles/openshift_storage_glusterfs/templates/v3.6/glusterfs-storageclass.yml.j2 @@ -3,10 +3,6 @@ apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: glusterfs-{{ glusterfs_name }} -{% if glusterfs_storageclass_default is defined and glusterfs_storageclass_default %} - annotations: - storageclass.kubernetes.io/is-default-class: "true" -{% endif %} provisioner: kubernetes.io/glusterfs parameters: resturl: "http://{% if glusterfs_heketi_is_native %}{{ glusterfs_heketi_route }}{% else %}{{ glusterfs_heketi_url }}:{{ glusterfs_heketi_port }}{% endif %}" diff --git a/roles/openshift_storage_glusterfs/templates/v3.6/heketi.json.j2 b/roles/openshift_storage_glusterfs/templates/v3.6/heketi.json.j2 index 579b11bb7..565e9be98 100644 --- a/roles/openshift_storage_glusterfs/templates/v3.6/heketi.json.j2 +++ b/roles/openshift_storage_glusterfs/templates/v3.6/heketi.json.j2 @@ -31,6 +31,12 @@ "port" : "{{ glusterfs_heketi_ssh_port }}", "user" : "{{ glusterfs_heketi_ssh_user }}", "sudo" : {{ glusterfs_heketi_ssh_sudo | lower }} - } + }, + + "_auto_create_block_hosting_volume": "Creates Block Hosting volumes automatically if not found or exsisting volume exhausted", + "auto_create_block_hosting_volume": {{ glusterfs_block_host_vol_create | lower }}, + + "_block_hosting_volume_size": "New block hosting volume will be created in size mentioned, This is considered only if auto-create is enabled.", + "block_hosting_volume_size": {{ glusterfs_block_host_vol_size }} } } diff --git a/roles/openshift_version/defaults/main.yml b/roles/openshift_version/defaults/main.yml index 513dff045..c807df9d3 100644 --- a/roles/openshift_version/defaults/main.yml +++ b/roles/openshift_version/defaults/main.yml @@ -10,4 +10,6 @@ openshift_service_type: "{{ openshift_service_type_dict[openshift_deployment_typ openshift_use_crio_only: False l_first_master_version_task_file: "{{ openshift_is_containerized | ternary('first_master_containerized_version.yml', 'first_master_rpm_version.yml') }}" -l_force_image_tag_to_version: False + +# Used during double control plane upgrades. +l_double_upgrade_cp_reset_version: False diff --git a/roles/openshift_version/tasks/first_master.yml b/roles/openshift_version/tasks/first_master.yml index b0d155c2c..022ac30fc 100644 --- a/roles/openshift_version/tasks/first_master.yml +++ b/roles/openshift_version/tasks/first_master.yml @@ -13,20 +13,30 @@ - include_tasks: "{{ l_first_master_version_task_file }}" +# When double upgrade is in process, we want to set everything to match +# openshift_verison. - block: - debug: msg: "openshift_pkg_version was not defined. Falling back to -{{ openshift_version }}" - set_fact: - openshift_pkg_version: -{{ openshift_version }} + openshift_pkg_version: "-{{ openshift_version }}" when: - - openshift_pkg_version is not defined or openshift_pkg_version == "" - - openshift_upgrade_target is not defined + - openshift_pkg_version is not defined or l_double_upgrade_cp_reset_version +# When double upgrade is in process, we want to set everything to match +# openshift_verison. - block: - debug: - msg: "openshift_image_tag set to v{{ openshift_version }}" + msg: "openshift_image_tag was not defined. Falling back to v{{ openshift_version }}" - set_fact: - openshift_image_tag: v{{ openshift_version }} - when: > - openshift_image_tag is not defined or openshift_image_tag == "" - or l_force_image_tag_to_version | bool + openshift_image_tag: "v{{ openshift_version }}" + when: openshift_image_tag is not defined or l_double_upgrade_cp_reset_version + +# The end result of these three variables is quite important so make sure they are displayed and logged: +- debug: var=openshift_release + +- debug: var=openshift_image_tag + +- debug: var=openshift_pkg_version + +- debug: var=openshift_version diff --git a/roles/openshift_version/tasks/first_master_containerized_version.yml b/roles/openshift_version/tasks/first_master_containerized_version.yml index 9eb38cb2b..e02a75eab 100644 --- a/roles/openshift_version/tasks/first_master_containerized_version.yml +++ b/roles/openshift_version/tasks/first_master_containerized_version.yml @@ -6,9 +6,7 @@ openshift_version: "{{ openshift_image_tag[1:].split('-')[0] if openshift_image_tag != 'latest' else openshift_image_tag }}" when: - openshift_image_tag is defined - - openshift_image_tag != "" - openshift_version is not defined - - not (openshift_version_reinit | default(false)) - name: Set containerized version to configure if openshift_release specified set_fact: @@ -22,7 +20,7 @@ docker run --rm {{ openshift_cli_image }}:latest version register: cli_image_version when: - - openshift_version is not defined or openshift_version_reinit | default(false) + - openshift_version is not defined - not openshift_use_crio_only # Origin latest = pre-release version (i.e. v1.3.0-alpha.1-321-gb095e3a) @@ -36,7 +34,7 @@ - set_fact: openshift_version: "{{ cli_image_version.stdout_lines[0].split(' ')[1].split('-')[0][1:] }}" - when: openshift_version is not defined or openshift_version_reinit | default(false) + when: openshift_version is not defined # If we got an openshift_version like "3.2", lookup the latest 3.2 container version # and use that value instead. diff --git a/roles/openshift_version/tasks/first_master_rpm_version.yml b/roles/openshift_version/tasks/first_master_rpm_version.yml index 85e440513..9a5f0c568 100644 --- a/roles/openshift_version/tasks/first_master_rpm_version.yml +++ b/roles/openshift_version/tasks/first_master_rpm_version.yml @@ -5,17 +5,14 @@ openshift_version: "{{ openshift_pkg_version[1:].split('-')[0] }}" when: - openshift_pkg_version is defined - - openshift_pkg_version != "" - openshift_version is not defined - - not (openshift_version_reinit | default(false)) # These tasks should only be run against masters and nodes - name: Set openshift_version for rpm installation include_tasks: check_available_rpms.yml +# If double upgrade is in process, we want to set openshift_version to whatever +# rpm package is available. - set_fact: openshift_version: "{{ rpm_results.results.versions.available_versions.0 }}" - when: openshift_version is not defined or ( openshift_version_reinit | default(false) ) -- set_fact: - openshift_pkg_version: "-{{ rpm_results.results.versions.available_versions.0 }}" - when: openshift_version_reinit | default(false) + when: openshift_version is not defined or l_double_upgrade_cp_reset_version diff --git a/roles/openshift_version/tasks/masters_and_nodes.yml b/roles/openshift_version/tasks/masters_and_nodes.yml index eddd5ff42..c4dbc2a5f 100644 --- a/roles/openshift_version/tasks/masters_and_nodes.yml +++ b/roles/openshift_version/tasks/masters_and_nodes.yml @@ -8,10 +8,7 @@ fail: msg: "OCP rpm version {{ rpm_results.results.versions.available_versions.0 }} is different from OCP image version {{ openshift_version }}" # Both versions have the same string representation - when: - - openshift_version not in rpm_results.results.versions.available_versions.0 - - openshift_version_reinit | default(false) - + when: rpm_results.results.versions.available_versions.0 != openshift_version # block when when: not openshift_is_atomic | bool |