diff options
Diffstat (limited to 'playbooks')
201 files changed, 6849 insertions, 1229 deletions
diff --git a/playbooks/adhoc/atomic_openshift_tutorial_reset.yml b/playbooks/adhoc/atomic_openshift_tutorial_reset.yml new file mode 100644 index 000000000..5a5a00ea4 --- /dev/null +++ b/playbooks/adhoc/atomic_openshift_tutorial_reset.yml @@ -0,0 +1,29 @@ +# This deletes *ALL* Docker images, and uninstalls OpenShift and +# Atomic Enterprise RPMs. It is primarily intended for use +# with the tutorial as well as for developers to reset state. +# +--- +- include: uninstall.yml + +- hosts: + - OSEv3:children + + become: yes + + tasks: + - shell: docker ps -a -q | xargs docker stop + changed_when: False + failed_when: False + + - shell: docker ps -a -q| xargs docker rm + changed_when: False + failed_when: False + + - shell: docker images -q |xargs docker rmi + changed_when: False + failed_when: False + + - user: name={{ item }} state=absent remove=yes + with_items: + - alice + - joe diff --git a/playbooks/adhoc/bootstrap-fedora.yml b/playbooks/adhoc/bootstrap-fedora.yml new file mode 100644 index 000000000..b370d7fba --- /dev/null +++ b/playbooks/adhoc/bootstrap-fedora.yml @@ -0,0 +1,5 @@ +- hosts: OSEv3 + gather_facts: false + tasks: + - name: install python and deps for ansible modules + raw: dnf install -y python2 python2-dnf libselinux-python libsemanage-python python2-firewall pyOpenSSL python-cryptography diff --git a/playbooks/adhoc/create_pv/create_pv.yaml b/playbooks/adhoc/create_pv/create_pv.yaml new file mode 100644 index 000000000..81c1ee653 --- /dev/null +++ b/playbooks/adhoc/create_pv/create_pv.yaml @@ -0,0 +1,160 @@ +--- +#example run: +# ansible-playbook -e "cli_volume_size=1" \ +# -e "cli_device_name=/dev/xvdf" \ +# -e "cli_hosttype=master" \ +# -e "cli_clusterid=ops" \ +# create_pv.yaml +# +- name: Create a volume and attach it to master + hosts: localhost + connection: local + become: no + gather_facts: no + vars: + cli_volume_type: gp2 + cli_volume_iops: '' + oo_name: "{{ groups['tag_host-type_' ~ cli_hosttype] | + intersect(groups['oo_clusterid_' ~ cli_clusterid]) | + first }}" + pre_tasks: + - fail: + msg: "This playbook requires {{item}} to be set." + when: "{{ item }} is not defined or {{ item }} == ''" + with_items: + - cli_volume_size + - cli_device_name + - cli_hosttype + - cli_clusterid + + - name: set oo_name fact + set_fact: + oo_name: "{{ oo_name }}" + + + - name: Select a single master to run this on + add_host: + hostname: "{{ oo_name }}" + ansible_ssh_host: "{{ hostvars[oo_name].ec2_public_dns_name }}" + groups: oo_master + + - name: Create a volume and attach it + ec2_vol: + state: present + instance: "{{ hostvars[oo_name]['ec2_id'] }}" + region: "{{ hostvars[oo_name]['ec2_region'] }}" + volume_size: "{{ cli_volume_size }}" + volume_type: "{{ cli_volume_type }}" + device_name: "{{ cli_device_name }}" + iops: "{{ cli_volume_iops }}" + register: vol + + - debug: var=vol + + - name: tag the vol with a name + ec2_tag: region={{ hostvars[oo_name]['ec2_region'] }} resource={{vol.volume_id}} + args: + tags: + Name: "pv-{{ hostvars[oo_name]['ec2_tag_Name'] }}" + clusterid: "{{cli_clusterid}}" + register: voltags + + - debug: var=voltags + +- name: Configure the drive + gather_facts: no + hosts: oo_master + user: root + connection: ssh + vars: + pv_tmpdir: /tmp/persistentvolumes + + post_tasks: + - name: Setting facts for template + set_fact: + pv_name: "pv-{{cli_volume_size}}-{{ hostvars[hostvars.localhost.oo_name]['ec2_tag_Name'] }}-{{hostvars.localhost.vol.volume_id }}" + vol_az: "{{ hostvars[hostvars.localhost.oo_name]['ec2_placement'] }}" + vol_id: "{{ hostvars.localhost.vol.volume_id }}" + vol_size: "{{ cli_volume_size }}" + pv_mntdir: "{{ pv_tmpdir }}/mnt-{{ 1000 | random }}" + + - set_fact: + pv_template: "{{ pv_tmpdir }}/{{ pv_name }}.yaml" + + - name: "Mkdir {{ pv_tmpdir }}" + file: + state: directory + path: "{{ pv_tmpdir }}" + mode: '0750' + + - name: "Mkdir {{ pv_mntdir }}" + file: + state: directory + path: "{{ pv_mntdir }}" + mode: '0750' + + - name: Create pv file from template + template: + src: ./pv-template.j2 + dest: "{{ pv_template }}" + owner: root + mode: '0640' + + - name: mkfs + filesystem: + dev: "{{ cli_device_name }}" + fstype: ext4 + + - name: Mount the dev + mount: + name: "{{ pv_mntdir }}" + src: "{{ cli_device_name }}" + fstype: ext4 + state: mounted + + - name: chgrp g+rwXs + file: + path: "{{ pv_mntdir }}" + mode: 'g+rwXs' + recurse: yes + seuser: system_u + serole: object_r + setype: svirt_sandbox_file_t + selevel: s0 + + - name: umount + mount: + name: "{{ pv_mntdir }}" + src: "{{ cli_device_name }}" + state: unmounted + fstype: ext4 + + - name: remove from fstab + mount: + name: "{{ pv_mntdir }}" + src: "{{ cli_device_name }}" + state: absent + fstype: ext4 + + - name: detach drive + delegate_to: localhost + ec2_vol: + region: "{{ hostvars[hostvars.localhost.oo_name].ec2_region }}" + id: "{{ hostvars.localhost.vol.volume_id }}" + instance: None + + - name: "Remove {{ pv_mntdir }}" + file: + state: absent + path: "{{ pv_mntdir }}" + + # We have to use the shell module because we can't set env vars with the command module. + - name: "Place PV into oc" + shell: "KUBECONFIG=/etc/origin/master/admin.kubeconfig oc create -f {{ pv_template | quote }}" + register: oc_output + + - debug: var=oc_output + + - fail: + msg: "Failed to add {{ pv_template }} to master." + when: oc_output.rc != 0 diff --git a/playbooks/adhoc/create_pv/pv-template.j2 b/playbooks/adhoc/create_pv/pv-template.j2 new file mode 100644 index 000000000..df082614b --- /dev/null +++ b/playbooks/adhoc/create_pv/pv-template.j2 @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ pv_name }} + labels: + type: ebs +spec: + capacity: + storage: {{ vol_size }}Gi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + awsElasticBlockStore: + volumeID: aws://{{ vol_az }}/{{ vol_id }} + fsType: ext4 diff --git a/playbooks/adhoc/docker_loopback_to_lvm/docker-storage-setup b/playbooks/adhoc/docker_loopback_to_lvm/docker-storage-setup new file mode 100644 index 000000000..059058823 --- /dev/null +++ b/playbooks/adhoc/docker_loopback_to_lvm/docker-storage-setup @@ -0,0 +1,2 @@ +DEVS=/dev/xvdb +VG=docker_vg diff --git a/playbooks/adhoc/docker_loopback_to_lvm/docker_loopback_to_direct_lvm.yml b/playbooks/adhoc/docker_loopback_to_lvm/docker_loopback_to_direct_lvm.yml new file mode 100644 index 000000000..4d32fc40b --- /dev/null +++ b/playbooks/adhoc/docker_loopback_to_lvm/docker_loopback_to_direct_lvm.yml @@ -0,0 +1,142 @@ +--- +# This playbook coverts docker to go from loopback to direct-lvm (the Red Hat recommended way to run docker) +# in AWS. This adds an additional EBS volume and creates the Volume Group on this EBS volume to use. +# +# To run: +# 1. Source your AWS credentials (make sure it's the corresponding AWS account) into your environment +# export AWS_ACCESS_KEY_ID='XXXXX' +# export AWS_SECRET_ACCESS_KEY='XXXXXX' +# +# 2. run the playbook: +# ansible-playbook -e 'cli_tag_name=<tag-name>' -e "cli_volume_size=30" docker_loopback_to_direct_lvm.yml +# +# Example: +# ansible-playbook -e 'cli_tag_name=ops-master-12345' -e "cli_volume_size=30" docker_loopback_to_direct_lvm.yml +# +# Notes: +# * By default this will do a 30GB volume. +# * iops are calculated by Disk Size * 30. e.g ( 30GB * 30) = 900 iops +# * This will remove /var/lib/docker! +# * You may need to re-deploy docker images after this is run (like monitoring) +# + +- name: Fix docker to have a provisioned iops drive + hosts: "tag_Name_{{ cli_tag_name }}" + user: root + connection: ssh + gather_facts: no + + vars: + cli_volume_type: gp2 + cli_volume_size: 30 + + pre_tasks: + - fail: + msg: "This playbook requires {{item}} to be set." + when: "{{ item }} is not defined or {{ item }} == ''" + with_items: + - cli_tag_name + - cli_volume_size + + - debug: + var: hosts + + - name: start docker + service: + name: docker + state: started + + - name: Determine if loopback + shell: docker info | grep 'Data file:.*loop' + register: loop_device_check + ignore_errors: yes + + - debug: + var: loop_device_check + + - name: fail if we don't detect loopback + fail: + msg: loopback not detected! Please investigate manually. + when: loop_device_check.rc == 1 + + - name: stop zagg client monitoring container + service: + name: oso-rhel7-zagg-client + state: stopped + ignore_errors: yes + + - name: stop pcp client monitoring container + service: + name: oso-f22-host-monitoring + state: stopped + ignore_errors: yes + + - name: stop docker + service: + name: docker + state: stopped + + - name: delete /var/lib/docker + command: rm -rf /var/lib/docker + + - name: remove /var/lib/docker + command: rm -rf /var/lib/docker + + - name: check to see if /dev/xvdb exists + command: test -e /dev/xvdb + register: xvdb_check + ignore_errors: yes + + - debug: var=xvdb_check + + - name: fail if /dev/xvdb already exists + fail: + msg: /dev/xvdb already exists. Please investigate + when: xvdb_check.rc == 0 + + - name: Create a volume and attach it + delegate_to: localhost + ec2_vol: + state: present + instance: "{{ ec2_id }}" + region: "{{ ec2_region }}" + volume_size: "{{ cli_volume_size | default(30, True)}}" + volume_type: "{{ cli_volume_type }}" + device_name: /dev/xvdb + register: vol + + - debug: var=vol + + - name: tag the vol with a name + delegate_to: localhost + ec2_tag: region={{ ec2_region }} resource={{ vol.volume_id }} + args: + tags: + Name: "{{ ec2_tag_Name }}" + clusterid: "{{ ec2_tag_clusterid }}" + register: voltags + + - name: Wait for volume to attach + pause: + seconds: 30 + + - name: copy the docker-storage-setup config file + copy: + src: docker-storage-setup + dest: /etc/sysconfig/docker-storage-setup + owner: root + group: root + mode: 0664 + + - name: docker storage setup + command: docker-storage-setup + register: setup_output + + - debug: var=setup_output + + - name: start docker + command: systemctl start docker.service + register: dockerstart + + - debug: var=dockerstart + diff --git a/playbooks/adhoc/docker_loopback_to_lvm/ops-docker-loopback-to-direct-lvm.yml b/playbooks/adhoc/docker_loopback_to_lvm/ops-docker-loopback-to-direct-lvm.yml new file mode 100755 index 000000000..1438fd7d5 --- /dev/null +++ b/playbooks/adhoc/docker_loopback_to_lvm/ops-docker-loopback-to-direct-lvm.yml @@ -0,0 +1,115 @@ +#!/usr/bin/ansible-playbook +--- +# This playbook coverts docker to go from loopback to direct-lvm (the Red Hat recommended way to run docker). +# +# It requires the block device to be already provisioned and attached to the host. This is a generic playbook, +# meant to be used for manual conversion. For AWS specific conversions, use the other playbook in this directory. +# +# To run: +# ./ops-docker-loopback-to-direct-lvm.yml -e cli_host=<host to run on> -e cli_docker_device=<path to device> +# +# Example: +# ./ops-docker-loopback-to-direct-lvm.yml -e cli_host=twiesttest-master-fd32 -e cli_docker_device=/dev/sdb +# +# Notes: +# * This will remove /var/lib/docker! +# * You may need to re-deploy docker images after this is run (like monitoring) + +- name: Fix docker to have a provisioned iops drive + hosts: "{{ cli_host }}" + user: root + connection: ssh + gather_facts: no + + pre_tasks: + - fail: + msg: "This playbook requires {{item}} to be set." + when: "{{ item }} is not defined or {{ item }} == ''" + with_items: + - cli_docker_device + + - name: start docker + service: + name: docker + state: started + + - name: Determine if loopback + shell: docker info | grep 'Data file:.*loop' + register: loop_device_check + ignore_errors: yes + + - debug: + var: loop_device_check + + - name: fail if we don't detect loopback + fail: + msg: loopback not detected! Please investigate manually. + when: loop_device_check.rc == 1 + + - name: stop zagg client monitoring container + service: + name: oso-rhel7-zagg-client + state: stopped + ignore_errors: yes + + - name: stop pcp client monitoring container + service: + name: oso-f22-host-monitoring + state: stopped + ignore_errors: yes + + - name: "check to see if {{ cli_docker_device }} exists" + command: "test -e {{ cli_docker_device }}" + register: docker_dev_check + ignore_errors: yes + + - debug: var=docker_dev_check + + - name: "fail if {{ cli_docker_device }} doesn't exist" + fail: + msg: "{{ cli_docker_device }} doesn't exist. Please investigate" + when: docker_dev_check.rc != 0 + + - name: stop docker + service: + name: docker + state: stopped + + - name: delete /var/lib/docker + command: rm -rf /var/lib/docker + + - name: remove /var/lib/docker + command: rm -rf /var/lib/docker + + - name: copy the docker-storage-setup config file + copy: + content: > + DEVS={{ cli_docker_device }} + VG=docker_vg + dest: /etc/sysconfig/docker-storage-setup + owner: root + group: root + mode: 0664 + + - name: docker storage setup + command: docker-storage-setup + register: setup_output + + - debug: var=setup_output + + - name: extend the vg + command: lvextend -l 90%VG /dev/docker_vg/docker-pool + register: extend_output + + - debug: var=extend_output + + - name: start docker + service: + name: docker + state: restarted + + - name: docker info + command: docker info + register: dockerinfo + + - debug: var=dockerinfo diff --git a/playbooks/adhoc/docker_storage_cleanup/docker_storage_cleanup.yml b/playbooks/adhoc/docker_storage_cleanup/docker_storage_cleanup.yml new file mode 100644 index 000000000..b6dde357e --- /dev/null +++ b/playbooks/adhoc/docker_storage_cleanup/docker_storage_cleanup.yml @@ -0,0 +1,69 @@ +--- +# This playbook attempts to cleanup unwanted docker files to help alleviate docker disk space issues. +# +# To run: +# +# 1. run the playbook: +# +# ansible-playbook -e 'cli_tag_name=<tag-name>' docker_storage_cleanup.yml +# +# Example: +# +# ansible-playbook -e 'cli_tag_name=ops-node-compute-12345' docker_storage_cleanup.yml +# +# Notes: +# * This *should* not interfere with running docker images +# + +- name: Clean up Docker Storage + gather_facts: no + hosts: "tag_Name_{{ cli_tag_name }}" + user: root + connection: ssh + + pre_tasks: + + - fail: + msg: "This playbook requires {{item}} to be set." + when: "{{ item }} is not defined or {{ item }} == ''" + with_items: + - cli_tag_name + + - name: Ensure docker is running + service: + name: docker + state: started + enabled: yes + + - name: Get docker info + command: docker info + register: docker_info + + - name: Show docker info + debug: + var: docker_info.stdout_lines + + - name: Remove exited and dead containers + shell: "docker ps -a | awk '/Exited|Dead/ {print $1}' | xargs --no-run-if-empty docker rm" + ignore_errors: yes + + - name: Remove dangling docker images + shell: "docker images -q -f dangling=true | xargs --no-run-if-empty docker rmi" + ignore_errors: yes + + - name: Remove non-running docker images + shell: "docker images | grep -v -e registry.access.redhat.com -e docker-registry.usersys.redhat.com -e docker-registry.ops.rhcloud.com | awk '{print $3}' | xargs --no-run-if-empty docker rmi 2>/dev/null" + ignore_errors: yes + + # leaving off the '-t' for docker exec. With it, it doesn't work with ansible and tty support + - name: update zabbix docker items + command: docker exec -i oso-rhel7-host-monitoring /usr/local/bin/cron-send-docker-metrics.py + + # Get and show docker info again. + - name: Get docker info + command: docker info + register: docker_info + + - name: Show docker info + debug: + var: docker_info.stdout_lines diff --git a/playbooks/adhoc/grow_docker_vg/filter_plugins/oo_filters.py b/playbooks/adhoc/grow_docker_vg/filter_plugins/oo_filters.py new file mode 100644 index 000000000..d0264cde9 --- /dev/null +++ b/playbooks/adhoc/grow_docker_vg/filter_plugins/oo_filters.py @@ -0,0 +1,41 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# vim: expandtab:tabstop=4:shiftwidth=4 +''' +Custom filters for use in openshift-ansible +''' + +import pdb + + +class FilterModule(object): + ''' Custom ansible filters ''' + + @staticmethod + def oo_pdb(arg): + ''' This pops you into a pdb instance where arg is the data passed in + from the filter. + Ex: "{{ hostvars | oo_pdb }}" + ''' + pdb.set_trace() + return arg + + @staticmethod + def translate_volume_name(volumes, target_volume): + ''' + This filter matches a device string /dev/sdX to /dev/xvdX + It will then return the AWS volume ID + ''' + for vol in volumes: + translated_name = vol["attachment_set"]["device"].replace("/dev/sd", "/dev/xvd") + if target_volume.startswith(translated_name): + return vol["id"] + + return None + + + def filters(self): + ''' returns a mapping of filters to methods ''' + return { + "translate_volume_name": self.translate_volume_name, + } diff --git a/playbooks/adhoc/grow_docker_vg/grow_docker_vg.yml b/playbooks/adhoc/grow_docker_vg/grow_docker_vg.yml new file mode 100644 index 000000000..d24e9cafa --- /dev/null +++ b/playbooks/adhoc/grow_docker_vg/grow_docker_vg.yml @@ -0,0 +1,206 @@ +--- +# This playbook grows the docker VG on a node by: +# * add a new volume +# * add volume to the existing VG. +# * pv move to the new volume. +# * remove old volume +# * detach volume +# * mark old volume in AWS with "REMOVE ME" tag +# * grow docker LVM to 90% of the VG +# +# To run: +# 1. Source your AWS credentials (make sure it's the corresponding AWS account) into your environment +# export AWS_ACCESS_KEY_ID='XXXXX' +# export AWS_SECRET_ACCESS_KEY='XXXXXX' +# +# 2. run the playbook: +# ansible-playbook -e 'cli_tag_name=<tag-name>' grow_docker_vg.yml +# +# Example: +# ansible-playbook -e 'cli_tag_name=ops-compute-12345' grow_docker_vg.yml +# +# Notes: +# * By default this will do a 200GB GP2 volume. The can be overidden with the "-e 'cli_volume_size=100'" variable +# * This does a GP2 by default. Support for Provisioned IOPS has not been added +# * This will assign the new volume to /dev/xvdc. This is not variablized, yet. +# * This can be done with NO downtime on the host +# * This playbook assumes that there is a Logical Volume that is installed and called "docker-pool". This is +# the LV that gets created via the "docker-storage-setup" command +# + +- name: Grow the docker volume group + hosts: "tag_Name_{{ cli_tag_name }}" + user: root + connection: ssh + gather_facts: no + + vars: + cli_volume_type: gp2 + cli_volume_size: 200 +# cli_volume_iops: "{{ 30 * cli_volume_size }}" + + pre_tasks: + - fail: + msg: "This playbook requires {{item}} to be set." + when: "{{ item }} is not defined or {{ item }} == ''" + with_items: + - cli_tag_name + - cli_volume_size + + - debug: + var: hosts + + - name: start docker + service: + name: docker + state: started + + - name: Determine if Storage Driver (docker info) is devicemapper + shell: docker info | grep 'Storage Driver:.*devicemapper' + register: device_mapper_check + ignore_errors: yes + + - debug: + var: device_mapper_check + + - name: fail if we don't detect devicemapper + fail: + msg: The "Storage Driver" in "docker info" is not set to "devicemapper"! Please investigate manually. + when: device_mapper_check.rc == 1 + + # docker-storage-setup creates a docker-pool as the lvm. I am using docker-pool lvm to test + # and find the volume group. + - name: Attempt to find the Volume Group that docker is using + shell: lvs | grep docker-pool | awk '{print $2}' + register: docker_vg_name + ignore_errors: yes + + - debug: + var: docker_vg_name + + - name: fail if we don't find a docker volume group + fail: + msg: Unable to find docker volume group. Please investigate manually. + when: docker_vg_name.stdout_lines|length != 1 + + # docker-storage-setup creates a docker-pool as the lvm. I am using docker-pool lvm to test + # and find the physical volume. + - name: Attempt to find the Phyisical Volume that docker is using + shell: "pvs | grep {{ docker_vg_name.stdout }} | awk '{print $1}'" + register: docker_pv_name + ignore_errors: yes + + - debug: + var: docker_pv_name + + - name: fail if we don't find a docker physical volume + fail: + msg: Unable to find docker physical volume. Please investigate manually. + when: docker_pv_name.stdout_lines|length != 1 + + + - name: get list of volumes from AWS + delegate_to: localhost + ec2_vol: + state: list + instance: "{{ ec2_id }}" + region: "{{ ec2_region }}" + register: attached_volumes + + - debug: var=attached_volumes + + - name: get volume id of current docker volume + set_fact: + old_docker_volume_id: "{{ attached_volumes.volumes | translate_volume_name(docker_pv_name.stdout) }}" + + - debug: var=old_docker_volume_id + + - name: check to see if /dev/xvdc exists + command: test -e /dev/xvdc + register: xvdc_check + ignore_errors: yes + + - debug: var=xvdc_check + + - name: fail if /dev/xvdc already exists + fail: + msg: /dev/xvdc already exists. Please investigate + when: xvdc_check.rc == 0 + + - name: Create a volume and attach it + delegate_to: localhost + ec2_vol: + state: present + instance: "{{ ec2_id }}" + region: "{{ ec2_region }}" + volume_size: "{{ cli_volume_size | default(30, True)}}" + volume_type: "{{ cli_volume_type }}" + device_name: /dev/xvdc + register: create_volume + + - debug: var=create_volume + + - name: Fail when problems creating volumes and attaching + fail: + msg: "Failed to create or attach volume msg: {{ create_volume.msg }}" + when: create_volume.msg is defined + + - name: tag the vol with a name + delegate_to: localhost + ec2_tag: region={{ ec2_region }} resource={{ create_volume.volume_id }} + args: + tags: + Name: "{{ ec2_tag_Name }}" + clusterid: "{{ ec2_tag_clusterid }}" + register: voltags + + - name: check for attached drive + command: test -b /dev/xvdc + register: attachment_check + until: attachment_check.rc == 0 + retries: 30 + delay: 2 + + - name: partition the new drive and make it lvm + command: parted /dev/xvdc --script -- mklabel msdos mkpart primary 0% 100% set 1 lvm + + - name: pvcreate /dev/xvdc + command: pvcreate /dev/xvdc1 + + - name: Extend the docker volume group + command: vgextend "{{ docker_vg_name.stdout }}" /dev/xvdc1 + + - name: pvmove onto new volume + command: "pvmove {{ docker_pv_name.stdout }} /dev/xvdc1" + async: 43200 + poll: 10 + + - name: Remove the old docker drive from the volume group + command: "vgreduce {{ docker_vg_name.stdout }} {{ docker_pv_name.stdout }}" + + - name: Remove the pv from the old drive + command: "pvremove {{ docker_pv_name.stdout }}" + + - name: Extend the docker lvm + command: "lvextend -l '90%VG' /dev/{{ docker_vg_name.stdout }}/docker-pool" + + - name: detach old docker volume + delegate_to: localhost + ec2_vol: + region: "{{ ec2_region }}" + id: "{{ old_docker_volume_id }}" + instance: None + + - name: tag the old vol valid label + delegate_to: localhost + ec2_tag: region={{ ec2_region }} resource={{old_docker_volume_id}} + args: + tags: + Name: "{{ ec2_tag_Name }} REMOVE ME" + register: voltags + + - name: Update the /etc/sysconfig/docker-storage-setup with new device + lineinfile: + dest: /etc/sysconfig/docker-storage-setup + regexp: ^DEVS= + line: DEVS=/dev/xvdc diff --git a/playbooks/adhoc/noc/create_host.yml b/playbooks/adhoc/noc/create_host.yml index d250e6e69..2d2cae2b5 100644 --- a/playbooks/adhoc/noc/create_host.yml +++ b/playbooks/adhoc/noc/create_host.yml @@ -1,6 +1,8 @@ --- - name: 'Create a host object in zabbix' hosts: localhost + connection: local + become: no gather_facts: no roles: - os_zabbix @@ -23,6 +25,8 @@ #ansible-playbook -e 'oo_desc=kwoodson test' -e 'oo_name=kwoodson test name' -e 'oo_start=1435715357' -e 'oo_stop=1435718985' -e 'oo_hostids=11549' create_maintenance.yml - name: 'Create a host object in zabbix' hosts: localhost + connection: local + become: no gather_facts: no roles: - os_zabbix diff --git a/playbooks/adhoc/noc/create_maintenance.yml b/playbooks/adhoc/noc/create_maintenance.yml index c0ec57ce1..8ad5fa0e2 100644 --- a/playbooks/adhoc/noc/create_maintenance.yml +++ b/playbooks/adhoc/noc/create_maintenance.yml @@ -2,6 +2,8 @@ #ansible-playbook -e 'oo_desc=kwoodson test' -e 'oo_name=kwoodson test name' -e 'oo_start=1435715357' -e 'oo_stop=1435718985' -e 'oo_hostids=11549' create_maintenance.yml - name: 'Create a maintenace object in zabbix' hosts: localhost + connection: local + become: no gather_facts: no roles: - os_zabbix diff --git a/playbooks/adhoc/noc/get_zabbix_problems.yml b/playbooks/adhoc/noc/get_zabbix_problems.yml index 4b94fa228..32fc7ce68 100644 --- a/playbooks/adhoc/noc/get_zabbix_problems.yml +++ b/playbooks/adhoc/noc/get_zabbix_problems.yml @@ -1,6 +1,8 @@ --- - name: 'Get current hosts who have triggers that are alerting by trigger description' hosts: localhost + connection: local + become: no gather_facts: no roles: - os_zabbix @@ -31,7 +33,7 @@ - add_host: name: "{{ item }}" groups: problem_hosts_group - with_items: problem_hosts + with_items: "{{ problem_hosts }}" - name: "Run on problem hosts" hosts: problem_hosts_group diff --git a/playbooks/adhoc/openshift_hosted_logging_efk.yaml b/playbooks/adhoc/openshift_hosted_logging_efk.yaml new file mode 100644 index 000000000..a3121d046 --- /dev/null +++ b/playbooks/adhoc/openshift_hosted_logging_efk.yaml @@ -0,0 +1,6 @@ +--- +- hosts: masters[0] + roles: + - role: openshift_hosted_logging + openshift_hosted_logging_cleanup: no + diff --git a/playbooks/adhoc/s3_registry/s3_registry.j2 b/playbooks/adhoc/s3_registry/s3_registry.j2 new file mode 100644 index 000000000..10454ad11 --- /dev/null +++ b/playbooks/adhoc/s3_registry/s3_registry.j2 @@ -0,0 +1,23 @@ +version: 0.1 +log: + level: debug +http: + addr: :5000 +storage: + cache: + layerinfo: inmemory + s3: + accesskey: {{ aws_access_key }} + secretkey: {{ aws_secret_key }} + region: {{ aws_bucket_region }} + bucket: {{ aws_bucket_name }} + encrypt: true + secure: true + v4auth: true + rootdirectory: /registry +auth: + openshift: + realm: openshift +middleware: + repository: + - name: openshift diff --git a/playbooks/adhoc/s3_registry/s3_registry.yml b/playbooks/adhoc/s3_registry/s3_registry.yml new file mode 100644 index 000000000..daf84e242 --- /dev/null +++ b/playbooks/adhoc/s3_registry/s3_registry.yml @@ -0,0 +1,78 @@ +--- +# This playbook creates an S3 bucket named after your cluster and configures the docker-registry service to use the bucket as its backend storage. +# Usage: +# ansible-playbook s3_registry.yml -e clusterid="mycluster" -e aws_bucket="clusterid-docker" -e aws_region="us-east-1" +# +# The AWS access/secret keys should be the keys of a separate user (not your main user), containing only the necessary S3 access role. +# The 'clusterid' is the short name of your cluster. + +- hosts: tag_clusterid_{{ clusterid }}:&tag_host-type_openshift-master + remote_user: root + gather_facts: False + + vars: + aws_access_key: "{{ lookup('env', 'S3_ACCESS_KEY_ID') }}" + aws_secret_key: "{{ lookup('env', 'S3_SECRET_ACCESS_KEY') }}" + aws_bucket_name: "{{ aws_bucket | default(clusterid ~ '-docker') }}" + aws_bucket_region: "{{ aws_region | default(lookup('env', 'S3_REGION') | default('us-east-1', true)) }}" + aws_create_bucket: "{{ aws_create | default(True) }}" + aws_tmp_path: "{{ aws_tmp_pathfile | default('/root/config.yml')}}" + aws_delete_tmp_file: "{{ aws_delete_tmp | default(True) }}" + + tasks: + + - name: Check for AWS creds + fail: + msg: "Couldn't find {{ item }} creds in ENV" + when: "{{ item }} == ''" + with_items: + - aws_access_key + - aws_secret_key + + - name: Scale down registry + command: oc scale --replicas=0 dc/docker-registry + + - name: Create S3 bucket + when: aws_create_bucket | bool + local_action: + module: s3 bucket="{{ aws_bucket_name }}" mode=create + + - name: Set up registry environment variable + command: oc env dc/docker-registry REGISTRY_CONFIGURATION_PATH=/etc/registryconfig/config.yml + + - name: Generate docker registry config + template: src="s3_registry.j2" dest="/root/config.yml" owner=root mode=0600 + + - name: Determine if new secrets are needed + command: oc get secrets + register: secrets + + - name: Create registry secrets + command: oc secrets new dockerregistry /root/config.yml + when: "'dockerregistry' not in secrets.stdout" + + - name: Determine if service account contains secrets + command: oc describe serviceaccount/registry + register: serviceaccount + + - name: Add secrets to registry service account + command: oc secrets add serviceaccount/registry secrets/dockerregistry + when: "'dockerregistry' not in serviceaccount.stdout" + + - name: Determine if deployment config contains secrets + command: oc volume dc/docker-registry --list + register: dc + + - name: Add secrets to registry deployment config + command: oc volume dc/docker-registry --add --name=dockersecrets -m /etc/registryconfig --type=secret --secret-name=dockerregistry + when: "'dockersecrets' not in dc.stdout" + + - name: Wait for deployment config to take effect before scaling up + pause: seconds=30 + + - name: Scale up registry + command: oc scale --replicas=1 dc/docker-registry + + - name: Delete temporary config file + file: path={{ aws_tmp_path }} state=absent + when: aws_delete_tmp_file | bool diff --git a/playbooks/adhoc/sdn_restart/oo-sdn-restart.yml b/playbooks/adhoc/sdn_restart/oo-sdn-restart.yml new file mode 100755 index 000000000..08e8f8968 --- /dev/null +++ b/playbooks/adhoc/sdn_restart/oo-sdn-restart.yml @@ -0,0 +1,52 @@ +#!/usr/bin/ansible-playbook +--- +#example run: +# ansible-playbook -e "host=ops-node-compute-abcde" oo-sdn-restart.yml +# + +- name: Check vars + hosts: localhost + gather_facts: false + + pre_tasks: + - fail: + msg: "Playbook requires host to be set" + when: host is not defined or host == '' + +- name: Restart openshift/docker (and monitoring containers) + hosts: oo_version_3:&oo_name_{{ host }} + gather_facts: false + user: root + + tasks: + - name: stop openshift/docker + service: + name: "{{ item }}" + state: stopped + with_items: + - atomic-openshift-node + - docker + + - name: restart openvswitch + service: + name: openvswitch + state: restarted + + - name: wait 5 sec + pause: + seconds: 5 + + - name: start openshift/docker + service: + name: "{{ item }}" + state: started + with_items: + - atomic-openshift-node + - docker + + - name: start monitoring containers + service: + name: "{{ item }}" + state: restarted + with_items: + - oso-rhel7-host-monitoring diff --git a/playbooks/adhoc/setupnfs.yml b/playbooks/adhoc/setupnfs.yml new file mode 100644 index 000000000..fd489dc70 --- /dev/null +++ b/playbooks/adhoc/setupnfs.yml @@ -0,0 +1,21 @@ +--- +### This playbook is old and we are currently not using NFS. +- hosts: tag_Name_nfs-v3-stg + become: no + remote_user: root + gather_facts: no + roles: + - role: openshift_storage_nfs_lvm + mount_dir: /exports/stg-black + volume_prefix: "kwoodsontest" + volume_size: 5 + volume_num_start: 222 + number_of_volumes: 3 + tasks: + - fetch: + dest: json/ + src: /root/"{{ item }}" + with_items: + - persistent-volume.kwoodsontest5g0222.json + - persistent-volume.kwoodsontest5g0223.json + - persistent-volume.kwoodsontest5g0224.json diff --git a/playbooks/adhoc/uninstall.yml b/playbooks/adhoc/uninstall.yml new file mode 100644 index 000000000..4ea639cbe --- /dev/null +++ b/playbooks/adhoc/uninstall.yml @@ -0,0 +1,406 @@ +# This deletes *ALL* Origin, Atomic Enterprise Platform and OpenShift +# Enterprise content installed by ansible. This includes: +# +# configuration +# containers +# example templates and imagestreams +# images +# RPMs +--- +- hosts: OSEv3:children + become: yes + tasks: + - name: Detecting Operating System + shell: ls /run/ostree-booted + ignore_errors: yes + failed_when: false + register: ostree_output + + # Since we're not calling openshift_facts we'll do this for now + - set_fact: + is_atomic: "{{ ostree_output.rc == 0 }}" + - set_fact: + is_containerized: "{{ is_atomic or containerized | default(false) | bool }}" + +# Stop services on all hosts prior to removing files. +- hosts: nodes + become: yes + tasks: + - name: Stop services + service: name={{ item }} state=stopped + with_items: + - atomic-enterprise-node + - atomic-openshift-node + - openshift-node + - openvswitch + - origin-node + failed_when: false + +- hosts: masters + become: yes + tasks: + - name: Stop services + service: name={{ item }} state=stopped + with_items: + - atomic-enterprise-master + - atomic-openshift-master + - atomic-openshift-master-api + - atomic-openshift-master-controllers + - openshift-master + - openshift-master-api + - openshift-master-controllers + - origin-master + - origin-master-api + - origin-master-controllers + - pcsd + failed_when: false + +- hosts: etcd + become: yes + tasks: + - name: Stop services + service: name={{ item }} state=stopped + with_items: + - etcd + failed_when: false + +- hosts: lb + become: yes + tasks: + - name: Stop services + service: name={{ item }} state=stopped + with_items: + - haproxy + failed_when: false + +- hosts: nodes + become: yes + tasks: + - name: unmask services + command: systemctl unmask "{{ item }}" + changed_when: False + failed_when: False + with_items: + - firewalld + + - name: Remove packages + action: "{{ ansible_pkg_mgr }} name={{ item }} state=absent" + when: not is_atomic | bool + with_items: + - atomic-enterprise + - atomic-enterprise-node + - atomic-enterprise-sdn-ovs + - atomic-openshift + - atomic-openshift-clients + - atomic-openshift-node + - atomic-openshift-sdn-ovs + - cockpit-bridge + - cockpit-docker + - cockpit-shell + - cockpit-ws + - kubernetes-client + - openshift + - openshift-node + - openshift-sdn + - openshift-sdn-ovs + - openvswitch + - origin + - origin-clients + - origin-node + - origin-sdn-ovs + - tuned-profiles-atomic-enterprise-node + - tuned-profiles-atomic-openshift-node + - tuned-profiles-openshift-node + - tuned-profiles-origin-node + + - name: Remove flannel package + action: "{{ ansible_pkg_mgr }} name=flannel state=absent" + when: openshift_use_flannel | default(false) | bool and not is_atomic | bool + + - shell: systemctl reset-failed + changed_when: False + + - shell: systemctl daemon-reload + changed_when: False + + - name: Remove br0 interface + shell: ovs-vsctl del-br br0 + changed_when: False + failed_when: False + + - name: Remove linux interfaces + shell: ip link del "{{ item }}" + changed_when: False + failed_when: False + with_items: + - lbr0 + - vlinuxbr + - vovsbr + + - shell: find /var/lib/origin/openshift.local.volumes -type d -exec umount {} \; 2>/dev/null || true + changed_when: False + + - shell: find /var/lib/atomic-enterprise/openshift.local.volumes -type d -exec umount {} \; 2>/dev/null || true + changed_when: False + + - shell: find /var/lib/openshift/openshift.local.volumes -type d -exec umount {} \; 2>/dev/null || true + changed_when: False + + - shell: docker rm -f "{{ item }}"-master "{{ item }}"-node + changed_when: False + failed_when: False + with_items: + - openshift-enterprise + - atomic-enterprise + - origin + + - shell: docker ps -a | grep Exited | egrep "{{ item }}" | awk '{print $1}' + changed_when: False + failed_when: False + register: exited_containers_to_delete + with_items: + - aep3.*/aep + - aep3.*/node + - aep3.*/openvswitch + - openshift3/ose + - openshift3/node + - openshift3/openvswitch + - openshift/origin + + - shell: "docker rm {{ item.stdout_lines | join(' ') }}" + changed_when: False + failed_when: False + with_items: "{{ exited_containers_to_delete.results }}" + + - shell: docker images | egrep {{ item }} | awk '{ print $3 }' + changed_when: False + failed_when: False + register: images_to_delete + with_items: + - registry\.access\..*redhat\.com/openshift3 + - registry\.access\..*redhat\.com/aep3 + - registry\.qe\.openshift\.com/.* + - registry\.access\..*redhat\.com/rhel7/etcd + - docker.io/openshift + when: openshift_uninstall_images | default(True) | bool + + - shell: "docker rmi -f {{ item.stdout_lines | join(' ') }}" + changed_when: False + failed_when: False + with_items: "{{ images_to_delete.results }}" + when: openshift_uninstall_images | default(True) | bool + + - name: Remove sdn drop files + file: + path: /run/openshift-sdn + state: absent + + - name: Remove remaining files + file: path={{ item }} state=absent + with_items: + - /etc/ansible/facts.d/openshift.fact + - /etc/atomic-enterprise + - /etc/dnsmasq.d/origin-dns.conf + - /etc/dnsmasq.d/origin-upstream-dns.conf + - /etc/NetworkManager/dispatcher.d/99-origin-dns.sh + - /etc/openshift + - /etc/openshift-sdn + - /etc/origin + - /etc/sysconfig/atomic-enterprise-node + - /etc/sysconfig/atomic-openshift-node + - /etc/sysconfig/atomic-openshift-node-dep + - /etc/sysconfig/openshift-node + - /etc/sysconfig/openshift-node-dep + - /etc/sysconfig/openvswitch + - /etc/sysconfig/origin-node + - /etc/sysconfig/origin-node + - /etc/sysconfig/origin-node-dep + - /etc/systemd/system/atomic-openshift-node-dep.service + - /etc/systemd/system/atomic-openshift-node.service + - /etc/systemd/system/atomic-openshift-node.service.wants + - /etc/systemd/system/docker.service.d/docker-sdn-ovs.conf + - /etc/systemd/system/openvswitch.service + - /etc/systemd/system/origin-node-dep.service + - /etc/systemd/system/origin-node.service + - /etc/systemd/system/origin-node.service.wants + - /run/openshift-sdn + - /var/lib/atomic-enterprise + - /var/lib/openshift + - /var/lib/origin + + - name: restart docker + service: name=docker state=restarted + + - name: restart NetworkManager + service: name=NetworkManager state=restarted + + +- hosts: masters + become: yes + tasks: + - name: unmask services + command: systemctl unmask "{{ item }}" + changed_when: False + failed_when: False + with_items: + - firewalld + - atomic-openshift-master + + - name: Remove packages + action: "{{ ansible_pkg_mgr }} name={{ item }} state=absent" + when: not is_atomic | bool + with_items: + - atomic-enterprise + - atomic-enterprise-master + - atomic-openshift + - atomic-openshift-clients + - atomic-openshift-master + - cockpit-bridge + - cockpit-docker + - cockpit-shell + - cockpit-ws + - corosync + - kubernetes-client + - openshift + - openshift-master + - origin + - origin-clients + - origin-master + - pacemaker + - pcs + + - shell: systemctl reset-failed + changed_when: False + + - shell: systemctl daemon-reload + changed_when: False + + - name: Remove remaining files + file: path={{ item }} state=absent + with_items: + - "~{{ ansible_ssh_user }}/.kube" + - /etc/ansible/facts.d/openshift.fact + - /etc/atomic-enterprise + - /etc/corosync + - /etc/openshift + - /etc/openshift-sdn + - /etc/origin + - /etc/systemd/system/atomic-openshift-master.service + - /etc/systemd/system/atomic-openshift-master-api.service + - /etc/systemd/system/atomic-openshift-master-controllers.service + - /etc/systemd/system/origin-master.service + - /etc/systemd/system/origin-master-api.service + - /etc/systemd/system/origin-master-controllers.service + - /etc/systemd/system/openvswitch.service + - /etc/sysconfig/atomic-enterprise-master + - /etc/sysconfig/atomic-enterprise-master-api + - /etc/sysconfig/atomic-enterprise-master-controllers + - /etc/sysconfig/atomic-openshift-master + - /etc/sysconfig/atomic-openshift-master-api + - /etc/sysconfig/atomic-openshift-master-controllers + - /etc/sysconfig/origin-master + - /etc/sysconfig/origin-master-api + - /etc/sysconfig/origin-master-controllers + - /etc/sysconfig/openshift-master + - /etc/sysconfig/openvswitch + - /etc/sysconfig/origin-master + - /etc/sysconfig/origin-master-api + - /etc/sysconfig/origin-master-controllers + - /root/.kube + - /usr/share/openshift/examples + - /var/lib/atomic-enterprise + - /var/lib/openshift + - /var/lib/origin + - /var/lib/pacemaker + - /var/lib/pcsd + - /usr/lib/systemd/system/atomic-openshift-master-api.service + - /usr/lib/systemd/system/atomic-openshift-master-controllers.service + - /usr/lib/systemd/system/origin-master-api.service + - /usr/lib/systemd/system/origin-master-controllers.service + - /usr/local/bin/openshift + - /usr/local/bin/oadm + - /usr/local/bin/oc + - /usr/local/bin/kubectl + - /etc/flannel + + # Since we are potentially removing the systemd unit files for separated + # master-api and master-controllers services, so we need to reload the + # systemd configuration manager + - name: Reload systemd manager configuration + command: systemctl daemon-reload + +- hosts: etcd + become: yes + tasks: + - name: unmask services + command: systemctl unmask "{{ item }}" + changed_when: False + failed_when: False + with_items: + - etcd + - etcd3 + - firewalld + + - name: Stop additional atomic services + service: name={{ item }} state=stopped + when: is_containerized | bool + with_items: + - etcd_container + failed_when: false + + - name: Remove packages + action: "{{ ansible_pkg_mgr }} name={{ item }} state=absent" + when: not is_atomic | bool + with_items: + - etcd + - etcd3 + + - shell: systemctl reset-failed + changed_when: False + + - shell: systemctl daemon-reload + changed_when: False + + - name: Remove remaining files + file: path={{ item }} state=absent + with_items: + - /etc/ansible/facts.d/openshift.fact + - /etc/etcd + - /etc/systemd/system/etcd_container.service + - /etc/profile.d/etcdctl.sh + + # Intenationally using rm command over file module because if someone had mounted a filesystem + # at /var/lib/etcd then the contents was not removed correctly + - name: Remove etcd data + shell: rm -rf /var/lib/etcd/* + args: + warn: no + failed_when: false + +- hosts: lb + become: yes + tasks: + - name: unmask services + command: systemctl unmask "{{ item }}" + changed_when: False + failed_when: False + with_items: + - firewalld + + - name: Remove packages + action: "{{ ansible_pkg_mgr }} name={{ item }} state=absent" + when: not is_atomic | bool + with_items: + - haproxy + + - shell: systemctl reset-failed + changed_when: False + + - shell: systemctl daemon-reload + changed_when: False + + - name: Remove remaining files + file: path={{ item }} state=absent + with_items: + - /etc/ansible/facts.d/openshift.fact + - /var/lib/haproxy diff --git a/playbooks/adhoc/zabbix_setup/clean_zabbix.yml b/playbooks/adhoc/zabbix_setup/clean_zabbix.yml new file mode 100644 index 000000000..09f7c76cc --- /dev/null +++ b/playbooks/adhoc/zabbix_setup/clean_zabbix.yml @@ -0,0 +1,60 @@ +--- +- hosts: localhost + gather_facts: no + connection: local + become: no + vars: + g_server: http://localhost:8080/zabbix/api_jsonrpc.php + g_user: '' + g_password: '' + + roles: + - lib_zabbix + + post_tasks: + - name: CLEAN List template for heartbeat + zbx_template: + zbx_server: "{{ g_server }}" + zbx_user: "{{ g_user }}" + zbx_password: "{{ g_password }}" + state: list + name: 'Template Heartbeat' + register: templ_heartbeat + + - name: CLEAN List template app zabbix server + zbx_template: + zbx_server: "{{ g_server }}" + zbx_user: "{{ g_user }}" + zbx_password: "{{ g_password }}" + state: list + name: 'Template App Zabbix Server' + register: templ_zabbix_server + + - name: CLEAN List template app zabbix server + zbx_template: + zbx_server: "{{ g_server }}" + zbx_user: "{{ g_user }}" + zbx_password: "{{ g_password }}" + state: list + name: 'Template App Zabbix Agent' + register: templ_zabbix_agent + + - name: CLEAN List all templates + zbx_template: + zbx_server: "{{ g_server }}" + zbx_user: "{{ g_user }}" + zbx_password: "{{ g_password }}" + state: list + register: templates + + - debug: var=templ_heartbeat.results + + - name: Remove templates if heartbeat template is missing + zbx_template: + zbx_server: "{{ g_server }}" + zbx_user: "{{ g_user }}" + zbx_password: "{{ g_password }}" + name: "{{ item }}" + state: absent + with_items: "{{ templates.results | difference(templ_zabbix_agent.results) | difference(templ_zabbix_server.results) | oo_collect('host') }}" + when: templ_heartbeat.results | length == 0 diff --git a/playbooks/adhoc/zabbix_setup/filter_plugins b/playbooks/adhoc/zabbix_setup/filter_plugins new file mode 120000 index 000000000..b0b7a3414 --- /dev/null +++ b/playbooks/adhoc/zabbix_setup/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins/
\ No newline at end of file diff --git a/playbooks/adhoc/zabbix_setup/oo-clean-zaio.yml b/playbooks/adhoc/zabbix_setup/oo-clean-zaio.yml new file mode 100755 index 000000000..0fe65b338 --- /dev/null +++ b/playbooks/adhoc/zabbix_setup/oo-clean-zaio.yml @@ -0,0 +1,7 @@ +#!/usr/bin/env ansible-playbook +--- +- include: clean_zabbix.yml + vars: + g_server: http://localhost/zabbix/api_jsonrpc.php + g_user: Admin + g_password: zabbix diff --git a/playbooks/adhoc/zabbix_setup/oo-config-zaio.yml b/playbooks/adhoc/zabbix_setup/oo-config-zaio.yml new file mode 100755 index 000000000..2f1d003ff --- /dev/null +++ b/playbooks/adhoc/zabbix_setup/oo-config-zaio.yml @@ -0,0 +1,19 @@ +#!/usr/bin/ansible-playbook +--- +- hosts: localhost + gather_facts: no + connection: local + become: no + vars: + g_server: http://localhost/zabbix/api_jsonrpc.php + g_user: Admin + g_password: zabbix + g_zbx_scriptrunner_user: scriptrunner + g_zbx_scriptrunner_bastion_host: specialhost.example.com + roles: + - role: os_zabbix + ozb_server: "{{ g_server }}" + ozb_user: "{{ g_user }}" + ozb_password: "{{ g_password }}" + ozb_scriptrunner_user: "{{ g_zbx_scriptrunner_user }}" + ozb_scriptrunner_bastion_host: "{{ g_zbx_scriptrunner_bastion_host }}" diff --git a/playbooks/adhoc/noc/roles b/playbooks/adhoc/zabbix_setup/roles index 20c4c58cf..20c4c58cf 120000 --- a/playbooks/adhoc/noc/roles +++ b/playbooks/adhoc/zabbix_setup/roles diff --git a/playbooks/aws/ansible-tower/config.yml b/playbooks/aws/ansible-tower/config.yml deleted file mode 100644 index efd1b9911..000000000 --- a/playbooks/aws/ansible-tower/config.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -- name: "populate oo_hosts_to_config host group if needed" - hosts: localhost - gather_facts: no - tasks: - - name: Evaluate oo_host_group_exp if it's set - add_host: "name={{ item }} groups=oo_hosts_to_config" - with_items: "{{ oo_host_group_exp | default(['']) }}" - when: oo_host_group_exp is defined - -- name: "Configure instances" - hosts: oo_hosts_to_config - connection: ssh - user: root - vars_files: - - vars.yml - - "vars.{{ oo_env }}.yml" - roles: - - os_ipv6_disable - - ansible - - ansible_tower - - os_env_extras diff --git a/playbooks/aws/ansible-tower/launch.yml b/playbooks/aws/ansible-tower/launch.yml deleted file mode 100644 index 850238ffb..000000000 --- a/playbooks/aws/ansible-tower/launch.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- -- name: Launch instance(s) - hosts: localhost - connection: local - gather_facts: no - - vars: - inst_region: us-east-1 - rhel7_ami: ami-9101c8fa - user_data_file: user_data.txt - - vars_files: - - vars.yml - - "vars.{{ oo_env }}.yml" - - tasks: - - name: Launch instances in VPC - ec2: - state: present - region: "{{ inst_region }}" - keypair: mmcgrath_libra - group_id: "{{ oo_security_group_ids }}" - instance_type: c4.xlarge - image: "{{ rhel7_ami }}" - count: "{{ oo_new_inst_names | length }}" - user_data: "{{ lookup('file', user_data_file) }}" - wait: yes - assign_public_ip: "{{ oo_assign_public_ip }}" - vpc_subnet_id: "{{ oo_vpc_subnet_id }}" - register: ec2 - - - name: Add Name and environment tags to instances - ec2_tag: "resource={{ item.1.id }} region={{ inst_region }} state=present" - with_together: - - oo_new_inst_names - - ec2.instances - args: - tags: - Name: "{{ item.0 }}" - - - name: Add other tags to instances - ec2_tag: "resource={{ item.id }} region={{ inst_region }} state=present" - with_items: ec2.instances - args: - tags: "{{ oo_new_inst_tags }}" - - - name: Add new instances public IPs to oo_hosts_to_config - add_host: "hostname={{ item.0 }} ansible_ssh_host={{ item.1.public_ip }} groupname=oo_hosts_to_config" - with_together: - - oo_new_inst_names - - ec2.instances - - - debug: var=ec2 - - - name: Wait for ssh - wait_for: "port=22 host={{ item.public_ip }}" - with_items: ec2.instances - - - name: Wait for root user setup - command: "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null root@{{ item.public_ip }} echo root user is setup" - register: result - until: result.rc == 0 - retries: 20 - delay: 10 - with_items: ec2.instances - -- name: Initial setup - hosts: oo_hosts_to_config - user: root - gather_facts: true - - tasks: - - - name: Yum update - yum: name=* state=latest - -# Apply the configs, seprate so that just the configs can be run by themselves -- include: config.yml diff --git a/playbooks/aws/ansible-tower/user_data.txt b/playbooks/aws/ansible-tower/user_data.txt deleted file mode 100644 index 643d17c32..000000000 --- a/playbooks/aws/ansible-tower/user_data.txt +++ /dev/null @@ -1,6 +0,0 @@ -#cloud-config -disable_root: 0 - -system_info: - default_user: - name: root diff --git a/playbooks/aws/ansible-tower/vars.ops.yml b/playbooks/aws/ansible-tower/vars.ops.yml deleted file mode 100644 index feb5d786a..000000000 --- a/playbooks/aws/ansible-tower/vars.ops.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -oo_env_long: operations -oo_zabbix_hostgroups: ['OPS Environment'] -oo_vpc_subnet_id: subnet-4f0bdd38 # USE OPS -oo_assign_public_ip: yes -oo_security_group_ids: - - sg-02c2f267 # Libra (vpc) - - sg-7fc4f41a # ops (vpc) - - sg-4dc26829 # ops_tower (vpc) diff --git a/playbooks/aws/ansible-tower/vars.yml b/playbooks/aws/ansible-tower/vars.yml deleted file mode 100644 index ed97d539c..000000000 --- a/playbooks/aws/ansible-tower/vars.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/playbooks/aws/openshift-cluster/add_nodes.yml b/playbooks/aws/openshift-cluster/add_nodes.yml new file mode 100644 index 000000000..0e8eb90c1 --- /dev/null +++ b/playbooks/aws/openshift-cluster/add_nodes.yml @@ -0,0 +1,35 @@ +--- +- name: Launch instance(s) + hosts: localhost + connection: local + become: no + gather_facts: no + vars_files: + - vars.yml + vars: + oo_extend_env: True + tasks: + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "compute" + count: "{{ num_nodes }}" + - include: tasks/launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" + + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "infra" + count: "{{ num_infra }}" + - include: tasks/launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" + +- include: scaleup.yml +- include: list.yml diff --git a/playbooks/aws/openshift-cluster/cluster_hosts.yml b/playbooks/aws/openshift-cluster/cluster_hosts.yml new file mode 100644 index 000000000..119b376aa --- /dev/null +++ b/playbooks/aws/openshift-cluster/cluster_hosts.yml @@ -0,0 +1,21 @@ +--- +g_all_hosts: "{{ groups['tag_clusterid_' ~ cluster_id] | default([]) + | intersect(groups['tag_environment_' ~ cluster_env] | default([])) }}" + +g_etcd_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type_etcd'] | default([])) }}" + +g_lb_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type_lb'] | default([])) }}" + +g_nfs_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type_nfs'] | default([])) }}" + +g_master_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type_master'] | default([])) }}" + +g_new_master_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type_new_master'] | default([])) }}" + +g_node_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type_node'] | default([])) }}" + +g_new_node_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type_new_node'] | default([])) }}" + +g_infra_hosts: "{{ g_node_hosts | intersect(groups['tag_sub-host-type_infra'] | default([])) }}" + +g_compute_hosts: "{{ g_node_hosts | intersect(groups['tag_sub-host-type_compute'] | default([])) }}" diff --git a/playbooks/aws/openshift-cluster/config.yml b/playbooks/aws/openshift-cluster/config.yml index 6ee539c7e..05cfe7d6e 100644 --- a/playbooks/aws/openshift-cluster/config.yml +++ b/playbooks/aws/openshift-cluster/config.yml @@ -1,22 +1,39 @@ --- +- include: ../../common/openshift-cluster/verify_ansible_version.yml + - hosts: localhost gather_facts: no - vars_files: - - vars.yml tasks: - - set_fact: - g_ssh_user_tmp: "{{ deployment_vars[deployment_type].ssh_user }}" - g_sudo_tmp: "{{ deployment_vars[deployment_type].sudo }}" + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml - include: ../../common/openshift-cluster/config.yml vars: - g_etcd_group: "{{ 'tag_env-host-type_' ~ cluster_id ~ '-openshift-etcd' }}" - g_masters_group: "{{ 'tag_env-host-type_' ~ cluster_id ~ '-openshift-master' }}" - g_nodes_group: "{{ 'tag_env-host-type_' ~ cluster_id ~ '-openshift-node' }}" - g_ssh_user: "{{ hostvars.localhost.g_ssh_user_tmp }}" - g_sudo: "{{ hostvars.localhost.g_sudo_tmp }}" + g_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + g_sudo: "{{ deployment_vars[deployment_type].become }}" + g_nodeonmaster: true openshift_cluster_id: "{{ cluster_id }}" - openshift_debug_level: 4 + openshift_debug_level: "{{ debug_level }}" openshift_deployment_type: "{{ deployment_type }}" - openshift_hostname: "{{ ec2_private_ip_address }}" openshift_public_hostname: "{{ ec2_ip_address }}" + openshift_hosted_registry_selector: 'type=infra' + openshift_hosted_router_selector: 'type=infra' + openshift_node_labels: + region: "{{ deployment_vars[deployment_type].region }}" + type: "{{ hostvars[inventory_hostname]['ec2_tag_sub-host-type'] }}" + openshift_master_cluster_method: 'native' + openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}" + os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}" + openshift_use_flannel: "{{ lookup('oo_option', 'use_flannel') }}" + openshift_use_fluentd: "{{ lookup('oo_option', 'use_fluentd') }}" + openshift_use_dnsmasq: false diff --git a/playbooks/aws/openshift-cluster/launch.yml b/playbooks/aws/openshift-cluster/launch.yml index 5db87fa90..3edace493 100644 --- a/playbooks/aws/openshift-cluster/launch.yml +++ b/playbooks/aws/openshift-cluster/launch.yml @@ -2,35 +2,48 @@ - name: Launch instance(s) hosts: localhost connection: local + become: no gather_facts: no vars_files: - vars.yml - - ["vars.{{ deployment_type }}.{{ cluster_id }}.yml", vars.defaults.yml] tasks: - - fail: - msg: Deployment type not supported for aws provider yet - when: deployment_type == 'enterprise' - - - include: ../../common/openshift-cluster/set_etcd_launch_facts_tasks.yml + - include: ../../common/openshift-cluster/tasks/set_etcd_launch_facts.yml - include: tasks/launch_instances.yml vars: instances: "{{ etcd_names }}" cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" + g_sub_host_type: "default" - - include: ../../common/openshift-cluster/set_master_launch_facts_tasks.yml + - include: ../../common/openshift-cluster/tasks/set_master_launch_facts.yml - include: tasks/launch_instances.yml vars: instances: "{{ master_names }}" cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" + g_sub_host_type: "default" - - include: ../../common/openshift-cluster/set_node_launch_facts_tasks.yml + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "compute" + count: "{{ num_nodes }}" - include: tasks/launch_instances.yml vars: instances: "{{ node_names }}" cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" + + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "infra" + count: "{{ num_infra }}" + - include: tasks/launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" - add_host: name: "{{ master_names.0 }}" @@ -38,9 +51,4 @@ when: master_names is defined and master_names.0 is defined - include: update.yml - -- include: ../../common/openshift-cluster/create_services.yml - vars: - g_svc_master: "{{ service_master }}" - - include: list.yml diff --git a/playbooks/aws/openshift-cluster/library/ec2_ami_find.py b/playbooks/aws/openshift-cluster/library/ec2_ami_find.py index 29e594a65..2b1db62d8 100644 --- a/playbooks/aws/openshift-cluster/library/ec2_ami_find.py +++ b/playbooks/aws/openshift-cluster/library/ec2_ami_find.py @@ -158,7 +158,7 @@ EXAMPLES = ''' # Launch an EC2 instance - ec2: image: "{{ ami_search.results[0].ami_id }}" - instance_type: m3.medium + instance_type: m4.medium key_name: mykey wait: yes ''' diff --git a/playbooks/aws/openshift-cluster/list.yml b/playbooks/aws/openshift-cluster/list.yml index 04fcdc0a1..ed8aac398 100644 --- a/playbooks/aws/openshift-cluster/list.yml +++ b/playbooks/aws/openshift-cluster/list.yml @@ -2,10 +2,12 @@ - name: Generate oo_list_hosts group hosts: localhost gather_facts: no + connection: local + become: no vars_files: - vars.yml tasks: - - set_fact: scratch_group=tag_env_{{ cluster_id }} + - set_fact: scratch_group=tag_clusterid_{{ cluster_id }} when: cluster_id != '' - set_fact: scratch_group=all when: cluster_id == '' @@ -13,12 +15,9 @@ name: "{{ item }}" groups: oo_list_hosts ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[scratch_group] | default([]) | difference(['localhost']) - -- name: List Hosts - hosts: oo_list_hosts - gather_facts: no - tasks: + ansible_become: "{{ deployment_vars[deployment_type].become }}" + oo_public_ipv4: "{{ hostvars[item].ec2_ip_address }}" + oo_private_ipv4: "{{ hostvars[item].ec2_private_ip_address }}" + with_items: "{{ groups[scratch_group] | default([]) | difference(['localhost']) }}" - debug: - msg: "public ip:{{ hostvars[inventory_hostname].ec2_ip_address }} private ip:{{ hostvars[inventory_hostname].ec2_private_ip_address }}" + msg: "{{ hostvars | oo_select_keys(groups[scratch_group] | default([])) | oo_pretty_print_cluster }}" diff --git a/playbooks/aws/openshift-cluster/scaleup.yml b/playbooks/aws/openshift-cluster/scaleup.yml new file mode 100644 index 000000000..6fa9142a0 --- /dev/null +++ b/playbooks/aws/openshift-cluster/scaleup.yml @@ -0,0 +1,32 @@ +--- + +- hosts: localhost + gather_facts: no + connection: local + become: no + vars_files: + - vars.yml + tasks: + - name: Evaluate oo_hosts_to_update + add_host: + name: "{{ item }}" + groups: oo_hosts_to_update + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ groups.nodes_to_add }}" + +- include: ../../common/openshift-cluster/update_repos_and_packages.yml + +- include: ../../common/openshift-cluster/scaleup.yml + vars_files: + - ../../aws/openshift-cluster/vars.yml + - ../../aws/openshift-cluster/cluster_hosts.yml + vars: + g_new_node_hosts: "{{ groups.nodes_to_add }}" + g_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + g_sudo: "{{ deployment_vars[deployment_type].become }}" + g_nodeonmaster: true + openshift_cluster_id: "{{ cluster_id }}" + openshift_debug_level: "{{ debug_level }}" + openshift_deployment_type: "{{ deployment_type }}" + openshift_public_hostname: "{{ ec2_ip_address }}" diff --git a/playbooks/aws/openshift-cluster/service.yml b/playbooks/aws/openshift-cluster/service.yml index 25cf48505..f7f4812bb 100644 --- a/playbooks/aws/openshift-cluster/service.yml +++ b/playbooks/aws/openshift-cluster/service.yml @@ -1,9 +1,12 @@ --- - name: Call same systemctl command for openshift on all instance(s) hosts: localhost + connection: local + become: no gather_facts: no vars_files: - vars.yml + - cluster_hosts.yml tasks: - fail: msg="cluster_id is required to be injected in this playbook" when: cluster_id is not defined @@ -13,16 +16,16 @@ name: "{{ item }}" groups: g_service_masters ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups["tag_env-host-type_{{ cluster_id }}-openshift-master"] | default([]) + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ master_hosts | default([]) }}" - name: Evaluate g_service_nodes add_host: name: "{{ item }}" groups: g_service_nodes ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups["tag_env-host-type_{{ cluster_id }}-openshift-node"] | default([]) + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ node_hosts | default([]) }}" - include: ../../common/openshift-node/service.yml - include: ../../common/openshift-master/service.yml diff --git a/playbooks/aws/openshift-cluster/tasks/launch_instances.yml b/playbooks/aws/openshift-cluster/tasks/launch_instances.yml index 25a87aaf6..4d76d3bfe 100644 --- a/playbooks/aws/openshift-cluster/tasks/launch_instances.yml +++ b/playbooks/aws/openshift-cluster/tasks/launch_instances.yml @@ -2,74 +2,68 @@ - set_fact: created_by: "{{ lookup('env', 'LOGNAME')|default(cluster, true) }}" docker_vol_ephemeral: "{{ lookup('env', 'os_docker_vol_ephemeral') | default(false, true) }}" - env: "{{ cluster }}" - env_host_type: "{{ cluster }}-openshift-{{ type }}" + cluster: "{{ cluster_id }}" + env: "{{ cluster_env }}" host_type: "{{ type }}" + sub_host_type: "{{ g_sub_host_type }}" - set_fact: - ec2_region: "{{ lookup('env', 'ec2_region') - | default(deployment_vars[deployment_type].region, true) }}" - when: ec2_region is not defined -- set_fact: - ec2_image_name: "{{ lookup('env', 'ec2_image_name') - | default(deployment_vars[deployment_type].image_name, true) }}" - when: ec2_image_name is not defined and ec2_image is not defined -- set_fact: - ec2_image: "{{ lookup('env', 'ec2_image') - | default(deployment_vars[deployment_type].image, true) }}" - when: ec2_image is not defined and not ec2_image_name + ec2_instance_type: "{{ lookup('env', 'ec2_master_instance_type') | default(deployment_vars[deployment_type].type, true) }}" + ec2_security_groups: "{{ lookup('env', 'ec2_master_security_groups') | default(deployment_vars[deployment_type].security_groups, true) }}" + when: host_type == "master" and sub_host_type == "default" + - set_fact: - ec2_instance_type: "{{ lookup('env', 'ec2_instance_type') - | default(deployment_vars[deployment_type].type, true) }}" - when: ec2_instance_type is not defined + ec2_instance_type: "{{ lookup('env', 'ec2_etcd_instance_type') | default(deployment_vars[deployment_type].type, true) }}" + ec2_security_groups: "{{ lookup('env', 'ec2_etcd_security_groups') | default(deployment_vars[deployment_type].security_groups, true) }}" + when: host_type == "etcd" and sub_host_type == "default" + - set_fact: - ec2_keypair: "{{ lookup('env', 'ec2_keypair') - | default(deployment_vars[deployment_type].keypair, true) }}" - when: ec2_keypair is not defined + ec2_instance_type: "{{ lookup('env', 'ec2_infra_instance_type') | default(deployment_vars[deployment_type].type, true) }}" + ec2_security_groups: "{{ lookup('env', 'ec2_infra_security_groups') | default(deployment_vars[deployment_type].security_groups, true) }}" + when: host_type == "node" and sub_host_type == "infra" + - set_fact: - ec2_vpc_subnet: "{{ lookup('env', 'ec2_vpc_subnet') - | default(deployment_vars[deployment_type].vpc_subnet, true) }}" - when: ec2_vpc_subnet is not defined + ec2_instance_type: "{{ lookup('env', 'ec2_node_instance_type') | default(deployment_vars[deployment_type].type, true) }}" + ec2_security_groups: "{{ lookup('env', 'ec2_node_security_groups') | default(deployment_vars[deployment_type].security_groups, true) }}" + when: host_type == "node" and sub_host_type == "compute" + - set_fact: - ec2_assign_public_ip: "{{ lookup('env', 'ec2_assign_public_ip') - | default(deployment_vars[deployment_type].assign_public_ip, true) }}" - when: ec2_assign_public_ip is not defined + ec2_instance_type: "{{ deployment_vars[deployment_type].type }}" + when: ec2_instance_type is not defined - set_fact: - ec2_security_groups: "{{ lookup('env', 'ec2_security_groups') - | default(deployment_vars[deployment_type].security_groups, true) }}" + ec2_security_groups: "{{ deployment_vars[deployment_type].security_groups }}" when: ec2_security_groups is not defined - name: Find amis for deployment_type ec2_ami_find: - region: "{{ ec2_region }}" - ami_id: "{{ ec2_image | default(omit, true) }}" - name: "{{ ec2_image_name | default(omit, true) }}" + region: "{{ deployment_vars[deployment_type].region }}" + ami_id: "{{ deployment_vars[deployment_type].image }}" + name: "{{ deployment_vars[deployment_type].image_name }}" register: ami_result - fail: msg="Could not find requested ami" when: not ami_result.results - set_fact: - latest_ami: "{{ ami_result.results | oo_ami_selector(ec2_image_name) }}" - user_data: "{{ lookup('template', '../templates/user_data.j2') }}" + latest_ami: "{{ ami_result.results | oo_ami_selector(deployment_vars[deployment_type].image_name) }}" volume_defs: etcd: root: volume_size: "{{ lookup('env', 'os_etcd_root_vol_size') | default(25, true) }}" device_type: "{{ lookup('env', 'os_etcd_root_vol_type') | default('gp2', true) }}" iops: "{{ lookup('env', 'os_etcd_root_vol_iops') | default(500, true) }}" - etcd: - volume_size: "{{ lookup('env', 'os_etcd_vol_size') | default(32, true) }}" - device_type: "{{ lookup('env', 'os_etcd_vol_type') | default('gp2', true) }}" - iops: "{{ lookup('env', 'os_etcd_vol_iops') | default(500, true) }}" master: root: volume_size: "{{ lookup('env', 'os_master_root_vol_size') | default(25, true) }}" device_type: "{{ lookup('env', 'os_master_root_vol_type') | default('gp2', true) }}" iops: "{{ lookup('env', 'os_master_root_vol_iops') | default(500, true) }}" + docker: + volume_size: "{{ lookup('env', 'os_docker_vol_size') | default(10, true) }}" + device_type: "{{ lookup('env', 'os_docker_vol_type') | default('gp2', true) }}" + iops: "{{ lookup('env', 'os_docker_vol_iops') | default(500, true) }}" node: root: - volume_size: "{{ lookup('env', 'os_node_root_vol_size') | default(25, true) }}" + volume_size: "{{ lookup('env', 'os_node_root_vol_size') | default(85, true) }}" device_type: "{{ lookup('env', 'os_node_root_vol_type') | default('gp2', true) }}" iops: "{{ lookup('env', 'os_node_root_vol_iops') | default(500, true) }}" docker: @@ -83,53 +77,105 @@ - name: Launch instance(s) ec2: state: present - region: "{{ ec2_region }}" - keypair: "{{ ec2_keypair }}" - group: "{{ ec2_security_groups }}" + region: "{{ deployment_vars[deployment_type].region }}" + keypair: "{{ deployment_vars[deployment_type].keypair }}" + group: "{{ deployment_vars[deployment_type].security_groups }}" instance_type: "{{ ec2_instance_type }}" - image: "{{ latest_ami }}" + image: "{{ deployment_vars[deployment_type].image }}" count: "{{ instances | length }}" - vpc_subnet_id: "{{ ec2_vpc_subnet | default(omit, true) }}" - assign_public_ip: "{{ ec2_assign_public_ip | default(omit, true) }}" - user_data: "{{ user_data }}" + vpc_subnet_id: "{{ deployment_vars[deployment_type].vpc_subnet }}" + assign_public_ip: "{{ deployment_vars[deployment_type].assign_public_ip }}" + user_data: "{{ lookup('template', '../templates/user_data.j2') }}" wait: yes instance_tags: created-by: "{{ created_by }}" - environment: "{{ env }}" - env: "{{ env }}" + clusterid: "{{ cluster }}" + environment: "{{ cluster_env }}" host-type: "{{ host_type }}" - env-host-type: "{{ env_host_type }}" + sub-host-type: "{{ sub_host_type }}" volumes: "{{ volumes }}" register: ec2 - name: Add Name tag to instances - ec2_tag: resource={{ item.1.id }} region={{ ec2_region }} state=present + ec2_tag: resource={{ item.1.id }} region={{ deployment_vars[deployment_type].region }} state=present with_together: - - instances - - ec2.instances + - "{{ instances }}" + - "{{ ec2.instances }}" args: tags: Name: "{{ item.0 }}" - set_fact: - instance_groups: tag_created-by_{{ created_by }}, tag_env_{{ env }}, tag_host-type_{{ host_type }}, tag_env-host-type_{{ env_host_type }} + instance_groups: > + tag_created-by_{{ created_by }}, tag_clusterid_{{ cluster }}, + tag_environment_{{ cluster_env }}, tag_host-type_{{ host_type }}, + tag_sub-host-type_{{ sub_host_type }} + +- set_fact: + node_label: + region: "{{ deployment_vars[deployment_type].region }}" + type: "{{sub_host_type}}" + when: host_type == "node" + +- set_fact: + node_label: + region: "{{ deployment_vars[deployment_type].region }}" + type: "{{host_type}}" + when: host_type != "node" + +- set_fact: + logrotate: + - name: syslog + path: | + /var/log/cron + /var/log/maillog + /var/log/messages + /var/log/secure + /var/log/spooler" + options: + - daily + - rotate 7 + - compress + - sharedscripts + - missingok + scripts: + postrotate: "/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true" - name: Add new instances groups and variables add_host: hostname: "{{ item.0 }}" ansible_ssh_host: "{{ item.1.dns_name }}" ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" groups: "{{ instance_groups }}" ec2_private_ip_address: "{{ item.1.private_ip }}" ec2_ip_address: "{{ item.1.public_ip }}" + ec2_tag_sub-host-type: "{{ sub_host_type }}" + openshift_node_labels: "{{ node_label }}" + logrotate_scripts: "{{ logrotate }}" + with_together: + - "{{ instances }}" + - "{{ ec2.instances }}" + +- name: Add new instances to nodes_to_add group if needed + add_host: + hostname: "{{ item.0 }}" + ansible_ssh_host: "{{ item.1.dns_name }}" + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + groups: nodes_to_add + ec2_private_ip_address: "{{ item.1.private_ip }}" + ec2_ip_address: "{{ item.1.public_ip }}" + openshift_node_labels: "{{ node_label }}" + logrotate_scripts: "{{ logrotate }}" with_together: - - instances - - ec2.instances + - "{{ instances }}" + - "{{ ec2.instances }}" + when: oo_extend_env is defined and oo_extend_env | bool - name: Wait for ssh wait_for: "port=22 host={{ item.dns_name }}" - with_items: ec2.instances + with_items: "{{ ec2.instances }}" - name: Wait for user setup command: "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null {{ hostvars[item.0].ansible_ssh_user }}@{{ item.1.dns_name }} echo {{ hostvars[item.0].ansible_ssh_user }} user is setup" @@ -138,5 +184,5 @@ retries: 20 delay: 10 with_together: - - instances - - ec2.instances + - "{{ instances }}" + - "{{ ec2.instances }}" diff --git a/playbooks/aws/openshift-cluster/templates/user_data.j2 b/playbooks/aws/openshift-cluster/templates/user_data.j2 index 82c2f4d57..b1087f9c4 100644 --- a/playbooks/aws/openshift-cluster/templates/user_data.j2 +++ b/playbooks/aws/openshift-cluster/templates/user_data.j2 @@ -1,30 +1,12 @@ #cloud-config -{% if type =='etcd' %} -cloud_config_modules: -- disk_setup -- mounts - -mounts: -- [ xvdb, /var/lib/etcd, xfs, "defaults" ] - -disk_setup: - xvdb: - table_type: mbr - layout: True - -fs_setup: -- label: etcd_storage - filesystem: xfs - device: /dev/xvdb - partition: auto -{% endif %} - -{% if type == 'node' %} +{% if type in ['node', 'master'] and 'docker' in volume_defs[type] %} mounts: - [ xvdb ] - [ ephemeral0 ] +{% endif %} write_files: +{% if type in ['node', 'master'] and 'docker' in volume_defs[type] %} - content: | DEVS=/dev/xvdb VG=docker_vg @@ -32,14 +14,9 @@ write_files: owner: root:root permissions: '0644' {% endif %} - -{% if deployment_type == 'online' %} -devices: ['/var'] # Workaround for https://bugs.launchpad.net/bugs/1455436 - -disable_root: 0 -growpart: - mode: auto - devices: ['/var'] -runcmd: -- xfs_growfs /var +{% if deployment_vars[deployment_type].become | bool %} +- path: /etc/sudoers.d/99-{{ deployment_vars[deployment_type].ssh_user }}-cloud-init-requiretty + permissions: 440 + content: | + Defaults:{{ deployment_vars[deployment_type].ssh_user }} !requiretty {% endif %} diff --git a/playbooks/aws/openshift-cluster/terminate.yml b/playbooks/aws/openshift-cluster/terminate.yml index 9c3703aba..7a8375d0e 100644 --- a/playbooks/aws/openshift-cluster/terminate.yml +++ b/playbooks/aws/openshift-cluster/terminate.yml @@ -1,51 +1,63 @@ --- - name: Terminate instance(s) hosts: localhost + connection: local + become: no gather_facts: no vars_files: - vars.yml tasks: - - set_fact: scratch_group=tag_env_{{ cluster_id }} - add_host: name: "{{ item }}" groups: oo_hosts_to_terminate ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[scratch_group] | default([]) | difference(['localhost']) + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ (groups['tag_clusterid_' ~ cluster_id] | default([])) | difference(['localhost']) }}" + +- name: Unsubscribe VMs + hosts: oo_hosts_to_terminate + roles: + - role: rhel_unsubscribe + when: deployment_type in ['atomic-enterprise', 'enterprise', 'openshift-enterprise'] and + ansible_distribution == "RedHat" and + lookup('oo_option', 'rhel_skip_subscription') | default(rhsub_skip, True) | + default('no', True) | lower in ['no', 'false'] - name: Terminate instances hosts: localhost connection: local + become: no gather_facts: no - vars: - host_vars: "{{ hostvars - | oo_select_keys(groups['oo_hosts_to_terminate']) }}" tasks: - name: Remove tags from instances - ec2_tag: resource={{ item.ec2_id }} region={{ item.ec2_region }} state=absent - args: + ec2_tag: + resource: "{{ hostvars[item]['ec2_id'] }}" + region: "{{ hostvars[item]['ec2_region'] }}" + state: absent tags: - env: "{{ item['ec2_tag_env'] }}" - host-type: "{{ item['ec2_tag_host-type'] }}" - env-host-type: "{{ item['ec2_tag_env-host-type'] }}" - with_items: host_vars + environment: "{{ hostvars[item]['ec2_tag_environment'] }}" + clusterid: "{{ hostvars[item]['ec2_tag_clusterid'] }}" + host-type: "{{ hostvars[item]['ec2_tag_host-type'] }}" + sub_host_type: "{{ hostvars[item]['ec2_tag_sub-host-type'] }}" + with_items: "{{ groups.oo_hosts_to_terminate }}" when: "'oo_hosts_to_terminate' in groups" - name: Terminate instances ec2: state: absent - instance_ids: ["{{ item.ec2_id }}"] - region: "{{ item.ec2_region }}" + instance_ids: ["{{ hostvars[item].ec2_id }}"] + region: "{{ hostvars[item].ec2_region }}" ignore_errors: yes register: ec2_term - with_items: host_vars + with_items: "{{ groups.oo_hosts_to_terminate }}" when: "'oo_hosts_to_terminate' in groups" # Fail if any of the instances failed to terminate with an error other # than 403 Forbidden - - fail: msg=Terminating instance {{ item.ec2_id }} failed with message {{ item.msg }} - when: "'oo_hosts_to_terminate' in groups and item.failed and not item.msg | search(\"error: EC2ResponseError: 403 Forbidden\")" - with_items: ec2_term.results + - fail: + msg: "Terminating instance {{ item.ec2_id }} failed with message {{ item.msg }}" + when: "'oo_hosts_to_terminate' in groups and item.has_key('failed') and item.failed" + with_items: "{{ ec2_term.results }}" - name: Stop instance if termination failed ec2: @@ -53,13 +65,13 @@ instance_ids: ["{{ item.item.ec2_id }}"] region: "{{ item.item.ec2_region }}" register: ec2_stop - when: "'oo_hosts_to_terminate' in groups and item.failed" - with_items: ec2_term.results + when: "'oo_hosts_to_terminate' in groups and item.has_key('failed') and item.failed" + with_items: "{{ ec2_term.results }}" - name: Rename stopped instances ec2_tag: resource={{ item.item.item.ec2_id }} region={{ item.item.item.ec2_region }} state=present args: tags: Name: "{{ item.item.item.ec2_tag_Name }}-terminate" - with_items: ec2_stop.results - when: "'oo_hosts_to_terminate' in groups" + with_items: "{{ ec2_stop.results }}" + when: ec2_stop | changed diff --git a/playbooks/aws/openshift-cluster/update.yml b/playbooks/aws/openshift-cluster/update.yml index e006aa74a..ed05d61ed 100644 --- a/playbooks/aws/openshift-cluster/update.yml +++ b/playbooks/aws/openshift-cluster/update.yml @@ -1,19 +1,33 @@ --- -- name: Populate oo_hosts_to_update group +- hosts: localhost + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + +- name: Update - Populate oo_hosts_to_update group hosts: localhost + connection: local + become: no gather_facts: no - vars_files: - - vars.yml tasks: - - name: Evaluate oo_hosts_to_update + - name: Update - Evaluate oo_hosts_to_update add_host: name: "{{ item }}" groups: oo_hosts_to_update ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: (groups["tag_env-host-type_{{ cluster_id }}-openshift-master"] | default([])) - | union(groups["tag_env-host-type_{{ cluster_id }}-openshift-node"] | default([])) - | union(groups["tag_env-host-type_{{ cluster_id }}-openshift-etcd"] | default([])) + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ g_all_hosts | default([]) }}" - include: ../../common/openshift-cluster/update_repos_and_packages.yml diff --git a/playbooks/aws/openshift-cluster/vars.defaults.yml b/playbooks/aws/openshift-cluster/vars.defaults.yml deleted file mode 100644 index ed97d539c..000000000 --- a/playbooks/aws/openshift-cluster/vars.defaults.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/playbooks/aws/openshift-cluster/vars.online.int.yml b/playbooks/aws/openshift-cluster/vars.online.int.yml deleted file mode 100644 index e406a7635..000000000 --- a/playbooks/aws/openshift-cluster/vars.online.int.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -ec2_image: ami-9101c8fa -ec2_image_name: libra-ops-rhel7* -ec2_region: us-east-1 -ec2_keypair: mmcgrath_libra -ec2_instance_type: m3.large -ec2_security_groups: [ 'int-v3' ] -ec2_vpc_subnet: subnet-987c0def -ec2_assign_public_ip: yes diff --git a/playbooks/aws/openshift-cluster/vars.online.prod.yml b/playbooks/aws/openshift-cluster/vars.online.prod.yml deleted file mode 100644 index e406a7635..000000000 --- a/playbooks/aws/openshift-cluster/vars.online.prod.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -ec2_image: ami-9101c8fa -ec2_image_name: libra-ops-rhel7* -ec2_region: us-east-1 -ec2_keypair: mmcgrath_libra -ec2_instance_type: m3.large -ec2_security_groups: [ 'int-v3' ] -ec2_vpc_subnet: subnet-987c0def -ec2_assign_public_ip: yes diff --git a/playbooks/aws/openshift-cluster/vars.online.stage.yml b/playbooks/aws/openshift-cluster/vars.online.stage.yml deleted file mode 100644 index e406a7635..000000000 --- a/playbooks/aws/openshift-cluster/vars.online.stage.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -ec2_image: ami-9101c8fa -ec2_image_name: libra-ops-rhel7* -ec2_region: us-east-1 -ec2_keypair: mmcgrath_libra -ec2_instance_type: m3.large -ec2_security_groups: [ 'int-v3' ] -ec2_vpc_subnet: subnet-987c0def -ec2_assign_public_ip: yes diff --git a/playbooks/aws/openshift-cluster/vars.yml b/playbooks/aws/openshift-cluster/vars.yml index 07e453f89..d774187f0 100644 --- a/playbooks/aws/openshift-cluster/vars.yml +++ b/playbooks/aws/openshift-cluster/vars.yml @@ -1,38 +1,33 @@ --- +debug_level: 2 + +deployment_rhel7_ent_base: + # rhel-7.1, requires cloud access subscription + image: "{{ lookup('oo_option', 'ec2_image') | default('ami-10251c7a', True) }}" + image_name: "{{ lookup('oo_option', 'ec2_image_name') | default(None, True) }}" + region: "{{ lookup('oo_option', 'ec2_region') | default('us-east-1', True) }}" + ssh_user: ec2-user + become: yes + keypair: "{{ lookup('oo_option', 'ec2_keypair') | default('libra', True) }}" + type: "{{ lookup('oo_option', 'ec2_instance_type') | default('m4.large', True) }}" + security_groups: "{{ lookup('oo_option', 'ec2_security_groups') | default([ 'public' ], True) }}" + vpc_subnet: "{{ lookup('oo_option', 'ec2_vpc_subnet') | default(omit, True) }}" + assign_public_ip: "{{ lookup('oo_option', 'ec2_assign_public_ip') | default(omit, True) }}" + deployment_vars: origin: - # fedora, since centos requires marketplace - image: ami-acd999c4 - image_name: - region: us-east-1 - ssh_user: fedora - sudo: yes - keypair: libra - type: m3.large - security_groups: [ 'public' ] - vpc_subnet: - assign_public_ip: - online: - # private ami - image: ami-7a9e9812 - image_name: openshift-rhel7_* - region: us-east-1 - ssh_user: root - sudo: no - keypair: libra - type: m3.large - security_groups: [ 'public' ] - vpc_subnet: - assign_public_ip: - enterprise: - # rhel-7.1, requires cloud access subscription - image: ami-10663b78 - image_name: - region: us-east-1 - ssh_user: ec2-user - sudo: yes - keypair: libra - type: m3.large - security_groups: [ 'public' ] - vpc_subnet: - assign_public_ip: + # centos-7, requires marketplace + image: "{{ lookup('oo_option', 'ec2_image') | default('ami-6d1c2007', True) }}" + image_name: "{{ lookup('oo_option', 'ec2_image_name') | default(None, True) }}" + region: "{{ lookup('oo_option', 'ec2_region') | default('us-east-1', True) }}" + ssh_user: centos + become: yes + keypair: "{{ lookup('oo_option', 'ec2_keypair') | default('libra', True) }}" + type: "{{ lookup('oo_option', 'ec2_instance_type') | default('m4.large', True) }}" + security_groups: "{{ lookup('oo_option', 'ec2_security_groups') | default([ 'public' ], True) }}" + vpc_subnet: "{{ lookup('oo_option', 'ec2_vpc_subnet') | default(omit, True) }}" + assign_public_ip: "{{ lookup('oo_option', 'ec2_assign_public_ip') | default(omit, True) }}" + + enterprise: "{{ deployment_rhel7_ent_base }}" + openshift-enterprise: "{{ deployment_rhel7_ent_base }}" + atomic-enterprise: "{{ deployment_rhel7_ent_base }}" diff --git a/playbooks/byo/openshift-cluster/cluster_hosts.yml b/playbooks/byo/openshift-cluster/cluster_hosts.yml new file mode 100644 index 000000000..658204c17 --- /dev/null +++ b/playbooks/byo/openshift-cluster/cluster_hosts.yml @@ -0,0 +1,19 @@ +--- +g_etcd_hosts: "{{ groups.etcd | default([]) }}" + +g_lb_hosts: "{{ groups.lb | default([]) }}" + +g_master_hosts: "{{ groups.masters | default([]) }}" + +g_new_master_hosts: "{{ groups.new_masters | default([]) }}" + +g_node_hosts: "{{ groups.nodes | default([]) }}" + +g_new_node_hosts: "{{ groups.new_nodes | default([]) }}" + +g_nfs_hosts: "{{ groups.nfs | default([]) }}" + +g_all_hosts: "{{ g_master_hosts | union(g_node_hosts) | union(g_etcd_hosts) + | union(g_lb_hosts) | union(g_nfs_hosts) + | union(g_new_node_hosts)| union(g_new_master_hosts) + | default([]) }}" diff --git a/playbooks/byo/openshift-cluster/config.yml b/playbooks/byo/openshift-cluster/config.yml index 2ee1d50a7..fccb03982 100644 --- a/playbooks/byo/openshift-cluster/config.yml +++ b/playbooks/byo/openshift-cluster/config.yml @@ -1,9 +1,31 @@ --- +- include: ../../common/openshift-cluster/verify_ansible_version.yml + +- name: Create initial host groups for localhost + hosts: localhost + connection: local + become: no + gather_facts: no + tags: + - always + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + +- name: Create initial host groups for all hosts + hosts: l_oo_all_hosts + gather_facts: no + tags: + - always + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + - include: ../../common/openshift-cluster/config.yml vars: - g_etcd_group: "{{ 'etcd' }}" - g_masters_group: "{{ 'masters' }}" - g_nodes_group: "{{ 'nodes' }}" openshift_cluster_id: "{{ cluster_id | default('default') }}" - openshift_debug_level: 4 + openshift_debug_level: "{{ debug_level | default(2) }}" openshift_deployment_type: "{{ deployment_type }}" + openshift_deployment_subtype: "{{ deployment_subtype | default(none) }}" diff --git a/playbooks/byo/openshift-cluster/enable_dnsmasq.yml b/playbooks/byo/openshift-cluster/enable_dnsmasq.yml new file mode 100644 index 000000000..0ba11a21b --- /dev/null +++ b/playbooks/byo/openshift-cluster/enable_dnsmasq.yml @@ -0,0 +1,20 @@ +--- +- include: ../../common/openshift-cluster/verify_ansible_version.yml + +- hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + +- include: ../../common/openshift-cluster/enable_dnsmasq.yml diff --git a/playbooks/byo/openshift-cluster/redeploy-certificates.yml b/playbooks/byo/openshift-cluster/redeploy-certificates.yml new file mode 100644 index 000000000..6d1247e0f --- /dev/null +++ b/playbooks/byo/openshift-cluster/redeploy-certificates.yml @@ -0,0 +1,22 @@ +--- +- include: ../../common/openshift-cluster/verify_ansible_version.yml + +- hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + +- include: ../../common/openshift-cluster/redeploy-certificates.yml + vars: + openshift_deployment_type: "{{ deployment_type }}" diff --git a/playbooks/byo/openshift-cluster/upgrades/README.md b/playbooks/byo/openshift-cluster/upgrades/README.md new file mode 100644 index 000000000..de4e34e2d --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/README.md @@ -0,0 +1,8 @@ +# Upgrade playbooks +The playbooks provided in this directory can be used for upgrading an existing +cluster. Additional notes for the associated upgrade playbooks are +provided in their respective directories. + +# Upgrades available +- [OpenShift Enterprise 3.2 to 3.3](v3_3/README.md) +- [OpenShift Enterprise 3.1 to 3.2](v3_2/README.md) diff --git a/playbooks/byo/openshift-cluster/upgrades/docker/docker_upgrade.yml b/playbooks/byo/openshift-cluster/upgrades/docker/docker_upgrade.yml new file mode 100644 index 000000000..834461e14 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/docker/docker_upgrade.yml @@ -0,0 +1,47 @@ + +- name: Check for appropriate Docker versions + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config + roles: + - openshift_facts + tasks: + - set_fact: + repoquery_cmd: "{{ 'dnf repoquery --latest-limit 1 -d 0' if ansible_pkg_mgr == 'dnf' else 'repoquery --plugins' }}" + + - fail: + msg: Cannot upgrade Docker on Atomic operating systems. + when: openshift.common.is_atomic | bool + + - include: ../../../../common/openshift-cluster/upgrades/docker/upgrade_check.yml + when: docker_upgrade is not defined or docker_upgrade | bool + + +# If a node fails, halt everything, the admin will need to clean up and we +# don't want to carry on, potentially taking out every node. The playbook can safely be re-run +# and will not take any action on a node already running the requested docker version. +- name: Evacuate and upgrade nodes + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config + serial: 1 + any_errors_fatal: true + tasks: + - name: Prepare for Node evacuation + command: > + {{ openshift.common.client_binary }} adm manage-node {{ openshift.node.nodename }} --schedulable=false + delegate_to: "{{ groups.oo_first_master.0 }}" + when: l_docker_upgrade is defined and l_docker_upgrade | bool and inventory_hostname in groups.oo_nodes_to_upgrade + + - name: Evacuate Node for Kubelet upgrade + command: > + {{ openshift.common.client_binary }} adm manage-node {{ openshift.node.nodename }} --evacuate --force + delegate_to: "{{ groups.oo_first_master.0 }}" + when: l_docker_upgrade is defined and l_docker_upgrade | bool and inventory_hostname in groups.oo_nodes_to_upgrade + + - include: ../../../../common/openshift-cluster/upgrades/docker/upgrade.yml + when: l_docker_upgrade is defined and l_docker_upgrade | bool + + - name: Set node schedulability + command: > + {{ openshift.common.client_binary }} adm manage-node {{ openshift.node.nodename }} --schedulable=true + delegate_to: "{{ groups.oo_first_master.0 }}" + when: openshift.node.schedulable | bool + when: l_docker_upgrade is defined and l_docker_upgrade | bool and inventory_hostname in groups.oo_nodes_to_upgrade and openshift.node.schedulable | bool + diff --git a/playbooks/byo/openshift-cluster/upgrades/docker/nuke_images.sh b/playbooks/byo/openshift-cluster/upgrades/docker/nuke_images.sh new file mode 120000 index 000000000..d5d864b63 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/docker/nuke_images.sh @@ -0,0 +1 @@ +../../../../common/openshift-cluster/upgrades/files/nuke_images.sh
\ No newline at end of file diff --git a/playbooks/byo/openshift-cluster/upgrades/docker/roles b/playbooks/byo/openshift-cluster/upgrades/docker/roles new file mode 120000 index 000000000..6bc1a7aef --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/docker/roles @@ -0,0 +1 @@ +../../../../../roles
\ No newline at end of file diff --git a/playbooks/byo/openshift-cluster/upgrades/docker/upgrade.yml b/playbooks/byo/openshift-cluster/upgrades/docker/upgrade.yml new file mode 100644 index 000000000..a3ab78ccf --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/docker/upgrade.yml @@ -0,0 +1,31 @@ +# Playbook to upgrade Docker to the max allowable version for an OpenShift cluster. +# +# Currently only supports upgrading 1.9.x to >= 1.10.x. +- hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - include_vars: ../../cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + changed_when: false + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: ../../cluster_hosts.yml + +- include: ../../../../common/openshift-cluster/evaluate_groups.yml + vars: + # Do not allow adding hosts during upgrade. + g_new_master_hosts: [] + g_new_node_hosts: [] + openshift_cluster_id: "{{ cluster_id | default('default') }}" + openshift_deployment_type: "{{ deployment_type }}" + +- include: ../../../../common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml + +- include: docker_upgrade.yml diff --git a/playbooks/byo/openshift-cluster/upgrades/upgrade_etcd.yml b/playbooks/byo/openshift-cluster/upgrades/upgrade_etcd.yml new file mode 100644 index 000000000..c25f96212 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/upgrade_etcd.yml @@ -0,0 +1,26 @@ +--- +- include: ../../../common/openshift-cluster/verify_ansible_version.yml + +- name: Create initial host groups for localhost + hosts: localhost + connection: local + become: no + gather_facts: no + tags: + - always + tasks: + - include_vars: ../cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + +- name: Create initial host groups for all hosts + hosts: l_oo_all_hosts + gather_facts: no + tags: + - always + tasks: + - include_vars: ../cluster_hosts.yml + +- include: ../../../common/openshift-cluster/upgrades/etcd/main.yml diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_2/README.md b/playbooks/byo/openshift-cluster/upgrades/v3_2/README.md new file mode 100644 index 000000000..30603463a --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_2/README.md @@ -0,0 +1,18 @@ +# v3.2 Major and Minor Upgrade Playbook + +## Overview +This playbook currently performs the +following steps. + + * Upgrade and restart master services + * Unschedule node. + * Upgrade and restart docker + * Upgrade and restart node services + * Modifies the subset of the configuration necessary + * Applies the latest cluster policies + * Updates the default router if one exists + * Updates the default registry if one exists + * Updates image streams and quickstarts + +## Usage +ansible-playbook -i ~/ansible-inventory openshift-ansible/playbooks/byo/openshift-cluster/upgrades/v3_2/upgrade.yml diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_2/upgrade.yml b/playbooks/byo/openshift-cluster/upgrades/v3_2/upgrade.yml new file mode 100644 index 000000000..d92761e48 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_2/upgrade.yml @@ -0,0 +1,65 @@ +--- +- include: ../../../../common/openshift-cluster/verify_ansible_version.yml + +- hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - include_vars: ../../../../byo/openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: ../../../../byo/openshift-cluster/cluster_hosts.yml + +- include: ../../../../common/openshift-cluster/evaluate_groups.yml + vars: + # Do not allow adding hosts during upgrade. + g_new_master_hosts: [] + g_new_node_hosts: [] + openshift_cluster_id: "{{ cluster_id | default('default') }}" + openshift_deployment_type: "{{ deployment_type }}" + +- name: Set oo_options + hosts: oo_all_hosts + tasks: + - set_fact: + openshift_docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries') }}" + when: openshift_docker_additional_registries is not defined + - set_fact: + openshift_docker_insecure_registries: "{{ lookup('oo_option', 'docker_insecure_registries') }}" + when: openshift_docker_insecure_registries is not defined + - set_fact: + openshift_docker_blocked_registries: "{{ lookup('oo_option', 'docker_blocked_registries') }}" + when: openshift_docker_blocked_registries is not defined + - set_fact: + openshift_docker_options: "{{ lookup('oo_option', 'docker_options') }}" + when: openshift_docker_options is not defined + - set_fact: + openshift_docker_log_driver: "{{ lookup('oo_option', 'docker_log_driver') }}" + when: openshift_docker_log_driver is not defined + - set_fact: + openshift_docker_log_options: "{{ lookup('oo_option', 'docker_log_options') }}" + when: openshift_docker_log_options is not defined + + +# Configure the upgrade target for the common upgrade tasks: +- hosts: l_oo_all_hosts + tasks: + - set_fact: + openshift_upgrade_target: "{{ '1.2' if deployment_type == 'origin' else '3.2' }}" + openshift_upgrade_min: "{{ '1.1' if deployment_type == 'origin' else '3.1' }}" + +- include: ../../../../common/openshift-cluster/upgrades/pre.yml + vars: + openshift_deployment_type: "{{ deployment_type }}" +- include: ../../../../common/openshift-cluster/upgrades/upgrade.yml + vars: + openshift_deployment_type: "{{ deployment_type }}" +- include: ../../../openshift-master/restart.yml +- include: ../../../../common/openshift-cluster/upgrades/post.yml diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_3/README.md b/playbooks/byo/openshift-cluster/upgrades/v3_3/README.md new file mode 100644 index 000000000..6892f6324 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_3/README.md @@ -0,0 +1,18 @@ +# v3.3 Major and Minor Upgrade Playbook + +## Overview +This playbook currently performs the +following steps. + + * Upgrade and restart master services + * Unschedule node. + * Upgrade and restart docker + * Upgrade and restart node services + * Modifies the subset of the configuration necessary + * Applies the latest cluster policies + * Updates the default router if one exists + * Updates the default registry if one exists + * Updates image streams and quickstarts + +## Usage +ansible-playbook -i ~/ansible-inventory openshift-ansible/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade.yml diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_3/roles b/playbooks/byo/openshift-cluster/upgrades/v3_3/roles new file mode 120000 index 000000000..6bc1a7aef --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_3/roles @@ -0,0 +1 @@ +../../../../../roles
\ No newline at end of file diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade.yml b/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade.yml new file mode 100644 index 000000000..9a5d84751 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade.yml @@ -0,0 +1,100 @@ +--- +# +# Full Control Plane + Nodes Upgrade +# +- include: ../../../../common/openshift-cluster/upgrades/init.yml + tags: + - pre_upgrade + +# Configure the upgrade target for the common upgrade tasks: +- hosts: l_oo_all_hosts + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_upgrade_target: "{{ '1.3' if deployment_type == 'origin' else '3.3' }}" + openshift_upgrade_min: "{{ '1.2' if deployment_type == 'origin' else '3.2' }}" + +# Pre-upgrade + +- include: ../../../../common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml + tags: + - pre_upgrade + +- name: Update repos and initialize facts on all hosts + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config:oo_lb_to_config + tags: + - pre_upgrade + roles: + - openshift_repos + +- name: Set openshift_no_proxy_internal_hostnames + hosts: oo_masters_to_config:oo_nodes_to_upgrade + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_no_proxy_internal_hostnames: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_config'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" + when: "{{ (openshift_http_proxy is defined or openshift_https_proxy is defined) and + openshift_generate_no_proxy_hosts | default(True) | bool }}" + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_inventory_vars.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/initialize_openshift_version.yml + tags: + - pre_upgrade + vars: + # Request specific openshift_release and let the openshift_version role handle converting this + # to a more specific version, respecting openshift_image_tag and openshift_pkg_version if + # defined, and overriding the normal behavior of protecting the installed version + openshift_release: "{{ openshift_upgrade_target }}" + openshift_protect_installed_version: False + + # We skip the docker role at this point in upgrade to prevent + # unintended package, container, or config upgrades which trigger + # docker restarts. At this early stage of upgrade we can assume + # docker is configured and running. + skip_docker_role: True + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_control_plane_running.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_docker_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/gate_checks.yml + tags: + - pre_upgrade + +# Pre-upgrade completed, nothing after this should be tagged pre_upgrade. + +# Separate step so we can execute in parallel and clear out anything unused +# before we get into the serialized upgrade process which will then remove +# remaining images if possible. +- name: Cleanup unused Docker images + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config + tasks: + - include: ../../../../common/openshift-cluster/upgrades/cleanup_unused_images.yml + +- include: ../../../../common/openshift-cluster/upgrades/upgrade_control_plane.yml + vars: + master_config_hook: "v3_3/master_config_upgrade.yml" + +- include: ../../../../common/openshift-cluster/upgrades/post_control_plane.yml + +- include: ../../../../common/openshift-cluster/upgrades/upgrade_nodes.yml + vars: + node_config_hook: "v3_3/node_config_upgrade.yml" + diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade_control_plane.yml b/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade_control_plane.yml new file mode 100644 index 000000000..c9338a960 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade_control_plane.yml @@ -0,0 +1,101 @@ +--- +# +# Control Plane Upgrade Playbook +# +# Upgrades masters and Docker (only on standalone etcd hosts) +# +# This upgrade does not include: +# - node service running on masters +# - docker running on masters +# - node service running on dedicated nodes +# +# You can run the upgrade_nodes.yml playbook after this to upgrade these components separately. +# +- include: ../../../../common/openshift-cluster/upgrades/init.yml + tags: + - pre_upgrade + +# Configure the upgrade target for the common upgrade tasks: +- hosts: l_oo_all_hosts + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_upgrade_target: "{{ '1.3' if deployment_type == 'origin' else '3.3' }}" + openshift_upgrade_min: "{{ '1.2' if deployment_type == 'origin' else '3.2' }}" + +# Pre-upgrade + +- name: Update repos on control plane hosts + hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config + tags: + - pre_upgrade + roles: + - openshift_repos + +- name: Set openshift_no_proxy_internal_hostnames + hosts: oo_masters_to_config:oo_nodes_to_upgrade + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_no_proxy_internal_hostnames: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_config'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" + when: "{{ (openshift_http_proxy is defined or openshift_https_proxy is defined) and + openshift_generate_no_proxy_hosts | default(True) | bool }}" + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_inventory_vars.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/initialize_openshift_version.yml + tags: + - pre_upgrade + vars: + # Request specific openshift_release and let the openshift_version role handle converting this + # to a more specific version, respecting openshift_image_tag and openshift_pkg_version if + # defined, and overriding the normal behavior of protecting the installed version + openshift_release: "{{ openshift_upgrade_target }}" + openshift_protect_installed_version: False + + # We skip the docker role at this point in upgrade to prevent + # unintended package, container, or config upgrades which trigger + # docker restarts. At this early stage of upgrade we can assume + # docker is configured and running. + skip_docker_role: True + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_control_plane_running.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_docker_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/gate_checks.yml + tags: + - pre_upgrade + +# Pre-upgrade completed, nothing after this should be tagged pre_upgrade. + +# Separate step so we can execute in parallel and clear out anything unused +# before we get into the serialized upgrade process which will then remove +# remaining images if possible. +- name: Cleanup unused Docker images + hosts: oo_masters_to_config:oo_etcd_to_config + tasks: + - include: ../../../../common/openshift-cluster/upgrades/cleanup_unused_images.yml + +- include: ../../../../common/openshift-cluster/upgrades/upgrade_control_plane.yml + vars: + master_config_hook: "v3_3/master_config_upgrade.yml" + +- include: ../../../../common/openshift-cluster/upgrades/post_control_plane.yml + diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade_nodes.yml b/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade_nodes.yml new file mode 100644 index 000000000..e2a33cc00 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_3/upgrade_nodes.yml @@ -0,0 +1,102 @@ +--- +# +# Node Upgrade Playbook +# +# Upgrades nodes only, but requires the control plane to have already been upgraded. +# +- include: ../../../../common/openshift-cluster/upgrades/init.yml + tags: + - pre_upgrade + +# Configure the upgrade target for the common upgrade tasks: +- hosts: l_oo_all_hosts + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_upgrade_target: "{{ '1.3' if deployment_type == 'origin' else '3.3' }}" + openshift_upgrade_min: "{{ '1.2' if deployment_type == 'origin' else '3.2' }}" + +# Pre-upgrade +- include: ../../../../common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml + tags: + - pre_upgrade + +- name: Update repos on nodes + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config:oo_lb_to_config + roles: + - openshift_repos + tags: + - pre_upgrade + +- name: Set openshift_no_proxy_internal_hostnames + hosts: oo_masters_to_config:oo_nodes_to_upgrade + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_no_proxy_internal_hostnames: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_upgrade'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" + when: "{{ (openshift_http_proxy is defined or openshift_https_proxy is defined) and + openshift_generate_no_proxy_hosts | default(True) | bool }}" + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_inventory_vars.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/initialize_openshift_version.yml + tags: + - pre_upgrade + vars: + # Request specific openshift_release and let the openshift_version role handle converting this + # to a more specific version, respecting openshift_image_tag and openshift_pkg_version if + # defined, and overriding the normal behavior of protecting the installed version + openshift_release: "{{ openshift_upgrade_target }}" + openshift_protect_installed_version: False + + # We skip the docker role at this point in upgrade to prevent + # unintended package, container, or config upgrades which trigger + # docker restarts. At this early stage of upgrade we can assume + # docker is configured and running. + skip_docker_role: True + +- name: Verify masters are already upgraded + hosts: oo_masters_to_config + tags: + - pre_upgrade + tasks: + - fail: msg="Master running {{ openshift.common.version }} must be upgraded to {{ openshift_version }} before node upgrade can be run." + when: openshift.common.version != openshift_version + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_control_plane_running.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_docker_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/gate_checks.yml + tags: + - pre_upgrade + +# Pre-upgrade completed, nothing after this should be tagged pre_upgrade. + +# Separate step so we can execute in parallel and clear out anything unused +# before we get into the serialized upgrade process which will then remove +# remaining images if possible. +- name: Cleanup unused Docker images + hosts: oo_nodes_to_upgrade + tasks: + - include: ../../../../common/openshift-cluster/upgrades/cleanup_unused_images.yml + +- include: ../../../../common/openshift-cluster/upgrades/upgrade_nodes.yml + vars: + node_config_hook: "v3_3/node_config_upgrade.yml" diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_4/README.md b/playbooks/byo/openshift-cluster/upgrades/v3_4/README.md new file mode 100644 index 000000000..85b807dc6 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_4/README.md @@ -0,0 +1,18 @@ +# v3.4 Major and Minor Upgrade Playbook + +## Overview +This playbook currently performs the +following steps. + + * Upgrade and restart master services + * Unschedule node. + * Upgrade and restart docker + * Upgrade and restart node services + * Modifies the subset of the configuration necessary + * Applies the latest cluster policies + * Updates the default router if one exists + * Updates the default registry if one exists + * Updates image streams and quickstarts + +## Usage +ansible-playbook -i ~/ansible-inventory openshift-ansible/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade.yml diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_4/roles b/playbooks/byo/openshift-cluster/upgrades/v3_4/roles new file mode 120000 index 000000000..6bc1a7aef --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_4/roles @@ -0,0 +1 @@ +../../../../../roles
\ No newline at end of file diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade.yml b/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade.yml new file mode 100644 index 000000000..4f8a80ee8 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade.yml @@ -0,0 +1,96 @@ +--- +# +# Full Control Plane + Nodes Upgrade +# +- include: ../../../../common/openshift-cluster/upgrades/init.yml + tags: + - pre_upgrade + +# Configure the upgrade target for the common upgrade tasks: +- hosts: l_oo_all_hosts + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_upgrade_target: "{{ '1.4' if deployment_type == 'origin' else '3.4' }}" + openshift_upgrade_min: "{{ '1.3' if deployment_type == 'origin' else '3.3' }}" + +# Pre-upgrade + +- include: ../../../../common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml + tags: + - pre_upgrade + +- name: Update repos and initialize facts on all hosts + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config:oo_lb_to_config + tags: + - pre_upgrade + roles: + - openshift_repos + +- name: Set openshift_no_proxy_internal_hostnames + hosts: oo_masters_to_config:oo_nodes_to_upgrade + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_no_proxy_internal_hostnames: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_config'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" + when: "{{ (openshift_http_proxy is defined or openshift_https_proxy is defined) and + openshift_generate_no_proxy_hosts | default(True) | bool }}" + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_inventory_vars.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/initialize_openshift_version.yml + tags: + - pre_upgrade + vars: + # Request specific openshift_release and let the openshift_version role handle converting this + # to a more specific version, respecting openshift_image_tag and openshift_pkg_version if + # defined, and overriding the normal behavior of protecting the installed version + openshift_release: "{{ openshift_upgrade_target }}" + openshift_protect_installed_version: False + + # We skip the docker role at this point in upgrade to prevent + # unintended package, container, or config upgrades which trigger + # docker restarts. At this early stage of upgrade we can assume + # docker is configured and running. + skip_docker_role: True + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_control_plane_running.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_docker_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/gate_checks.yml + tags: + - pre_upgrade + +# Pre-upgrade completed, nothing after this should be tagged pre_upgrade. + +# Separate step so we can execute in parallel and clear out anything unused +# before we get into the serialized upgrade process which will then remove +# remaining images if possible. +- name: Cleanup unused Docker images + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config + tasks: + - include: ../../../../common/openshift-cluster/upgrades/cleanup_unused_images.yml + +- include: ../../../../common/openshift-cluster/upgrades/upgrade_control_plane.yml + +- include: ../../../../common/openshift-cluster/upgrades/post_control_plane.yml + +- include: ../../../../common/openshift-cluster/upgrades/upgrade_nodes.yml + diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade_control_plane.yml b/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade_control_plane.yml new file mode 100644 index 000000000..8cde2ac88 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade_control_plane.yml @@ -0,0 +1,98 @@ +--- +# +# Control Plane Upgrade Playbook +# +# Upgrades masters and Docker (only on standalone etcd hosts) +# +# This upgrade does not include: +# - node service running on masters +# - docker running on masters +# - node service running on dedicated nodes +# +# You can run the upgrade_nodes.yml playbook after this to upgrade these components separately. +# +- include: ../../../../common/openshift-cluster/upgrades/init.yml + tags: + - pre_upgrade + +# Configure the upgrade target for the common upgrade tasks: +- hosts: l_oo_all_hosts + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_upgrade_target: "{{ '1.4' if deployment_type == 'origin' else '3.4' }}" + openshift_upgrade_min: "{{ '1.3' if deployment_type == 'origin' else '3.3' }}" + +# Pre-upgrade + +- name: Update repos on control plane hosts + hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config + tags: + - pre_upgrade + roles: + - openshift_repos + +- name: Set openshift_no_proxy_internal_hostnames + hosts: oo_masters_to_config:oo_nodes_to_upgrade + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_no_proxy_internal_hostnames: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_config'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" + when: "{{ (openshift_http_proxy is defined or openshift_https_proxy is defined) and + openshift_generate_no_proxy_hosts | default(True) | bool }}" + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_inventory_vars.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/initialize_openshift_version.yml + tags: + - pre_upgrade + vars: + # Request specific openshift_release and let the openshift_version role handle converting this + # to a more specific version, respecting openshift_image_tag and openshift_pkg_version if + # defined, and overriding the normal behavior of protecting the installed version + openshift_release: "{{ openshift_upgrade_target }}" + openshift_protect_installed_version: False + + # We skip the docker role at this point in upgrade to prevent + # unintended package, container, or config upgrades which trigger + # docker restarts. At this early stage of upgrade we can assume + # docker is configured and running. + skip_docker_role: True + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_control_plane_running.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_docker_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/gate_checks.yml + tags: + - pre_upgrade + +# Pre-upgrade completed, nothing after this should be tagged pre_upgrade. + +# Separate step so we can execute in parallel and clear out anything unused +# before we get into the serialized upgrade process which will then remove +# remaining images if possible. +- name: Cleanup unused Docker images + hosts: oo_masters_to_config:oo_etcd_to_config + tasks: + - include: ../../../../common/openshift-cluster/upgrades/cleanup_unused_images.yml + +- include: ../../../../common/openshift-cluster/upgrades/upgrade_control_plane.yml + +- include: ../../../../common/openshift-cluster/upgrades/post_control_plane.yml diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade_nodes.yml b/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade_nodes.yml new file mode 100644 index 000000000..f385d4f22 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_4/upgrade_nodes.yml @@ -0,0 +1,100 @@ +--- +# +# Node Upgrade Playbook +# +# Upgrades nodes only, but requires the control plane to have already been upgraded. +# +- include: ../../../../common/openshift-cluster/upgrades/init.yml + tags: + - pre_upgrade + +# Configure the upgrade target for the common upgrade tasks: +- hosts: l_oo_all_hosts + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_upgrade_target: "{{ '1.4' if deployment_type == 'origin' else '3.4' }}" + openshift_upgrade_min: "{{ '1.3' if deployment_type == 'origin' else '3.3' }}" + +# Pre-upgrade +- include: ../../../../common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml + tags: + - pre_upgrade + +- name: Update repos on nodes + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config:oo_lb_to_config + roles: + - openshift_repos + tags: + - pre_upgrade + +- name: Set openshift_no_proxy_internal_hostnames + hosts: oo_masters_to_config:oo_nodes_to_upgrade + tags: + - pre_upgrade + tasks: + - set_fact: + openshift_no_proxy_internal_hostnames: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_upgrade'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" + when: "{{ (openshift_http_proxy is defined or openshift_https_proxy is defined) and + openshift_generate_no_proxy_hosts | default(True) | bool }}" + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_inventory_vars.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/initialize_openshift_version.yml + tags: + - pre_upgrade + vars: + # Request specific openshift_release and let the openshift_version role handle converting this + # to a more specific version, respecting openshift_image_tag and openshift_pkg_version if + # defined, and overriding the normal behavior of protecting the installed version + openshift_release: "{{ openshift_upgrade_target }}" + openshift_protect_installed_version: False + + # We skip the docker role at this point in upgrade to prevent + # unintended package, container, or config upgrades which trigger + # docker restarts. At this early stage of upgrade we can assume + # docker is configured and running. + skip_docker_role: True + +- name: Verify masters are already upgraded + hosts: oo_masters_to_config + tags: + - pre_upgrade + tasks: + - fail: msg="Master running {{ openshift.common.version }} must be upgraded to {{ openshift_version }} before node upgrade can be run." + when: openshift.common.version != openshift_version + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_control_plane_running.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/verify_docker_upgrade_targets.yml + tags: + - pre_upgrade + +- include: ../../../../common/openshift-cluster/upgrades/pre/gate_checks.yml + tags: + - pre_upgrade + +# Pre-upgrade completed, nothing after this should be tagged pre_upgrade. + +# Separate step so we can execute in parallel and clear out anything unused +# before we get into the serialized upgrade process which will then remove +# remaining images if possible. +- name: Cleanup unused Docker images + hosts: oo_nodes_to_upgrade + tasks: + - include: ../../../../common/openshift-cluster/upgrades/cleanup_unused_images.yml + +- include: ../../../../common/openshift-cluster/upgrades/upgrade_nodes.yml diff --git a/playbooks/adhoc/noc/filter_plugins b/playbooks/byo/openshift-master/filter_plugins index 99a95e4ca..99a95e4ca 120000 --- a/playbooks/adhoc/noc/filter_plugins +++ b/playbooks/byo/openshift-master/filter_plugins diff --git a/playbooks/byo/openshift-master/lookup_plugins b/playbooks/byo/openshift-master/lookup_plugins new file mode 120000 index 000000000..ac79701db --- /dev/null +++ b/playbooks/byo/openshift-master/lookup_plugins @@ -0,0 +1 @@ +../../../lookup_plugins
\ No newline at end of file diff --git a/playbooks/byo/openshift-master/restart.yml b/playbooks/byo/openshift-master/restart.yml new file mode 100644 index 000000000..0a163526a --- /dev/null +++ b/playbooks/byo/openshift-master/restart.yml @@ -0,0 +1,18 @@ +--- +- hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + +- include: ../../common/openshift-master/restart.yml diff --git a/playbooks/aws/ansible-tower/roles b/playbooks/byo/openshift-master/roles index 20c4c58cf..20c4c58cf 120000 --- a/playbooks/aws/ansible-tower/roles +++ b/playbooks/byo/openshift-master/roles diff --git a/playbooks/byo/openshift-master/scaleup.yml b/playbooks/byo/openshift-master/scaleup.yml new file mode 100644 index 000000000..279eeab21 --- /dev/null +++ b/playbooks/byo/openshift-master/scaleup.yml @@ -0,0 +1,22 @@ +--- +- hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + +- include: ../../common/openshift-master/scaleup.yml + vars: + openshift_cluster_id: "{{ cluster_id | default('default') }}" + openshift_debug_level: "{{ debug_level | default(2) }}" + openshift_deployment_type: "{{ deployment_type }}" diff --git a/playbooks/aws/ansible-tower/filter_plugins b/playbooks/byo/openshift-node/filter_plugins index 99a95e4ca..99a95e4ca 120000 --- a/playbooks/aws/ansible-tower/filter_plugins +++ b/playbooks/byo/openshift-node/filter_plugins diff --git a/playbooks/byo/openshift-node/lookup_plugins b/playbooks/byo/openshift-node/lookup_plugins new file mode 120000 index 000000000..ac79701db --- /dev/null +++ b/playbooks/byo/openshift-node/lookup_plugins @@ -0,0 +1 @@ +../../../lookup_plugins
\ No newline at end of file diff --git a/playbooks/byo/openshift-node/roles b/playbooks/byo/openshift-node/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/byo/openshift-node/roles @@ -0,0 +1 @@ +../../../roles
\ No newline at end of file diff --git a/playbooks/byo/openshift-node/scaleup.yml b/playbooks/byo/openshift-node/scaleup.yml new file mode 100644 index 000000000..902221931 --- /dev/null +++ b/playbooks/byo/openshift-node/scaleup.yml @@ -0,0 +1,22 @@ +--- +- hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: ../../byo/openshift-cluster/cluster_hosts.yml + +- include: ../../common/openshift-node/scaleup.yml + vars: + openshift_cluster_id: "{{ cluster_id | default('default') }}" + openshift_debug_level: "{{ debug_level | default(2) }}" + openshift_deployment_type: "{{ deployment_type }}" diff --git a/playbooks/byo/openshift_facts.yml b/playbooks/byo/openshift_facts.yml index cd282270f..8c0708df0 100644 --- a/playbooks/byo/openshift_facts.yml +++ b/playbooks/byo/openshift_facts.yml @@ -1,10 +1,30 @@ --- -- name: Gather OpenShift facts - hosts: all +- include: ../common/openshift-cluster/verify_ansible_version.yml + +- hosts: localhost + connection: local + become: no gather_facts: no + tasks: + - include_vars: openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: openshift-cluster/cluster_hosts.yml + +- include: ../common/openshift-cluster/evaluate_groups.yml + +- name: Gather Cluster facts + hosts: OSEv3 roles: - openshift_facts tasks: - openshift_facts: + openshift_env: "{{ hostvars[inventory_hostname] | oo_openshift_env }}" register: result - debug: var=result diff --git a/playbooks/byo/rhel_subscribe.yml b/playbooks/byo/rhel_subscribe.yml new file mode 100644 index 000000000..f36caeb36 --- /dev/null +++ b/playbooks/byo/rhel_subscribe.yml @@ -0,0 +1,30 @@ +--- +- hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - include_vars: openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: openshift-cluster/cluster_hosts.yml + +- include: ../common/openshift-cluster/evaluate_groups.yml + +- hosts: l_oo_all_hosts + vars: + openshift_deployment_type: "{{ deployment_type }}" + roles: + - role: rhel_subscribe + when: deployment_type in ['atomic-enterprise', 'enterprise', 'openshift-enterprise'] and + ansible_distribution == "RedHat" and + lookup('oo_option', 'rhel_skip_subscription') | default(rhsub_skip, True) | + default('no', True) | lower in ['no', 'false'] + - openshift_repos + - os_update_latest diff --git a/playbooks/byo/vagrant.yml b/playbooks/byo/vagrant.yml new file mode 100644 index 000000000..76246e7b0 --- /dev/null +++ b/playbooks/byo/vagrant.yml @@ -0,0 +1,4 @@ +--- +- include: rhel_subscribe.yml + +- include: config.yml diff --git a/playbooks/common/openshift-cluster/additional_config.yml b/playbooks/common/openshift-cluster/additional_config.yml new file mode 100644 index 000000000..825f46415 --- /dev/null +++ b/playbooks/common/openshift-cluster/additional_config.yml @@ -0,0 +1,22 @@ +- name: Additional master configuration + hosts: oo_first_master + vars: + cockpit_plugins: "{{ osm_cockpit_plugins | default(['cockpit-kubernetes']) }}" + etcd_urls: "{{ openshift.master.etcd_urls }}" + openshift_master_ha: "{{ groups.oo_masters | length > 1 }}" + omc_cluster_hosts: "{{ groups.oo_masters | join(' ')}}" + roles: + - role: openshift_master_cluster + when: openshift_master_ha | bool and openshift.master.cluster_method == "pacemaker" + - role: openshift_examples + registry_url: "{{ openshift.master.registry_url }}" + when: openshift.common.install_examples | bool + - role: openshift_hosted_templates + registry_url: "{{ openshift.master.registry_url }}" + - role: openshift_manageiq + when: openshift.common.use_manageiq | bool + - role: cockpit + when: not openshift.common.is_atomic and ( deployment_type in ['atomic-enterprise','openshift-enterprise'] ) and + (osm_use_cockpit | bool or osm_use_cockpit is undefined ) and ( openshift.common.deployment_subtype != 'registry' ) + - role: flannel_register + when: openshift.common.use_flannel | bool diff --git a/playbooks/common/openshift-cluster/config.yml b/playbooks/common/openshift-cluster/config.yml index 0779cfe47..801c8065d 100644 --- a/playbooks/common/openshift-cluster/config.yml +++ b/playbooks/common/openshift-cluster/config.yml @@ -1,65 +1,66 @@ --- -- name: Populate config host groups - hosts: localhost - gather_facts: no - tasks: - - fail: - msg: This playbook rquires g_etcd_group to be set - when: g_etcd_group is not defined +- include: evaluate_groups.yml + tags: + - always - - fail: - msg: This playbook rquires g_masters_group to be set - when: g_masters_group is not defined +- include: initialize_facts.yml + tags: + - always - - fail: - msg: This playbook rquires g_nodes_group to be set - when: g_nodes_group is not defined +- include: validate_hostnames.yml + tags: + - node - - name: Evaluate oo_etcd_to_config - add_host: - name: "{{ item }}" - groups: oo_etcd_to_config - ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" - ansible_sudo: "{{ g_sudo | default(omit) }}" - with_items: groups[g_etcd_group] | default([]) +- include: initialize_openshift_version.yml - - name: Evaluate oo_masters_to_config - add_host: - name: "{{ item }}" - groups: oo_masters_to_config - ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" - ansible_sudo: "{{ g_sudo | default(omit) }}" - with_items: groups[g_masters_group] | default([]) +- name: Set oo_option facts + hosts: oo_all_hosts + tags: + - always + tasks: + - set_fact: + openshift_docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries') }}" + when: openshift_docker_additional_registries is not defined + - set_fact: + openshift_docker_insecure_registries: "{{ lookup('oo_option', 'docker_insecure_registries') }}" + when: openshift_docker_insecure_registries is not defined + - set_fact: + openshift_docker_blocked_registries: "{{ lookup('oo_option', 'docker_blocked_registries') }}" + when: openshift_docker_blocked_registries is not defined + - set_fact: + openshift_docker_options: "{{ lookup('oo_option', 'docker_options') }}" + when: openshift_docker_options is not defined + - set_fact: + openshift_docker_log_driver: "{{ lookup('oo_option', 'docker_log_driver') }}" + when: openshift_docker_log_driver is not defined + - set_fact: + openshift_docker_log_options: "{{ lookup('oo_option', 'docker_log_options') }}" + when: openshift_docker_log_options is not defined - - name: Evaluate oo_nodes_to_config - add_host: - name: "{{ item }}" - groups: oo_nodes_to_config - ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" - ansible_sudo: "{{ g_sudo | default(omit) }}" - with_items: groups[g_nodes_group] | default([]) +- include: ../openshift-etcd/config.yml + tags: + - etcd - - name: Evaluate oo_first_etcd - add_host: - name: "{{ groups[g_etcd_group][0] }}" - groups: oo_first_etcd - ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" - ansible_sudo: "{{ g_sudo | default(omit) }}" - when: g_etcd_group in groups and (groups[g_etcd_group] | length) > 0 +- include: ../openshift-nfs/config.yml + tags: + - nfs - - name: Evaluate oo_first_master - add_host: - name: "{{ groups[g_masters_group][0] }}" - groups: oo_first_master - ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" - ansible_sudo: "{{ g_sudo | default(omit) }}" - when: g_masters_group in groups and (groups[g_masters_group] | length) > 0 - -- include: ../openshift-etcd/config.yml +- include: ../openshift-loadbalancer/config.yml + tags: + - loadbalancer - include: ../openshift-master/config.yml + tags: + - master + +- include: additional_config.yml + tags: + - master - include: ../openshift-node/config.yml - vars: - osn_cluster_dns_domain: "{{ hostvars[groups.oo_first_master.0].openshift.dns.domain }}" - osn_cluster_dns_ip: "{{ hostvars[groups.oo_first_master.0].openshift.dns.ip }}" + tags: + - node + +- include: openshift_hosted.yml + tags: + - hosted diff --git a/playbooks/common/openshift-cluster/create_services.yml b/playbooks/common/openshift-cluster/create_services.yml deleted file mode 100644 index e70709d19..000000000 --- a/playbooks/common/openshift-cluster/create_services.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -- name: Deploy OpenShift Services - hosts: "{{ g_svc_master }}" - connection: ssh - gather_facts: yes - roles: - - openshift_registry - - openshift_router diff --git a/playbooks/common/openshift-cluster/enable_dnsmasq.yml b/playbooks/common/openshift-cluster/enable_dnsmasq.yml new file mode 100644 index 000000000..4cfe8617e --- /dev/null +++ b/playbooks/common/openshift-cluster/enable_dnsmasq.yml @@ -0,0 +1,68 @@ +--- +- include: evaluate_groups.yml + +- name: Load openshift_facts + hosts: oo_masters_to_config:oo_nodes_to_config + roles: + - openshift_facts + post_tasks: + - fail: msg="This playbook requires a master version of at least Origin 1.1 or OSE 3.1" + when: not openshift.common.version_gte_3_1_1_or_1_1_1 | bool + +- name: Reconfigure masters to listen on our new dns_port + hosts: oo_masters_to_config + handlers: + - include: ../../../roles/openshift_master/handlers/main.yml + static: yes + vars: + os_firewall_allow: + - service: skydns tcp + port: "{{ openshift.master.dns_port }}/tcp" + - service: skydns udp + port: "{{ openshift.master.dns_port }}/udp" + roles: + - os_firewall + tasks: + - openshift_facts: + role: "{{ item.role }}" + local_facts: "{{ item.local_facts }}" + with_items: + - role: common + local_facts: + use_dnsmasq: True + - role: master + local_facts: + dns_port: '8053' + - modify_yaml: + dest: "{{ openshift.common.config_base }}/master/master-config.yaml" + yaml_key: dnsConfig.bindAddress + yaml_value: "{{ openshift.master.bind_addr }}:{{ openshift.master.dns_port }}" + notify: restart master + - meta: flush_handlers + +- name: Configure nodes for dnsmasq + hosts: oo_nodes_to_config + handlers: + - include: ../../../roles/openshift_node/handlers/main.yml + static: yes + pre_tasks: + - openshift_facts: + role: "{{ item.role }}" + local_facts: "{{ item.local_facts }}" + with_items: + - role: common + local_facts: + use_dnsmasq: True + - role: node + local_facts: + dns_ip: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" + vars: + openshift_deployment_type: "{{ deployment_type }}" + roles: + - openshift_node_dnsmasq + post_tasks: + - modify_yaml: + dest: "{{ openshift.common.config_base }}/node/node-config.yaml" + yaml_key: dnsIP + yaml_value: "{{ openshift.node.dns_ip }}" + notify: restart node diff --git a/playbooks/common/openshift-cluster/evaluate_groups.yml b/playbooks/common/openshift-cluster/evaluate_groups.yml new file mode 100644 index 000000000..b3e02fb97 --- /dev/null +++ b/playbooks/common/openshift-cluster/evaluate_groups.yml @@ -0,0 +1,111 @@ +--- +- name: Populate config host groups + hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - fail: + msg: This playbook requires g_etcd_hosts to be set + when: g_etcd_hosts is not defined + + - fail: + msg: This playbook requires g_master_hosts or g_new_master_hosts to be set + when: g_master_hosts is not defined and g_new_master_hosts is not defined + + - fail: + msg: This playbook requires g_node_hosts or g_new_node_hosts to be set + when: g_node_hosts is not defined and g_new_node_hosts is not defined + + - fail: + msg: This playbook requires g_lb_hosts to be set + when: g_lb_hosts is not defined + + - fail: + msg: This playbook requires g_nfs_hosts to be set + when: g_nfs_hosts is not defined + + - fail: + msg: The nfs group must be limited to one host + when: (groups[g_nfs_hosts] | default([])) | length > 1 + + - name: Evaluate oo_all_hosts + add_host: + name: "{{ item }}" + groups: oo_all_hosts + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ g_all_hosts | default([]) }}" + + - name: Evaluate oo_masters + add_host: + name: "{{ item }}" + groups: oo_masters + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ g_master_hosts | union(g_new_master_hosts) | default([]) }}" + + - name: Evaluate oo_etcd_to_config + add_host: + name: "{{ item }}" + groups: oo_etcd_to_config + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ g_etcd_hosts | default([]) }}" + + - name: Evaluate oo_masters_to_config + add_host: + name: "{{ item }}" + groups: oo_masters_to_config + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ g_new_master_hosts | default(g_master_hosts | default([], true), true) }}" + + - name: Evaluate oo_nodes_to_config + add_host: + name: "{{ item }}" + groups: oo_nodes_to_config + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ g_new_node_hosts | default(g_node_hosts | default([], true), true) }}" + + # Skip adding the master to oo_nodes_to_config when g_new_node_hosts is + - name: Evaluate oo_nodes_to_config + add_host: + name: "{{ item }}" + groups: oo_nodes_to_config + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ g_master_hosts | default([]) }}" + when: g_nodeonmaster | default(false) | bool and not g_new_node_hosts | default(false) | bool + + - name: Evaluate oo_first_etcd + add_host: + name: "{{ g_etcd_hosts[0] }}" + groups: oo_first_etcd + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + when: g_etcd_hosts|length > 0 + + - name: Evaluate oo_first_master + add_host: + name: "{{ g_master_hosts[0] }}" + groups: oo_first_master + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + when: g_master_hosts|length > 0 + + - name: Evaluate oo_lb_to_config + add_host: + name: "{{ item }}" + groups: oo_lb_to_config + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ g_lb_hosts | default([]) }}" + + - name: Evaluate oo_nfs_to_config + add_host: + name: "{{ item }}" + groups: oo_nfs_to_config + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ g_nfs_hosts | default([]) }}" diff --git a/playbooks/common/openshift-cluster/initialize_facts.yml b/playbooks/common/openshift-cluster/initialize_facts.yml new file mode 100644 index 000000000..6d83d2527 --- /dev/null +++ b/playbooks/common/openshift-cluster/initialize_facts.yml @@ -0,0 +1,15 @@ +--- +- name: Initialize host facts + hosts: oo_all_hosts + any_errors_fatal: true + roles: + - openshift_facts + tasks: + - openshift_facts: + role: common + local_facts: + hostname: "{{ openshift_hostname | default(None) }}" + - set_fact: + openshift_docker_hosted_registry_network: "{{ hostvars[groups.oo_first_master.0].openshift.common.portal_net }}" + - set_fact: + openshift_deployment_type: "{{ deployment_type }}" diff --git a/playbooks/common/openshift-cluster/initialize_openshift_version.yml b/playbooks/common/openshift-cluster/initialize_openshift_version.yml new file mode 100644 index 000000000..2f384ddea --- /dev/null +++ b/playbooks/common/openshift-cluster/initialize_openshift_version.yml @@ -0,0 +1,32 @@ +--- +# NOTE: requires openshift_facts be run +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + # See: + # https://bugzilla.redhat.com/show_bug.cgi?id=1395047 + # https://bugzilla.redhat.com/show_bug.cgi?id=1282961 + # https://github.com/openshift/openshift-ansible/issues/1138 + - name: Check for bad combinations of yum and subscription-manager + command: > + {{ repoquery_cmd }} --installed --qf '%{version}' "yum" + register: yum_ver_test + changed_when: false + - fail: + msg: Incompatible versions of yum and subscription-manager found. You may need to update yum and yum-utils. + when: "'Plugin \"search-disabled-repos\" requires API 2.7. Supported API is 2.6.' in yum_ver_test.stdout" + +- name: Determine openshift_version to configure on first master + hosts: oo_first_master + roles: + - openshift_version + +# NOTE: We set this even on etcd hosts as they may also later run as masters, +# and we don't want to install wrong version of docker and have to downgrade +# later. +- name: Set openshift_version for all hosts + hosts: oo_all_hosts:!oo_first_master + vars: + openshift_version: "{{ hostvars[groups.oo_first_master.0].openshift_version }}" + roles: + - openshift_version diff --git a/playbooks/common/openshift-cluster/library b/playbooks/common/openshift-cluster/library new file mode 120000 index 000000000..d0b7393d3 --- /dev/null +++ b/playbooks/common/openshift-cluster/library @@ -0,0 +1 @@ +../../../library/
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/openshift_hosted.yml b/playbooks/common/openshift-cluster/openshift_hosted.yml new file mode 100644 index 000000000..ccbba54b4 --- /dev/null +++ b/playbooks/common/openshift-cluster/openshift_hosted.yml @@ -0,0 +1,68 @@ +--- +- name: Create persistent volumes + hosts: oo_first_master + tags: + - hosted + vars: + persistent_volumes: "{{ hostvars[groups.oo_first_master.0] | oo_persistent_volumes(groups) }}" + persistent_volume_claims: "{{ hostvars[groups.oo_first_master.0] | oo_persistent_volume_claims }}" + roles: + - role: openshift_persistent_volumes + when: persistent_volumes | length > 0 or persistent_volume_claims | length > 0 + +- name: Create Hosted Resources + hosts: oo_first_master + tags: + - hosted + pre_tasks: + - set_fact: + openshift_hosted_router_registryurl: "{{ hostvars[groups.oo_first_master.0].openshift.master.registry_url }}" + openshift_hosted_registry_registryurl: "{{ hostvars[groups.oo_first_master.0].openshift.master.registry_url }}" + when: "'master' in hostvars[groups.oo_first_master.0].openshift and 'registry_url' in hostvars[groups.oo_first_master.0].openshift.master" + - set_fact: + logging_hostname: "{{ openshift_hosted_logging_hostname | default('kibana.' ~ (openshift.master.default_subdomain | default('router.default.svc.cluster.local', true))) }}" + logging_ops_hostname: "{{ openshift_hosted_logging_ops_hostname | default('kibana-ops.' ~ (openshift.master.default_subdomain | default('router.default.svc.cluster.local', true))) }}" + logging_master_public_url: "{{ openshift_hosted_logging_master_public_url | default(openshift.master.public_api_url) }}" + logging_elasticsearch_cluster_size: "{{ openshift_hosted_logging_elasticsearch_cluster_size | default(1) }}" + logging_elasticsearch_ops_cluster_size: "{{ openshift_hosted_logging_elasticsearch_ops_cluster_size | default(1) }}" + roles: + - role: openshift_cli + - role: openshift_hosted_facts + - role: openshift_projects + # TODO: Move standard project definitions to openshift_hosted/vars/main.yml + # Vars are not accessible in meta/main.yml in ansible-1.9.x + openshift_projects: "{{ openshift_additional_projects | default({}) | oo_merge_dicts({'default':{'default_node_selector':''},'openshift-infra':{'default_node_selector':''},'logging':{'default_node_selector':''}}) }}" + - role: openshift_serviceaccounts + openshift_serviceaccounts_names: + - router + openshift_serviceaccounts_namespace: default + openshift_serviceaccounts_sccs: + - hostnetwork + when: openshift.common.version_gte_3_2_or_1_2 + - role: openshift_serviceaccounts + openshift_serviceaccounts_names: + - router + - registry + openshift_serviceaccounts_namespace: default + openshift_serviceaccounts_sccs: + - privileged + when: not openshift.common.version_gte_3_2_or_1_2 + - role: openshift_hosted + - role: openshift_metrics + when: openshift_hosted_metrics_deploy | default(false) | bool + - role: openshift_hosted_logging + when: openshift_hosted_logging_deploy | default(false) | bool + openshift_hosted_logging_hostname: "{{ logging_hostname }}" + openshift_hosted_logging_ops_hostname: "{{ logging_ops_hostname }}" + openshift_hosted_logging_master_public_url: "{{ logging_master_public_url }}" + openshift_hosted_logging_elasticsearch_cluster_size: "{{ logging_elasticsearch_cluster_size }}" + openshift_hosted_logging_elasticsearch_pvc_dynamic: "{{ 'true' if openshift_hosted_logging_storage_kind | default(none) == 'dynamic' else '' }}" + openshift_hosted_logging_elasticsearch_pvc_size: "{{ openshift.hosted.logging.storage.volume.size if openshift_hosted_logging_storage_kind | default(none) in ['dynamic','nfs'] else '' }}" + openshift_hosted_logging_elasticsearch_pvc_prefix: "{{ 'logging-es' if openshift_hosted_logging_storage_kind | default(none) == 'dynamic' else '' }}" + openshift_hosted_logging_elasticsearch_ops_cluster_size: "{{ logging_elasticsearch_ops_cluster_size }}" + openshift_hosted_logging_elasticsearch_ops_pvc_dynamic: "{{ 'true' if openshift_hosted_logging_storage_kind | default(none) == 'dynamic' else '' }}" + openshift_hosted_logging_elasticsearch_ops_pvc_size: "{{ openshift.hosted.logging.storage.volume.size if openshift_hosted_logging_storage_kind | default(none) in ['dynamic','nfs' ] else '' }}" + openshift_hosted_logging_elasticsearch_ops_pvc_prefix: "{{ 'logging-es' if openshift_hosted_logging_storage_kind | default(none) =='dynamic' else '' }}" + + - role: cockpit-ui + when: ( openshift.common.version_gte_3_3_or_1_3 | bool ) and ( openshift_hosted_manage_registry | default(true) | bool ) and not (openshift.docker.hosted_registry_insecure | default(false) | bool) diff --git a/playbooks/common/openshift-cluster/redeploy-certificates.yml b/playbooks/common/openshift-cluster/redeploy-certificates.yml new file mode 100644 index 000000000..5f008a045 --- /dev/null +++ b/playbooks/common/openshift-cluster/redeploy-certificates.yml @@ -0,0 +1,255 @@ +--- +- include: evaluate_groups.yml + +- include: initialize_facts.yml + +- include: initialize_openshift_version.yml + +- name: Load openshift_facts + hosts: oo_etcd_to_config:oo_masters_to_config:oo_nodes_to_config + roles: + - openshift_facts + +- name: Redeploy etcd certificates + hosts: oo_etcd_to_config + any_errors_fatal: true + vars: + etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" + etcd_conf_dir: /etc/etcd + etcd_generated_certs_dir: "{{ etcd_conf_dir }}/generated_certs" + + pre_tasks: + - stat: + path: "{{ etcd_generated_certs_dir }}" + register: etcd_generated_certs_dir_stat + - name: Backup etcd certificates + command: > + tar -czvf /etc/etcd/etcd-certificate-backup-{{ ansible_date_time.epoch }}.tgz + {{ etcd_conf_dir }}/ca.crt + {{ etcd_conf_dir }}/ca + {{ etcd_generated_certs_dir }} + when: etcd_generated_certs_dir_stat.stat.exists + delegate_to: "{{ etcd_ca_host }}" + run_once: true + - name: Remove existing etcd certificates + file: + path: "{{ item }}" + state: absent + with_items: + - "{{ etcd_conf_dir }}/ca.crt" + - "{{ etcd_conf_dir }}/ca" + - "{{ etcd_generated_certs_dir }}" + roles: + - role: openshift_etcd_server_certificates + etcd_peers: "{{ groups.oo_etcd_to_config | default([], true) }}" + etcd_certificates_etcd_hosts: "{{ groups.oo_etcd_to_config | default([], true) }}" + etcd_certificates_redeploy: true + +- name: Redeploy master certificates + hosts: oo_masters_to_config + any_errors_fatal: true + vars: + openshift_ca_host: "{{ groups.oo_first_master.0 }}" + openshift_master_count: "{{ openshift.master.master_count | default(groups.oo_masters | length) }}" + pre_tasks: + # set_fact task copied from playbooks/common/openshift-master/config.yml + # so that openshift_master_default_subdomain has a default value of "" + # (emptry string). openshift_master_default_subdomain must have a default + # value for openshift_master_facts to set metrics_public_url. + # TODO: clean this up. + - set_fact: + openshift_master_default_subdomain: "{{ lookup('oo_option', 'openshift_master_default_subdomain') | default(None, true) }}" + when: openshift_master_default_subdomain is not defined + - stat: + path: "{{ openshift_generated_configs_dir }}" + register: openshift_generated_configs_dir_stat + - name: Backup generated certificate and config directories + command: > + tar -czvf /etc/origin/master-node-cert-config-backup-{{ ansible_date_time.epoch }}.tgz + {{ openshift_generated_configs_dir }} + {{ openshift.common.config_base }}/master + when: openshift_generated_configs_dir_stat.stat.exists + delegate_to: "{{ openshift_ca_host }}" + run_once: true + - name: Remove generated certificate directories + file: + path: "{{ item }}" + state: absent + with_items: + - "{{ openshift_generated_configs_dir }}" + - name: Remove generated certificates + file: + path: "{{ openshift.common.config_base }}/master/{{ item }}" + state: absent + with_items: + - "{{ hostvars[inventory_hostname] | certificates_to_synchronize(include_keys=false) }}" + - "etcd.server.crt" + - "etcd.server.key" + - "master.etcd-client.crt" + - "master.etcd-client.key" + - "master.server.crt" + - "master.server.key" + - "openshift-master.crt" + - "openshift-master.key" + - "openshift-master.kubeconfig" + - name: Remove CA certificate + file: + path: "{{ openshift.common.config_base }}/master/{{ item }}" + state: absent + when: openshift_certificates_redeploy_ca | default(false) | bool + with_items: + - "ca.crt" + - "ca.key" + - "ca.serial.txt" + - "ca-bundle.crt" + roles: + - role: openshift_master_certificates + openshift_master_etcd_hosts: "{{ hostvars + | oo_select_keys(groups['oo_etcd_to_config'] | default([])) + | oo_collect('openshift.common.hostname') + | default(none, true) }}" + openshift_master_hostnames: "{{ hostvars + | oo_select_keys(groups['oo_masters_to_config'] | default([])) + | oo_collect('openshift.common.all_hostnames') + | oo_flatten | unique }}" + openshift_certificates_redeploy: true + - role: openshift_etcd_client_certificates + etcd_certificates_redeploy: true + etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" + etcd_cert_subdir: "openshift-master-{{ openshift.common.hostname }}" + etcd_cert_config_dir: "{{ openshift.common.config_base }}/master" + etcd_cert_prefix: "master.etcd-" + when: groups.oo_etcd_to_config is defined and groups.oo_etcd_to_config + +- name: Redeploy node certificates + hosts: oo_nodes_to_config + any_errors_fatal: true + pre_tasks: + - name: Remove CA certificate + file: + path: "{{ item }}" + state: absent + with_items: + - "{{ openshift.common.config_base }}/node/ca.crt" + roles: + - role: openshift_node_certificates + openshift_node_master_api_url: "{{ hostvars[groups.oo_first_master.0].openshift.master.api_url }}" + openshift_ca_host: "{{ groups.oo_first_master.0 }}" + openshift_certificates_redeploy: true + +- name: Restart etcd + hosts: oo_etcd_to_config + tasks: + - name: restart etcd + service: + name: "{{ 'etcd' if not openshift.common.is_containerized | bool else 'etcd_container' }}" + state: restarted + +- name: Stop master services + hosts: oo_masters_to_config + vars: + openshift_master_ha: "{{ groups.oo_masters_to_config | length > 1 }}" + tasks: + - name: stop master + service: name={{ openshift.common.service_type }}-master state=stopped + when: not openshift_master_ha | bool + - name: stop master api + service: name={{ openshift.common.service_type }}-master-api state=stopped + when: openshift_master_ha | bool and openshift_master_cluster_method == 'native' + - name: stop master controllers + service: name={{ openshift.common.service_type }}-master-controllers state=stopped + when: openshift_master_ha | bool and openshift_master_cluster_method == 'native' + +- name: Start master services + hosts: oo_masters_to_config + serial: 1 + vars: + openshift_master_ha: "{{ groups.oo_masters_to_config | length > 1 }}" + tasks: + - name: start master + service: name={{ openshift.common.service_type }}-master state=started + when: not openshift_master_ha | bool + - name: start master api + service: name={{ openshift.common.service_type }}-master-api state=started + when: openshift_master_ha | bool and openshift_master_cluster_method == 'native' + - name: start master controllers + service: name={{ openshift.common.service_type }}-master-controllers state=started + when: openshift_master_ha | bool and openshift_master_cluster_method == 'native' + +- name: Restart masters (pacemaker) + hosts: oo_first_master + vars: + openshift_master_ha: "{{ groups.oo_masters_to_config | length > 1 }}" + tasks: + - name: restart master + command: pcs resource restart master + when: openshift_master_ha | bool and openshift_master_cluster_method == 'pacemaker' + +- name: Restart nodes + hosts: oo_nodes_to_config + tasks: + - name: restart node + service: name={{ openshift.common.service_type }}-node state=restarted + +- name: Copy admin client config(s) + hosts: oo_first_master + tasks: + - name: Create temp directory for kubeconfig + command: mktemp -d /tmp/openshift-ansible-XXXXXX + register: mktemp + changed_when: False + + - name: Copy admin client config(s) + command: > + cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig + changed_when: False + +- name: Serially evacuate all nodes to trigger redeployments + hosts: oo_nodes_to_config + serial: 1 + any_errors_fatal: true + tasks: + - name: Determine if node is currently scheduleable + command: > + {{ openshift.common.client_binary }} --config={{ hostvars[groups.oo_first_master.0].mktemp.stdout }}/admin.kubeconfig + get node {{ openshift.node.nodename }} -o json + register: node_output + when: openshift_certificates_redeploy_ca | default(false) | bool + delegate_to: "{{ groups.oo_first_master.0 }}" + changed_when: false + + - set_fact: + was_schedulable: "{{ 'unschedulable' not in (node_output.stdout | from_json).spec }}" + when: openshift_certificates_redeploy_ca | default(false) | bool + + - name: Prepare for node evacuation + command: > + {{ openshift.common.client_binary }} adm --config={{ hostvars[groups.oo_first_master.0].mktemp.stdout }}/admin.kubeconfig + manage-node {{ openshift.node.nodename }} + --schedulable=false + delegate_to: "{{ groups.oo_first_master.0 }}" + when: openshift_certificates_redeploy_ca | default(false) | bool and was_schedulable | bool + + - name: Evacuate node + command: > + {{ openshift.common.client_binary }} adm --config={{ hostvars[groups.oo_first_master.0].mktemp.stdout }}/admin.kubeconfig + manage-node {{ openshift.node.nodename }} + --evacuate --force + delegate_to: "{{ groups.oo_first_master.0 }}" + when: openshift_certificates_redeploy_ca | default(false) | bool and was_schedulable | bool + + - name: Set node schedulability + command: > + {{ openshift.common.client_binary }} adm --config={{ hostvars[groups.oo_first_master.0].mktemp.stdout }}/admin.kubeconfig + manage-node {{ openshift.node.nodename }} --schedulable=true + delegate_to: "{{ groups.oo_first_master.0 }}" + when: openshift_certificates_redeploy_ca | default(false) | bool and was_schedulable | bool + +- name: Delete temporary directory + hosts: oo_first_master + tasks: + - name: Delete temp directory + file: + name: "{{ mktemp.stdout }}" + state: absent + changed_when: False diff --git a/playbooks/common/openshift-cluster/set_etcd_launch_facts_tasks.yml b/playbooks/common/openshift-cluster/tasks/set_etcd_launch_facts.yml index 1a6580795..1a6580795 100644 --- a/playbooks/common/openshift-cluster/set_etcd_launch_facts_tasks.yml +++ b/playbooks/common/openshift-cluster/tasks/set_etcd_launch_facts.yml diff --git a/playbooks/common/openshift-cluster/set_master_launch_facts_tasks.yml b/playbooks/common/openshift-cluster/tasks/set_master_launch_facts.yml index 36d7b7870..36d7b7870 100644 --- a/playbooks/common/openshift-cluster/set_master_launch_facts_tasks.yml +++ b/playbooks/common/openshift-cluster/tasks/set_master_launch_facts.yml diff --git a/playbooks/common/openshift-cluster/set_node_launch_facts_tasks.yml b/playbooks/common/openshift-cluster/tasks/set_node_launch_facts.yml index 96e1a9a63..278942f8b 100644 --- a/playbooks/common/openshift-cluster/set_node_launch_facts_tasks.yml +++ b/playbooks/common/openshift-cluster/tasks/set_node_launch_facts.yml @@ -1,11 +1,13 @@ --- -- set_fact: k8s_type="node" +- set_fact: k8s_type=node +- set_fact: sub_host_type="{{ type }}" +- set_fact: number_nodes="{{ count }}" - name: Generate node instance names(s) set_fact: - scratch_name: "{{ cluster_id }}-{{ k8s_type }}-{{ '%05x' | format(1048576 | random) }}" + scratch_name: "{{ cluster_id }}-{{ k8s_type }}-{{ sub_host_type }}-{{ '%05x' | format(1048576 | random) }}" register: node_names_output - with_sequence: count={{ num_nodes }} + with_sequence: count={{ number_nodes }} - set_fact: node_names: "{{ node_names_output.results | default([]) diff --git a/playbooks/common/openshift-cluster/update_repos_and_packages.yml b/playbooks/common/openshift-cluster/update_repos_and_packages.yml index e92c6f1ee..e3d16d359 100644 --- a/playbooks/common/openshift-cluster/update_repos_and_packages.yml +++ b/playbooks/common/openshift-cluster/update_repos_and_packages.yml @@ -1,7 +1,19 @@ --- +- include: evaluate_groups.yml + - hosts: oo_hosts_to_update vars: openshift_deployment_type: "{{ deployment_type }}" roles: + # Explicitly calling openshift_facts because it appears that when + # rhel_subscribe is skipped that the openshift_facts dependency for + # openshift_repos is also skipped (this is the case at least for Ansible + # 2.0.2) + - openshift_facts + - role: rhel_subscribe + when: deployment_type in ["enterprise", "atomic-enterprise", "openshift-enterprise"] and + ansible_distribution == "RedHat" and + lookup('oo_option', 'rhel_skip_subscription') | default(rhsub_skip, True) | + default('no', True) | lower in ['no', 'false'] - openshift_repos - os_update_latest diff --git a/playbooks/common/openshift-cluster/upgrades/atomic-openshift-master.j2 b/playbooks/common/openshift-cluster/upgrades/atomic-openshift-master.j2 new file mode 120000 index 000000000..2441f8887 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/atomic-openshift-master.j2 @@ -0,0 +1 @@ +../../../../roles/openshift_master/templates/atomic-openshift-master.j2
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/cleanup_unused_images.yml b/playbooks/common/openshift-cluster/upgrades/cleanup_unused_images.yml new file mode 100644 index 000000000..6e953be69 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/cleanup_unused_images.yml @@ -0,0 +1,22 @@ +--- +- name: Check Docker image count + shell: "docker images -aq | wc -l" + register: docker_image_count + when: docker_upgrade_nuke_images is defined and docker_upgrade_nuke_images | bool + +- debug: var=docker_image_count.stdout + when: docker_upgrade_nuke_images is defined and docker_upgrade_nuke_images | bool + +- name: Remove unused Docker images for Docker 1.10+ migration + shell: "docker rmi `docker images -aq`" + # Will fail on images still in use: + failed_when: false + when: docker_upgrade_nuke_images is defined and docker_upgrade_nuke_images | bool + +- name: Check Docker image count + shell: "docker images -aq | wc -l" + register: docker_image_count + when: docker_upgrade_nuke_images is defined and docker_upgrade_nuke_images | bool + +- debug: var=docker_image_count.stdout + when: docker_upgrade_nuke_images is defined and docker_upgrade_nuke_images | bool diff --git a/playbooks/common/openshift-cluster/upgrades/containerized_node_upgrade.yml b/playbooks/common/openshift-cluster/upgrades/containerized_node_upgrade.yml new file mode 100644 index 000000000..439df5ffd --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/containerized_node_upgrade.yml @@ -0,0 +1,9 @@ +- name: Update systemd units + include: ../../../../roles/openshift_node/tasks/systemd_units.yml openshift_version={{ openshift_image_tag }} + +- name: Verifying the correct version was configured + shell: grep {{ verify_upgrade_version }} {{ item }} + with_items: + - /etc/sysconfig/openvswitch + - /etc/sysconfig/{{ openshift.common.service_type }}* + when: verify_upgrade_version is defined diff --git a/playbooks/common/openshift-cluster/upgrades/create_service_signer_cert.yml b/playbooks/common/openshift-cluster/upgrades/create_service_signer_cert.yml new file mode 100644 index 000000000..23cf8cf76 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/create_service_signer_cert.yml @@ -0,0 +1,76 @@ +--- +- name: Create local temp directory for syncing certs + hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - name: Create local temp directory for syncing certs + local_action: command mktemp -d /tmp/openshift-ansible-XXXXXXX + register: local_cert_sync_tmpdir + changed_when: false + when: not (hostvars[groups.oo_first_master.0].service_signer_cert_stat.stat.exists | bool) + +- name: Create service signer certificate + hosts: oo_first_master + tasks: + - name: Create remote temp directory for creating certs + command: mktemp -d /tmp/openshift-ansible-XXXXXXX + register: remote_cert_create_tmpdir + changed_when: false + when: not (hostvars[groups.oo_first_master.0].service_signer_cert_stat.stat.exists | bool) + + - name: Create service signer certificate + command: > + {{ openshift.common.client_binary }} adm ca create-signer-cert + --cert="{{ remote_cert_create_tmpdir.stdout }}/"service-signer.crt + --key="{{ remote_cert_create_tmpdir.stdout }}/"service-signer.key + --name="{{ remote_cert_create_tmpdir.stdout }}/"openshift-service-serving-signer + --serial="{{ remote_cert_create_tmpdir.stdout }}/"service-signer.serial.txt + args: + chdir: "{{ remote_cert_create_tmpdir.stdout }}/" + when: not (hostvars[groups.oo_first_master.0].service_signer_cert_stat.stat.exists | bool) + + - name: Retrieve service signer certificate + fetch: + src: "{{ remote_cert_create_tmpdir.stdout }}/{{ item }}" + dest: "{{ hostvars.localhost.local_cert_sync_tmpdir.stdout }}/" + flat: yes + fail_on_missing: yes + validate_checksum: yes + with_items: + - "service-signer.crt" + - "service-signer.key" + when: not (hostvars[groups.oo_first_master.0].service_signer_cert_stat.stat.exists | bool) + + - name: Delete remote temp directory + file: + name: "{{ remote_cert_create_tmpdir.stdout }}" + state: absent + changed_when: false + when: not (hostvars[groups.oo_first_master.0].service_signer_cert_stat.stat.exists | bool) + +- name: Deploy service signer certificate + hosts: oo_masters_to_config + tasks: + - name: Deploy service signer certificate + copy: + src: "{{ hostvars.localhost.local_cert_sync_tmpdir.stdout }}/{{ item }}" + dest: "{{ openshift.common.config_base }}/master/" + with_items: + - "service-signer.crt" + - "service-signer.key" + when: not (hostvars[groups.oo_first_master.0].service_signer_cert_stat.stat.exists | bool) + +- name: Delete local temp directory + hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - name: Delete local temp directory + file: + name: "{{ local_cert_sync_tmpdir.stdout }}" + state: absent + changed_when: false + when: not (hostvars[groups.oo_first_master.0].service_signer_cert_stat.stat.exists | bool) diff --git a/playbooks/common/openshift-cluster/upgrades/docker-cluster b/playbooks/common/openshift-cluster/upgrades/docker-cluster new file mode 120000 index 000000000..055ad09fc --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/docker-cluster @@ -0,0 +1 @@ +../../../../roles/openshift_master/templates/docker-cluster
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/docker/upgrade.yml b/playbooks/common/openshift-cluster/upgrades/docker/upgrade.yml new file mode 100644 index 000000000..417096dd0 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/docker/upgrade.yml @@ -0,0 +1,66 @@ +--- +# We need docker service up to remove all the images, but these services will keep +# trying to re-start and thus re-pull the images we're trying to delete. +- name: Stop containerized services + service: name={{ item }} state=stopped + with_items: + - "{{ openshift.common.service_type }}-master" + - "{{ openshift.common.service_type }}-master-api" + - "{{ openshift.common.service_type }}-master-controllers" + - "{{ openshift.common.service_type }}-node" + - etcd_container + - openvswitch + failed_when: false + when: openshift.common.is_containerized | bool + +- name: Check Docker image count + shell: "docker images -aq | wc -l" + register: docker_image_count + +- debug: var=docker_image_count.stdout + +- name: Remove all containers and images + script: nuke_images.sh docker + register: nuke_images_result + when: docker_upgrade_nuke_images is defined and docker_upgrade_nuke_images | bool + +- name: Check Docker image count + shell: "docker images -aq | wc -l" + register: docker_image_count + when: docker_upgrade_nuke_images is defined and docker_upgrade_nuke_images | bool + +- debug: var=docker_image_count.stdout + when: docker_upgrade_nuke_images is defined and docker_upgrade_nuke_images | bool + +- service: name=docker state=stopped + +- name: Upgrade Docker + action: "{{ ansible_pkg_mgr }} name=docker{{ '-' + docker_version }} state=present" + +- service: name=docker state=started + +- name: Update docker facts + openshift_facts: + role: docker + +- name: Restart containerized services + service: name={{ item }} state=started + with_items: + - etcd_container + - openvswitch + - "{{ openshift.common.service_type }}-master" + - "{{ openshift.common.service_type }}-master-api" + - "{{ openshift.common.service_type }}-master-controllers" + - "{{ openshift.common.service_type }}-node" + failed_when: false + when: openshift.common.is_containerized | bool + +- name: Wait for master API to come back online + become: no + local_action: + module: wait_for + host="{{ inventory_hostname }}" + state=started + delay=10 + port="{{ openshift.master.api_port }}" + when: inventory_hostname in groups.oo_masters_to_config diff --git a/playbooks/common/openshift-cluster/upgrades/docker/upgrade_check.yml b/playbooks/common/openshift-cluster/upgrades/docker/upgrade_check.yml new file mode 100644 index 000000000..ee75aa853 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/docker/upgrade_check.yml @@ -0,0 +1,53 @@ +--- + +# This snippet determines if a Docker upgrade is required by checking the inventory +# variables, the available packages, and sets l_docker_upgrade to True if so. + +- set_fact: + docker_upgrade: True + when: docker_upgrade is not defined + +- name: Check if Docker is installed + command: rpm -q docker + register: pkg_check + failed_when: pkg_check.rc > 1 + changed_when: no + +- name: Get current version of Docker + command: "{{ repoquery_cmd }} --installed --qf '%{version}' docker" + register: curr_docker_version + changed_when: false + +- name: Get latest available version of Docker + command: > + {{ repoquery_cmd }} --qf '%{version}' "docker" + register: avail_docker_version + # Don't expect docker rpm to be available on hosts that don't already have it installed: + when: pkg_check.rc == 0 + failed_when: false + changed_when: false + +- fail: + msg: This playbook requires access to Docker 1.10 or later + # Disable the 1.10 requirement if the user set a specific Docker version + when: docker_version is not defined and (docker_upgrade is not defined or docker_upgrade | bool == True) and (pkg_check.rc == 0 and (avail_docker_version.stdout == "" or avail_docker_version.stdout | version_compare('1.10','<'))) + +# Default l_docker_upgrade to False, we'll set to True if an upgrade is required: +- set_fact: + l_docker_upgrade: False + +# Make sure a docker_version is set if none was requested: +- set_fact: + docker_version: "{{ avail_docker_version.stdout }}" + when: pkg_check.rc == 0 and docker_version is not defined + +- name: Flag for Docker upgrade if necessary + set_fact: + l_docker_upgrade: True + when: pkg_check.rc == 0 and curr_docker_version.stdout | version_compare(docker_version,'<') + +- name: Flag to delete all images prior to upgrade if crossing Docker 1.10 boundary + set_fact: + docker_upgrade_nuke_images: True + when: l_docker_upgrade | bool and docker_upgrade_nuke_images is not defined and curr_docker_version.stdout | version_compare('1.10','<') and docker_version | version_compare('1.10','>=') + diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/backup.yml b/playbooks/common/openshift-cluster/upgrades/etcd/backup.yml new file mode 100644 index 000000000..57b156b1c --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/etcd/backup.yml @@ -0,0 +1,73 @@ +- name: Backup etcd + hosts: etcd_hosts_to_backup + vars: + embedded_etcd: "{{ hostvars[groups.oo_first_master.0].openshift.master.embedded_etcd }}" + timestamp: "{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}" + roles: + - openshift_facts + tasks: + # Ensure we persist the etcd role for this host in openshift_facts + - openshift_facts: + role: etcd + local_facts: {} + when: "'etcd' not in openshift" + + - stat: path=/var/lib/openshift + register: var_lib_openshift + + - stat: path=/var/lib/origin + register: var_lib_origin + + - name: Create origin symlink if necessary + file: src=/var/lib/openshift/ dest=/var/lib/origin state=link + when: var_lib_openshift.stat.exists == True and var_lib_origin.stat.exists == False + + # TODO: replace shell module with command and update later checks + # We assume to be using the data dir for all backups. + - name: Check available disk space for etcd backup + shell: df --output=avail -k {{ openshift.common.data_dir }} | tail -n 1 + register: avail_disk + + # TODO: replace shell module with command and update later checks + - name: Check current embedded etcd disk usage + shell: du -k {{ openshift.etcd.etcd_data_dir }} | tail -n 1 | cut -f1 + register: etcd_disk_usage + when: embedded_etcd | bool + + - name: Abort if insufficient disk space for etcd backup + fail: + msg: > + {{ etcd_disk_usage.stdout }} Kb disk space required for etcd backup, + {{ avail_disk.stdout }} Kb available. + when: (embedded_etcd | bool) and (etcd_disk_usage.stdout|int > avail_disk.stdout|int) + + - name: Install etcd (for etcdctl) + action: "{{ ansible_pkg_mgr }} name=etcd state=present" + when: not openshift.common.is_atomic | bool + + - name: Generate etcd backup + command: > + etcdctl backup --data-dir={{ openshift.etcd.etcd_data_dir }} + --backup-dir={{ openshift.common.data_dir }}/etcd-backup-{{ backup_tag | default('') }}{{ timestamp }} + + - set_fact: + etcd_backup_complete: True + + - name: Display location of etcd backup + debug: + msg: "Etcd backup created in {{ openshift.common.data_dir }}/etcd-backup-{{ backup_tag | default('') }}{{ timestamp }}" + +- name: Gate on etcd backup + hosts: localhost + connection: local + become: no + tasks: + - set_fact: + etcd_backup_completed: "{{ hostvars + | oo_select_keys(groups.etcd_hosts_to_backup) + | oo_collect('inventory_hostname', {'etcd_backup_complete': true}) }}" + - set_fact: + etcd_backup_failed: "{{ groups.etcd_hosts_to_backup | difference(etcd_backup_completed) }}" + - fail: + msg: "Upgrade cannot continue. The following hosts did not complete etcd backup: {{ etcd_backup_failed | join(',') }}" + when: etcd_backup_failed | length > 0 diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/containerized_tasks.yml b/playbooks/common/openshift-cluster/upgrades/etcd/containerized_tasks.yml new file mode 100644 index 000000000..35f391f8c --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/etcd/containerized_tasks.yml @@ -0,0 +1,47 @@ +--- +- name: Verify cluster is healthy pre-upgrade + command: "etcdctl --cert-file /etc/etcd/peer.crt --key-file /etc/etcd/peer.key --ca-file /etc/etcd/ca.crt -C https://{{ openshift.common.hostname }}:2379 cluster-health" + +- name: Get current image + shell: grep 'ExecStart=' /etc/systemd/system/etcd_container.service | awk '{print $NF}' + register: current_image + +- name: Set new_etcd_image + set_fact: + new_etcd_image: "{{ current_image.stdout | regex_replace('/etcd.*$','/etcd3:' ~ upgrade_version ) if upgrade_version | version_compare('3.0','>=') + else current_image.stdout.split(':')[0] ~ ':' ~ upgrade_version }}" + +- name: Pull new etcd image + command: "docker pull {{ new_etcd_image }}" + +- name: Update to latest etcd image + replace: + dest: /etc/systemd/system/etcd_container.service + regexp: "{{ current_image.stdout }}$" + replace: "{{ new_etcd_image }}" + +- name: Restart etcd_container + systemd: + name: etcd_container + daemon_reload: yes + state: restarted + +## TODO: probably should just move this into the backup playbooks, also this +## will fail on atomic host. We need to revisit how to do etcd backups there as +## the container may be newer than etcdctl on the host. Assumes etcd3 obsoletes etcd (7.3.1) +- name: Upgrade etcd for etcdctl when not atomic + action: "{{ ansible_pkg_mgr }} name=etcd ensure=latest" + when: not openshift.common.is_atomic | bool + +- name: Verify cluster is healthy + command: "etcdctl --cert-file /etc/etcd/peer.crt --key-file /etc/etcd/peer.key --ca-file /etc/etcd/ca.crt -C https://{{ openshift.common.hostname }}:2379 cluster-health" + register: etcdctl + until: etcdctl.rc == 0 + retries: 3 + delay: 10 + +- name: Store new etcd_image + openshift_facts: + role: etcd + local_facts: + etcd_image: "{{ new_etcd_image }}" diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/fedora_tasks.yml b/playbooks/common/openshift-cluster/upgrades/etcd/fedora_tasks.yml new file mode 100644 index 000000000..30232110e --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/etcd/fedora_tasks.yml @@ -0,0 +1,23 @@ +--- +# F23 GA'd with etcd 2.0, currently has 2.2 in updates +# F24 GA'd with etcd-2.2, currently has 2.2 in updates +# F25 Beta currently has etcd 3.0 +- name: Verify cluster is healthy pre-upgrade + command: "etcdctl --cert-file /etc/etcd/peer.crt --key-file /etc/etcd/peer.key --ca-file /etc/etcd/ca.crt -C https://{{ openshift.common.hostname }}:2379 cluster-health" + +- name: Update etcd + package: + name: "etcd" + state: "latest" + +- name: Restart etcd + service: + name: etcd + state: restarted + +- name: Verify cluster is healthy + command: "etcdctl --cert-file /etc/etcd/peer.crt --key-file /etc/etcd/peer.key --ca-file /etc/etcd/ca.crt -C https://{{ openshift.common.hostname }}:2379 cluster-health" + register: etcdctl + until: etcdctl.rc == 0 + retries: 3 + delay: 10 diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/files/etcdctl.sh b/playbooks/common/openshift-cluster/upgrades/etcd/files/etcdctl.sh new file mode 120000 index 000000000..641e04e44 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/etcd/files/etcdctl.sh @@ -0,0 +1 @@ +../roles/etcd/files/etcdctl.sh
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/filter_plugins b/playbooks/common/openshift-cluster/upgrades/etcd/filter_plugins new file mode 120000 index 000000000..27ddaa18b --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/etcd/filter_plugins @@ -0,0 +1 @@ +../../../../../filter_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/lookup_plugins b/playbooks/common/openshift-cluster/upgrades/etcd/lookup_plugins new file mode 120000 index 000000000..cf407f69b --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/etcd/lookup_plugins @@ -0,0 +1 @@ +../../../../../lookup_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/main.yml b/playbooks/common/openshift-cluster/upgrades/etcd/main.yml new file mode 100644 index 000000000..cce844403 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/etcd/main.yml @@ -0,0 +1,122 @@ +--- +# For 1.4/3.4 we want to upgrade everyone to etcd-3.0. etcd docs say to +# upgrade from 2.0.x to 2.1.x to 2.2.x to 2.3.x to 3.0.x. While this is a tedius +# task for RHEL and CENTOS it's simply not possible in Fedora unless you've +# mirrored packages on your own because only the GA and latest versions are +# available in the repos. So for Fedora we'll simply skip this, sorry. + +- include: ../../evaluate_groups.yml + tags: + - always + +- name: Evaluate additional groups for upgrade + hosts: localhost + connection: local + become: no + tasks: + - name: Evaluate etcd_hosts_to_upgrade + add_host: + name: "{{ item }}" + groups: etcd_hosts_to_upgrade, etcd_hosts_to_backup + with_items: "{{ groups.oo_etcd_to_config if groups.oo_etcd_to_config is defined and groups.oo_etcd_to_config | length > 0 else groups.oo_first_master }}" + +- name: Backup etcd before upgrading anything + include: backup.yml + vars: + backup_tag: "pre-upgrade-" + +- name: Drop etcdctl profiles + hosts: etcd_hosts_to_upgrade + tasks: + - include: roles/etcd/tasks/etcdctl.yml + +- name: Determine etcd version + hosts: etcd_hosts_to_upgrade + tasks: + - name: Record RPM based etcd version + command: rpm -qa --qf '%{version}' etcd\* + register: etcd_installed_version + failed_when: false + when: not openshift.common.is_containerized | bool + - name: Record containerized etcd version + command: docker exec etcd_container rpm -qa --qf '%{version}' etcd\* + register: etcd_installed_version + failed_when: false + when: openshift.common.is_containerized | bool + +# I really dislike this copy/pasta but I wasn't able to find a way to get it to loop +# through hosts, then loop through tasks only when appropriate +- name: Upgrade to 2.1 + hosts: etcd_hosts_to_upgrade + serial: 1 + vars: + upgrade_version: '2.1' + tasks: + - include: rhel_tasks.yml + when: etcd_installed_version.stdout | default('99') | version_compare('2.1','<') and ansible_distribution == 'RedHat' and not openshift.common.is_containerized | bool + +- name: Upgrade RPM hosts to 2.2 + hosts: etcd_hosts_to_upgrade + serial: 1 + vars: + upgrade_version: '2.2' + tasks: + - include: rhel_tasks.yml + when: etcd_installed_version.stdout | default('99') | version_compare('2.2','<') and ansible_distribution == 'RedHat' and not openshift.common.is_containerized | bool + +- name: Upgrade containerized hosts to 2.2.5 + hosts: etcd_hosts_to_upgrade + serial: 1 + vars: + upgrade_version: 2.2.5 + tasks: + - include: containerized_tasks.yml + when: etcd_installed_version.stdout | default('99') | version_compare('2.2','<') and openshift.common.is_containerized | bool + +- name: Upgrade RPM hosts to 2.3 + hosts: etcd_hosts_to_upgrade + serial: 1 + vars: + upgrade_version: '2.3' + tasks: + - include: rhel_tasks.yml + when: etcd_installed_version.stdout | default('99') | version_compare('2.3','<') and ansible_distribution == 'RedHat' and not openshift.common.is_containerized | bool + +- name: Upgrade containerized hosts to 2.3.7 + hosts: etcd_hosts_to_upgrade + serial: 1 + vars: + upgrade_version: 2.3.7 + tasks: + - include: containerized_tasks.yml + when: etcd_installed_version.stdout | default('99') | version_compare('2.3','<') and openshift.common.is_containerized | bool + +- name: Upgrade RPM hosts to 3.0 + hosts: etcd_hosts_to_upgrade + serial: 1 + vars: + upgrade_version: '3.0' + tasks: + - include: rhel_tasks.yml + when: etcd_installed_version.stdout | default('99') | version_compare('3.0','<') and ansible_distribution == 'RedHat' and not openshift.common.is_containerized | bool + +- name: Upgrade containerized hosts to etcd3 image + hosts: etcd_hosts_to_upgrade + serial: 1 + vars: + upgrade_version: 3.0.3 + tasks: + - include: containerized_tasks.yml + when: etcd_installed_version.stdout | default('99') | version_compare('3.0','<') and openshift.common.is_containerized | bool + +- name: Upgrade fedora to latest + hosts: etcd_hosts_to_upgrade + serial: 1 + tasks: + - include: fedora_tasks.yml + when: ansible_distribution == 'Fedora' and not openshift.common.is_containerized | bool + +- name: Backup etcd + include: backup.yml + vars: + backup_tag: "post-3.0-" diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/rhel_tasks.yml b/playbooks/common/openshift-cluster/upgrades/etcd/rhel_tasks.yml new file mode 100644 index 000000000..8e7dc9d9b --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/etcd/rhel_tasks.yml @@ -0,0 +1,23 @@ +--- +- name: Verify cluster is healthy pre-upgrade + command: "etcdctl --cert-file /etc/etcd/peer.crt --key-file /etc/etcd/peer.key --ca-file /etc/etcd/ca.crt -C https://{{ openshift.common.hostname }}:2379 cluster-health" + +- name: Update etcd package but exclude etcd3 + command: "{{ ansible_pkg_mgr }} install -y etcd-{{ upgrade_version }}\\* --exclude etcd3" + when: upgrade_version | version_compare('3.0','<') + +- name: Update etcd package not excluding etcd3 + command: "{{ ansible_pkg_mgr }} install -y etcd3-{{ upgrade_version }}\\*" + when: not upgrade_version | version_compare('3.0','<') + +- name: Restart etcd + service: + name: etcd + state: restarted + +- name: Verify cluster is healthy + command: "etcdctl --cert-file /etc/etcd/peer.crt --key-file /etc/etcd/peer.key --ca-file /etc/etcd/ca.crt -C https://{{ openshift.common.hostname }}:2379 cluster-health" + register: etcdctl + until: etcdctl.rc == 0 + retries: 3 + delay: 10 diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/roles b/playbooks/common/openshift-cluster/upgrades/etcd/roles new file mode 120000 index 000000000..6bc1a7aef --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/etcd/roles @@ -0,0 +1 @@ +../../../../../roles
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/files/nuke_images.sh b/playbooks/common/openshift-cluster/upgrades/files/nuke_images.sh new file mode 100644 index 000000000..8635eab0d --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/files/nuke_images.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Stop any running containers +running_container_ids=`docker ps -q` +if test -n "$running_container_ids" +then + docker stop $running_container_ids +fi + +# Delete all containers +container_ids=`docker ps -a -q` +if test -n "$container_ids" +then + docker rm -f -v $container_ids +fi + +# Delete all images (forcefully) +image_ids=`docker images -aq` +if test -n "$image_ids" +then + # Some layers are deleted recursively and are no longer present + # when docker goes to remove them: + docker rmi -f `docker images -aq` || true +fi + diff --git a/playbooks/common/openshift-cluster/upgrades/files/pre-upgrade-check b/playbooks/common/openshift-cluster/upgrades/files/pre-upgrade-check new file mode 100644 index 000000000..e5c958ebb --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/files/pre-upgrade-check @@ -0,0 +1,193 @@ +#!/usr/bin/env python +""" +Pre-upgrade checks that must be run on a master before proceeding with upgrade. +""" +# This is a script not a python module: +# pylint: disable=invalid-name + +# NOTE: This script should not require any python libs other than what is +# in the standard library. + +__license__ = "ASL 2.0" + +import json +import os +import subprocess +import re + +# The maximum length of container.ports.name +ALLOWED_LENGTH = 15 +# The valid structure of container.ports.name +ALLOWED_CHARS = re.compile('^[a-z0-9][a-z0-9\\-]*[a-z0-9]$') +AT_LEAST_ONE_LETTER = re.compile('[a-z]') +# look at OS_PATH for the full path. Default ot 'oc' +OC_PATH = os.getenv('OC_PATH', 'oc') + + +def validate(value): + """ + validate verifies that value matches required conventions + + Rules of container.ports.name validation: + + * must be less that 16 chars + * at least one letter + * only a-z0-9- + * hyphens can not be leading or trailing or next to each other + + :Parameters: + - `value`: Value to validate + """ + if len(value) > ALLOWED_LENGTH: + return False + + if '--' in value: + return False + + # We search since it can be anywhere + if not AT_LEAST_ONE_LETTER.search(value): + return False + + # We match because it must start at the beginning + if not ALLOWED_CHARS.match(value): + return False + return True + + +def list_items(kind): + """ + list_items returns a list of items from the api + + :Parameters: + - `kind`: Kind of item to access + """ + response = subprocess.check_output([OC_PATH, 'get', '--all-namespaces', '-o', 'json', kind]) + items = json.loads(response) + return items.get("items", []) + + +def get(obj, *paths): + """ + Gets an object + + :Parameters: + - `obj`: A dictionary structure + - `path`: All other non-keyword arguments + """ + ret_obj = obj + for path in paths: + if ret_obj.get(path, None) is None: + return [] + ret_obj = ret_obj[path] + return ret_obj + + +# pylint: disable=too-many-arguments +def pretty_print_errors(namespace, kind, item_name, container_name, invalid_label, port_name, valid): + """ + Prints out results in human friendly way. + + :Parameters: + - `namespace`: Namespace of the resource + - `kind`: Kind of the resource + - `item_name`: Name of the resource + - `container_name`: Name of the container. May be "" when kind=Service. + - `port_name`: Name of the port + - `invalid_label`: The label of the invalid port. Port.name/targetPort + - `valid`: True if the port is valid + """ + if not valid: + if len(container_name) > 0: + print('%s/%s -n %s (Container="%s" %s="%s")' % ( + kind, item_name, namespace, container_name, invalid_label, port_name)) + else: + print('%s/%s -n %s (%s="%s")' % ( + kind, item_name, namespace, invalid_label, port_name)) + + +def print_validation_header(): + """ + Prints the error header. Should run on the first error to avoid + overwhelming the user. + """ + print """\ +At least one port name is invalid and must be corrected before upgrading. +Please update or remove any resources with invalid port names. + + Valid port names must: + + * be less that 16 characters + * have at least one letter + * contain only a-z0-9- + * not start or end with - + * not contain dashes next to each other ('--') +""" + + +def main(): + """ + main is the main entry point to this script + """ + try: + # the comma at the end suppresses the newline + print "Checking for oc ...", + subprocess.check_output([OC_PATH, 'whoami']) + print "found" + except: + print( + 'Unable to run "%s whoami"\n' + 'Please ensure OpenShift is running, and "oc" is on your system ' + 'path.\n' + 'You can override the path with the OC_PATH environment variable.' + % OC_PATH) + raise SystemExit(1) + + # Where the magic happens + first_error = True + for kind, path in [ + ('deploymentconfigs', ("spec", "template", "spec", "containers")), + ('replicationcontrollers', ("spec", "template", "spec", "containers")), + ('pods', ("spec", "containers"))]: + for item in list_items(kind): + namespace = item["metadata"]["namespace"] + item_name = item["metadata"]["name"] + for container in get(item, *path): + container_name = container["name"] + for port in get(container, "ports"): + port_name = port.get("name", None) + if not port_name: + # Unnamed ports are OK + continue + valid = validate(port_name) + if not valid and first_error: + first_error = False + print_validation_header() + pretty_print_errors( + namespace, kind, item_name, + container_name, "Port.name", port_name, valid) + + # Services follow a different flow + for item in list_items('services'): + namespace = item["metadata"]["namespace"] + item_name = item["metadata"]["name"] + for port in get(item, "spec", "ports"): + port_name = port.get("targetPort", None) + if isinstance(port_name, int) or port_name is None: + # Integer only or unnamed ports are OK + continue + valid = validate(port_name) + if not valid and first_error: + first_error = False + print_validation_header() + pretty_print_errors( + namespace, "services", item_name, "", + "targetPort", port_name, valid) + + # If we had at least 1 error then exit with 1 + if not first_error: + raise SystemExit(1) + + +if __name__ == '__main__': + main() + diff --git a/playbooks/common/openshift-cluster/upgrades/files/rpm_versions.sh b/playbooks/common/openshift-cluster/upgrades/files/rpm_versions.sh new file mode 100644 index 000000000..7bf249742 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/files/rpm_versions.sh @@ -0,0 +1,12 @@ +#!/bin/bash +if [ `which dnf 2> /dev/null` ]; then + installed=$(dnf repoquery --installed --latest-limit 1 -d 0 --qf '%{version}-%{release}' "${@}" 2> /dev/null) + available=$(dnf repoquery --available --latest-limit 1 -d 0 --qf '%{version}-%{release}' "${@}" 2> /dev/null) +else + installed=$(repoquery --plugins --pkgnarrow=installed --qf '%{version}-%{release}' "${@}" 2> /dev/null) + available=$(repoquery --plugins --pkgnarrow=available --qf '%{version}-%{release}' "${@}" 2> /dev/null) +fi + +echo "---" +echo "curr_version: ${installed}" +echo "avail_version: ${available}" diff --git a/playbooks/common/openshift-cluster/upgrades/filter_plugins b/playbooks/common/openshift-cluster/upgrades/filter_plugins new file mode 120000 index 000000000..b1213dedb --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/filter_plugins @@ -0,0 +1 @@ +../../../../filter_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/init.yml b/playbooks/common/openshift-cluster/upgrades/init.yml new file mode 100644 index 000000000..fbdb7900a --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/init.yml @@ -0,0 +1,50 @@ +--- +- include: ../verify_ansible_version.yml + +- hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - include_vars: ../../../byo/openshift-cluster/cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: ../../../byo/openshift-cluster/cluster_hosts.yml + +- include: ../evaluate_groups.yml + vars: + # Do not allow adding hosts during upgrade. + g_new_master_hosts: [] + g_new_node_hosts: [] + openshift_cluster_id: "{{ cluster_id | default('default') }}" + openshift_deployment_type: "{{ deployment_type }}" + +- name: Set oo_options + hosts: oo_all_hosts + tasks: + - set_fact: + openshift_docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries') }}" + when: openshift_docker_additional_registries is not defined + - set_fact: + openshift_docker_insecure_registries: "{{ lookup('oo_option', 'docker_insecure_registries') }}" + when: openshift_docker_insecure_registries is not defined + - set_fact: + openshift_docker_blocked_registries: "{{ lookup('oo_option', 'docker_blocked_registries') }}" + when: openshift_docker_blocked_registries is not defined + - set_fact: + openshift_docker_options: "{{ lookup('oo_option', 'docker_options') }}" + when: openshift_docker_options is not defined + - set_fact: + openshift_docker_log_driver: "{{ lookup('oo_option', 'docker_log_driver') }}" + when: openshift_docker_log_driver is not defined + - set_fact: + openshift_docker_log_options: "{{ lookup('oo_option', 'docker_log_options') }}" + when: openshift_docker_log_options is not defined + +- include: ../initialize_facts.yml diff --git a/playbooks/common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml b/playbooks/common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml new file mode 100644 index 000000000..4e375ac26 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml @@ -0,0 +1,40 @@ +--- +- name: Filter list of nodes to be upgraded if necessary + hosts: oo_first_master + tasks: + - name: Retrieve list of openshift nodes matching upgrade label + command: > + {{ openshift.common.client_binary }} + get nodes + --config={{ openshift.common.config_base }}/master/admin.kubeconfig + --selector={{ openshift_upgrade_nodes_label }} + -o jsonpath='{.items[*].metadata.name}' + register: matching_nodes + changed_when: false + when: openshift_upgrade_nodes_label is defined + + - set_fact: + nodes_to_upgrade: "{{ matching_nodes.stdout.split(' ') }}" + when: openshift_upgrade_nodes_label is defined + + # We got a list of nodes with the label, now we need to match these with inventory hosts + # using their openshift.common.hostname fact. + - name: Map labelled nodes to inventory hosts + add_host: + name: "{{ item }}" + groups: temp_nodes_to_upgrade + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: " {{ groups['oo_nodes_to_config'] }}" + when: openshift_upgrade_nodes_label is defined and hostvars[item].openshift.common.hostname in nodes_to_upgrade + changed_when: false + + # Build up the oo_nodes_to_upgrade group, use the list filtered by label if + # present, otherwise hit all nodes: + - name: Evaluate oo_nodes_to_upgrade + add_host: + name: "{{ item }}" + groups: oo_nodes_to_upgrade + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ groups['temp_nodes_to_upgrade'] | default(groups['oo_nodes_to_config']) }}" diff --git a/playbooks/common/openshift-cluster/upgrades/library/openshift_upgrade_config.py b/playbooks/common/openshift-cluster/upgrades/library/openshift_upgrade_config.py new file mode 100755 index 000000000..9a065fd1c --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/library/openshift_upgrade_config.py @@ -0,0 +1,158 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# vim: expandtab:tabstop=4:shiftwidth=4 + +"""Ansible module for modifying OpenShift configs during an upgrade""" + +import os +import yaml + +DOCUMENTATION = ''' +--- +module: openshift_upgrade_config +short_description: OpenShift Upgrade Config +author: Jason DeTiberus +requirements: [ ] +''' +EXAMPLES = ''' +''' + +def modify_api_levels(level_list, remove, ensure, msg_prepend='', + msg_append=''): + """ modify_api_levels """ + changed = False + changes = [] + + if not isinstance(remove, list): + remove = [] + + if not isinstance(ensure, list): + ensure = [] + + if not isinstance(level_list, list): + new_list = [] + changed = True + changes.append("%s created missing %s" % (msg_prepend, msg_append)) + else: + new_list = level_list + for level in remove: + if level in new_list: + new_list.remove(level) + changed = True + changes.append("%s removed %s %s" % (msg_prepend, level, msg_append)) + + for level in ensure: + if level not in new_list: + new_list.append(level) + changed = True + changes.append("%s added %s %s" % (msg_prepend, level, msg_append)) + + return {'new_list': new_list, 'changed': changed, 'changes': changes} + + +def upgrade_master_3_0_to_3_1(ansible_module, config_base, backup): + """Main upgrade method for 3.0 to 3.1.""" + changes = [] + + # Facts do not get transferred to the hosts where custom modules run, + # need to make some assumptions here. + master_config = os.path.join(config_base, 'master/master-config.yaml') + + master_cfg_file = open(master_config, 'r') + config = yaml.safe_load(master_cfg_file.read()) + master_cfg_file.close() + + + # Remove unsupported api versions and ensure supported api versions from + # master config + unsupported_levels = ['v1beta1', 'v1beta2', 'v1beta3'] + supported_levels = ['v1'] + + result = modify_api_levels(config.get('apiLevels'), unsupported_levels, + supported_levels, 'master-config.yaml:', 'from apiLevels') + if result['changed']: + config['apiLevels'] = result['new_list'] + changes.append(result['changes']) + + if 'kubernetesMasterConfig' in config and 'apiLevels' in config['kubernetesMasterConfig']: + config['kubernetesMasterConfig'].pop('apiLevels') + changes.append('master-config.yaml: removed kubernetesMasterConfig.apiLevels') + + # Add masterCA to serviceAccountConfig + if 'serviceAccountConfig' in config and 'masterCA' not in config['serviceAccountConfig']: + config['serviceAccountConfig']['masterCA'] = config['oauthConfig'].get('masterCA', 'ca.crt') + + # Add proxyClientInfo to master-config + if 'proxyClientInfo' not in config['kubernetesMasterConfig']: + config['kubernetesMasterConfig']['proxyClientInfo'] = { + 'certFile': 'master.proxy-client.crt', + 'keyFile': 'master.proxy-client.key' + } + changes.append("master-config.yaml: added proxyClientInfo") + + if len(changes) > 0: + if backup: + # TODO: Check success: + ansible_module.backup_local(master_config) + + # Write the modified config: + out_file = open(master_config, 'w') + out_file.write(yaml.safe_dump(config, default_flow_style=False)) + out_file.close() + + return changes + + +def upgrade_master(ansible_module, config_base, from_version, to_version, backup): + """Upgrade entry point.""" + if from_version == '3.0': + if to_version == '3.1': + return upgrade_master_3_0_to_3_1(ansible_module, config_base, backup) + + +def main(): + """ main """ + # disabling pylint errors for global-variable-undefined and invalid-name + # for 'global module' usage, since it is required to use ansible_facts + # pylint: disable=global-variable-undefined, invalid-name, + # redefined-outer-name + global module + + module = AnsibleModule( + argument_spec=dict( + config_base=dict(required=True), + from_version=dict(required=True, choices=['3.0']), + to_version=dict(required=True, choices=['3.1']), + role=dict(required=True, choices=['master']), + backup=dict(required=False, default=True, type='bool') + ), + supports_check_mode=True, + ) + + from_version = module.params['from_version'] + to_version = module.params['to_version'] + role = module.params['role'] + backup = module.params['backup'] + config_base = module.params['config_base'] + + try: + changes = [] + if role == 'master': + changes = upgrade_master(module, config_base, from_version, + to_version, backup) + + changed = len(changes) > 0 + return module.exit_json(changed=changed, changes=changes) + + # ignore broad-except error to avoid stack trace to ansible user + # pylint: disable=broad-except + except Exception, e: + return module.fail_json(msg=str(e)) + +# ignore pylint errors related to the module_utils import +# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import +# import module snippets +from ansible.module_utils.basic import * + +if __name__ == '__main__': + main() diff --git a/playbooks/common/openshift-cluster/upgrades/lookup_plugins b/playbooks/common/openshift-cluster/upgrades/lookup_plugins new file mode 120000 index 000000000..aff753026 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/lookup_plugins @@ -0,0 +1 @@ +../../../../lookup_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/master_docker b/playbooks/common/openshift-cluster/upgrades/master_docker new file mode 120000 index 000000000..6aeca2842 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/master_docker @@ -0,0 +1 @@ +../../../../roles/openshift_master/templates/master_docker
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/native-cluster b/playbooks/common/openshift-cluster/upgrades/native-cluster new file mode 120000 index 000000000..4af88e666 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/native-cluster @@ -0,0 +1 @@ +../../../../roles/openshift_master/templates/native-cluster
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/openshift.docker.node.dep.service b/playbooks/common/openshift-cluster/upgrades/openshift.docker.node.dep.service new file mode 120000 index 000000000..add8b7fa9 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/openshift.docker.node.dep.service @@ -0,0 +1 @@ +../../../../roles/openshift_node/templates/openshift.docker.node.dep.service
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/openshift.docker.node.service b/playbooks/common/openshift-cluster/upgrades/openshift.docker.node.service new file mode 120000 index 000000000..ed181633d --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/openshift.docker.node.service @@ -0,0 +1 @@ +../../../../roles/openshift_node/templates/openshift.docker.node.service
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/openvswitch-avoid-oom.conf b/playbooks/common/openshift-cluster/upgrades/openvswitch-avoid-oom.conf new file mode 120000 index 000000000..514526fe2 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/openvswitch-avoid-oom.conf @@ -0,0 +1 @@ +../../../../roles/openshift_node/templates/openvswitch-avoid-oom.conf
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/openvswitch.docker.service b/playbooks/common/openshift-cluster/upgrades/openvswitch.docker.service new file mode 120000 index 000000000..c21e895f2 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/openvswitch.docker.service @@ -0,0 +1 @@ +../../../../roles/openshift_node/templates/openvswitch.docker.service
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/openvswitch.sysconfig.j2 b/playbooks/common/openshift-cluster/upgrades/openvswitch.sysconfig.j2 new file mode 120000 index 000000000..ead6904c4 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/openvswitch.sysconfig.j2 @@ -0,0 +1 @@ +../../../../roles/openshift_node/templates/openvswitch.sysconfig.j2
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml new file mode 100644 index 000000000..2bbcbe1f8 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml @@ -0,0 +1,76 @@ +--- +############################################################################### +# Post upgrade - Upgrade default router, default registry and examples +############################################################################### +- name: Upgrade default router and default registry + hosts: oo_first_master + vars: + openshift_deployment_type: "{{ deployment_type }}" + registry_image: "{{ openshift.master.registry_url | replace( '${component}', 'docker-registry' ) | replace ( '${version}', openshift_image_tag ) }}" + router_image: "{{ openshift.master.registry_url | replace( '${component}', 'haproxy-router' ) | replace ( '${version}', openshift_image_tag ) }}" + oc_cmd: "{{ openshift.common.client_binary }} --config={{ openshift.common.config_base }}/master/admin.kubeconfig" + roles: + - openshift_manageiq + # Create the new templates shipped in 3.2, existing templates are left + # unmodified. This prevents the subsequent role definition for + # openshift_examples from failing when trying to replace templates that do + # not already exist. We could have potentially done a replace --force to + # create and update in one step. + - openshift_examples + - openshift_hosted_templates + # Update the existing templates + - role: openshift_examples + registry_url: "{{ openshift.master.registry_url }}" + openshift_examples_import_command: replace + - role: openshift_hosted_templates + registry_url: "{{ openshift.master.registry_url }}" + openshift_hosted_templates_import_command: replace + pre_tasks: + - name: Collect all routers + command: > + {{ oc_cmd }} get pods --all-namespaces -l 'router' -o json + register: all_routers + failed_when: false + changed_when: false + + - set_fact: haproxy_routers="{{ (all_routers.stdout | from_json)['items'] | oo_pods_match_component(openshift_deployment_type, 'haproxy-router') | oo_select_keys_from_list(['metadata']) }}" + when: all_routers.rc == 0 + + - set_fact: haproxy_routers=[] + when: all_routers.rc != 0 + + - name: Update router image to current version + when: all_routers.rc == 0 + command: > + {{ oc_cmd }} patch dc/{{ item['labels']['deploymentconfig'] }} -n {{ item['namespace'] }} -p + '{"spec":{"template":{"spec":{"containers":[{"name":"router","image":"{{ router_image }}","livenessProbe":{"tcpSocket":null,"httpGet":{"path": "/healthz", "port": 1936, "host": "localhost", "scheme": "HTTP"},"initialDelaySeconds":10,"timeoutSeconds":1}}]}}}}' + --api-version=v1 + with_items: "{{ haproxy_routers }}" + + - name: Check for default registry + command: > + {{ oc_cmd }} get -n default dc/docker-registry + register: _default_registry + failed_when: false + changed_when: false + + - name: Update registry image to current version + when: _default_registry.rc == 0 + command: > + {{ oc_cmd }} patch dc/docker-registry -n default -p + '{"spec":{"template":{"spec":{"containers":[{"name":"registry","image":"{{ registry_image }}"}]}}}}' + --api-version=v1 + +# Check for warnings to be printed at the end of the upgrade: +- name: Check for warnings + hosts: oo_masters_to_config + tasks: + # Check if any masters are using pluginOrderOverride and warn if so, only for 1.3/3.3 and beyond: + - command: > + grep pluginOrderOverride {{ openshift.common.config_base }}/master/master-config.yaml + register: grep_plugin_order_override + when: openshift.common.version_gte_3_3_or_1_3 | bool + failed_when: false + - name: Warn if pluginOrderOverride is in use in master-config.yaml + debug: msg="WARNING pluginOrderOverride is being deprecated in master-config.yaml, please see https://docs.openshift.com/enterprise/latest/architecture/additional_concepts/admission_controllers.html for more information." + when: not grep_plugin_order_override | skipped and grep_plugin_order_override.rc == 0 diff --git a/playbooks/common/openshift-cluster/upgrades/pre/gate_checks.yml b/playbooks/common/openshift-cluster/upgrades/pre/gate_checks.yml new file mode 100644 index 000000000..8ecae4539 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/pre/gate_checks.yml @@ -0,0 +1,6 @@ +--- +- name: Flag pre-upgrade checks complete for hosts without errors + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config + tasks: + - set_fact: + pre_upgrade_complete: True diff --git a/playbooks/common/openshift-cluster/upgrades/pre/roles b/playbooks/common/openshift-cluster/upgrades/pre/roles new file mode 120000 index 000000000..415645be6 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/pre/roles @@ -0,0 +1 @@ +../../../../../roles/
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/pre/verify_control_plane_running.yml b/playbooks/common/openshift-cluster/upgrades/pre/verify_control_plane_running.yml new file mode 100644 index 000000000..06eb5f936 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/pre/verify_control_plane_running.yml @@ -0,0 +1,31 @@ +--- +- name: Verify master processes + hosts: oo_masters_to_config + roles: + - openshift_facts + tasks: + - openshift_facts: + role: master + local_facts: + ha: "{{ groups.oo_masters_to_config | length > 1 }}" + + - name: Ensure Master is running + service: + name: "{{ openshift.common.service_type }}-master" + state: started + enabled: yes + when: openshift.master.ha is defined and not openshift.master.ha | bool and openshift.common.is_containerized | bool + + - name: Ensure HA Master is running + service: + name: "{{ openshift.common.service_type }}-master-api" + state: started + enabled: yes + when: openshift.master.ha is defined and openshift.master.ha | bool and openshift.common.is_containerized | bool + + - name: Ensure HA Master is running + service: + name: "{{ openshift.common.service_type }}-master-controllers" + state: started + enabled: yes + when: openshift.master.ha is defined and openshift.master.ha | bool and openshift.common.is_containerized | bool diff --git a/playbooks/common/openshift-cluster/upgrades/pre/verify_docker_upgrade_targets.yml b/playbooks/common/openshift-cluster/upgrades/pre/verify_docker_upgrade_targets.yml new file mode 100644 index 000000000..ba4d77617 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/pre/verify_docker_upgrade_targets.yml @@ -0,0 +1,23 @@ +--- +- name: Verify docker upgrade targets + hosts: oo_masters_to_config:oo_nodes_to_upgrade:oo_etcd_to_config + tasks: + # Only check if docker upgrade is required if docker_upgrade is not + # already set to False. + - include: ../docker/upgrade_check.yml + when: docker_upgrade is not defined or docker_upgrade | bool and not openshift.common.is_atomic | bool + + # Additional checks for Atomic hosts: + + - name: Determine available Docker + shell: "rpm -q --queryformat '---\ncurr_version: %{VERSION}\navail_version: \n' docker" + register: g_atomic_docker_version_result + when: openshift.common.is_atomic | bool + + - set_fact: + l_docker_version: "{{ g_atomic_docker_version_result.stdout | from_yaml }}" + when: openshift.common.is_atomic | bool + + - fail: + msg: This playbook requires access to Docker 1.10 or later + when: openshift.common.is_atomic | bool and l_docker_version.avail_version | default(l_docker_version.curr_version, true) | version_compare('1.10','<') diff --git a/playbooks/common/openshift-cluster/upgrades/pre/verify_inventory_vars.yml b/playbooks/common/openshift-cluster/upgrades/pre/verify_inventory_vars.yml new file mode 100644 index 000000000..9a959a959 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/pre/verify_inventory_vars.yml @@ -0,0 +1,37 @@ +--- +- name: Verify upgrade can proceed on first master + hosts: oo_first_master + gather_facts: no + tasks: + - fail: + msg: > + This upgrade is only supported for origin, openshift-enterprise, and online + deployment types + when: deployment_type not in ['origin','openshift-enterprise', 'online'] + + # Error out in situations where the user has older versions specified in their + # inventory in any of the openshift_release, openshift_image_tag, and + # openshift_pkg_version variables. These must be removed or updated to proceed + # with upgrade. + # TODO: Should we block if you're *over* the next major release version as well? + - fail: + msg: > + openshift_pkg_version is {{ openshift_pkg_version }} which is not a + valid version for a {{ openshift_upgrade_target }} upgrade + when: openshift_pkg_version is defined and openshift_pkg_version.split('-',1).1 | version_compare(openshift_upgrade_target ,'<') + + - fail: + msg: > + openshift_image_tag is {{ openshift_image_tag }} which is not a + valid version for a {{ openshift_upgrade_target }} upgrade + when: openshift_image_tag is defined and openshift_image_tag.split('v',1).1 | version_compare(openshift_upgrade_target ,'<') + + - set_fact: + openshift_release: "{{ openshift_release[1:] }}" + when: openshift_release is defined and openshift_release[0] == 'v' + + - fail: + msg: > + openshift_release is {{ openshift_release }} which is not a + valid release for a {{ openshift_upgrade_target }} upgrade + when: openshift_release is defined and not openshift_release | version_compare(openshift_upgrade_target ,'=') diff --git a/playbooks/common/openshift-cluster/upgrades/pre/verify_nodes_running.yml b/playbooks/common/openshift-cluster/upgrades/pre/verify_nodes_running.yml new file mode 100644 index 000000000..354af3cde --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/pre/verify_nodes_running.yml @@ -0,0 +1,13 @@ +--- +- name: Verify node processes + hosts: oo_nodes_to_config + roles: + - openshift_facts + - openshift_docker_facts + tasks: + - name: Ensure Node is running + service: + name: "{{ openshift.common.service_type }}-node" + state: started + enabled: yes + when: openshift.common.is_containerized | bool diff --git a/playbooks/common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml b/playbooks/common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml new file mode 100644 index 000000000..9632626a4 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml @@ -0,0 +1,45 @@ +--- +- name: Verify upgrade targets + hosts: oo_masters_to_config:oo_nodes_to_upgrade + vars: + openshift_docker_hosted_registry_network: "{{ hostvars[groups.oo_first_master.0].openshift.common.portal_net }}" + pre_tasks: + - fail: + msg: Verify OpenShift is already installed + when: openshift.common.version is not defined + + - fail: + msg: Verify the correct version was found + when: verify_upgrade_version is defined and openshift_version != verify_upgrade_version + + - name: Clean package cache + command: "{{ ansible_pkg_mgr }} clean all" + when: not openshift.common.is_atomic | bool + + - set_fact: + g_new_service_name: "{{ 'origin' if deployment_type =='origin' else 'atomic-openshift' }}" + when: not openshift.common.is_containerized | bool + + - name: Verify containers are available for upgrade + command: > + docker pull {{ openshift.common.cli_image }}:{{ openshift_image_tag }} + register: pull_result + changed_when: "'Downloaded newer image' in pull_result.stdout" + when: openshift.common.is_containerized | bool + + - name: Check latest available OpenShift RPM version + command: > + {{ repoquery_cmd }} --qf '%{version}' "{{ openshift.common.service_type }}" + failed_when: false + changed_when: false + register: avail_openshift_version + when: not openshift.common.is_containerized | bool + + - name: Verify OpenShift RPMs are available for upgrade + fail: + msg: "OpenShift {{ avail_openshift_version.stdout }} is available, but {{ openshift_upgrade_target }} or greater is required" + when: not openshift.common.is_containerized | bool and not avail_openshift_version | skipped and avail_openshift_version.stdout | default('0.0', True) | version_compare(openshift_release, '<') + + - fail: + msg: "This upgrade playbook must be run against OpenShift {{ openshift_upgrade_min }} or later" + when: deployment_type == 'origin' and openshift.common.version | version_compare(openshift_upgrade_min,'<') diff --git a/playbooks/common/openshift-cluster/upgrades/roles b/playbooks/common/openshift-cluster/upgrades/roles new file mode 120000 index 000000000..4bdbcbad3 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/roles @@ -0,0 +1 @@ +../../../../roles
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/rpm_upgrade.yml b/playbooks/common/openshift-cluster/upgrades/rpm_upgrade.yml new file mode 100644 index 000000000..cd1139b29 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/rpm_upgrade.yml @@ -0,0 +1,11 @@ +# We verified latest rpm available is suitable, so just yum update. +- name: Upgrade packages + action: "{{ ansible_pkg_mgr }} name={{ openshift.common.service_type }}-{{ component }}{{ openshift_pkg_version }} state=present" + +- name: Ensure python-yaml present for config upgrade + action: "{{ ansible_pkg_mgr }} name=PyYAML state=present" + when: not openshift.common.is_atomic | bool + +- name: Restart node service + service: name="{{ openshift.common.service_type }}-node" state=restarted + when: component == "node" diff --git a/playbooks/common/openshift-cluster/upgrades/upgrade_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/upgrade_control_plane.yml new file mode 100644 index 000000000..57c25aa41 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/upgrade_control_plane.yml @@ -0,0 +1,200 @@ +--- +############################################################################### +# Upgrade Masters +############################################################################### +- name: Evaluate additional groups for upgrade + hosts: localhost + connection: local + become: no + tasks: + - name: Evaluate etcd_hosts_to_backup + add_host: + name: "{{ item }}" + groups: etcd_hosts_to_backup + with_items: "{{ groups.oo_etcd_to_config if groups.oo_etcd_to_config is defined and groups.oo_etcd_to_config | length > 0 else groups.oo_first_master }}" + +# If facts cache were for some reason deleted, this fact may not be set, and if not set +# it will always default to true. This causes problems for the etcd data dir fact detection +# so we must first make sure this is set correctly before attempting the backup. +- name: Set master embedded_etcd fact + hosts: oo_masters_to_config + roles: + - openshift_facts + tasks: + - openshift_facts: + role: master + local_facts: + embedded_etcd: "{{ groups.oo_etcd_to_config | default([]) | length == 0 }}" + debug_level: "{{ openshift_master_debug_level | default(openshift.common.debug_level | default(2)) }}" + +- name: Backup etcd + include: ./etcd/backup.yml + +- name: Upgrade master packages + hosts: oo_masters_to_config + handlers: + - include: ../../../../roles/openshift_master/handlers/main.yml + static: yes + roles: + - openshift_facts + tasks: + - include: rpm_upgrade.yml component=master + when: not openshift.common.is_containerized | bool + +# Create service signer cert when missing. Service signer certificate +# is added to master config in the master config hook for v3_3. +- name: Determine if service signer cert must be created + hosts: oo_first_master + tasks: + - name: Determine if service signer certificate must be created + stat: + path: "{{ openshift.common.config_base }}/master/service-signer.crt" + register: service_signer_cert_stat + changed_when: false + +- include: create_service_signer_cert.yml + +- name: Upgrade master config and systemd units + hosts: oo_masters_to_config + handlers: + - include: ../../../../roles/openshift_master/handlers/main.yml + static: yes + roles: + - openshift_facts + tasks: + - include: "{{ master_config_hook }}" + when: master_config_hook is defined + + - include_vars: ../../../../roles/openshift_master/vars/main.yml + + - name: Update systemd units + include: ../../../../roles/openshift_master/tasks/systemd_units.yml + + - name: Check for ca-bundle.crt + stat: + path: "{{ openshift.common.config_base }}/master/ca-bundle.crt" + register: ca_bundle_stat + failed_when: false + + - name: Check for ca.crt + stat: + path: "{{ openshift.common.config_base }}/master/ca.crt" + register: ca_crt_stat + failed_when: false + + - name: Migrate ca.crt to ca-bundle.crt + command: mv ca.crt ca-bundle.crt + args: + chdir: "{{ openshift.common.config_base }}/master" + when: ca_crt_stat.stat.isreg and not ca_bundle_stat.stat.exists + + - name: Link ca.crt to ca-bundle.crt + file: + src: "{{ openshift.common.config_base }}/master/ca-bundle.crt" + path: "{{ openshift.common.config_base }}/master/ca.crt" + state: link + when: ca_crt_stat.stat.isreg and not ca_bundle_stat.stat.exists + +- name: Set master update status to complete + hosts: oo_masters_to_config + tasks: + - set_fact: + master_update_complete: True + +############################################################################## +# Gate on master update complete +############################################################################## +- name: Gate on master update + hosts: localhost + connection: local + become: no + tasks: + - set_fact: + master_update_completed: "{{ hostvars + | oo_select_keys(groups.oo_masters_to_config) + | oo_collect('inventory_hostname', {'master_update_complete': true}) }}" + - set_fact: + master_update_failed: "{{ groups.oo_masters_to_config | difference(master_update_completed) }}" + - fail: + msg: "Upgrade cannot continue. The following masters did not finish updating: {{ master_update_failed | join(',') }}" + when: master_update_failed | length > 0 + +# We are now ready to restart master services (or entire system +# depending on openshift_rolling_restart_mode): +- include: ../../openshift-master/restart.yml + +############################################################################### +# Reconcile Cluster Roles, Cluster Role Bindings and Security Context Constraints +############################################################################### + +- name: Reconcile Cluster Roles and Cluster Role Bindings and Security Context Constraints + hosts: oo_masters_to_config + roles: + - { role: openshift_cli } + vars: + origin_reconcile_bindings: "{{ deployment_type == 'origin' and openshift_version | version_compare('1.0.6', '>') }}" + ent_reconcile_bindings: true + openshift_docker_hosted_registry_network: "{{ hostvars[groups.oo_first_master.0].openshift.common.portal_net }}" + # Another spot where we assume docker is running and do not want to accidentally trigger an unsafe + # restart. + skip_docker_role: True + tasks: + - name: Reconcile Cluster Roles + command: > + {{ openshift.common.client_binary }} adm --config={{ openshift.common.config_base }}/master/admin.kubeconfig + policy reconcile-cluster-roles --additive-only=true --confirm + run_once: true + + - name: Reconcile Cluster Role Bindings + command: > + {{ openshift.common.client_binary }} adm --config={{ openshift.common.config_base }}/master/admin.kubeconfig + policy reconcile-cluster-role-bindings + --exclude-groups=system:authenticated + --exclude-groups=system:authenticated:oauth + --exclude-groups=system:unauthenticated + --exclude-users=system:anonymous + --additive-only=true --confirm + when: origin_reconcile_bindings | bool or ent_reconcile_bindings | bool + run_once: true + + - name: Reconcile Jenkins Pipeline Role Bindings + command: > + {{ openshift.common.client_binary }} adm --config={{ openshift.common.config_base }}/master/admin.kubeconfig policy reconcile-cluster-role-bindings system:build-strategy-jenkinspipeline --confirm + run_once: true + when: openshift.common.version_gte_3_4_or_1_4 | bool + + - name: Reconcile Security Context Constraints + command: > + {{ openshift.common.client_binary }} adm policy reconcile-sccs --confirm --additive-only=true + run_once: true + + - set_fact: + reconcile_complete: True + +############################################################################## +# Gate on reconcile +############################################################################## +- name: Gate on reconcile + hosts: localhost + connection: local + become: no + tasks: + - set_fact: + reconcile_completed: "{{ hostvars + | oo_select_keys(groups.oo_masters_to_config) + | oo_collect('inventory_hostname', {'reconcile_complete': true}) }}" + - set_fact: + reconcile_failed: "{{ groups.oo_masters_to_config | difference(reconcile_completed) }}" + - fail: + msg: "Upgrade cannot continue. The following masters did not finish reconciling: {{ reconcile_failed | join(',') }}" + when: reconcile_failed | length > 0 + +- name: Upgrade Docker on dedicated containerized etcd hosts + hosts: oo_etcd_to_config:!oo_nodes_to_upgrade + serial: 1 + any_errors_fatal: true + roles: + - openshift_facts + tasks: + - include: docker/upgrade.yml + when: l_docker_upgrade is defined and l_docker_upgrade | bool and not openshift.common.is_atomic | bool diff --git a/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml b/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml new file mode 100644 index 000000000..1f314c854 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml @@ -0,0 +1,75 @@ +--- +- name: Evacuate and upgrade nodes + hosts: oo_nodes_to_upgrade + # This var must be set with -e on invocation, as it is not a per-host inventory var + # and is evaluated early. Values such as "20%" can also be used. + serial: "{{ openshift_upgrade_nodes_serial | default(1) }}" + any_errors_fatal: true + roles: + - openshift_facts + - docker + handlers: + - include: ../../../../roles/openshift_node/handlers/main.yml + static: yes + pre_tasks: + # TODO: To better handle re-trying failed upgrades, it would be nice to check if the node + # or docker actually needs an upgrade before proceeding. Perhaps best to save this until + # we merge upgrade functionality into the base roles and a normal config.yml playbook run. + - name: Determine if node is currently scheduleable + command: > + {{ openshift.common.client_binary }} get node {{ openshift.node.nodename | lower }} -o json + register: node_output + delegate_to: "{{ groups.oo_first_master.0 }}" + changed_when: false + when: inventory_hostname in groups.oo_nodes_to_upgrade + + - set_fact: + was_schedulable: "{{ 'unschedulable' not in (node_output.stdout | from_json).spec }}" + when: inventory_hostname in groups.oo_nodes_to_upgrade + + - name: Mark unschedulable if host is a node + command: > + {{ openshift.common.client_binary }} adm manage-node {{ openshift.node.nodename | lower }} --schedulable=false + delegate_to: "{{ groups.oo_first_master.0 }}" + when: inventory_hostname in groups.oo_nodes_to_upgrade + # NOTE: There is a transient "object has been modified" error here, allow a couple + # retries for a more reliable upgrade. + register: node_unsched + until: node_unsched.rc == 0 + retries: 3 + delay: 1 + + - name: Evacuate Node for Kubelet upgrade + command: > + {{ openshift.common.client_binary }} adm manage-node {{ openshift.node.nodename | lower }} --evacuate --force + delegate_to: "{{ groups.oo_first_master.0 }}" + when: inventory_hostname in groups.oo_nodes_to_upgrade + tasks: + - include: docker/upgrade.yml + when: l_docker_upgrade is defined and l_docker_upgrade | bool and not openshift.common.is_atomic | bool + + - include: "{{ node_config_hook }}" + when: node_config_hook is defined and inventory_hostname in groups.oo_nodes_to_upgrade + + - include: rpm_upgrade.yml + vars: + component: "node" + openshift_version: "{{ openshift_pkg_version | default('') }}" + when: inventory_hostname in groups.oo_nodes_to_upgrade and not openshift.common.is_containerized | bool + + - include: containerized_node_upgrade.yml + when: inventory_hostname in groups.oo_nodes_to_upgrade and openshift.common.is_containerized | bool + + - meta: flush_handlers + + - name: Set node schedulability + command: > + {{ openshift.common.client_binary }} adm manage-node {{ openshift.node.nodename | lower }} --schedulable=true + delegate_to: "{{ groups.oo_first_master.0 }}" + when: inventory_hostname in groups.oo_nodes_to_upgrade and was_schedulable | bool + register: node_sched + until: node_sched.rc == 0 + retries: 3 + delay: 1 + + diff --git a/playbooks/common/openshift-cluster/upgrades/v3_1_to_v3_2/nuke_images.sh b/playbooks/common/openshift-cluster/upgrades/v3_1_to_v3_2/nuke_images.sh new file mode 120000 index 000000000..49a51bba9 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_1_to_v3_2/nuke_images.sh @@ -0,0 +1 @@ +../files/nuke_images.sh
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/v3_3/master_config_upgrade.yml b/playbooks/common/openshift-cluster/upgrades/v3_3/master_config_upgrade.yml new file mode 100644 index 000000000..684eea343 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_3/master_config_upgrade.yml @@ -0,0 +1,50 @@ +--- +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'masterClients.externalKubernetesClientConnectionOverrides.acceptContentTypes' + yaml_value: 'application/vnd.kubernetes.protobuf,application/json' + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'masterClients.externalKubernetesClientConnectionOverrides.contentType' + yaml_value: 'application/vnd.kubernetes.protobuf' + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'masterClients.externalKubernetesClientConnectionOverrides.burst' + yaml_value: 400 + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'masterClients.externalKubernetesClientConnectionOverrides.qps' + yaml_value: 200 + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'masterClients.openshiftLoopbackClientConnectionOverrides.acceptContentTypes' + yaml_value: 'application/vnd.kubernetes.protobuf,application/json' + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'masterClients.openshiftLoopbackClientConnectionOverrides.contentType' + yaml_value: 'application/vnd.kubernetes.protobuf' + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'masterClients.openshiftLoopbackClientConnectionOverrides.burst' + yaml_value: 600 + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'masterClients.openshiftLoopbackClientConnectionOverrides.qps' + yaml_value: 300 + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'controllerConfig.servicesServingCert.signer.certFile' + yaml_value: service-signer.crt + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'controllerConfig.servicesServingCert.signer.keyFile' + yaml_value: service-signer.key diff --git a/playbooks/common/openshift-cluster/upgrades/v3_3/node_config_upgrade.yml b/playbooks/common/openshift-cluster/upgrades/v3_3/node_config_upgrade.yml new file mode 100644 index 000000000..8f64636ae --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_3/node_config_upgrade.yml @@ -0,0 +1,21 @@ +--- +- modify_yaml: + dest: "{{ openshift.common.config_base}}/node/node-config.yaml" + yaml_key: 'masterClientConnectionOverrides.acceptContentTypes' + yaml_value: 'application/vnd.kubernetes.protobuf,application/json' + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/node/node-config.yaml" + yaml_key: 'masterClientConnectionOverrides.contentType' + yaml_value: 'application/vnd.kubernetes.protobuf' + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/node/node-config.yaml" + yaml_key: 'masterClientConnectionOverrides.burst' + yaml_value: 40 + +- modify_yaml: + dest: "{{ openshift.common.config_base}}/node/node-config.yaml" + yaml_key: 'masterClientConnectionOverrides.qps' + yaml_value: 20 + diff --git a/playbooks/common/openshift-cluster/validate_hostnames.yml b/playbooks/common/openshift-cluster/validate_hostnames.yml new file mode 100644 index 000000000..50e25984f --- /dev/null +++ b/playbooks/common/openshift-cluster/validate_hostnames.yml @@ -0,0 +1,16 @@ +--- +- name: Gather and set facts for node hosts + hosts: oo_nodes_to_config + roles: + - openshift_facts + tasks: + - shell: + getent ahostsv4 {{ openshift.common.hostname }} | head -n 1 | awk '{ print $1 }' + register: lookupip + changed_when: false + failed_when: false + - name: Warn user about bad openshift_hostname values + pause: + prompt: "The hostname \"{{ openshift.common.hostname }}\" for \"{{ ansible_nodename }}\" doesn't resolve to an ip address owned by this host. Please set openshift_hostname variable to a hostname that when resolved on the host in question resolves to an IP address matching an interface on this host. This host will fail liveness checks for pods utilizing hostPorts, press ENTER to continue or CTRL-C to abort." + seconds: "{{ 10 if openshift_override_hostname_check | default(false) | bool else omit }}" + when: lookupip.stdout not in ansible_all_ipv4_addresses diff --git a/playbooks/common/openshift-cluster/verify_ansible_version.yml b/playbooks/common/openshift-cluster/verify_ansible_version.yml new file mode 100644 index 000000000..d75b23bf7 --- /dev/null +++ b/playbooks/common/openshift-cluster/verify_ansible_version.yml @@ -0,0 +1,11 @@ +--- +- name: Verify Ansible version is greater than or equal to 2.1.0.0 + hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - name: Verify Ansible version is greater than or equal to 2.1.0.0 + fail: + msg: "Unsupported ansible version: {{ ansible_version.full }} found" + when: not ansible_version.full | version_compare('2.1.0.0', 'ge') diff --git a/playbooks/common/openshift-etcd/config.yml b/playbooks/common/openshift-etcd/config.yml index 3cc561ba0..1b8106e0e 100644 --- a/playbooks/common/openshift-etcd/config.yml +++ b/playbooks/common/openshift-etcd/config.yml @@ -1,96 +1,10 @@ --- -- name: Set etcd facts needed for generating certs +- name: Configure etcd hosts: oo_etcd_to_config + any_errors_fatal: true roles: - - openshift_facts - tasks: - - openshift_facts: - role: "{{ item.role }}" - local_facts: "{{ item.local_facts }}" - with_items: - - role: common - local_facts: - hostname: "{{ openshift_hostname | default(None) }}" - public_hostname: "{{ openshift_public_hostname | default(None) }}" - deployment_type: "{{ openshift_deployment_type }}" - - name: Check status of etcd certificates - stat: - path: "{{ item }}" - with_items: - - /etc/etcd/server.crt - - /etc/etcd/peer.crt - - /etc/etcd/ca.crt - register: g_etcd_server_cert_stat_result - - set_fact: - etcd_server_certs_missing: "{{ g_etcd_server_cert_stat_result.results | map(attribute='stat.exists') - | list | intersect([false])}}" - etcd_cert_subdir: etcd-{{ openshift.common.hostname }} - etcd_cert_config_dir: /etc/etcd - etcd_cert_prefix: - -- name: Create temp directory for syncing certs - hosts: localhost - connection: local - sudo: false - gather_facts: no - tasks: - - name: Create local temp directory for syncing certs - local_action: command mktemp -d /tmp/openshift-ansible-XXXXXXX - register: g_etcd_mktemp - changed_when: False - -- name: Configure etcd certificates - hosts: oo_first_etcd - vars: - etcd_generated_certs_dir: /etc/etcd/generated_certs - etcd_needing_server_certs: "{{ hostvars - | oo_select_keys(groups['oo_etcd_to_config']) - | oo_filter_list(filter_attr='etcd_server_certs_missing') }}" - sync_tmpdir: "{{ hostvars.localhost.g_etcd_mktemp.stdout }}" - roles: - - etcd_certificates - post_tasks: - - name: Create a tarball of the etcd certs - command: > - tar -czvf {{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}.tgz - -C {{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }} . - args: - creates: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}.tgz" - with_items: etcd_needing_server_certs - - name: Retrieve the etcd cert tarballs - fetch: - src: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}.tgz" - dest: "{{ sync_tmpdir }}/" - flat: yes - fail_on_missing: yes - validate_checksum: yes - with_items: etcd_needing_server_certs - -- name: Configure etcd hosts - hosts: oo_etcd_to_config - vars: - sync_tmpdir: "{{ hostvars.localhost.g_etcd_mktemp.stdout }}" - etcd_url_scheme: https - etcd_peer_url_scheme: https - etcd_peers_group: oo_etcd_to_config - pre_tasks: - - name: Ensure certificate directory exists - file: - path: "{{ etcd_cert_config_dir }}" - state: directory - - name: Unarchive the tarball on the etcd host - unarchive: - src: "{{ sync_tmpdir }}/{{ etcd_cert_subdir }}.tgz" - dest: "{{ etcd_cert_config_dir }}" - when: etcd_server_certs_missing - roles: - - etcd - -- name: Delete temporary directory on localhost - hosts: localhost - connection: local - sudo: false - gather_facts: no - tasks: - - file: name={{ g_etcd_mktemp.stdout }} state=absent - changed_when: False + - role: openshift_etcd + etcd_peers: "{{ groups.oo_etcd_to_config | default([], true) }}" + etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" + etcd_certificates_etcd_hosts: "{{ groups.oo_etcd_to_config | default([], true) }}" + - role: nickhammond.logrotate diff --git a/playbooks/common/openshift-etcd/service.yml b/playbooks/common/openshift-etcd/service.yml index 0bf69b22f..f460612ba 100644 --- a/playbooks/common/openshift-etcd/service.yml +++ b/playbooks/common/openshift-etcd/service.yml @@ -1,6 +1,8 @@ --- - name: Populate g_service_masters host group if needed hosts: localhost + connection: local + become: no gather_facts: no tasks: - fail: msg="new_cluster_state is required to be injected in this playbook" @@ -8,7 +10,7 @@ - name: Evaluate g_service_etcd add_host: name={{ item }} groups=g_service_etcd - with_items: oo_host_group_exp | default([]) + with_items: "{{ oo_host_group_exp | default([]) }}" - name: Change etcd state on etcd instance(s) hosts: g_service_etcd diff --git a/playbooks/common/openshift-loadbalancer/config.yml b/playbooks/common/openshift-loadbalancer/config.yml new file mode 100644 index 000000000..c414913bf --- /dev/null +++ b/playbooks/common/openshift-loadbalancer/config.yml @@ -0,0 +1,16 @@ +--- +- name: Configure load balancers + hosts: oo_lb_to_config + vars: + openshift_loadbalancer_frontends: "{{ (openshift_master_api_port | default(8443) + | oo_openshift_loadbalancer_frontends(hostvars | oo_select_keys(groups['oo_masters']), + openshift_use_nuage | default(false), + nuage_mon_rest_server_port | default(none))) + + openshift_loadbalancer_additional_frontends | default([]) }}" + openshift_loadbalancer_backends: "{{ (openshift_master_api_port | default(8443) + | oo_openshift_loadbalancer_backends(hostvars | oo_select_keys(groups['oo_masters']), + openshift_use_nuage | default(false), + nuage_mon_rest_server_port | default(none))) + + openshift_loadbalancer_additional_backends | default([]) }}" + roles: + - role: openshift_loadbalancer diff --git a/playbooks/common/openshift-loadbalancer/filter_plugins b/playbooks/common/openshift-loadbalancer/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/common/openshift-loadbalancer/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-loadbalancer/lookup_plugins b/playbooks/common/openshift-loadbalancer/lookup_plugins new file mode 120000 index 000000000..ac79701db --- /dev/null +++ b/playbooks/common/openshift-loadbalancer/lookup_plugins @@ -0,0 +1 @@ +../../../lookup_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-loadbalancer/roles b/playbooks/common/openshift-loadbalancer/roles new file mode 120000 index 000000000..e2b799b9d --- /dev/null +++ b/playbooks/common/openshift-loadbalancer/roles @@ -0,0 +1 @@ +../../../roles/
\ No newline at end of file diff --git a/playbooks/common/openshift-loadbalancer/service.yml b/playbooks/common/openshift-loadbalancer/service.yml new file mode 100644 index 000000000..efc80edf9 --- /dev/null +++ b/playbooks/common/openshift-loadbalancer/service.yml @@ -0,0 +1,20 @@ +--- +- name: Populate g_service_nodes host group if needed + hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - fail: msg="new_cluster_state is required to be injected in this playbook" + when: new_cluster_state is not defined + + - name: Evaluate g_service_lb + add_host: name={{ item }} groups=g_service_lb + with_items: "{{ oo_host_group_exp | default([]) }}" + +- name: Change state on lb instance(s) + hosts: g_service_lb + connection: ssh + gather_facts: no + tasks: + - service: name=haproxy state="{{ new_cluster_state }}" diff --git a/playbooks/common/openshift-master/config.yml b/playbooks/common/openshift-master/config.yml index 3956128e1..5fcb850a2 100644 --- a/playbooks/common/openshift-master/config.yml +++ b/playbooks/common/openshift-master/config.yml @@ -1,7 +1,29 @@ --- -- name: Set master facts and determine if external etcd certs need to be generated +- name: Gather and set facts for master hosts hosts: oo_masters_to_config + vars: + t_oo_option_master_debug_level: "{{ lookup('oo_option', 'openshift_master_debug_level') }}" + pre_tasks: + - name: Check for RPM generated config marker file .config_managed + stat: + path: /etc/origin/.config_managed + register: rpmgenerated_config + + - name: Remove RPM generated config files if present + file: + path: "/etc/origin/{{ item }}" + state: absent + when: rpmgenerated_config.stat.exists == true and deployment_type in ['openshift-enterprise', 'atomic-enterprise'] + with_items: + - master + - node + - .config_managed + + - set_fact: + openshift_master_pod_eviction_timeout: "{{ lookup('oo_option', 'openshift_master_pod_eviction_timeout') | default(none, true) }}" + when: openshift_master_pod_eviction_timeout is not defined + - set_fact: openshift_master_etcd_port: "{{ (etcd_client_port | default('2379')) if (groups.oo_etcd_to_config is defined and groups.oo_etcd_to_config) else none }}" openshift_master_etcd_hosts: "{{ hostvars @@ -9,49 +31,59 @@ | default([])) | oo_collect('openshift.common.hostname') | default(none, true) }}" + + - set_fact: + openshift_master_debug_level: "{{ t_oo_option_master_debug_level }}" + when: openshift_master_debug_level is not defined and t_oo_option_master_debug_level != "" + + - set_fact: + openshift_master_default_subdomain: "{{ lookup('oo_option', 'openshift_master_default_subdomain') | default(None, true) }}" + when: openshift_master_default_subdomain is not defined + - set_fact: + openshift_hosted_metrics_deploy: "{{ lookup('oo_option', 'openshift_hosted_metrics_deploy') | default(false, true) }}" + when: openshift_hosted_metrics_deploy is not defined + - set_fact: + openshift_hosted_metrics_duration: "{{ lookup('oo_option', 'openshift_hosted_metrics_duration') | default(7) }}" + when: openshift_hosted_metrics_duration is not defined + - set_fact: + openshift_hosted_metrics_resolution: "{{ lookup('oo_option', 'openshift_hosted_metrics_resolution') | default('10s', true) }}" + when: openshift_hosted_metrics_resolution is not defined + - set_fact: + openshift_hosted_metrics_deployer_prefix: "{{ lookup('oo_option', 'openshift_hosted_metrics_deployer_prefix') | default('openshift') }}" + when: openshift_hosted_metrics_deployer_prefix is not defined + - set_fact: + openshift_hosted_metrics_deployer_version: "{{ lookup('oo_option', 'openshift_hosted_metrics_deployer_version') | default('latest') }}" + when: openshift_hosted_metrics_deployer_version is not defined roles: - openshift_facts post_tasks: - openshift_facts: - role: "{{ item.role }}" - local_facts: "{{ item.local_facts }}" - with_items: - - role: common - local_facts: - hostname: "{{ openshift_hostname | default(None) }}" - public_hostname: "{{ openshift_public_hostname | default(None) }}" - deployment_type: "{{ openshift_deployment_type }}" - - role: master - local_facts: - api_port: "{{ openshift_master_api_port | default(None) }}" - api_url: "{{ openshift_master_api_url | default(None) }}" - api_use_ssl: "{{ openshift_master_api_use_ssl | default(None) }}" - public_api_url: "{{ openshift_master_public_api_url | default(None) }}" - console_path: "{{ openshift_master_console_path | default(None) }}" - console_port: "{{ openshift_master_console_port | default(None) }}" - console_url: "{{ openshift_master_console_url | default(None) }}" - console_use_ssl: "{{ openshift_master_console_use_ssl | default(None) }}" - public_console_url: "{{ openshift_master_public_console_url | default(None) }}" - - name: Check status of external etcd certificatees - stat: - path: "/etc/openshift/master/{{ item }}" - with_items: - - master.etcd-client.crt - - master.etcd-ca.crt - register: g_external_etcd_cert_stat_result - - set_fact: - etcd_client_certs_missing: "{{ g_external_etcd_cert_stat_result.results - | map(attribute='stat.exists') - | list | intersect([false])}}" - etcd_cert_subdir: openshift-master-{{ openshift.common.hostname }} - etcd_cert_config_dir: /etc/openshift/master - etcd_cert_prefix: master.etcd- - when: groups.oo_etcd_to_config is defined and groups.oo_etcd_to_config + role: master + local_facts: + api_port: "{{ openshift_master_api_port | default(None) }}" + api_url: "{{ openshift_master_api_url | default(None) }}" + api_use_ssl: "{{ openshift_master_api_use_ssl | default(None) }}" + controllers_port: "{{ openshift_master_controllers_port | default(None) }}" + public_api_url: "{{ openshift_master_public_api_url | default(None) }}" + cluster_hostname: "{{ openshift_master_cluster_hostname | default(None) }}" + cluster_public_hostname: "{{ openshift_master_cluster_public_hostname | default(None) }}" + console_path: "{{ openshift_master_console_path | default(None) }}" + console_port: "{{ openshift_master_console_port | default(None) }}" + console_url: "{{ openshift_master_console_url | default(None) }}" + console_use_ssl: "{{ openshift_master_console_use_ssl | default(None) }}" + public_console_url: "{{ openshift_master_public_console_url | default(None) }}" + ha: "{{ openshift_master_ha | default(groups.oo_masters | length > 1) }}" + master_count: "{{ openshift_master_count | default(groups.oo_masters | length) }}" + - openshift_facts: + role: hosted + openshift_env: + openshift_hosted_registry_storage_kind: 'nfs' + when: openshift_hosted_registry_storage_kind is not defined and groups.oo_nfs_to_config is defined and groups.oo_nfs_to_config | length > 0 - name: Create temp directory for syncing certs hosts: localhost connection: local - sudo: false + become: no gather_facts: no tasks: - name: Create local temp directory for syncing certs @@ -59,155 +91,105 @@ register: g_master_mktemp changed_when: False -- name: Configure etcd certificates - hosts: oo_first_etcd - vars: - etcd_generated_certs_dir: /etc/etcd/generated_certs - etcd_needing_client_certs: "{{ hostvars - | oo_select_keys(groups['oo_masters_to_config']) - | oo_filter_list(filter_attr='etcd_client_certs_missing') }}" - sync_tmpdir: "{{ hostvars.localhost.g_master_mktemp.stdout }}" +- name: Determine if session secrets must be generated + hosts: oo_first_master roles: - - etcd_certificates + - role: openshift_facts post_tasks: - - name: Create a tarball of the etcd certs - command: > - tar -czvf {{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}.tgz - -C {{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }} . - args: - creates: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}.tgz" - with_items: etcd_needing_client_certs - - name: Retrieve the etcd cert tarballs - fetch: - src: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}.tgz" - dest: "{{ sync_tmpdir }}/" - flat: yes - fail_on_missing: yes - validate_checksum: yes - with_items: etcd_needing_client_certs - -- name: Copy the external etcd certs to the masters - hosts: oo_masters_to_config - vars: - sync_tmpdir: "{{ hostvars.localhost.g_master_mktemp.stdout }}" - tasks: - - name: Ensure certificate directory exists - file: - path: /etc/openshift/master - state: directory - when: etcd_client_certs_missing is defined and etcd_client_certs_missing - - name: Unarchive the tarball on the master - unarchive: - src: "{{ sync_tmpdir }}/{{ etcd_cert_subdir }}.tgz" - dest: "{{ etcd_cert_config_dir }}" - when: etcd_client_certs_missing is defined and etcd_client_certs_missing - - file: - path: "{{ etcd_cert_config_dir }}/{{ item }}" - owner: root - group: root - mode: 0600 - with_items: - - master.etcd-client.crt - - master.etcd-client.key - - master.etcd-ca.crt - when: etcd_client_certs_missing is defined and etcd_client_certs_missing - -- name: Determine if master certificates need to be generated - hosts: oo_masters_to_config - tasks: - - set_fact: - openshift_master_certs_no_etcd: - - admin.crt - - master.kubelet-client.crt - - master.server.crt - - openshift-master.crt - - openshift-registry.crt - - openshift-router.crt - - etcd.server.crt - openshift_master_certs_etcd: - - master.etcd-client.crt - - set_fact: - openshift_master_certs: "{{ (openshift_master_certs_no_etcd | union(openshift_master_certs_etcd)) if (groups.oo_etcd_to_config is defined and groups.oo_etcd_to_config) else openshift_master_certs_no_etcd }}" - - - name: Check status of master certificates - stat: - path: "/etc/openshift/master/{{ item }}" - with_items: openshift_master_certs - register: g_master_cert_stat_result - - set_fact: - master_certs_missing: "{{ g_master_cert_stat_result.results - | map(attribute='stat.exists') - | list | intersect([false])}}" - master_cert_subdir: master-{{ openshift.common.hostname }} - master_cert_config_dir: /etc/openshift/master + - openshift_facts: + role: master + local_facts: + session_auth_secrets: "{{ openshift_master_session_auth_secrets | default(openshift.master.session_auth_secrets | default(None)) }}" + session_encryption_secrets: "{{ openshift_master_session_encryption_secrets | default(openshift.master.session_encryption_secrets | default(None)) }}" -- name: Configure master certificates +- name: Generate master session secrets hosts: oo_first_master vars: - master_generated_certs_dir: /etc/openshift/generated-configs - masters_needing_certs: "{{ hostvars - | oo_select_keys(groups['oo_masters_to_config'] | difference(groups['oo_first_master'])) - | oo_filter_list(filter_attr='master_certs_missing') }}" - sync_tmpdir: "{{ hostvars.localhost.g_master_mktemp.stdout }}" + g_session_secrets_present: "{{ (openshift.master.session_auth_secrets | default([])) | length > 0 and (openshift.master.session_encryption_secrets | default([])) | length > 0 }}" + g_session_auth_secrets: "{{ [ 24 | oo_generate_secret ] }}" + g_session_encryption_secrets: "{{ [ 24 | oo_generate_secret ] }}" roles: - - openshift_master_certificates - post_tasks: - - name: Create a tarball of the master certs - command: > - tar -czvf {{ master_generated_certs_dir }}/{{ item.master.cert_subdir }}.tgz - -C {{ master_generated_certs_dir }}/{{ item.master.cert_subdir }} . - args: - creates: "{{ master_generated_certs_dir }}/{{ item.master.cert_subdir }}.tgz" - with_items: masters_needing_certs - - name: Retrieve the master cert tarball from the master - fetch: - src: "{{ master_generated_certs_dir }}/{{ item.master.cert_subdir }}.tgz" - dest: "{{ sync_tmpdir }}/" - flat: yes - fail_on_missing: yes - validate_checksum: yes - with_items: masters_needing_certs + - role: openshift_facts + tasks: + - openshift_facts: + role: master + local_facts: + session_auth_secrets: "{{ g_session_auth_secrets }}" + session_encryption_secrets: "{{ g_session_encryption_secrets }}" + when: not g_session_secrets_present | bool -- name: Configure master instances +- name: Configure masters hosts: oo_masters_to_config + any_errors_fatal: true vars: sync_tmpdir: "{{ hostvars.localhost.g_master_mktemp.stdout }}" - pre_tasks: - - name: Ensure certificate directory exists - file: - path: /etc/openshift/master - state: directory - when: master_certs_missing and 'oo_first_master' not in group_names - - name: Unarchive the tarball on the master - unarchive: - src: "{{ sync_tmpdir }}/{{ master_cert_subdir }}.tgz" - dest: "{{ master_cert_config_dir }}" - when: master_certs_missing and 'oo_first_master' not in group_names + openshift_master_ha: "{{ openshift.master.ha }}" + openshift_master_count: "{{ openshift.master.master_count }}" + openshift_master_session_auth_secrets: "{{ hostvars[groups.oo_first_master.0].openshift.master.session_auth_secrets }}" + openshift_master_session_encryption_secrets: "{{ hostvars[groups.oo_first_master.0].openshift.master.session_encryption_secrets }}" + openshift_no_proxy_internal_hostnames: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_config'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" roles: - - openshift_master - - role: fluentd_master - when: openshift.common.use_fluentd | bool + - role: openshift_master_facts + - role: openshift_hosted_facts + - role: openshift_master_certificates + openshift_ca_host: "{{ groups.oo_first_master.0 }}" + openshift_master_etcd_hosts: "{{ hostvars + | oo_select_keys(groups['oo_etcd_to_config'] | default([])) + | oo_collect('openshift.common.hostname') + | default(none, true) }}" + openshift_master_hostnames: "{{ hostvars + | oo_select_keys(groups['oo_masters_to_config'] | default([])) + | oo_collect('openshift.common.all_hostnames') + | oo_flatten | unique }}" + - role: openshift_etcd_client_certificates + etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" + etcd_cert_subdir: "openshift-master-{{ openshift.common.hostname }}" + etcd_cert_config_dir: "{{ openshift.common.config_base }}/master" + etcd_cert_prefix: "master.etcd-" + when: groups.oo_etcd_to_config is defined and groups.oo_etcd_to_config + - role: openshift_clock + - role: openshift_cloud_provider + - role: openshift_builddefaults + - role: os_firewall + os_firewall_allow: + - service: etcd embedded + port: 4001/tcp + - service: api server https + port: "{{ openshift.master.api_port }}/tcp" + - service: api controllers https + port: "{{ openshift.master.controllers_port }}/tcp" + - service: skydns tcp + port: "{{ openshift.master.dns_port }}/tcp" + - service: skydns udp + port: "{{ openshift.master.dns_port }}/udp" + - service: Fluentd td-agent tcp + port: 24224/tcp + - service: Fluentd td-agent udp + port: 24224/udp + - service: pcsd + port: 2224/tcp + - service: Corosync UDP + port: 5404/udp + - service: Corosync UDP + port: 5405/udp + - role: openshift_master + openshift_master_hosts: "{{ groups.oo_masters_to_config }}" + - role: nickhammond.logrotate + - role: nuage_master + when: openshift.common.use_nuage | bool post_tasks: - name: Create group for deployment type group_by: key=oo_masters_deployment_type_{{ openshift.common.deployment_type }} changed_when: False -- name: Deploy OpenShift examples - hosts: oo_first_master - roles: - - openshift_examples - -# Additional instance config for online deployments -- name: Additional instance config - hosts: oo_masters_deployment_type_online - roles: - - pods - - os_env_extras - - name: Delete temporary directory on localhost hosts: localhost connection: local - sudo: false + become: no gather_facts: no tasks: - file: name={{ g_master_mktemp.stdout }} state=absent diff --git a/playbooks/common/openshift-master/library b/playbooks/common/openshift-master/library new file mode 120000 index 000000000..d0b7393d3 --- /dev/null +++ b/playbooks/common/openshift-master/library @@ -0,0 +1 @@ +../../../library/
\ No newline at end of file diff --git a/playbooks/common/openshift-master/restart.yml b/playbooks/common/openshift-master/restart.yml new file mode 100644 index 000000000..5769ef5cd --- /dev/null +++ b/playbooks/common/openshift-master/restart.yml @@ -0,0 +1,79 @@ +--- +- include: ../openshift-cluster/evaluate_groups.yml + +- name: Validate configuration for rolling restart + hosts: oo_masters_to_config + roles: + - openshift_facts + tasks: + - fail: + msg: "openshift_rolling_restart_mode must be set to either 'services' or 'system'" + when: openshift_rolling_restart_mode is defined and openshift_rolling_restart_mode not in ["services", "system"] + - openshift_facts: + role: "{{ item.role }}" + local_facts: "{{ item.local_facts }}" + with_items: + - role: common + local_facts: + rolling_restart_mode: "{{ openshift_rolling_restart_mode | default('services') }}" + - role: master + local_facts: + cluster_method: "{{ openshift_master_cluster_method | default(None) }}" + +# Creating a temp file on localhost, we then check each system that will +# be rebooted to see if that file exists, if so we know we're running +# ansible on a machine that needs a reboot, and we need to error out. +- name: Create temp file on localhost + hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - local_action: command mktemp + register: mktemp + changed_when: false + +- name: Check if temp file exists on any masters + hosts: oo_masters_to_config + tasks: + - stat: path="{{ hostvars.localhost.mktemp.stdout }}" + register: exists + changed_when: false + +- name: Cleanup temp file on localhost + hosts: localhost + connection: local + become: no + gather_facts: no + tasks: + - file: path="{{ hostvars.localhost.mktemp.stdout }}" state=absent + changed_when: false + +- name: Warn if restarting the system where ansible is running + hosts: oo_masters_to_config + tasks: + - pause: + prompt: > + Warning: Running playbook from a host that will be restarted! + Press CTRL+C and A to abort playbook execution. You may + continue by pressing ENTER but the playbook will stop + executing after this system has been restarted and services + 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' + - set_fact: + current_host: "{{ exists.stat.exists }}" + when: openshift.common.rolling_restart_mode == 'system' + +- name: Restart masters + hosts: oo_masters_to_config + vars: + openshift_master_ha: "{{ groups.oo_masters_to_config | length > 1 }}" + serial: 1 + tasks: + - include: restart_hosts.yml + when: openshift.common.rolling_restart_mode == 'system' + - include: restart_services.yml + when: openshift.common.rolling_restart_mode == 'services' + diff --git a/playbooks/common/openshift-master/restart_hosts.yml b/playbooks/common/openshift-master/restart_hosts.yml new file mode 100644 index 000000000..b1c36718c --- /dev/null +++ b/playbooks/common/openshift-master/restart_hosts.yml @@ -0,0 +1,17 @@ +- name: Restart master system + # https://github.com/ansible/ansible/issues/10616 + shell: sleep 2 && shutdown -r now "OpenShift Ansible master rolling restart" + async: 1 + poll: 0 + ignore_errors: true + become: yes + +# Ensure the api_port is available. +- name: Wait for master API to come back online + become: no + local_action: + module: wait_for + host="{{ inventory_hostname }}" + state=started + delay=10 + port="{{ openshift.master.api_port }}" diff --git a/playbooks/common/openshift-master/restart_services.yml b/playbooks/common/openshift-master/restart_services.yml new file mode 100644 index 000000000..5e539cd65 --- /dev/null +++ b/playbooks/common/openshift-master/restart_services.yml @@ -0,0 +1,27 @@ +- name: Restart master + service: + name: "{{ openshift.common.service_type }}-master" + state: restarted + when: not openshift_master_ha | bool +- name: Restart master API + service: + name: "{{ openshift.common.service_type }}-master-api" + state: restarted + when: openshift_master_ha | bool and openshift.master.cluster_method != 'pacemaker' +- name: Wait for master API to come back online + become: no + local_action: + module: wait_for + host="{{ inventory_hostname }}" + state=started + delay=10 + port="{{ openshift.master.api_port }}" + when: openshift_master_ha | bool and openshift.master.cluster_method != 'pacemaker' +- name: Restart master controllers + service: + name: "{{ openshift.common.service_type }}-master-controllers" + state: restarted + # Ignore errrors since it is possible that type != simple for + # pre-3.1.1 installations. + ignore_errors: true + when: openshift_master_ha | bool and openshift.master.cluster_method != 'pacemaker' diff --git a/playbooks/common/openshift-master/scaleup.yml b/playbooks/common/openshift-master/scaleup.yml new file mode 100644 index 000000000..18e5c665f --- /dev/null +++ b/playbooks/common/openshift-master/scaleup.yml @@ -0,0 +1,67 @@ +--- +- include: ../openshift-cluster/evaluate_groups.yml + +- name: Gather facts + hosts: oo_etcd_to_config:oo_masters_to_config:oo_nodes_to_config + roles: + - openshift_facts + +- name: Update master count + hosts: oo_masters:!oo_masters_to_config + serial: 1 + roles: + - openshift_facts + post_tasks: + - openshift_facts: + role: master + local_facts: + ha: "{{ openshift_master_ha | default(groups.oo_masters | length > 1) }}" + master_count: "{{ openshift_master_count | default(groups.oo_masters | length) }}" + - name: Update master count + modify_yaml: + dest: "{{ openshift.common.config_base}}/master/master-config.yaml" + yaml_key: 'kubernetesMasterConfig.masterCount' + yaml_value: "{{ openshift.master.master_count }}" + notify: + - restart master api + - restart master controllers + handlers: + - name: restart master api + service: name={{ openshift.common.service_type }}-master-controllers state=restarted + notify: verify api server + - name: restart master controllers + service: name={{ openshift.common.service_type }}-master-controllers state=restarted + - name: verify api server + command: > + curl --silent --tlsv1.2 + {% if openshift.common.version_gte_3_2_or_1_2 | bool %} + --cacert {{ openshift.common.config_base }}/master/ca-bundle.crt + {% else %} + --cacert {{ openshift.common.config_base }}/master/ca.crt + {% endif %} + {{ openshift.master.api_url }}/healthz/ready + args: + # Disables the following warning: + # Consider using get_url or uri module rather than running curl + warn: no + register: api_available_output + until: api_available_output.stdout == 'ok' + retries: 120 + delay: 1 + changed_when: false + +- name: Configure docker hosts + hosts: oo_masters_to-config:oo_nodes_to_config + vars: + docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries') | oo_split }}" + docker_insecure_registries: "{{ lookup('oo_option', 'docker_insecure_registries') | oo_split }}" + docker_blocked_registries: "{{ lookup('oo_option', 'docker_blocked_registries') | oo_split }}" + roles: + - openshift_facts + - openshift_docker + +- include: ../openshift-master/config.yml + +- include: ../openshift-loadbalancer/config.yml + +- include: ../openshift-node/config.yml diff --git a/playbooks/common/openshift-master/service.yml b/playbooks/common/openshift-master/service.yml index 5636ad156..5e5198335 100644 --- a/playbooks/common/openshift-master/service.yml +++ b/playbooks/common/openshift-master/service.yml @@ -2,17 +2,19 @@ - name: Populate g_service_masters host group if needed hosts: localhost gather_facts: no + connection: local + become: no tasks: - fail: msg="new_cluster_state is required to be injected in this playbook" when: new_cluster_state is not defined - name: Evaluate g_service_masters add_host: name={{ item }} groups=g_service_masters - with_items: oo_host_group_exp | default([]) + with_items: "{{ oo_host_group_exp | default([]) }}" -- name: Change openshift-master state on master instance(s) +- name: Change state on master instance(s) hosts: g_service_masters connection: ssh gather_facts: no tasks: - - service: name=openshift-master state="{{ new_cluster_state }}" + - service: name={{ openshift.common.service_type }}-master state="{{ new_cluster_state }}" diff --git a/playbooks/common/openshift-nfs/config.yml b/playbooks/common/openshift-nfs/config.yml new file mode 100644 index 000000000..000e46e80 --- /dev/null +++ b/playbooks/common/openshift-nfs/config.yml @@ -0,0 +1,6 @@ +--- +- name: Configure nfs + hosts: oo_nfs_to_config + roles: + - role: openshift_facts + - role: openshift_storage_nfs diff --git a/playbooks/common/openshift-nfs/filter_plugins b/playbooks/common/openshift-nfs/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/common/openshift-nfs/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-nfs/lookup_plugins b/playbooks/common/openshift-nfs/lookup_plugins new file mode 120000 index 000000000..ac79701db --- /dev/null +++ b/playbooks/common/openshift-nfs/lookup_plugins @@ -0,0 +1 @@ +../../../lookup_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-nfs/roles b/playbooks/common/openshift-nfs/roles new file mode 120000 index 000000000..e2b799b9d --- /dev/null +++ b/playbooks/common/openshift-nfs/roles @@ -0,0 +1 @@ +../../../roles/
\ No newline at end of file diff --git a/playbooks/common/openshift-nfs/service.yml b/playbooks/common/openshift-nfs/service.yml new file mode 100644 index 000000000..8468014da --- /dev/null +++ b/playbooks/common/openshift-nfs/service.yml @@ -0,0 +1,18 @@ +--- +- name: Populate g_service_nfs host group if needed + hosts: localhost + gather_facts: no + tasks: + - fail: msg="new_cluster_state is required to be injected in this playbook" + when: new_cluster_state is not defined + + - name: Evaluate g_service_nfs + add_host: name={{ item }} groups=g_service_nfs + with_items: "{{ oo_host_group_exp | default([]) }}" + +- name: Change state on nfs instance(s) + hosts: g_service_nfs + connection: ssh + gather_facts: no + tasks: + - service: name=nfs-server state="{{ new_cluster_state }}" diff --git a/playbooks/common/openshift-node/config.yml b/playbooks/common/openshift-node/config.yml index bd35008b8..4824eeef3 100644 --- a/playbooks/common/openshift-node/config.yml +++ b/playbooks/common/openshift-node/config.yml @@ -1,6 +1,12 @@ --- - name: Gather and set facts for node hosts hosts: oo_nodes_to_config + vars: + t_oo_option_node_debug_level: "{{ lookup('oo_option', 'openshift_node_debug_level') }}" + pre_tasks: + - set_fact: + openshift_node_debug_level: "{{ t_oo_option_node_debug_level }}" + when: openshift_node_debug_level is not defined and t_oo_option_node_debug_level != "" roles: - openshift_facts tasks: @@ -8,40 +14,16 @@ # configured, we need to make sure to set the node properties beforehand if # we do not want the defaults - openshift_facts: - role: "{{ item.role }}" - local_facts: "{{ item.local_facts }}" - with_items: - - role: common - local_facts: - hostname: "{{ openshift_hostname | default(None) }}" - public_hostname: "{{ openshift_public_hostname | default(None) }}" - deployment_type: "{{ openshift_deployment_type }}" - - role: node - local_facts: - labels: "{{ openshift_node_labels | default(None) }}" - annotations: "{{ openshift_node_annotations | default(None) }}" - - name: Check status of node certificates - stat: - path: "/etc/openshift/node/{{ item }}" - with_items: - - "system:node:{{ openshift.common.hostname }}.crt" - - "system:node:{{ openshift.common.hostname }}.key" - - "system:node:{{ openshift.common.hostname }}.kubeconfig" - - ca.crt - - server.key - - server.crt - register: stat_result - - set_fact: - certs_missing: "{{ stat_result.results | map(attribute='stat.exists') - | list | intersect([false])}}" - node_subdir: node-{{ openshift.common.hostname }} - config_dir: /etc/openshift/generated-configs/node-{{ openshift.common.hostname }} - node_cert_dir: /etc/openshift/node + role: node + local_facts: + labels: "{{ openshift_node_labels | default(None) }}" + annotations: "{{ openshift_node_annotations | default(None) }}" + schedulable: "{{ openshift_schedulable | default(openshift_scheduleable) | default(None) }}" - name: Create temp directory for syncing certs hosts: localhost connection: local - sudo: false + become: no gather_facts: no tasks: - name: Create local temp directory for syncing certs @@ -49,58 +31,114 @@ register: mktemp changed_when: False -- name: Create node certificates - hosts: oo_first_master +- name: Evaluate node groups + hosts: localhost + become: no + connection: local + tasks: + - name: Evaluate oo_containerized_master_nodes + add_host: + name: "{{ item }}" + groups: oo_containerized_master_nodes + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_become: "{{ g_sudo | default(omit) }}" + with_items: "{{ groups.oo_nodes_to_config | default([]) }}" + when: hostvars[item].openshift.common is defined and hostvars[item].openshift.common.is_containerized | bool and (item in groups.oo_nodes_to_config and item in groups.oo_masters_to_config) + +- name: Configure containerized nodes + hosts: oo_containerized_master_nodes + serial: 1 vars: - nodes_needing_certs: "{{ hostvars - | oo_select_keys(groups['oo_nodes_to_config'] - | default([])) - | oo_filter_list(filter_attr='certs_missing') }}" - sync_tmpdir: "{{ hostvars.localhost.mktemp.stdout }}" + openshift_node_master_api_url: "{{ hostvars[groups.oo_first_master.0].openshift.master.api_url }}" + openshift_node_first_master_ip: "{{ hostvars[groups.oo_first_master.0].openshift.common.ip }}" + openshift_docker_hosted_registry_network: "{{ hostvars[groups.oo_first_master.0].openshift.common.portal_net }}" + openshift_no_proxy_internal_hostnames: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_config'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" + when: "{{ (openshift_http_proxy is defined or openshift_https_proxy is defined) and + openshift_generate_no_proxy_hosts | default(True) | bool }}" roles: - - openshift_node_certificates - post_tasks: - - name: Create a tarball of the node config directories - command: > - tar -czvf {{ item.config_dir }}.tgz - --transform 's|system:{{ item.node_subdir }}|node|' - -C {{ item.config_dir }} . - args: - creates: "{{ item.config_dir }}.tgz" - with_items: nodes_needing_certs + - role: openshift_common + - role: openshift_clock + - role: openshift_docker + - role: openshift_node_certificates + openshift_ca_host: "{{ groups.oo_first_master.0 }}" + - role: openshift_cloud_provider + - role: openshift_node_dnsmasq + when: openshift.common.use_dnsmasq | bool + - role: os_firewall + os_firewall_allow: + - service: Kubernetes kubelet + port: 10250/tcp + - service: http + port: 80/tcp + - service: https + port: 443/tcp + - service: Openshift kubelet ReadOnlyPort + port: 10255/tcp + - service: Openshift kubelet ReadOnlyPort udp + port: 10255/udp + - service: OpenShift OVS sdn + port: 4789/udp + when: openshift.node.use_openshift_sdn | bool + - role: openshift_node - - name: Retrieve the node config tarballs from the master - fetch: - src: "{{ item.config_dir }}.tgz" - dest: "{{ sync_tmpdir }}/" - flat: yes - fail_on_missing: yes - validate_checksum: yes - with_items: nodes_needing_certs +- name: Configure nodes + hosts: oo_nodes_to_config:!oo_containerized_master_nodes + vars: + openshift_node_master_api_url: "{{ hostvars[groups.oo_first_master.0].openshift.master.api_url }}" + openshift_node_first_master_ip: "{{ hostvars[groups.oo_first_master.0].openshift.common.ip }}" + openshift_docker_hosted_registry_network: "{{ hostvars[groups.oo_first_master.0].openshift.common.portal_net }}" + openshift_no_proxy_internal_hostnames: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_config'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" + when: "{{ (openshift_http_proxy is defined or openshift_https_proxy is defined) and + openshift_generate_no_proxy_hosts | default(True) | bool }}" + roles: + - role: openshift_common + - role: openshift_clock + - role: openshift_docker + - role: openshift_node_certificates + openshift_ca_host: "{{ groups.oo_first_master.0 }}" + - role: openshift_cloud_provider + - role: openshift_node_dnsmasq + when: openshift.common.use_dnsmasq | bool + - role: os_firewall + os_firewall_allow: + - service: Kubernetes kubelet + port: 10250/tcp + - service: http + port: 80/tcp + - service: https + port: 443/tcp + - service: Openshift kubelet ReadOnlyPort + port: 10255/tcp + - service: Openshift kubelet ReadOnlyPort udp + port: 10255/udp + - service: OpenShift OVS sdn + port: 4789/udp + when: openshift.node.use_openshift_sdn | bool + - role: openshift_node -- name: Configure node instances +- name: Additional node config hosts: oo_nodes_to_config vars: - sync_tmpdir: "{{ hostvars.localhost.mktemp.stdout }}" openshift_node_master_api_url: "{{ hostvars[groups.oo_first_master.0].openshift.master.api_url }}" - pre_tasks: - - name: Ensure certificate directory exists - file: - path: "{{ node_cert_dir }}" - state: directory - - # TODO: notify restart openshift-node - # possibly test service started time against certificate/config file - # timestamps in openshift-node to trigger notify - - name: Unarchive the tarball on the node - unarchive: - src: "{{ sync_tmpdir }}/{{ node_subdir }}.tgz" - dest: "{{ node_cert_dir }}" - when: certs_missing roles: - - openshift_node - - role: fluentd_node - when: openshift.common.use_fluentd | bool + - role: flannel + etcd_urls: "{{ hostvars[groups.oo_first_master.0].openshift.master.etcd_urls }}" + embedded_etcd: "{{ hostvars[groups.oo_first_master.0].openshift.master.embedded_etcd }}" + etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" + etcd_cert_subdir: "openshift-node-{{ openshift.common.hostname }}" + etcd_cert_config_dir: "{{ openshift.common.config_base }}/node" + when: openshift.common.use_flannel | bool + - role: nuage_node + when: openshift.common.use_nuage | bool + - role: nickhammond.logrotate tasks: - name: Create group for deployment type group_by: key=oo_nodes_deployment_type_{{ openshift.common.deployment_type }} @@ -109,36 +147,40 @@ - name: Delete temporary directory on localhost hosts: localhost connection: local - sudo: false + become: no gather_facts: no tasks: - file: name={{ mktemp.stdout }} state=absent changed_when: False -# Additional config for online type deployments -- name: Additional instance config - hosts: oo_nodes_deployment_type_online - gather_facts: no - roles: - - os_env_extras - - os_env_extras_node - -- name: Set scheduleability +- name: Set node schedulability hosts: oo_first_master vars: - openshift_nodes: "{{ hostvars - | oo_select_keys(groups['oo_nodes_to_config']) - | oo_collect('openshift.common.hostname') }}" - openshift_unscheduleable_nodes: "{{ hostvars - | oo_select_keys(groups['oo_nodes_to_config'] - | default([])) - | oo_collect('openshift.common.hostname', {'openshift_scheduleable': False}) }}" + openshift_nodes: "{{ groups.oo_nodes_to_config | default([]) }}" pre_tasks: - - set_fact: - openshift_scheduleable_nodes: "{{ hostvars - | oo_select_keys(groups['oo_nodes_to_config'] - | default([])) - | oo_collect('openshift.common.hostname') - | difference(openshift_unscheduleable_nodes) }}" + # Necessary because when you're on a node that's also a master the master will be + # restarted after the node restarts docker and it will take up to 60 seconds for + # systemd to start the master again + - name: Wait for master API to become available before proceeding + # Using curl here since the uri module requires python-httplib2 and + # wait_for port doesn't provide health information. + command: > + curl --silent --tlsv1.2 + {% if openshift.common.version_gte_3_2_or_1_2 | bool %} + --cacert {{ openshift.common.config_base }}/master/ca-bundle.crt + {% else %} + --cacert {{ openshift.common.config_base }}/master/ca.crt + {% endif %} + {{ openshift.master.api_url }}/healthz/ready + args: + # Disables the following warning: + # Consider using get_url or uri module rather than running curl + warn: no + register: api_available_output + until: api_available_output.stdout == 'ok' + retries: 120 + delay: 1 + changed_when: false + when: openshift.common.is_containerized | bool roles: - openshift_manage_node diff --git a/playbooks/common/openshift-node/scaleup.yml b/playbooks/common/openshift-node/scaleup.yml new file mode 100644 index 000000000..bb3b1e780 --- /dev/null +++ b/playbooks/common/openshift-node/scaleup.yml @@ -0,0 +1,30 @@ +--- +- include: ../openshift-cluster/evaluate_groups.yml + +- name: Gather facts + hosts: oo_etcd_to_config:oo_masters_to_config:oo_nodes_to_config + roles: + - openshift_facts + +- name: Gather and set facts for first master + hosts: oo_first_master + vars: + openshift_master_count: "{{ groups.oo_masters | length }}" + pre_tasks: + - set_fact: + openshift_master_default_subdomain: "{{ lookup('oo_option', 'openshift_master_default_subdomain') | default(None, true) }}" + when: openshift_master_default_subdomain is not defined + roles: + - openshift_master_facts + +- name: Configure docker hosts + hosts: oo_nodes_to_config + vars: + docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries') | oo_split }}" + docker_insecure_registries: "{{ lookup('oo_option', 'docker_insecure_registries') | oo_split }}" + docker_blocked_registries: "{{ lookup('oo_option', 'docker_blocked_registries') | oo_split }}" + roles: + - openshift_facts + - openshift_docker + +- include: ../openshift-node/config.yml diff --git a/playbooks/common/openshift-node/service.yml b/playbooks/common/openshift-node/service.yml index f76df089f..33095c9fb 100644 --- a/playbooks/common/openshift-node/service.yml +++ b/playbooks/common/openshift-node/service.yml @@ -1,6 +1,8 @@ --- - name: Populate g_service_nodes host group if needed hosts: localhost + connection: local + become: no gather_facts: no tasks: - fail: msg="new_cluster_state is required to be injected in this playbook" @@ -8,11 +10,11 @@ - name: Evaluate g_service_nodes add_host: name={{ item }} groups=g_service_nodes - with_items: oo_host_group_exp | default([]) + with_items: "{{ oo_host_group_exp | default([]) }}" -- name: Change openshift-node state on node instance(s) +- name: Change state on node instance(s) hosts: g_service_nodes connection: ssh gather_facts: no tasks: - - service: name=openshift-node state="{{ new_cluster_state }}" + - service: name={{ service_type }}-node state="{{ new_cluster_state }}" diff --git a/playbooks/gce/openshift-cluster/add_nodes.yml b/playbooks/gce/openshift-cluster/add_nodes.yml new file mode 100644 index 000000000..765e03fdc --- /dev/null +++ b/playbooks/gce/openshift-cluster/add_nodes.yml @@ -0,0 +1,43 @@ +--- +- name: Launch instance(s) + hosts: localhost + connection: local + become: no + gather_facts: no + vars_files: + - vars.yml + vars: + oo_extend_env: True + tasks: + - fail: + msg: Deployment type not supported for gce provider yet + when: deployment_type == 'enterprise' + + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "compute" + count: "{{ num_nodes }}" + - include: tasks/launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" + gce_machine_type: "{{ lookup('env', 'gce_machine_node_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_node_image') | default(lookup('env', 'gce_machine_image'), true) }}" + + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "infra" + count: "{{ num_infra }}" + - include: tasks/launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" + gce_machine_type: "{{ lookup('env', 'gce_machine_node_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_node_image') | default(lookup('env', 'gce_machine_image'), true) }}" + +- include: scaleup.yml +- include: list.yml diff --git a/playbooks/gce/openshift-cluster/cluster_hosts.yml b/playbooks/gce/openshift-cluster/cluster_hosts.yml new file mode 100644 index 000000000..a7baea915 --- /dev/null +++ b/playbooks/gce/openshift-cluster/cluster_hosts.yml @@ -0,0 +1,21 @@ +--- +g_all_hosts: "{{ groups['tag_clusterid-' ~ cluster_id] | default([]) + | intersect(groups['tag_environment-' ~ cluster_env] | default([])) }}" + +g_etcd_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-etcd'] | default([])) }}" + +g_lb_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-lb'] | default([])) }}" + +g_nfs_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-nfs'] | default([])) }}" + +g_master_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-master'] | default([])) }}" + +g_new_master_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-new-master'] | default([])) }}" + +g_node_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-node'] | default([])) }}" + +g_new_node_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-new-node'] | default([])) }}" + +g_infra_hosts: "{{ g_node_hosts | intersect(groups['tag_sub-host-type-infra'] | default([])) }}" + +g_compute_hosts: "{{ g_node_hosts | intersect(groups['tag_sub-host-type-compute'] | default([])) }}" diff --git a/playbooks/gce/openshift-cluster/config.yml b/playbooks/gce/openshift-cluster/config.yml index 219ebe6a0..8e46c5919 100644 --- a/playbooks/gce/openshift-cluster/config.yml +++ b/playbooks/gce/openshift-cluster/config.yml @@ -1,24 +1,35 @@ --- -# TODO: fix firewall related bug with GCE and origin, since GCE is overriding -# /etc/sysconfig/iptables - - hosts: localhost gather_facts: no - vars_files: - - vars.yml tasks: - - set_fact: - g_ssh_user_tmp: "{{ deployment_vars[deployment_type].ssh_user }}" - g_sudo_tmp: "{{ deployment_vars[deployment_type].sudo }}" + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ g_all_hosts | default([]) }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml - include: ../../common/openshift-cluster/config.yml vars: - g_etcd_group: "{{ 'tag_env-host-type-' ~ cluster_id ~ '-openshift-etcd' }}" - g_masters_group: "{{ 'tag_env-host-type-' ~ cluster_id ~ '-openshift-master' }}" - g_nodes_group: "{{ 'tag_env-host-type-' ~ cluster_id ~ '-openshift-node' }}" - g_ssh_user: "{{ hostvars.localhost.g_ssh_user_tmp }}" - g_sudo: "{{ hostvars.localhost.g_sudo_tmp }}" + g_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + g_sudo: "{{ deployment_vars[deployment_type].become }}" + g_nodeonmaster: true openshift_cluster_id: "{{ cluster_id }}" - openshift_debug_level: 4 + openshift_debug_level: "{{ debug_level }}" openshift_deployment_type: "{{ deployment_type }}" openshift_hostname: "{{ gce_private_ip }}" + openshift_hosted_registry_selector: 'type=infra' + openshift_hosted_router_selector: 'type=infra' + openshift_master_cluster_method: 'native' + openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}" + os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}" + openshift_use_flannel: "{{ lookup('oo_option', 'use_flannel') }}" + openshift_use_fluentd: "{{ lookup('oo_option', 'use_fluentd') }}" diff --git a/playbooks/gce/openshift-cluster/launch.yml b/playbooks/gce/openshift-cluster/launch.yml index 35737f03d..7532a678b 100644 --- a/playbooks/gce/openshift-cluster/launch.yml +++ b/playbooks/gce/openshift-cluster/launch.yml @@ -2,6 +2,7 @@ - name: Launch instance(s) hosts: localhost connection: local + become: no gather_facts: no vars_files: - vars.yml @@ -9,36 +10,58 @@ - fail: msg="Deployment type not supported for gce provider yet" when: deployment_type == 'enterprise' - - include: ../../common/openshift-cluster/set_master_launch_facts_tasks.yml + - include: ../../common/openshift-cluster/tasks/set_etcd_launch_facts.yml + - include: tasks/launch_instances.yml + vars: + instances: "{{ etcd_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "default" + gce_machine_type: "{{ lookup('env', 'gce_machine_etcd_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_etcd_image') | default(lookup('env', 'gce_machine_image'), true) }}" + + + - include: ../../common/openshift-cluster/tasks/set_master_launch_facts.yml - include: tasks/launch_instances.yml vars: instances: "{{ master_names }}" cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" + g_sub_host_type: "default" + gce_machine_type: "{{ lookup('env', 'gce_machine_master_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_master_image') | default(lookup('env', 'gce_machine_image'), true) }}" - - include: ../../common/openshift-cluster/set_node_launch_facts_tasks.yml + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "compute" + count: "{{ num_nodes }}" - include: tasks/launch_instances.yml vars: instances: "{{ node_names }}" cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" + gce_machine_type: "{{ lookup('env', 'gce_machine_node_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_node_image') | default(lookup('env', 'gce_machine_image'), true) }}" - - set_fact: - a_master: "{{ master_names[0] }}" - - add_host: name={{ a_master }} groups=service_master + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "infra" + count: "{{ num_infra }}" + - include: tasks/launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" + gce_machine_type: "{{ lookup('env', 'gce_machine_node_type') | default(lookup('env', 'gce_machine_type'), true) }}" + gce_machine_image: "{{ lookup('env', 'gce_machine_node_image') | default(lookup('env', 'gce_machine_image'), true) }}" -- include: update.yml + - add_host: + name: "{{ master_names.0 }}" + groups: service_master + when: master_names is defined and master_names.0 is defined -- name: Deploy OpenShift Services - hosts: service_master - connection: ssh - gather_facts: yes - roles: - - openshift_registry - - openshift_router - -- include: ../../common/openshift-cluster/create_services.yml - vars: - g_svc_master: "{{ service_master }}" +- include: update.yml - include: list.yml diff --git a/playbooks/gce/openshift-cluster/list.yml b/playbooks/gce/openshift-cluster/list.yml index 5ba0f5a48..34ab09533 100644 --- a/playbooks/gce/openshift-cluster/list.yml +++ b/playbooks/gce/openshift-cluster/list.yml @@ -1,24 +1,23 @@ --- - name: Generate oo_list_hosts group hosts: localhost + connection: local + become: no gather_facts: no vars_files: - vars.yml tasks: - - set_fact: scratch_group=tag_env-{{ cluster_id }} + - set_fact: scratch_group=tag_clusterid-{{ cluster_id }} when: cluster_id != '' - set_fact: scratch_group=all when: cluster_id == '' - add_host: name: "{{ item }}" groups: oo_list_hosts - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[scratch_group] | default([]) | difference(['localhost']) | difference(groups.status_terminated) - -- name: List instance(s) - hosts: oo_list_hosts - gather_facts: no - tasks: + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + oo_public_ipv4: "{{ hostvars[item].gce_public_ip }}" + oo_private_ipv4: "{{ hostvars[item].gce_private_ip }}" + with_items: "{{ groups[scratch_group] | default([], true) | difference(['localhost']) | difference(groups.status_terminated | default([], true)) }}" - debug: - msg: "public ip:{{ hostvars[inventory_hostname].gce_public_ip }} private ip:{{ hostvars[inventory_hostname].gce_private_ip }}" + msg: "{{ hostvars | oo_select_keys(groups[scratch_group] | default([])) | oo_pretty_print_cluster }}" diff --git a/playbooks/gce/openshift-cluster/service.yml b/playbooks/gce/openshift-cluster/service.yml index 2d0f2ab95..13b267976 100644 --- a/playbooks/gce/openshift-cluster/service.yml +++ b/playbooks/gce/openshift-cluster/service.yml @@ -1,28 +1,29 @@ --- - name: Call same systemctl command for openshift on all instance(s) hosts: localhost + connection: local + become: no gather_facts: no vars_files: - vars.yml + - cluster_hosts.yml tasks: - fail: msg="cluster_id is required to be injected in this playbook" when: cluster_id is not defined - - set_fact: scratch_group=tag_env-host-type-{{ cluster_id }}-openshift-node - add_host: name: "{{ item }}" groups: g_service_nodes - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[scratch_group] | default([]) | difference(['localhost']) | difference(groups.status_terminated) + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ node_hosts | default([]) | difference(['localhost']) | difference(groups.status_terminated) }}" - - set_fact: scratch_group=tag_env-host-type-{{ cluster_id }}-openshift-master - add_host: name: "{{ item }}" groups: g_service_masters - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[scratch_group] | default([]) | difference(['localhost']) | difference(groups.status_terminated) + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ master_hosts | default([]) | difference(['localhost']) | difference(groups.status_terminated) }}" - include: ../../common/openshift-node/service.yml - include: ../../common/openshift-master/service.yml diff --git a/playbooks/gce/openshift-cluster/tasks/launch_instances.yml b/playbooks/gce/openshift-cluster/tasks/launch_instances.yml index 9a9848f05..b7604580c 100644 --- a/playbooks/gce/openshift-cluster/tasks/launch_instances.yml +++ b/playbooks/gce/openshift-cluster/tasks/launch_instances.yml @@ -1,41 +1,65 @@ --- -# TODO: when we are ready to go to ansible 1.9+ support only, we can update to -# the gce task to use the disk_auto_delete parameter to avoid having to delete -# the disk as a separate step on termination - name: Launch instance(s) gce: - instance_names: "{{ instances }}" - machine_type: "{{ lookup('env', 'gce_machine_type') | default('n1-standard-1', true) }}" - image: "{{ lookup('env', 'gce_machine_image') | default(deployment_vars[deployment_type].image, true) }}" + instance_names: "{{ instances|join(',') }}" + machine_type: "{{ gce_machine_type | default(deployment_vars[deployment_type].machine_type, true) }}" + image: "{{ gce_machine_image | default(deployment_vars[deployment_type].image, true) }}" service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}" pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" project_id: "{{ lookup('env', 'gce_project_id') }}" + zone: "{{ lookup('env', 'zone') }}" + network: "{{ lookup('env', 'network') }}" + subnetwork: "{{ lookup('env', 'subnetwork') | default(omit, True) }}" +# unsupported in 1.9.+ + #service_account_permissions: "datastore,logging-write" tags: - created-by-{{ lookup('env', 'LOGNAME') |default(cluster, true) }} - - env-{{ cluster }} + - environment-{{ cluster_env }} + - clusterid-{{ cluster_id }} - host-type-{{ type }} - - env-host-type-{{ cluster }}-openshift-{{ type }} + - sub-host-type-{{ g_sub_host_type }} + metadata: + startup-script: | + #!/bin/bash + echo "Defaults:{{ deployment_vars[deployment_type].ssh_user }} !requiretty" > /etc/sudoers.d/99-{{ deployment_vars[deployment_type].ssh_user }} + + when: instances |length > 0 register: gce +- set_fact: + node_label: + # There doesn't seem to be a way to get the region directly, so parse it out of the zone. + region: "{{ gce.zone | regex_replace('^(.*)-.*$', '\\\\1') }}" + type: "{{ g_sub_host_type }}" + when: instances |length > 0 and type == "node" + +- set_fact: + node_label: + # There doesn't seem to be a way to get the region directly, so parse it out of the zone. + region: "{{ gce.zone | regex_replace('^(.*)-.*$', '\\\\1') }}" + type: "{{ type }}" + when: instances |length > 0 and type != "node" + - name: Add new instances to groups and set variables needed add_host: hostname: "{{ item.name }}" ansible_ssh_host: "{{ item.public_ip }}" - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" groups: "{{ item.tags | oo_prepend_strings_in_list('tag_') | join(',') }}" gce_public_ip: "{{ item.public_ip }}" gce_private_ip: "{{ item.private_ip }}" - with_items: gce.instance_data + openshift_node_labels: "{{ node_label }}" + with_items: "{{ gce.instance_data | default([], true) }}" - name: Wait for ssh wait_for: port=22 host={{ item.public_ip }} - with_items: gce.instance_data + with_items: "{{ gce.instance_data | default([], true) }}" - name: Wait for user setup command: "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null {{ hostvars[item.name].ansible_ssh_user }}@{{ item.public_ip }} echo {{ hostvars[item.name].ansible_ssh_user }} user is setup" register: result until: result.rc == 0 - retries: 20 - delay: 10 - with_items: gce.instance_data + retries: 30 + delay: 5 + with_items: "{{ gce.instance_data | default([], true) }}" diff --git a/playbooks/gce/openshift-cluster/terminate.yml b/playbooks/gce/openshift-cluster/terminate.yml index abe6a4c95..68e60f9d4 100644 --- a/playbooks/gce/openshift-cluster/terminate.yml +++ b/playbooks/gce/openshift-cluster/terminate.yml @@ -1,34 +1,59 @@ --- - name: Terminate instance(s) hosts: localhost + connection: local + become: no gather_facts: no vars_files: - vars.yml tasks: - - set_fact: scratch_group=tag_env-host-type-{{ cluster_id }}-openshift-node - add_host: name: "{{ item }}" - groups: oo_nodes_to_terminate - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[scratch_group] | default([]) | difference(['localhost']) | difference(groups.status_terminated) + groups: oo_hosts_to_terminate + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ (groups['tag_clusterid-' ~ cluster_id] | default([])) | difference(['localhost']) }}" - - set_fact: scratch_group=tag_env-host-type-{{ cluster_id }}-openshift-master - - add_host: - name: "{{ item }}" - groups: oo_masters_to_terminate - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[scratch_group] | default([]) | difference(['localhost']) | difference(groups.status_terminated) +- name: Unsubscribe VMs + hosts: oo_hosts_to_terminate + vars_files: + - vars.yml + roles: + - role: rhel_unsubscribe + when: deployment_type in ['atomic-enterprise', 'enterprise', 'openshift-enterprise'] and + ansible_distribution == "RedHat" and + lookup('oo_option', 'rhel_skip_subscription') | default(rhsub_skip, True) | + default('no', True) | lower in ['no', 'false'] + +- name: Terminate instances(s) + hosts: localhost + become: no + connection: local + gather_facts: no + vars_files: + - vars.yml + tasks: -- include: ../openshift-node/terminate.yml - vars: - gce_service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}" - gce_pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" - gce_project_id: "{{ lookup('env', 'gce_project_id') }}" + - name: Terminate instances that were previously launched + local_action: + module: gce + state: 'absent' + name: "{{ item }}" + service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}" + pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" + project_id: "{{ lookup('env', 'gce_project_id') }}" + zone: "{{ lookup('env', 'zone') }}" + with_items: "{{ groups['oo_hosts_to_terminate'] | default([], true) }}" + when: item is defined -- include: ../openshift-master/terminate.yml - vars: - gce_service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}" - gce_pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" - gce_project_id: "{{ lookup('env', 'gce_project_id') }}" +#- include: ../openshift-node/terminate.yml +# vars: +# gce_service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}" +# gce_pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" +# gce_project_id: "{{ lookup('env', 'gce_project_id') }}" +# +#- include: ../openshift-master/terminate.yml +# vars: +# gce_service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}" +# gce_pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" +# gce_project_id: "{{ lookup('env', 'gce_project_id') }}" diff --git a/playbooks/gce/openshift-cluster/update.yml b/playbooks/gce/openshift-cluster/update.yml index 8096aa654..6d2af3d26 100644 --- a/playbooks/gce/openshift-cluster/update.yml +++ b/playbooks/gce/openshift-cluster/update.yml @@ -1,19 +1,33 @@ --- +- hosts: localhost + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - name: Populate oo_hosts_to_update group hosts: localhost + connection: local + become: no gather_facts: no - vars_files: - - vars.yml tasks: - name: Evaluate oo_hosts_to_update add_host: name: "{{ item }}" groups: oo_hosts_to_update - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: (groups["tag_env-host-type-{{ cluster_id }}-openshift-master"] | default([])) - | union(groups["tag_env-host-type-{{ cluster_id }}-openshift-node"] | default([])) - | union(groups["tag_env-host-type-{{ cluster_id }}-openshift-etcd"] | default([])) + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ g_all_hosts | default([]) }}" - include: ../../common/openshift-cluster/update_repos_and_packages.yml diff --git a/playbooks/gce/openshift-cluster/vars.yml b/playbooks/gce/openshift-cluster/vars.yml index ae33083b9..13c754c1e 100644 --- a/playbooks/gce/openshift-cluster/vars.yml +++ b/playbooks/gce/openshift-cluster/vars.yml @@ -1,15 +1,18 @@ --- +debug_level: 2 + +deployment_rhel7_ent_base: + image: "{{ lookup('oo_option', 'image_name') | default('rhel-7', True) }}" + machine_type: "{{ lookup('oo_option', 'machine_type') | default('n1-standard-1', True) }}" + ssh_user: "{{ lookup('env', 'gce_ssh_user') | default(ansible_ssh_user, true) }}" + become: yes + deployment_vars: origin: - image: centos-7 - ssh_user: - sudo: yes - online: - image: libra-rhel7 - ssh_user: root - sudo: no - enterprise: - image: rhel-7 - ssh_user: - sudo: yes - + image: "{{ lookup('oo_option', 'image_name') | default('centos-7', True) }}" + machine_type: "{{ lookup('oo_option', 'machine_type') | default('n1-standard-1', True) }}" + ssh_user: "{{ lookup('env', 'gce_ssh_user') | default(ansible_ssh_user, true) }}" + become: yes + enterprise: "{{ deployment_rhel7_ent_base }}" + openshift-enterprise: "{{ deployment_rhel7_ent_base }}" + atomic-enterprise: "{{ deployment_rhel7_ent_base }}" diff --git a/playbooks/gce/openshift-cluster/wip.yml b/playbooks/gce/openshift-cluster/wip.yml deleted file mode 100644 index 51a521a6b..000000000 --- a/playbooks/gce/openshift-cluster/wip.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -- name: WIP - hosts: localhost - connection: local - gather_facts: no - vars_files: - - vars.yml - tasks: - - name: Evaluate oo_masters_for_deploy - add_host: - name: "{{ item }}" - groups: oo_masters_for_deploy - ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user | default(ansible_ssh_user, true) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups["tag_env-host-type-{{ cluster_id }}-openshift-master"] | default([]) - -- name: Deploy OpenShift Services - hosts: oo_masters_for_deploy - connection: ssh - gather_facts: yes - user: root - vars_files: - - vars.yml - roles: - - openshift_registry - - openshift_router diff --git a/playbooks/libvirt/openshift-cluster/cluster_hosts.yml b/playbooks/libvirt/openshift-cluster/cluster_hosts.yml new file mode 100644 index 000000000..a7baea915 --- /dev/null +++ b/playbooks/libvirt/openshift-cluster/cluster_hosts.yml @@ -0,0 +1,21 @@ +--- +g_all_hosts: "{{ groups['tag_clusterid-' ~ cluster_id] | default([]) + | intersect(groups['tag_environment-' ~ cluster_env] | default([])) }}" + +g_etcd_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-etcd'] | default([])) }}" + +g_lb_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-lb'] | default([])) }}" + +g_nfs_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-nfs'] | default([])) }}" + +g_master_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-master'] | default([])) }}" + +g_new_master_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-new-master'] | default([])) }}" + +g_node_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-node'] | default([])) }}" + +g_new_node_hosts: "{{ g_all_hosts | intersect(groups['tag_host-type-new-node'] | default([])) }}" + +g_infra_hosts: "{{ g_node_hosts | intersect(groups['tag_sub-host-type-infra'] | default([])) }}" + +g_compute_hosts: "{{ g_node_hosts | intersect(groups['tag_sub-host-type-compute'] | default([])) }}" diff --git a/playbooks/libvirt/openshift-cluster/config.yml b/playbooks/libvirt/openshift-cluster/config.yml index 98fe11251..299325fc4 100644 --- a/playbooks/libvirt/openshift-cluster/config.yml +++ b/playbooks/libvirt/openshift-cluster/config.yml @@ -3,22 +3,37 @@ # is localhost, so no hostname value (or public_hostname) value is getting # assigned +- include: ../../common/openshift-cluster/verify_ansible_version.yml + - hosts: localhost gather_facts: no - vars_files: - - vars.yml tasks: - - set_fact: - g_ssh_user_tmp: "{{ deployment_vars[deployment_type].ssh_user }}" - g_sudo_tmp: "{{ deployment_vars[deployment_type].sudo }}" + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml - include: ../../common/openshift-cluster/config.yml vars: - g_etcd_group: "{{ 'tag_env-host-type-' ~ cluster_id ~ '-openshift-etcd' }}" - g_masters_group: "{{ 'tag_env-host-type-' ~ cluster_id ~ '-openshift-master' }}" - g_nodes_group: "{{ 'tag_env-host-type-' ~ cluster_id ~ '-openshift-node' }}" - g_ssh_user: "{{ hostvars.localhost.g_ssh_user_tmp }}" - g_sudo: "{{ hostvars.localhost.g_sudo_tmp }}" + g_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + g_sudo: "{{ deployment_vars[deployment_type].become }}" + g_nodeonmaster: true openshift_cluster_id: "{{ cluster_id }}" - openshift_debug_level: 4 + openshift_debug_level: "{{ debug_level }}" openshift_deployment_type: "{{ deployment_type }}" + openshift_hosted_registry_selector: 'type=infra' + openshift_hosted_router_selector: 'type=infra' + openshift_master_cluster_method: 'native' + openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}" + os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}" + openshift_use_flannel: "{{ lookup('oo_option', 'use_flannel') }}" + openshift_use_fluentd: "{{ lookup('oo_option', 'use_fluentd') }}" + openshift_use_dnsmasq: false diff --git a/playbooks/libvirt/openshift-cluster/launch.yml b/playbooks/libvirt/openshift-cluster/launch.yml index a7ddc1e7e..2475b9d6b 100644 --- a/playbooks/libvirt/openshift-cluster/launch.yml +++ b/playbooks/libvirt/openshift-cluster/launch.yml @@ -1,35 +1,56 @@ --- - name: Launch instance(s) hosts: localhost + become: no + connection: local gather_facts: no vars_files: - vars.yml vars: - os_libvirt_storage_pool: "{{ libvirt_storage_pool | default('images') }}" - os_libvirt_storage_pool_path: "{{ libvirt_storage_pool_path | default('/var/lib/libvirt/images') }}" - os_libvirt_network: "{{ libvirt_network | default('default') }}" image_url: "{{ deployment_vars[deployment_type].image.url }}" image_sha256: "{{ deployment_vars[deployment_type].image.sha256 }}" image_name: "{{ deployment_vars[deployment_type].image.name }}" + image_compression: "{{ deployment_vars[deployment_type].image.compression }}" tasks: - - fail: msg="Deployment type not supported for libvirt provider yet" - when: deployment_type in ['online', 'enterprise'] - - include: tasks/configure_libvirt.yml - - include: ../../common/openshift-cluster/set_master_launch_facts_tasks.yml + - include: ../../common/openshift-cluster/tasks/set_etcd_launch_facts.yml + - include: tasks/launch_instances.yml + vars: + instances: "{{ etcd_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "default" + + - include: ../../common/openshift-cluster/tasks/set_master_launch_facts.yml - include: tasks/launch_instances.yml vars: instances: "{{ master_names }}" cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" + g_sub_host_type: "default" + + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "compute" + count: "{{ num_nodes }}" + - include: tasks/launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" - - include: ../../common/openshift-cluster/set_node_launch_facts_tasks.yml + - include: ../../common/openshift-cluster/tasks/set_node_launch_facts.yml + vars: + type: "infra" + count: "{{ num_infra }}" - include: tasks/launch_instances.yml vars: instances: "{{ node_names }}" cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" + g_sub_host_type: "{{ sub_host_type }}" - include: update.yml diff --git a/playbooks/libvirt/openshift-cluster/list.yml b/playbooks/libvirt/openshift-cluster/list.yml index eaedc4d0d..579cd7ac6 100644 --- a/playbooks/libvirt/openshift-cluster/list.yml +++ b/playbooks/libvirt/openshift-cluster/list.yml @@ -1,11 +1,13 @@ --- - name: Generate oo_list_hosts group hosts: localhost + become: no + connection: local gather_facts: no vars_files: - vars.yml tasks: - - set_fact: scratch_group=tag_env-{{ cluster_id }} + - set_fact: scratch_group=tag_clusterid-{{ cluster_id }} when: cluster_id != '' - set_fact: scratch_group=all when: cluster_id == '' @@ -13,11 +15,9 @@ name: "{{ item }}" groups: oo_list_hosts ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[scratch_group] | default([]) | difference(['localhost']) - -- name: List Hosts - hosts: oo_list_hosts - tasks: + ansible_become: "{{ deployment_vars[deployment_type].become }}" + oo_public_ipv4: "" + oo_private_ipv4: "{{ hostvars[item].libvirt_ip_address }}" + with_items: "{{ groups[scratch_group] | default([]) | difference(['localhost']) }}" - debug: - msg: 'public:{{ansible_default_ipv4.address}} private:{{ansible_default_ipv4.address}}' + msg: "{{ hostvars | oo_select_keys(groups[scratch_group] | default([])) | oo_pretty_print_cluster }}" diff --git a/playbooks/libvirt/openshift-cluster/service.yml b/playbooks/libvirt/openshift-cluster/service.yml index ae095f5a2..8bd24a8cf 100644 --- a/playbooks/libvirt/openshift-cluster/service.yml +++ b/playbooks/libvirt/openshift-cluster/service.yml @@ -5,6 +5,8 @@ - name: Call same systemctl command for openshift on all instance(s) hosts: localhost + become: no + connection: local gather_facts: no vars_files: - vars.yml @@ -16,17 +18,17 @@ add_host: name: "{{ item }}" ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" groups: g_service_masters - with_items: groups["tag_env-host-type-{{ cluster_id }}-openshift-master"] | default([]) + with_items: "{{ g_master_hosts | default([]) }}" - name: Evaluate g_service_nodes add_host: name: "{{ item }}" ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" groups: g_service_nodes - with_items: groups["tag_env-host-type-{{ cluster_id }}-openshift-node"] | default([]) + with_items: "{{ g_node_hosts | default([]) }}" - include: ../../common/openshift-node/service.yml - include: ../../common/openshift-master/service.yml diff --git a/playbooks/libvirt/openshift-cluster/tasks/configure_libvirt_network.yml b/playbooks/libvirt/openshift-cluster/tasks/configure_libvirt_network.yml index 3117d9edc..b42ca83af 100644 --- a/playbooks/libvirt/openshift-cluster/tasks/configure_libvirt_network.yml +++ b/playbooks/libvirt/openshift-cluster/tasks/configure_libvirt_network.yml @@ -1,27 +1,11 @@ --- -- name: Test if libvirt network for openshift already exists - command: "virsh -c {{ libvirt_uri }} net-info {{ libvirt_network }}" - register: net_info_result - changed_when: False - failed_when: "net_info_result.rc != 0 and 'no network with matching name' not in net_info_result.stderr" - -- name: Create a temp directory for the template xml file - command: "mktemp -d /tmp/openshift-ansible-XXXXXXX" - register: mktemp - when: net_info_result.rc == 1 - -- name: Create network xml file - template: - src: templates/network.xml - dest: "{{ mktemp.stdout }}/network.xml" - when: net_info_result.rc == 1 - -- name: Create libvirt network for openshift - command: "virsh -c {{ libvirt_uri }} net-create {{ mktemp.stdout }}/network.xml" - when: net_info_result.rc == 1 - -- name: Remove the temp directory - file: - path: "{{ mktemp.stdout }}" - state: absent - when: net_info_result.rc == 1 +- name: Create the libvirt network for OpenShift + virt_net: + name: '{{ libvirt_network }}' + state: '{{ item }}' + autostart: 'yes' + xml: "{{ lookup('template', 'network.xml') }}" + uri: '{{ libvirt_uri }}' + with_items: + - present + - active diff --git a/playbooks/libvirt/openshift-cluster/tasks/configure_libvirt_storage_pool.yml b/playbooks/libvirt/openshift-cluster/tasks/configure_libvirt_storage_pool.yml index 8a67d713f..8685624ec 100644 --- a/playbooks/libvirt/openshift-cluster/tasks/configure_libvirt_storage_pool.yml +++ b/playbooks/libvirt/openshift-cluster/tasks/configure_libvirt_storage_pool.yml @@ -4,20 +4,27 @@ dest: "{{ libvirt_storage_pool_path }}" state: directory +# We need to set permissions on the directory and any items created under the directory, so we need to call the acl module with and without default set. - acl: - default: yes + default: '{{ item.default }}' entity: kvm etype: group name: "{{ libvirt_storage_pool_path }}" - permissions: rwx + permissions: '{{ item.permissions }}' state: present + with_items: + - default: no + permissions: x + - default: yes + permissions: rwx -- name: Test if libvirt storage pool for openshift already exists - command: "virsh -c {{ libvirt_uri }} pool-info {{ libvirt_storage_pool }}" - register: pool_info_result - changed_when: False - failed_when: "pool_info_result.rc != 0 and 'no storage pool with matching name' not in pool_info_result.stderr" - -- name: Create the libvirt storage pool for openshift - command: 'virsh -c {{ libvirt_uri }} pool-create-as {{ libvirt_storage_pool }} dir --target {{ libvirt_storage_pool_path }}' - when: pool_info_result.rc == 1 +- name: Create the libvirt storage pool for OpenShift + virt_pool: + name: '{{ libvirt_storage_pool }}' + state: '{{ item }}' + autostart: 'yes' + xml: "{{ lookup('template', 'storage-pool.xml') }}" + uri: '{{ libvirt_uri }}' + with_items: + - present + - active diff --git a/playbooks/libvirt/openshift-cluster/tasks/launch_instances.yml b/playbooks/libvirt/openshift-cluster/tasks/launch_instances.yml index 4cb494056..e0afc43ba 100644 --- a/playbooks/libvirt/openshift-cluster/tasks/launch_instances.yml +++ b/playbooks/libvirt/openshift-cluster/tasks/launch_instances.yml @@ -1,7 +1,7 @@ --- # TODO: Add support for choosing base image based on deployment_type and os # wanted (os wanted needs support added in bin/cluster with sane defaults: -# fedora/centos for origin, rhel for online/enterprise) +# fedora/centos for origin, rhel for enterprise) # TODO: create a role to encapsulate some of this complexity, possibly also # create a module to manage the storage tasks, network tasks, and possibly @@ -13,36 +13,59 @@ get_url: url: '{{ image_url }}' sha256sum: '{{ image_sha256 }}' - dest: '{{ os_libvirt_storage_pool_path }}/{{ image_name }}' + dest: '{{ libvirt_storage_pool_path }}/{{ [image_name, image_compression] | difference([""]) | join(".") }}' when: '{{ ( lookup("oo_option", "skip_image_download") | default("no", True) | lower ) in ["false", "no"] }}' + register: downloaded_image + +- name: Uncompress xz compressed base cloud image + command: 'unxz -kf {{ libvirt_storage_pool_path }}/{{ [image_name, image_compression] | join(".") }}' + args: + creates: '{{ libvirt_storage_pool_path }}/{{ image_name }}' + when: image_compression in ["xz"] and downloaded_image.changed + +- name: Uncompress tgz compressed base cloud image + command: 'tar zxvf {{ libvirt_storage_pool_path }}/{{ [image_name, image_compression] | join(".") }}' + args: + creates: '{{ libvirt_storage_pool_path }}/{{ image_name }}' + when: image_compression in ["tgz"] and downloaded_image.changed + +- name: Uncompress gzip compressed base cloud image + command: 'gunzip {{ libvirt_storage_pool_path }}/{{ [image_name, image_compression] | join(".") }}' + args: + creates: '{{ libvirt_storage_pool_path }}/{{ image_name }}' + when: image_compression in ["gz"] and downloaded_image.changed - name: Create the cloud-init config drive path file: - dest: '{{ os_libvirt_storage_pool_path }}/{{ item }}_configdrive/' + dest: '{{ libvirt_storage_pool_path }}/{{ item }}_configdrive/' state: directory - with_items: instances + with_items: '{{ instances }}' - name: Create the cloud-init config drive files template: src: '{{ item[1] }}' - dest: '{{ os_libvirt_storage_pool_path }}/{{ item[0] }}_configdrive/{{ item[1] }}' + dest: '{{ libvirt_storage_pool_path }}/{{ item[0] }}_configdrive/{{ item[1] }}' with_nested: - - instances + - '{{ instances }}' - [ user-data, meta-data ] - name: Create the cloud-init config drive - command: 'genisoimage -output {{ os_libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso -volid cidata -joliet -rock user-data meta-data' + command: 'genisoimage -output {{ libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso -volid cidata -joliet -rock user-data meta-data' args: - chdir: '{{ os_libvirt_storage_pool_path }}/{{ item }}_configdrive/' - creates: '{{ os_libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso' - with_items: instances + chdir: '{{ libvirt_storage_pool_path }}/{{ item }}_configdrive/' + creates: '{{ libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso' + with_items: '{{ instances }}' - name: Refresh the libvirt storage pool for openshift command: 'virsh -c {{ libvirt_uri }} pool-refresh {{ libvirt_storage_pool }}' -- name: Create VMs drives - command: 'virsh -c {{ libvirt_uri }} vol-create-as {{ os_libvirt_storage_pool }} {{ item }}.qcow2 10G --format qcow2 --backing-vol {{ image_name }} --backing-vol-format qcow2' - with_items: instances +- name: Create VM drives + command: 'virsh -c {{ libvirt_uri }} vol-create-as {{ libvirt_storage_pool }} {{ item }}.qcow2 10G --format qcow2 --backing-vol {{ image_name }} --backing-vol-format qcow2' + with_items: '{{ instances }}' + +- name: Create VM docker drives + command: 'virsh -c {{ libvirt_uri }} vol-create-as {{ libvirt_storage_pool }} {{ item }}-docker.qcow2 10G --format qcow2 --allocation 0' + with_items: '{{ instances }}' - name: Create VMs virt: @@ -50,46 +73,58 @@ command: define xml: "{{ lookup('template', '../templates/domain.xml') }}" uri: '{{ libvirt_uri }}' - with_items: instances + with_items: '{{ instances }}' - name: Start VMs virt: name: '{{ item }}' state: running uri: '{{ libvirt_uri }}' - with_items: instances + with_items: '{{ instances }}' - name: Wait for the VMs to get an IP - shell: 'virsh -c {{ libvirt_uri }} net-dhcp-leases openshift-ansible | egrep -c ''{{ instances | join("|") }}''' + shell: 'virsh -c {{ libvirt_uri }} net-dhcp-leases {{ libvirt_network }} | egrep -c ''{{ instances | join("|") }}''' register: nb_allocated_ips until: nb_allocated_ips.stdout == '{{ instances | length }}' - retries: 30 - delay: 1 + retries: 60 + delay: 3 + when: instances | length != 0 - name: Collect IP addresses of the VMs - shell: 'virsh -c {{ libvirt_uri }} net-dhcp-leases openshift-ansible | awk ''$6 == "{{ item }}" {gsub(/\/.*/, "", $5); print $5}''' + shell: 'virsh -c {{ libvirt_uri }} net-dhcp-leases {{ libvirt_network }} | awk ''$6 == "{{ item }}" {gsub(/\/.*/, "", $5); print $5}''' register: scratch_ip - with_items: instances + with_items: '{{ instances }}' + +- set_fact: + ips: "{{ scratch_ip.results | default([]) | oo_collect('stdout') }}" + +- set_fact: + node_label: + type: "{{ g_sub_host_type }}" + when: instances | length > 0 and type == "node" - set_fact: - ips: "{{ scratch_ip.results | oo_collect('stdout') }}" + node_label: + type: "{{ type }}" + when: instances | length > 0 and type != "node" - name: Add new instances add_host: hostname: '{{ item.0 }}' ansible_ssh_host: '{{ item.1 }}' ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - groups: 'tag_env-{{ cluster }}, tag_host-type-{{ type }}, tag_env-host-type-{{ cluster }}-openshift-{{ type }}' + ansible_become: "{{ deployment_vars[deployment_type].become }}" + groups: "tag_environment-{{ cluster_env }}, tag_host-type-{{ type }}, tag_sub-host-type-{{ g_sub_host_type }}, tag_clusterid-{{ cluster_id }}" + openshift_node_labels: "{{ node_label }}" with_together: - - instances - - ips + - '{{ instances }}' + - '{{ ips }}' - name: Wait for ssh wait_for: host: '{{ item }}' port: 22 - with_items: ips + with_items: '{{ ips }}' - name: Wait for openshift user setup command: 'ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null openshift@{{ item.1 }} echo openshift user is setup' @@ -98,5 +133,5 @@ retries: 30 delay: 1 with_together: - - instances - - ips + - '{{ instances }}' + - '{{ ips }}' diff --git a/playbooks/libvirt/openshift-cluster/templates/domain.xml b/playbooks/libvirt/openshift-cluster/templates/domain.xml index df200e374..88504a5f6 100644 --- a/playbooks/libvirt/openshift-cluster/templates/domain.xml +++ b/playbooks/libvirt/openshift-cluster/templates/domain.xml @@ -1,15 +1,15 @@ <domain type='kvm' id='8'> <name>{{ item }}</name> - <memory unit='GiB'>1</memory> + <memory unit='MiB'>{{ libvirt_instance_memory_mib }}</memory> <metadata xmlns:ansible="https://github.com/ansible/ansible"> <ansible:tags> - <ansible:tag>env-{{ cluster }}</ansible:tag> - <ansible:tag>env-host-type-{{ cluster }}-openshift-{{ type }}</ansible:tag> + <ansible:tag>environment-{{ cluster_env }}</ansible:tag> + <ansible:tag>clusterid-{{ cluster }}</ansible:tag> <ansible:tag>host-type-{{ type }}</ansible:tag> + <ansible:tag>sub-host-type-{{ g_sub_host_type }}</ansible:tag> </ansible:tags> </metadata> - <currentMemory unit='GiB'>1</currentMemory> - <vcpu placement='static'>2</vcpu> + <vcpu placement='static'>{{ libvirt_instance_vcpu }}</vcpu> <os> <type arch='x86_64' machine='pc'>hvm</type> <boot dev='hd'/> @@ -19,6 +19,9 @@ <apic/> <pae/> </features> + <cpu mode='host-model'> + <model fallback='allow'/> + </cpu> <clock offset='utc'> <timer name='rtc' tickpolicy='catchup'/> <timer name='pit' tickpolicy='delay'/> @@ -30,19 +33,24 @@ <devices> <emulator>/usr/bin/qemu-system-x86_64</emulator> <disk type='file' device='disk'> - <driver name='qemu' type='qcow2'/> - <source file='{{ os_libvirt_storage_pool_path }}/{{ item }}.qcow2'/> - <target dev='vda' bus='virtio'/> + <driver name='qemu' type='qcow2' discard='unmap'/> + <source file='{{ libvirt_storage_pool_path }}/{{ item }}.qcow2'/> + <target dev='sda' bus='scsi'/> + </disk> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' discard='unmap'/> + <source file='{{ libvirt_storage_pool_path }}/{{ item }}-docker.qcow2'/> + <target dev='sdb' bus='scsi'/> </disk> <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> - <source file='{{ os_libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso'/> - <target dev='vdb' bus='virtio'/> + <source file='{{ libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso'/> + <target dev='sdc' bus='scsi'/> <readonly/> </disk> - <controller type='usb' index='0' /> + <controller type='scsi' model='virtio-scsi' /> <interface type='network'> - <source network='{{ os_libvirt_network }}'/> + <source network='{{ libvirt_network }}'/> <model type='virtio'/> </interface> <serial type='pty'> @@ -51,17 +59,6 @@ <console type='pty'> <target type='serial' port='0'/> </console> - <channel type='spicevmc'> - <target type='virtio' name='com.redhat.spice.0'/> - </channel> - <input type='tablet' bus='usb' /> - <input type='mouse' bus='ps2'/> - <graphics type='spice' autoport='yes' /> - <video> - <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1'/> - </video> - <redirdev bus='usb' type='spicevmc'> - </redirdev> <memballoon model='virtio'> </memballoon> </devices> diff --git a/playbooks/libvirt/openshift-cluster/templates/network.xml b/playbooks/libvirt/openshift-cluster/templates/network.xml index 86dcd62bb..0ce2a8342 100644 --- a/playbooks/libvirt/openshift-cluster/templates/network.xml +++ b/playbooks/libvirt/openshift-cluster/templates/network.xml @@ -1,5 +1,5 @@ <network> - <name>openshift-ansible</name> + <name>{{ libvirt_network }}</name> <forward mode='nat'> <nat> <port start='1024' end='65535'/> @@ -8,7 +8,7 @@ <!-- TODO: query for first available virbr interface available --> <bridge name='virbr3' stp='on' delay='0'/> <!-- TODO: make overridable --> - <domain name='example.com'/> + <domain name='example.com' localOnly='yes' /> <dns> <!-- TODO: automatically add host entries --> </dns> diff --git a/playbooks/libvirt/openshift-cluster/templates/storage-pool.xml b/playbooks/libvirt/openshift-cluster/templates/storage-pool.xml new file mode 100644 index 000000000..da139afd0 --- /dev/null +++ b/playbooks/libvirt/openshift-cluster/templates/storage-pool.xml @@ -0,0 +1,6 @@ +<pool type='dir'> + <name>{{ libvirt_storage_pool }}</name> + <target> + <path>{{ libvirt_storage_pool_path }}</path> + </target> +</pool> diff --git a/playbooks/libvirt/openshift-cluster/templates/user-data b/playbooks/libvirt/openshift-cluster/templates/user-data index 77b788109..fbcf7c886 100644 --- a/playbooks/libvirt/openshift-cluster/templates/user-data +++ b/playbooks/libvirt/openshift-cluster/templates/user-data @@ -3,7 +3,9 @@ disable_root: true hostname: {{ item[0] }} fqdn: {{ item[0] }}.example.com -manage_etc_hosts: true + +mounts: +- [ sdb ] users: - default @@ -19,5 +21,23 @@ system_info: ssh_authorized_keys: - {{ lookup('file', '~/.ssh/id_rsa.pub') }} -bootcmd: +write_files: + - path: /etc/sudoers.d/00-openshift-no-requiretty + permissions: 440 + content: | + Defaults:openshift !requiretty + - path: /etc/sysconfig/docker-storage-setup + owner: root:root + permissions: '0644' + content: | + DEVS=/dev/sdb + VG=docker_vg + EXTRA_DOCKER_STORAGE_OPTIONS='--storage-opt dm.blkdiscard=true' + - path: /etc/systemd/system/fstrim.timer.d/hourly.conf + content: | + [Timer] + OnCalendar=hourly + +runcmd: - NETWORK_CONFIG=/etc/sysconfig/network-scripts/ifcfg-eth0; if ! grep DHCP_HOSTNAME ${NETWORK_CONFIG}; then echo 'DHCP_HOSTNAME="{{ item[0] }}.example.com"' >> ${NETWORK_CONFIG}; fi; pkill -9 dhclient; service network restart + - systemctl enable --now fstrim.timer diff --git a/playbooks/libvirt/openshift-cluster/terminate.yml b/playbooks/libvirt/openshift-cluster/terminate.yml index b173a09dd..81e6d8f05 100644 --- a/playbooks/libvirt/openshift-cluster/terminate.yml +++ b/playbooks/libvirt/openshift-cluster/terminate.yml @@ -1,44 +1,71 @@ --- -# TODO: does not handle a non-existant cluster gracefully +# TODO: does not handle a non-existent cluster gracefully - name: Terminate instance(s) hosts: localhost + become: no + connection: local gather_facts: no vars_files: - vars.yml tasks: - - set_fact: cluster_group=tag_env-{{ cluster_id }} + - set_fact: cluster_group=tag_clusterid-{{ cluster_id }} - add_host: name: "{{ item }}" groups: oo_hosts_to_terminate ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[cluster_group] | default([]) + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: '{{ groups[cluster_group] | default([]) }}' +- name: Unsubscribe VMs + hosts: oo_hosts_to_terminate + vars_files: + - vars.yml + roles: + - role: rhel_unsubscribe + when: deployment_type in ['atomic-enterprise', 'enterprise', 'openshift-enterprise'] and + ansible_distribution == "RedHat" and + lookup('oo_option', 'rhel_skip_subscription') | default(rhsub_skip, True) | + default('no', True) | lower in ['no', 'false'] + +- name: Terminate instance(s) + hosts: localhost + become: no + connection: local + gather_facts: no + vars_files: + - vars.yml + tasks: - name: Destroy VMs virt: name: '{{ item[0] }}' command: '{{ item[1] }}' uri: '{{ libvirt_uri }}' with_nested: - - groups['oo_hosts_to_terminate'] + - "{{ groups['oo_hosts_to_terminate'] }}" - [ destroy, undefine ] - - name: Delete VMs drives + - name: Delete VM drives command: 'virsh -c {{ libvirt_uri }} vol-delete --pool {{ libvirt_storage_pool }} {{ item }}.qcow2' args: removes: '{{ libvirt_storage_pool_path }}/{{ item }}.qcow2' - with_items: groups['oo_hosts_to_terminate'] + with_items: "{{ groups['oo_hosts_to_terminate'] }}" + + - name: Delete VM docker drives + command: 'virsh -c {{ libvirt_uri }} vol-delete --pool {{ libvirt_storage_pool }} {{ item }}-docker.qcow2' + args: + removes: '{{ libvirt_storage_pool_path }}/{{ item }}-docker.qcow2' + with_items: "{{ groups['oo_hosts_to_terminate'] }}" - name: Delete the VM cloud-init image file: path: '{{ libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso' state: absent - with_items: groups['oo_hosts_to_terminate'] + with_items: "{{ groups['oo_hosts_to_terminate'] }}" - name: Remove the cloud-init config directory file: path: '{{ libvirt_storage_pool_path }}/{{ item }}_configdrive/' state: absent - with_items: groups['oo_hosts_to_terminate'] + with_items: "{{ groups['oo_hosts_to_terminate'] }}" diff --git a/playbooks/libvirt/openshift-cluster/update.yml b/playbooks/libvirt/openshift-cluster/update.yml index d09832c16..a152135fc 100644 --- a/playbooks/libvirt/openshift-cluster/update.yml +++ b/playbooks/libvirt/openshift-cluster/update.yml @@ -1,19 +1,36 @@ --- +- hosts: localhost + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: '{{ g_all_hosts }}' + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - name: Populate oo_hosts_to_update group hosts: localhost + connection: local + become: no gather_facts: no vars_files: - vars.yml + - cluster_hosts.yml tasks: - name: Evaluate oo_hosts_to_update add_host: name: "{{ item }}" groups: oo_hosts_to_update ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: (groups["tag_env-host-type-{{ cluster_id }}-openshift-master"] | default([])) - | union(groups["tag_env-host-type-{{ cluster_id }}-openshift-node"] | default([])) - | union(groups["tag_env-host-type-{{ cluster_id }}-openshift-etcd"] | default([])) + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: '{{ g_all_hosts | default([]) }}' - include: ../../common/openshift-cluster/update_repos_and_packages.yml diff --git a/playbooks/libvirt/openshift-cluster/vars.yml b/playbooks/libvirt/openshift-cluster/vars.yml index e3c8cd8d0..4daaf1c91 100644 --- a/playbooks/libvirt/openshift-cluster/vars.yml +++ b/playbooks/libvirt/openshift-cluster/vars.yml @@ -1,36 +1,40 @@ --- -libvirt_storage_pool_path: "{{ lookup('env','HOME') }}/libvirt-storage-pool-openshift-ansible" -libvirt_storage_pool: 'openshift-ansible' -libvirt_network: openshift-ansible -libvirt_uri: 'qemu:///system' +default_pool_path: "{{ lookup('env','HOME') }}/libvirt-storage-pool-openshift-ansible" +libvirt_storage_pool_path: "{{ lookup('oo_option', 'libvirt_storage_pool_path') | default(default_pool_path, True) }}" +libvirt_storage_pool: "{{ lookup('oo_option', 'libvirt_storage_pool') | default('openshift-ansible', True) }}" +libvirt_network: "{{ lookup('oo_option', 'libvirt_network') | default('openshift-ansible', True) }}" +libvirt_instance_memory_mib: "{{ lookup('oo_option', 'libvirt_instance_memory_mib') | default(1024, True) }}" +libvirt_instance_vcpu: "{{ lookup('oo_option', 'libvirt_instance_vcpu') | default(2, True) }}" +libvirt_uri: "{{ lookup('oo_option', 'libvirt_uri') | default('qemu:///system', True) }}" +debug_level: 2 + +# Automatic download of the qcow2 image for RHEL cannot be done directly from the RedHat portal because it requires authentication. +# The default value of image_url for enterprise and openshift-enterprise deployment types below won't work. +deployment_rhel7_ent_base: + image: + url: "{{ lookup('oo_option', 'image_url') | + default('https://access.cdn.redhat.com//content/origin/files/sha256/25/25f880767ec6bf71beb532e17f1c45231640bbfdfbbb1dffb79d2c1b328388e0/rhel-guest-image-7.2-20151102.0.x86_64.qcow2', True) }}" + name: "{{ lookup('oo_option', 'image_name') | + default('rhel-guest-image-7.2-20151102.0.x86_64.qcow2', True) }}" + sha256: "{{ lookup('oo_option', 'image_sha256') | + default('25f880767ec6bf71beb532e17f1c45231640bbfdfbbb1dffb79d2c1b328388e0', True) }}" + compression: "" + ssh_user: openshift + become: yes deployment_vars: origin: image: url: "{{ lookup('oo_option', 'image_url') | - default('http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2', True) }}" + default('http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1602.qcow2.xz', True) }}" + compression: "{{ lookup('oo_option', 'image_compression') | + default('xz', True) }}" name: "{{ lookup('oo_option', 'image_name') | default('CentOS-7-x86_64-GenericCloud.qcow2', True) }}" sha256: "{{ lookup('oo_option', 'image_sha256') | - default('e324e3ab1d24a1bbf035ddb365e7f9058c0b454acf48d7aa15c5519fae5998ab', True) }}" - ssh_user: openshift - sudo: yes - online: - image: - url: - name: - sha256: - ssh_user: root - sudo: no - enterprise: - image: - url: - name: - sha256: + default('dd0f5e610e7c5ffacaca35ed7a78a19142a588f4543da77b61c1fb0d74400471', True) }}" ssh_user: openshift - sudo: yes -# origin: -# fedora: -# url: "http://download.fedoraproject.org/pub/fedora/linux/releases/21/Cloud/Images/x86_64/Fedora-Cloud-Base-20141203-21.x86_64.qcow2" -# name: Fedora-Cloud-Base-20141203-21.x86_64.qcow2 -# sha256: 3a99bb89f33e3d4ee826c8160053cdb8a72c80cd23350b776ce73cd244467d86 + become: yes + enterprise: "{{ deployment_rhel7_ent_base }}" + openshift-enterprise: "{{ deployment_rhel7_ent_base }}" + atomic-enterprise: "{{ deployment_rhel7_ent_base }}" diff --git a/playbooks/openstack/openshift-cluster/cluster_hosts.yml b/playbooks/openstack/openshift-cluster/cluster_hosts.yml new file mode 100644 index 000000000..12c436eaf --- /dev/null +++ b/playbooks/openstack/openshift-cluster/cluster_hosts.yml @@ -0,0 +1,21 @@ +--- +g_all_hosts: "{{ groups['meta-clusterid_' ~ cluster_id] | default([]) + | intersect(groups['meta-environment_' ~ cluster_env] | default([])) }}" + +g_etcd_hosts: "{{ g_all_hosts | intersect(groups['meta-host-type_etcd'] | default([])) }}" + +g_lb_hosts: "{{ g_all_hosts | intersect(groups['meta-host-type_lb'] | default([])) }}" + +g_nfs_hosts: "{{ g_all_hosts | intersect(groups['meta-host-type_nfs'] | default([])) }}" + +g_master_hosts: "{{ g_all_hosts | intersect(groups['meta-host-type_master'] | default([])) }}" + +g_new_master_hosts: "{{ g_all_hosts | intersect(groups['meta-host-type_new_master'] | default([])) }}" + +g_node_hosts: "{{ g_all_hosts | intersect(groups['meta-host-type_node'] | default([])) }}" + +g_new_node_hosts: "{{ g_all_hosts | intersect(groups['meta-host-type_new_node'] | default([])) }}" + +g_infra_hosts: "{{ g_node_hosts | intersect(groups['meta-sub-host-type_infra'] | default([])) }}" + +g_compute_hosts: "{{ g_node_hosts | intersect(groups['meta-sub-host-type_compute'] | default([])) }}" diff --git a/playbooks/openstack/openshift-cluster/config.yml b/playbooks/openstack/openshift-cluster/config.yml index 3c9a231e3..f6550b2c4 100644 --- a/playbooks/openstack/openshift-cluster/config.yml +++ b/playbooks/openstack/openshift-cluster/config.yml @@ -1,20 +1,34 @@ +--- +- include: ../../common/openshift-cluster/verify_ansible_version.yml + - hosts: localhost gather_facts: no - vars_files: - - vars.yml tasks: - - set_fact: - g_ssh_user_tmp: "{{ deployment_vars[deployment_type].ssh_user }}" - g_sudo_tmp: "{{ deployment_vars[deployment_type].sudo }}" + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts | default([]) }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml - include: ../../common/openshift-cluster/config.yml vars: - g_etcd_group: "{{ 'tag_env-host-type_' ~ cluster_id ~ '-openshift-etcd' }}" - g_masters_group: "{{ 'tag_env-host-type_' ~ cluster_id ~ '-openshift-master' }}" - g_nodes_group: "{{ 'tag_env-host-type_' ~ cluster_id ~ '-openshift-node' }}" - g_ssh_user: "{{ hostvars.localhost.g_ssh_user_tmp }}" - g_sudo: "{{ hostvars.localhost.g_sudo_tmp }}" + g_nodeonmaster: true + g_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + g_sudo: "{{ deployment_vars[deployment_type].become }}" openshift_cluster_id: "{{ cluster_id }}" - openshift_debug_level: 4 + openshift_debug_level: "{{ debug_level }}" openshift_deployment_type: "{{ deployment_type }}" - openshift_hostname: "{{ ansible_default_ipv4.address }}" + openshift_hosted_registry_selector: 'type=infra' + openshift_hosted_router_selector: 'type=infra' + openshift_master_cluster_method: 'native' + openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}" + os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}" + openshift_use_flannel: "{{ lookup('oo_option', 'use_flannel') }}" + openshift_use_fluentd: "{{ lookup('oo_option', 'use_fluentd') }}" diff --git a/playbooks/openstack/openshift-cluster/files/heat_stack.yaml b/playbooks/openstack/openshift-cluster/files/heat_stack.yaml index a15ec749c..20ce47c07 100644 --- a/playbooks/openstack/openshift-cluster/files/heat_stack.yaml +++ b/playbooks/openstack/openshift-cluster/files/heat_stack.yaml @@ -4,25 +4,20 @@ description: OpenShift cluster parameters: + cluster_env: + type: string + label: Cluster environment + description: Environment of the cluster + cluster_id: type: string label: Cluster ID description: Identifier of the cluster - num_masters: - type: number - label: Number of masters - description: Number of masters - - num_nodes: - type: number - label: Number of nodes - description: Number of nodes - - cidr: + subnet_24_prefix: type: string - label: CIDR - description: CIDR of the network of the cluster + label: subnet /24 prefix + description: /24 subnet prefix of the network of the cluster (dot separated number triplet) dns_nameservers: type: comma_delimited_list @@ -47,6 +42,37 @@ parameters: description: Source of legitimate ssh connections default: 0.0.0.0/0 + node_port_incoming: + type: string + label: Source of node port connections + description: Authorized sources targeting node ports + default: 0.0.0.0/0 + + num_etcd: + type: number + label: Number of etcd nodes + description: Number of etcd nodes + + num_masters: + type: number + label: Number of masters + description: Number of masters + + num_nodes: + type: number + label: Number of compute nodes + description: Number of compute nodes + + num_infra: + type: number + label: Number of infrastructure nodes + description: Number of infrastructure nodes + + etcd_image: + type: string + label: Etcd image + description: Name of the image for the etcd servers + master_image: type: string label: Master image @@ -55,7 +81,17 @@ parameters: node_image: type: string label: Node image - description: Name of the image for the node servers + description: Name of the image for the compute node servers + + infra_image: + type: string + label: Infra image + description: Name of the image for the infra node servers + + etcd_flavor: + type: string + label: Etcd flavor + description: Flavor of the etcd servers master_flavor: type: string @@ -65,10 +101,27 @@ parameters: node_flavor: type: string label: Node flavor - description: Flavor of the node servers + description: Flavor of the compute node servers + + infra_flavor: + type: string + label: Infra flavor + description: Flavor of the infra node servers outputs: + etcd_names: + description: Name of the etcds + value: { get_attr: [ etcd, name ] } + + etcd_ips: + description: IPs of the etcds + value: { get_attr: [ etcd, private_ip ] } + + etcd_floating_ips: + description: Floating IPs of the etcds + value: { get_attr: [ etcd, floating_ip ] } + master_names: description: Name of the masters value: { get_attr: [ masters, name ] } @@ -83,15 +136,27 @@ outputs: node_names: description: Name of the nodes - value: { get_attr: [ nodes, name ] } + value: { get_attr: [ compute_nodes, name ] } node_ips: description: IPs of the nodes - value: { get_attr: [ nodes, private_ip ] } + value: { get_attr: [ compute_nodes, private_ip ] } node_floating_ips: description: Floating IPs of the nodes - value: { get_attr: [ nodes, floating_ip ] } + value: { get_attr: [ compute_nodes, floating_ip ] } + + infra_names: + description: Name of the nodes + value: { get_attr: [ infra_nodes, name ] } + + infra_ips: + description: IPs of the nodes + value: { get_attr: [ infra_nodes, private_ip ] } + + infra_floating_ips: + description: Floating IPs of the nodes + value: { get_attr: [ infra_nodes, floating_ip ] } resources: @@ -113,7 +178,11 @@ resources: params: cluster_id: { get_param: cluster_id } network: { get_resource: net } - cidr: { get_param: cidr } + cidr: + str_replace: + template: subnet_24_prefix.0/24 + params: + subnet_24_prefix: { get_param: subnet_24_prefix } dns_nameservers: { get_param: dns_nameservers } router: @@ -172,6 +241,10 @@ resources: port_range_max: 8443 - direction: ingress protocol: tcp + port_range_min: 8444 + port_range_max: 8444 + - direction: ingress + protocol: tcp port_range_min: 53 port_range_max: 53 - direction: ingress @@ -180,12 +253,67 @@ resources: port_range_max: 53 - direction: ingress protocol: tcp + port_range_min: 8053 + port_range_max: 8053 + - direction: ingress + protocol: udp + port_range_min: 8053 + port_range_max: 8053 + - direction: ingress + protocol: tcp port_range_min: 24224 port_range_max: 24224 - direction: ingress protocol: udp port_range_min: 24224 port_range_max: 24224 + - direction: ingress + protocol: tcp + port_range_min: 2224 + port_range_max: 2224 + - direction: ingress + protocol: udp + port_range_min: 5404 + port_range_max: 5404 + - direction: ingress + protocol: udp + port_range_min: 5405 + port_range_max: 5405 + - direction: ingress + protocol: tcp + port_range_min: 9090 + port_range_max: 9090 + + etcd-secgrp: + type: OS::Neutron::SecurityGroup + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-etcd-secgrp + params: + cluster_id: { get_param: cluster_id } + description: + str_replace: + template: Security group for cluster_id etcd cluster + params: + cluster_id: { get_param: cluster_id } + rules: + - direction: ingress + protocol: tcp + port_range_min: 22 + port_range_max: 22 + remote_ip_prefix: { get_param: ssh_incoming } + - direction: ingress + protocol: tcp + port_range_min: 2379 + port_range_max: 2379 + remote_mode: remote_group_id + remote_group_id: { get_resource: master-secgrp } + - direction: ingress + protocol: tcp + port_range_min: 2380 + port_range_max: 2380 + remote_mode: remote_group_id node-secgrp: type: OS::Neutron::SecurityGroup @@ -207,16 +335,85 @@ resources: port_range_max: 22 remote_ip_prefix: { get_param: ssh_incoming } - direction: ingress + protocol: tcp + port_range_min: 10250 + port_range_max: 10250 + remote_mode: remote_group_id + - direction: ingress + protocol: tcp + port_range_min: 10255 + port_range_max: 10255 + remote_mode: remote_group_id + - direction: ingress + protocol: udp + port_range_min: 10255 + port_range_max: 10255 + remote_mode: remote_group_id + - direction: ingress protocol: udp port_range_min: 4789 port_range_max: 4789 remote_mode: remote_group_id - direction: ingress protocol: tcp - port_range_min: 10250 - port_range_max: 10250 - remote_mode: remote_group_id - remote_group_id: { get_resource: master-secgrp } + port_range_min: 30000 + port_range_max: 32767 + remote_ip_prefix: { get_param: node_port_incoming } + + infra-secgrp: + type: OS::Neutron::SecurityGroup + properties: + name: + str_replace: + template: openshift-ansible-cluster_id-infra-secgrp + params: + cluster_id: { get_param: cluster_id } + description: + str_replace: + template: Security group for cluster_id OpenShift infrastructure cluster nodes + params: + cluster_id: { get_param: cluster_id } + rules: + - direction: ingress + protocol: tcp + port_range_min: 80 + port_range_max: 80 + - direction: ingress + protocol: tcp + port_range_min: 443 + port_range_max: 443 + + etcd: + type: OS::Heat::ResourceGroup + properties: + count: { get_param: num_etcd } + resource_def: + type: heat_stack_server.yaml + properties: + name: + str_replace: + template: cluster_id-k8s_type-%index% + params: + cluster_id: { get_param: cluster_id } + k8s_type: etcd + cluster_env: { get_param: cluster_env } + cluster_id: { get_param: cluster_id } + type: etcd + image: { get_param: etcd_image } + flavor: { get_param: etcd_flavor } + key_name: { get_resource: keypair } + net: { get_resource: net } + subnet: { get_resource: subnet } + secgrp: + - { get_resource: etcd-secgrp } + floating_network: { get_param: external_net } + net_name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: { get_param: cluster_id } + depends_on: + - interface masters: type: OS::Heat::ResourceGroup @@ -231,24 +428,27 @@ resources: params: cluster_id: { get_param: cluster_id } k8s_type: master - cluster_id: { get_param: cluster_id } - type: master - image: { get_param: master_image } - flavor: { get_param: master_flavor } - key_name: { get_resource: keypair } - net: { get_resource: net } - subnet: { get_resource: subnet } + cluster_env: { get_param: cluster_env } + cluster_id: { get_param: cluster_id } + type: master + image: { get_param: master_image } + flavor: { get_param: master_flavor } + key_name: { get_resource: keypair } + net: { get_resource: net } + subnet: { get_resource: subnet } secgrp: - { get_resource: master-secgrp } + - { get_resource: node-secgrp } floating_network: { get_param: external_net } net_name: str_replace: template: openshift-ansible-cluster_id-net params: cluster_id: { get_param: cluster_id } - depends_on: interface + depends_on: + - interface - nodes: + compute_nodes: type: OS::Heat::ResourceGroup properties: count: { get_param: num_nodes } @@ -257,23 +457,62 @@ resources: properties: name: str_replace: - template: cluster_id-k8s_type-%index% + template: cluster_id-k8s_type-sub_host_type-%index% + params: + cluster_id: { get_param: cluster_id } + k8s_type: node + sub_host_type: compute + cluster_env: { get_param: cluster_env } + cluster_id: { get_param: cluster_id } + type: node + subtype: compute + image: { get_param: node_image } + flavor: { get_param: node_flavor } + key_name: { get_resource: keypair } + net: { get_resource: net } + subnet: { get_resource: subnet } + secgrp: + - { get_resource: node-secgrp } + floating_network: { get_param: external_net } + net_name: + str_replace: + template: openshift-ansible-cluster_id-net + params: + cluster_id: { get_param: cluster_id } + depends_on: + - interface + + infra_nodes: + type: OS::Heat::ResourceGroup + properties: + count: { get_param: num_infra } + resource_def: + type: heat_stack_server.yaml + properties: + name: + str_replace: + template: cluster_id-k8s_type-sub_host_type-%index% params: cluster_id: { get_param: cluster_id } k8s_type: node - cluster_id: { get_param: cluster_id } - type: node - image: { get_param: node_image } - flavor: { get_param: node_flavor } - key_name: { get_resource: keypair } - net: { get_resource: net } - subnet: { get_resource: subnet } + sub_host_type: infra + cluster_env: { get_param: cluster_env } + cluster_id: { get_param: cluster_id } + type: node + subtype: infra + image: { get_param: infra_image } + flavor: { get_param: infra_flavor } + key_name: { get_resource: keypair } + net: { get_resource: net } + subnet: { get_resource: subnet } secgrp: - { get_resource: node-secgrp } + - { get_resource: infra-secgrp } floating_network: { get_param: external_net } net_name: str_replace: template: openshift-ansible-cluster_id-net params: cluster_id: { get_param: cluster_id } - depends_on: interface + depends_on: + - interface diff --git a/playbooks/openstack/openshift-cluster/files/heat_stack_server.yaml b/playbooks/openstack/openshift-cluster/files/heat_stack_server.yaml index 55f64211a..435139849 100644 --- a/playbooks/openstack/openshift-cluster/files/heat_stack_server.yaml +++ b/playbooks/openstack/openshift-cluster/files/heat_stack_server.yaml @@ -9,6 +9,11 @@ parameters: label: Name description: Name + cluster_env: + type: string + label: Cluster environment + description: Environment of the cluster + cluster_id: type: string label: Cluster ID @@ -19,6 +24,12 @@ parameters: label: Type description: Type master or node + subtype: + type: string + label: Sub-type + description: Sub-type compute or infra for nodes, default otherwise + default: default + key_name: type: string label: Key name @@ -96,17 +107,13 @@ resources: flavor: { get_param: flavor } networks: - port: { get_resource: port } - user_data: { get_file: user-data } + user_data: { get_resource: config } user_data_format: RAW metadata: - env: { get_param: cluster_id } + environment: { get_param: cluster_env } + clusterid: { get_param: cluster_id } host-type: { get_param: type } - env-host-type: - str_template: - template: cluster_id-openshift-type - params: - cluster_id: { get_param: cluster_id } - type: { get_param: type } + sub-host-type: { get_param: subtype } port: type: OS::Neutron::Port @@ -121,3 +128,25 @@ resources: properties: floating_network: { get_param: floating_network } port_id: { get_resource: port } + + config: + type: OS::Heat::CloudConfig + properties: + cloud_config: + disable_root: true + + hostname: { get_param: name } + + system_info: + default_user: + name: openshift + sudo: ["ALL=(ALL) NOPASSWD: ALL"] + + write_files: + - path: /etc/sudoers.d/00-openshift-no-requiretty + permissions: 440 + # content: Defaults:openshift !requiretty + # Encoded in base64 to be sure that we do not forget the trailing newline or + # sudo will not be able to parse that file + encoding: b64 + content: RGVmYXVsdHM6b3BlbnNoaWZ0ICFyZXF1aXJldHR5Cg== diff --git a/playbooks/openstack/openshift-cluster/files/user-data b/playbooks/openstack/openshift-cluster/files/user-data deleted file mode 100644 index e789a5b69..000000000 --- a/playbooks/openstack/openshift-cluster/files/user-data +++ /dev/null @@ -1,7 +0,0 @@ -#cloud-config -disable_root: true - -system_info: - default_user: - name: openshift - sudo: ["ALL=(ALL) NOPASSWD: ALL"] diff --git a/playbooks/openstack/openshift-cluster/launch.yml b/playbooks/openstack/openshift-cluster/launch.yml index 3cdd2ae4d..7e037f2af 100644 --- a/playbooks/openstack/openshift-cluster/launch.yml +++ b/playbooks/openstack/openshift-cluster/launch.yml @@ -1,15 +1,12 @@ --- - name: Launch instance(s) hosts: localhost + become: no connection: local gather_facts: no vars_files: - vars.yml tasks: - - fail: - msg: "Deployment type not supported for OpenStack provider yet" - when: deployment_type == 'online' - # TODO: Write an Ansible module for dealing with HEAT stacks # Dealing with the outputs is currently terrible @@ -19,45 +16,80 @@ changed_when: false failed_when: stack_show_result.rc != 0 and 'Stack not found' not in stack_show_result.stderr - - name: Create OpenStack Stack - command: 'heat stack-create -f {{ openstack_infra_heat_stack }} - -P cluster_id={{ cluster_id }} - -P dns_nameservers={{ openstack_network_dns | join(",") }} - -P cidr={{ openstack_network_cidr }} - -P ssh_incoming={{ openstack_ssh_access_from }} - -P num_masters={{ num_masters }} - -P num_nodes={{ num_nodes }} - -P master_image={{ deployment_vars[deployment_type].image }} - -P node_image={{ deployment_vars[deployment_type].image }} - -P master_flavor={{ openstack_flavor["master"] }} - -P node_flavor={{ openstack_flavor["node"] }} - -P ssh_public_key="{{ openstack_ssh_public_key }}" - openshift-ansible-{{ cluster_id }}-stack' + - set_fact: + heat_stack_action: 'stack-create' when: stack_show_result.rc == 1 + - set_fact: + heat_stack_action: 'stack-update' + when: stack_show_result.rc == 0 - - name: Update OpenStack Stack - command: 'heat stack-update -f {{ openstack_infra_heat_stack }} + - name: Create or Update OpenStack Stack + command: 'heat {{ heat_stack_action }} -f {{ openstack_infra_heat_stack }} + --timeout {{ openstack_heat_timeout }} + -P cluster_env={{ cluster_env }} -P cluster_id={{ cluster_id }} + -P subnet_24_prefix={{ openstack_subnet_24_prefix }} -P dns_nameservers={{ openstack_network_dns | join(",") }} - -P cidr={{ openstack_network_cidr }} + -P external_net={{ openstack_network_external_net }} + -P ssh_public_key="{{ openstack_ssh_public_key }}" -P ssh_incoming={{ openstack_ssh_access_from }} + -P node_port_incoming={{ openstack_node_port_access_from }} + -P num_etcd={{ num_etcd }} -P num_masters={{ num_masters }} -P num_nodes={{ num_nodes }} + -P num_infra={{ num_infra }} + -P etcd_image={{ deployment_vars[deployment_type].image }} -P master_image={{ deployment_vars[deployment_type].image }} -P node_image={{ deployment_vars[deployment_type].image }} + -P infra_image={{ deployment_vars[deployment_type].image }} + -P etcd_flavor={{ openstack_flavor["etcd"] }} -P master_flavor={{ openstack_flavor["master"] }} -P node_flavor={{ openstack_flavor["node"] }} - -P ssh_public_key="{{ openstack_ssh_public_key }}" + -P infra_flavor={{ openstack_flavor["infra"] }} openshift-ansible-{{ cluster_id }}-stack' - when: stack_show_result.rc == 0 + args: + chdir: '{{ playbook_dir }}' - name: Wait for OpenStack Stack readiness shell: 'heat stack-show openshift-ansible-{{ cluster_id }}-stack | awk ''$2 == "stack_status" {print $4}''' register: stack_show_status_result until: stack_show_status_result.stdout not in ['CREATE_IN_PROGRESS', 'UPDATE_IN_PROGRESS'] retries: 30 - delay: 1 - failed_when: stack_show_status_result.stdout not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE'] + delay: 5 + + - name: Display the stack resources + command: 'heat resource-list openshift-ansible-{{ cluster_id }}-stack' + register: stack_resource_list_result + when: stack_show_status_result.stdout not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE'] + + - name: Display the stack status + command: 'heat stack-show openshift-ansible-{{ cluster_id }}-stack' + register: stack_show_result + when: stack_show_status_result.stdout not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE'] + + - name: Delete the stack + command: 'heat stack-delete openshift-ansible-{{ cluster_id }}-stack' + when: stack_show_status_result.stdout not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE'] + + - fail: + msg: | + + +--------------------------------------+ + | ^ | + | /!\ Failed to create the heat stack | + | /___\ | + +--------------------------------------+ + + Here is the list of stack resources and their status: + {{ stack_resource_list_result.stdout }} + + Here is the status of the stack: + {{ stack_show_result.stdout }} + + ^ Failed to create the heat stack + /!\ + /___\ Please check the `stack_status_reason` line in the above array to know why. + when: stack_show_status_result.stdout not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE'] - name: Read OpenStack Stack outputs command: 'heat stack-show openshift-ansible-{{ cluster_id }}-stack' @@ -66,37 +98,70 @@ - set_fact: parsed_outputs: "{{ stack_show_result | oo_parse_heat_stack_outputs }}" + - name: Add new etcd instances groups and variables + add_host: + hostname: '{{ item[0] }}' + ansible_ssh_host: '{{ item[2] }}' + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + groups: 'meta-environment_{{ cluster_env }}, meta-host-type_etcd, meta-sub-host-type_default, meta-clusterid_{{ cluster_id }}' + openshift_node_labels: + type: "etcd" + with_together: + - '{{ parsed_outputs.etcd_names }}' + - '{{ parsed_outputs.etcd_ips }}' + - '{{ parsed_outputs.etcd_floating_ips }}' + - name: Add new master instances groups and variables add_host: hostname: '{{ item[0] }}' ansible_ssh_host: '{{ item[2] }}' ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - groups: 'tag_env_{{ cluster_id }}, tag_host-type_master, tag_env-host-type_{{ cluster_id }}-openshift-master' + ansible_become: "{{ deployment_vars[deployment_type].become }}" + groups: 'meta-environment_{{ cluster_env }}, meta-host-type_master, meta-sub-host-type_default, meta-clusterid_{{ cluster_id }}' + openshift_node_labels: + type: "master" with_together: - - parsed_outputs.master_names - - parsed_outputs.master_ips - - parsed_outputs.master_floating_ips + - '{{ parsed_outputs.master_names }}' + - '{{ parsed_outputs.master_ips }}' + - '{{ parsed_outputs.master_floating_ips }}' - name: Add new node instances groups and variables add_host: hostname: '{{ item[0] }}' ansible_ssh_host: '{{ item[2] }}' ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - groups: 'tag_env_{{ cluster_id }}, tag_host-type_node, tag_env-host-type_{{ cluster_id }}-openshift-node' + ansible_become: "{{ deployment_vars[deployment_type].become }}" + groups: 'meta-environment_{{ cluster_env }}, meta-host-type_node, meta-sub-host-type_compute, meta-clusterid_{{ cluster_id }}' + openshift_node_labels: + type: "compute" + with_together: + - '{{ parsed_outputs.node_names }}' + - '{{ parsed_outputs.node_ips }}' + - '{{ parsed_outputs.node_floating_ips }}' + + - name: Add new infra instances groups and variables + add_host: + hostname: '{{ item[0] }}' + ansible_ssh_host: '{{ item[2] }}' + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + groups: 'meta-environment_{{ cluster_env }}, meta-host-type_node, meta-sub-host-type_infra, meta-clusterid_{{ cluster_id }}' + openshift_node_labels: + type: "infra" with_together: - - parsed_outputs.node_names - - parsed_outputs.node_ips - - parsed_outputs.node_floating_ips + - '{{ parsed_outputs.infra_names }}' + - '{{ parsed_outputs.infra_ips }}' + - '{{ parsed_outputs.infra_floating_ips }}' - name: Wait for ssh wait_for: host: '{{ item }}' port: 22 with_flattened: - - parsed_outputs.master_floating_ips - - parsed_outputs.node_floating_ips + - '{{ parsed_outputs.master_floating_ips }}' + - '{{ parsed_outputs.node_floating_ips }}' + - '{{ parsed_outputs.infra_floating_ips }}' - name: Wait for user setup command: 'ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null {{ deployment_vars[deployment_type].ssh_user }}@{{ item }} echo {{ deployment_vars[deployment_type].ssh_user }} user is setup' @@ -105,8 +170,9 @@ retries: 30 delay: 1 with_flattened: - - parsed_outputs.master_floating_ips - - parsed_outputs.node_floating_ips + - '{{ parsed_outputs.master_floating_ips }}' + - '{{ parsed_outputs.node_floating_ips }}' + - '{{ parsed_outputs.infra_floating_ips }}' - include: update.yml diff --git a/playbooks/openstack/openshift-cluster/list.yml b/playbooks/openstack/openshift-cluster/list.yml index a75e350c7..6c6f671be 100644 --- a/playbooks/openstack/openshift-cluster/list.yml +++ b/playbooks/openstack/openshift-cluster/list.yml @@ -1,11 +1,13 @@ --- - name: Generate oo_list_hosts group hosts: localhost + become: no + connection: local gather_facts: no vars_files: - vars.yml tasks: - - set_fact: scratch_group=tag_env_{{ cluster_id }} + - set_fact: scratch_group=meta-clusterid_{{ cluster_id }} when: cluster_id != '' - set_fact: scratch_group=all when: cluster_id == '' @@ -14,11 +16,9 @@ groups: oo_list_hosts ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" ansible_ssh_host: "{{ hostvars[item].ansible_ssh_host | default(item) }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: groups[scratch_group] | default([]) | difference(['localhost']) - -- name: List Hosts - hosts: oo_list_hosts - tasks: + ansible_become: "{{ deployment_vars[deployment_type].become }}" + oo_public_ipv4: "{{ hostvars[item].openstack.public_v4 }}" + oo_private_ipv4: "{{ hostvars[item].openstack.private_v4 }}" + with_items: "{{ groups[scratch_group] | default([]) | difference(['localhost']) }}" - debug: - msg: 'public:{{ansible_ssh_host}} private:{{ansible_default_ipv4.address}}' + msg: "{{ hostvars | oo_select_keys(groups[scratch_group] | default([])) | oo_pretty_print_cluster('meta-') }}" diff --git a/playbooks/openstack/openshift-cluster/tasks/configure_openstack.yml b/playbooks/openstack/openshift-cluster/tasks/configure_openstack.yml deleted file mode 100644 index 2cbdb4805..000000000 --- a/playbooks/openstack/openshift-cluster/tasks/configure_openstack.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -- name: Check infra - command: 'heat stack-show {{ openstack_network_prefix }}-stack' - register: stack_show_result - changed_when: false - failed_when: stack_show_result.rc != 0 and 'Stack not found' not in stack_show_result.stderr - -- name: Create infra - command: 'heat stack-create -f {{ openstack_infra_heat_stack }} -P cluster-id={{ cluster_id }} -P network-prefix={{ openstack_network_prefix }} -P dns-nameservers={{ openstack_network_dns | join(",") }} -P cidr={{ openstack_network_cidr }} -P ssh-incoming={{ openstack_ssh_access_from }} {{ openstack_network_prefix }}-stack' - when: stack_show_result.rc == 1 - -- name: Update infra - command: 'heat stack-update -f {{ openstack_infra_heat_stack }} -P cluster-id={{ cluster_id }} -P network-prefix={{ openstack_network_prefix }} -P dns-nameservers={{ openstack_network_dns | join(",") }} -P cidr={{ openstack_network_cidr }} -P ssh-incoming={{ openstack_ssh_access_from }} {{ openstack_network_prefix }}-stack' - when: stack_show_result.rc == 0 - -- name: Wait for infra readiness - shell: 'heat stack-show {{ openstack_network_prefix }}-stack | awk ''$2 == "stack_status" {print $4}''' - register: stack_show_status_result - until: stack_show_status_result.stdout not in ['CREATE_IN_PROGRESS', 'UPDATE_IN_PROGRESS'] - retries: 30 - delay: 1 - failed_when: stack_show_status_result.stdout not in ['CREATE_COMPLETE', 'UPDATE_COMPLETE'] - -- name: Create ssh keypair - nova_keypair: - name: "{{ openstack_ssh_keypair }}" - public_key: "{{ openstack_ssh_public_key }}" diff --git a/playbooks/openstack/openshift-cluster/terminate.yml b/playbooks/openstack/openshift-cluster/terminate.yml index fc4ec3c88..4527f4a28 100644 --- a/playbooks/openstack/openshift-cluster/terminate.yml +++ b/playbooks/openstack/openshift-cluster/terminate.yml @@ -1,5 +1,31 @@ - name: Terminate instance(s) hosts: localhost + become: no + connection: local + gather_facts: no + vars_files: + - vars.yml + tasks: + - add_host: + name: "{{ item }}" + groups: oo_hosts_to_terminate + ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ (groups['meta-environment_' ~ cluster_env]|default([])) | intersect(groups['meta-clusterid_' ~ cluster_id ]|default([])) }}" + +- name: Unsubscribe VMs + hosts: oo_hosts_to_terminate + vars_files: + - vars.yml + roles: + - role: rhel_unsubscribe + when: deployment_type in ['atomic-enterprise', 'enterprise', 'openshift-enterprise'] and + ansible_distribution == "RedHat" and + lookup('oo_option', 'rhel_skip_subscription') | default(rhsub_skip, True) | + default('no', True) | lower in ['no', 'false'] + +- hosts: localhost + become: no connection: local gather_facts: no vars_files: @@ -17,6 +43,6 @@ register: stack_show_result until: stack_show_result.stdout != 'DELETE_IN_PROGRESS' retries: 60 - delay: 1 + delay: 5 failed_when: '"Stack not found" not in stack_show_result.stderr and stack_show_result.stdout != "DELETE_COMPLETE"' diff --git a/playbooks/openstack/openshift-cluster/update.yml b/playbooks/openstack/openshift-cluster/update.yml index e006aa74a..6d2af3d26 100644 --- a/playbooks/openstack/openshift-cluster/update.yml +++ b/playbooks/openstack/openshift-cluster/update.yml @@ -1,19 +1,33 @@ --- +- hosts: localhost + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - add_host: + name: "{{ item }}" + groups: l_oo_all_hosts + with_items: "{{ g_all_hosts }}" + +- hosts: l_oo_all_hosts + gather_facts: no + tasks: + - include_vars: vars.yml + - include_vars: cluster_hosts.yml + - name: Populate oo_hosts_to_update group hosts: localhost + connection: local + become: no gather_facts: no - vars_files: - - vars.yml tasks: - name: Evaluate oo_hosts_to_update add_host: name: "{{ item }}" groups: oo_hosts_to_update ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}" - ansible_sudo: "{{ deployment_vars[deployment_type].sudo }}" - with_items: (groups["tag_env-host-type_{{ cluster_id }}-openshift-master"] | default([])) - | union(groups["tag_env-host-type_{{ cluster_id }}-openshift-node"] | default([])) - | union(groups["tag_env-host-type_{{ cluster_id }}-openshift-etcd"] | default([])) + ansible_become: "{{ deployment_vars[deployment_type].become }}" + with_items: "{{ g_all_hosts | default([]) }}" - include: ../../common/openshift-cluster/update_repos_and_packages.yml diff --git a/playbooks/openstack/openshift-cluster/vars.yml b/playbooks/openstack/openshift-cluster/vars.yml index d077a6ced..79b336ce7 100644 --- a/playbooks/openstack/openshift-cluster/vars.yml +++ b/playbooks/openstack/openshift-cluster/vars.yml @@ -1,36 +1,37 @@ --- +debug_level: 2 openstack_infra_heat_stack: "{{ lookup('oo_option', 'infra_heat_stack' ) | default('files/heat_stack.yaml', True) }}" -openstack_network_prefix: "{{ lookup('oo_option', 'network_prefix' ) | - default('openshift-ansible-'+cluster_id, True) }}" -openstack_network_cidr: "{{ lookup('oo_option', 'net_cidr' ) | - default('192.168.' + ( ( 1048576 | random % 256 ) | string() ) + '.0/24', True) }}" +openstack_subnet_24_prefix: "{{ lookup('oo_option', 'subnet_24_prefix' ) | + default('192.168.' + ( ( 1048576 | random % 256 ) | string() ), True) }}" openstack_network_external_net: "{{ lookup('oo_option', 'external_net' ) | default('external', True) }}" -openstack_floating_ip_pools: "{{ lookup('oo_option', 'floating_ip_pools') | - default('external', True) | oo_split() }}" openstack_network_dns: "{{ lookup('oo_option', 'dns' ) | default('8.8.8.8,8.8.4.4', True) | oo_split() }}" -openstack_ssh_keypair: "{{ lookup('oo_option', 'keypair' ) | - default(lookup('env', 'LOGNAME')+'_key', True) }}" openstack_ssh_public_key: "{{ lookup('file', lookup('oo_option', 'public_key') | default('~/.ssh/id_rsa.pub', True)) }}" openstack_ssh_access_from: "{{ lookup('oo_option', 'ssh_from') | default('0.0.0.0/0', True) }}" +openstack_node_port_access_from: "{{ lookup('oo_option', 'node_port_from') | + default('0.0.0.0/0', True) }}" +openstack_heat_timeout: "{{ lookup('oo_option', 'heat_timeout') | + default('3', True) }}" openstack_flavor: + etcd: "{{ lookup('oo_option', 'etcd_flavor' ) | default('m1.small', True) }}" master: "{{ lookup('oo_option', 'master_flavor' ) | default('m1.small', True) }}" + infra: "{{ lookup('oo_option', 'infra_flavor' ) | default('m1.small', True) }}" node: "{{ lookup('oo_option', 'node_flavor' ) | default('m1.medium', True) }}" +deployment_rhel7_ent_base: + image: "{{ lookup('oo_option', 'image_name') | default('rhel-guest-image-7.2-20151102.0.x86_64', True) }}" + ssh_user: openshift + become: yes + deployment_vars: origin: image: "{{ lookup('oo_option', 'image_name') | default('centos-70-raw', True) }}" ssh_user: openshift - sudo: yes - online: - image: - ssh_user: root - sudo: no - enterprise: - image: "{{ lookup('oo_option', 'image_name') | default('rhel-guest-image-7.1-20150224.0.x86_64', True) }}" - ssh_user: openshift - sudo: yes + become: yes + enterprise: "{{ deployment_rhel7_ent_base }}" + openshift-enterprise: "{{ deployment_rhel7_ent_base }}" + atomic-enterprise: "{{ deployment_rhel7_ent_base }}" |