diff options
Diffstat (limited to 'roles')
129 files changed, 2495 insertions, 990 deletions
diff --git a/roles/ansible_service_broker/vars/openshift-enterprise.yml b/roles/ansible_service_broker/vars/openshift-enterprise.yml index 0b3a2a69d..ce2ae8365 100644 --- a/roles/ansible_service_broker/vars/openshift-enterprise.yml +++ b/roles/ansible_service_broker/vars/openshift-enterprise.yml @@ -1,7 +1,7 @@ --- __ansible_service_broker_image_prefix: registry.access.redhat.com/openshift3/ose- -__ansible_service_broker_image_tag: latest +__ansible_service_broker_image_tag: v3.6 __ansible_service_broker_etcd_image_prefix: rhel7/ __ansible_service_broker_etcd_image_tag: latest diff --git a/roles/calico/defaults/main.yaml b/roles/calico/defaults/main.yaml index b1907f8cb..be73e8a73 100644 --- a/roles/calico/defaults/main.yaml +++ b/roles/calico/defaults/main.yaml @@ -11,4 +11,4 @@ calico_url_ipam: "https://github.com/projectcalico/cni-plugin/releases/download/ calico_ipv4pool_ipip: "always" calico_log_dir: "/var/log/calico" -calico_node_image: "calico/node:v2.4.1" +calico_node_image: "calico/node:v2.5.0" diff --git a/roles/calico_master/defaults/main.yaml b/roles/calico_master/defaults/main.yaml index d40286aba..01a2b9529 100644 --- a/roles/calico_master/defaults/main.yaml +++ b/roles/calico_master/defaults/main.yaml @@ -3,5 +3,5 @@ kubeconfig: "{{ openshift.common.config_base }}/master/openshift-master.kubeconf calicoctl_bin_dir: "/usr/local/bin/" -calico_url_calicoctl: "https://github.com/projectcalico/calicoctl/releases/download/v1.4.0/calicoctl" +calico_url_calicoctl: "https://github.com/projectcalico/calicoctl/releases/download/v1.5.0/calicoctl" calico_url_policy_controller: "quay.io/calico/kube-policy-controller:v0.7.0" diff --git a/roles/cockpit/defaults/main.yml b/roles/cockpit/defaults/main.yml index cbe5bb92b..15c40e3b5 100644 --- a/roles/cockpit/defaults/main.yml +++ b/roles/cockpit/defaults/main.yml @@ -1,6 +1,6 @@ --- -r_cockpit_firewall_enabled: True -r_cockpit_use_firewalld: False +r_cockpit_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_cockpit_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" r_cockpit_os_firewall_deny: [] r_cockpit_os_firewall_allow: diff --git a/roles/dns/README.md b/roles/dns/README.md deleted file mode 100644 index 9a88ce97c..000000000 --- a/roles/dns/README.md +++ /dev/null @@ -1,45 +0,0 @@ -dns -=== - -Configure a DNS server serving IPs of all the nodes of the cluster - -Requirements ------------- - -Ansible 2.2 - -Role Variables --------------- - -| Name | Mandatory / Optional | Description | -|------|----------------------|-------------| -| `dns_zones` | Mandatory | DNS zones in which we must find the hosts | -| `dns_forwarders` | If not set, the DNS will be a recursive non-forwarding DNS server | DNS forwarders to delegate the requests for hosts outside of `dns_zones` | -| `dns_all_hosts` | Mandatory | Exhaustive list of hosts | -| `base_docker_image` | Optional | Base docker image to build Bind image from, used only in containerized deployments | - -Dependencies ------------- - -None - -Example Playbook ----------------- - - - hosts: dns_hosts - roles: - - role: dns - dns_forwarders: [ '8.8.8.8', '8.8.4.4' ] - dns_zones: [ novalocal, openstacklocal ] - dns_all_hosts: "{{ g_all_hosts }}" - base_docker_image: 'centos:centos7' - -License -------- - -ASL 2.0 - -Author Information ------------------- - -OpenShift operations, Red Hat, Inc diff --git a/roles/dns/defaults/main.yml b/roles/dns/defaults/main.yml deleted file mode 100644 index 82055c8cd..000000000 --- a/roles/dns/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -base_docker_image: "{{ 'centos:centos7' if openshift.common.deployment_type == 'origin' else 'rhel7' }}" diff --git a/roles/dns/handlers/main.yml b/roles/dns/handlers/main.yml deleted file mode 100644 index 61fd7a10e..000000000 --- a/roles/dns/handlers/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: restart bind - systemd: - name: named - state: restarted diff --git a/roles/dns/meta/main.yml b/roles/dns/meta/main.yml deleted file mode 100644 index 64d56114e..000000000 --- a/roles/dns/meta/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -galaxy_info: - author: Lénaïc Huard - description: Deploy and configure a DNS server - company: Amadeus SAS - license: ASL 2.0 - min_ansible_version: 2.2 -dependencies: -- { role: openshift_facts } diff --git a/roles/dns/tasks/main.yml b/roles/dns/tasks/main.yml deleted file mode 100644 index c5ab53b4d..000000000 --- a/roles/dns/tasks/main.yml +++ /dev/null @@ -1,46 +0,0 @@ ---- -- name: Install Bind - package: name=bind state=present - when: not openshift.common.is_containerized | bool - -- name: Create docker build dir - file: path=/tmp/dockerbuild state=directory - when: openshift.common.is_containerized | bool - -- name: Install dockerfile - template: - dest: "/tmp/dockerbuild/Dockerfile" - src: Dockerfile - when: openshift.common.is_containerized | bool - -- name: Build Bind image - docker_image: path="/tmp/dockerbuild" name="bind" state=present - when: openshift.common.is_containerized | bool - -- name: Install bind service file - template: - dest: "/etc/systemd/system/named.service" - src: named.service.j2 - when: openshift.common.is_containerized | bool - -- name: Create bind zone dir - file: path=/var/named state=directory - when: openshift.common.is_containerized | bool - -- name: Configure Bind - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - with_items: - - src: openshift-cluster.zone - dest: /var/named/openshift-cluster.zone - - src: named.conf - dest: /etc/named.conf - notify: restart bind - -- name: Enable Bind - systemd: - name: named - state: started - enabled: yes - daemon_reload: yes diff --git a/roles/dns/templates/Dockerfile b/roles/dns/templates/Dockerfile deleted file mode 100644 index cdff0a228..000000000 --- a/roles/dns/templates/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM {{ base_docker_image }} -MAINTAINER Jan Provaznik <jprovazn@redhat.com> - -# install main packages: -RUN yum -y update; yum clean all; -RUN yum -y install bind-utils bind - -EXPOSE 53 - -# start services: -CMD ["/usr/sbin/named", "-f"] diff --git a/roles/dns/templates/named.conf b/roles/dns/templates/named.conf deleted file mode 100644 index 22c1ff935..000000000 --- a/roles/dns/templates/named.conf +++ /dev/null @@ -1,23 +0,0 @@ -options -{ - directory "/var/named"; - - allow-query { {{ ansible_default_ipv4.network }}/24; }; - - recursion yes; - -{% if dns_forwarders is defined %} - forwarders { - {% for dns in dns_forwarders %} - {{ dns }}; - {% endfor %} - }; -{% endif %} -}; -{% for zone in dns_zones %} - -zone "{{ zone }}" IN { - type master; - file "openshift-cluster.zone"; -}; -{% endfor %} diff --git a/roles/dns/templates/named.service.j2 b/roles/dns/templates/named.service.j2 deleted file mode 100644 index 6e0a7a640..000000000 --- a/roles/dns/templates/named.service.j2 +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Requires={{ openshift.docker.service_name }}.service -After={{ openshift.docker.service_name }}.service -PartOf={{ openshift.docker.service_name }}.service - -[Service] -Type=simple -TimeoutStartSec=5m -ExecStartPre=/usr/bin/docker run --rm -v /etc/named.conf:/etc/named.conf -v /var/named:/var/named:z bind named-checkconf -z /etc/named.conf -ExecStartPre=-/usr/bin/docker rm -f bind -ExecStart=/usr/bin/docker run --name bind -p 53:53/udp -v /var/log:/var/log -v /etc/named.conf:/etc/named.conf -v /var/named:/var/named:z bind -ExecStop=/usr/bin/docker stop bind - -[Install] -WantedBy={{ openshift.docker.service_name }}.service diff --git a/roles/dns/templates/openshift-cluster.zone b/roles/dns/templates/openshift-cluster.zone deleted file mode 100644 index 03f5dc089..000000000 --- a/roles/dns/templates/openshift-cluster.zone +++ /dev/null @@ -1,14 +0,0 @@ -$TTL 1d -@ IN SOA {{ ansible_hostname }} openshift ( - {{ ansible_date_time.epoch }} ; Serial (To be fixed before 2039) - 12h ; Refresh - 3m ; Retry - 4w ; Expire - 3h ; TTL for negative replies - ) - - IN NS {{ ansible_hostname }} -{{ ansible_hostname }} IN A {{ ansible_default_ipv4.address }} -{% for host in dns_all_hosts %} -{{ hostvars[host].ansible_hostname }} IN A {{ hostvars[host]['ansible_default_ipv4'].address }} -{% endfor %} diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml index 1f9ac5059..78c6671d8 100644 --- a/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -7,8 +7,8 @@ - set_fact: l_use_system_container: "{{ openshift.docker.use_system_container | default(False) }}" - l_use_crio: "{{ openshift.docker.use_crio | default(False) }}" - l_use_crio_only: "{{ openshift.docker.use_crio_only | default(False) }}" + l_use_crio: "{{ openshift_use_crio | default(False) }}" + l_use_crio_only: "{{ openshift_use_crio_only | default(False) }}" - name: Use Package Docker if Requested include: package_docker.yml diff --git a/roles/docker/templates/crio.conf.j2 b/roles/docker/templates/crio.conf.j2 index 5805b2fb1..b4ee84fd0 100644 --- a/roles/docker/templates/crio.conf.j2 +++ b/roles/docker/templates/crio.conf.j2 @@ -43,7 +43,7 @@ stream_port = "10010" # This is a mandatory setting as this runtime will be the default one # and will also be used for untrusted container workloads if # runtime_untrusted_workload is not set. -runtime = "/usr/libexec/crio/runc" +runtime = "/usr/bin/runc" # runtime_untrusted_workload is the OCI compatible runtime used for untrusted # container workloads. This is an optional setting, except if diff --git a/roles/etcd/defaults/main.yaml b/roles/etcd/defaults/main.yaml index d12d7a358..3cc2bbb18 100644 --- a/roles/etcd/defaults/main.yaml +++ b/roles/etcd/defaults/main.yaml @@ -1,6 +1,6 @@ --- -r_etcd_firewall_enabled: True -r_etcd_use_firewalld: False +r_etcd_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_etcd_use_firewalld: "{{ os_firewall_use_firewalld | default(Falsel) }}" etcd_initial_cluster_state: new etcd_initial_cluster_token: etcd-cluster-1 diff --git a/roles/etcd/templates/etcd.conf.j2 b/roles/etcd/templates/etcd.conf.j2 index ce362c743..2c2803aee 100644 --- a/roles/etcd/templates/etcd.conf.j2 +++ b/roles/etcd/templates/etcd.conf.j2 @@ -11,7 +11,8 @@ ETCD_NAME={{ etcd_hostname }} ETCD_LISTEN_PEER_URLS={{ etcd_listen_peer_urls }} ETCD_DATA_DIR={{ etcd_data_dir }} -#ETCD_SNAPSHOT_COUNTER=10000 +#ETCD_WAL_DIR="" +#ETCD_SNAPSHOT_COUNT=10000 ETCD_HEARTBEAT_INTERVAL=500 ETCD_ELECTION_TIMEOUT=2500 ETCD_LISTEN_CLIENT_URLS={{ etcd_listen_client_urls }} @@ -41,24 +42,43 @@ ETCD_INITIAL_CLUSTER_TOKEN={{ etcd_initial_cluster_token }} #ETCD_DISCOVERY_PROXY= {% endif %} ETCD_ADVERTISE_CLIENT_URLS={{ etcd_advertise_client_urls }} +#ETCD_STRICT_RECONFIG_CHECK="false" +#ETCD_AUTO_COMPACTION_RETENTION="0" +#ETCD_ENABLE_V2="true" #[proxy] #ETCD_PROXY=off +#ETCD_PROXY_FAILURE_WAIT="5000" +#ETCD_PROXY_REFRESH_INTERVAL="30000" +#ETCD_PROXY_DIAL_TIMEOUT="1000" +#ETCD_PROXY_WRITE_TIMEOUT="5000" +#ETCD_PROXY_READ_TIMEOUT="0" #[security] {% if etcd_url_scheme == 'https' -%} -ETCD_CA_FILE={{ etcd_ca_file }} +ETCD_TRUSTED_CA_FILE={{ etcd_ca_file }} +ETCD_CLIENT_CERT_AUTH="true" ETCD_CERT_FILE={{ etcd_cert_file }} ETCD_KEY_FILE={{ etcd_key_file }} {% endif -%} +#ETCD_AUTO_TLS="false" {% if etcd_peer_url_scheme == 'https' -%} -ETCD_PEER_CA_FILE={{ etcd_peer_ca_file }} +ETCD_PEER_TRUSTED_CA_FILE={{ etcd_peer_ca_file }} +ETCD_PEER_CLIENT_CERT_AUTH="true" ETCD_PEER_CERT_FILE={{ etcd_peer_cert_file }} ETCD_PEER_KEY_FILE={{ etcd_peer_key_file }} {% endif -%} +#ETCD_PEER_AUTO_TLS="false" #[logging] ETCD_DEBUG="{{ etcd_debug | default(false) | bool | string }}" {% if etcd_log_package_levels is defined %} ETCD_LOG_PACKAGE_LEVELS="{{ etcd_log_package_levels }}" {% endif %} + +#[profiling] +#ETCD_ENABLE_PPROF="false" +#ETCD_METRICS="basic" +# +#[auth] +#ETCD_AUTH_TOKEN="simple" diff --git a/roles/etcd_migrate/tasks/migrate.yml b/roles/etcd_migrate/tasks/migrate.yml index 173de77f4..54a9c74ff 100644 --- a/roles/etcd_migrate/tasks/migrate.yml +++ b/roles/etcd_migrate/tasks/migrate.yml @@ -21,15 +21,24 @@ lineinfile: line: "ETCD_FORCE_NEW_CLUSTER=true" dest: /etc/etcd/etcd.conf + backup: true - name: Start etcd systemd: name: "{{ l_etcd_service }}" state: started +- name: Wait for cluster to become healthy after bringing up first member + command: > + etcdctl --cert-file {{ etcd_peer_cert_file }} --key-file {{ etcd_peer_key_file }} --ca-file {{ etcd_peer_ca_file }} --endpoint https://{{ etcd_peer }}:{{ etcd_client_port }} cluster-health + register: l_etcd_migrate_health + until: l_etcd_migrate_health.rc == 0 + retries: 3 + delay: 30 - name: Unset ETCD_FORCE_NEW_CLUSTER=true on first etcd host lineinfile: line: "ETCD_FORCE_NEW_CLUSTER=true" dest: /etc/etcd/etcd.conf state: absent + backup: true - name: Restart first etcd host systemd: name: "{{ l_etcd_service }}" diff --git a/roles/lib_openshift/library/oc_atomic_container.py b/roles/lib_openshift/library/oc_atomic_container.py index 955c6313e..79bd08f4e 100644 --- a/roles/lib_openshift/library/oc_atomic_container.py +++ b/roles/lib_openshift/library/oc_atomic_container.py @@ -83,7 +83,7 @@ def _install(module, container, image, values_list): if rc != 0: return rc, out, err, False else: - changed = "Extracting" in out + changed = "Extracting" in out or "Copying blob" in out return rc, out, err, changed def _uninstall(module, name): @@ -127,7 +127,7 @@ def do_update(module, container, old_image, image, values_list): if rc != 0: module.fail_json(rc=rc, msg=err) else: - changed = "Extracting" in out + changed = "Extracting" in out or "Copying blob" in out module.exit_json(msg=out, changed=changed) diff --git a/roles/lib_openshift/library/oc_route.py b/roles/lib_openshift/library/oc_route.py index d6db75e1e..8f8e46e1e 100644 --- a/roles/lib_openshift/library/oc_route.py +++ b/roles/lib_openshift/library/oc_route.py @@ -1665,9 +1665,6 @@ class OCRoute(OpenShiftCLI): @staticmethod def get_cert_data(path, content): '''get the data for a particular value''' - if not path and not content: - return None - rval = None if path and os.path.exists(path) and os.access(path, os.R_OK): rval = open(path).read() @@ -1706,14 +1703,14 @@ class OCRoute(OpenShiftCLI): if params['tls_termination'] and params['tls_termination'].lower() != 'passthrough': # E501 for key, option in files.items(): - if key == 'destcacert' and params['tls_termination'] != 'reencrypt': + if not option['path'] and not option['content']: continue option['value'] = OCRoute.get_cert_data(option['path'], option['content']) # E501 if not option['value']: return {'failed': True, - 'msg': 'Verify that you pass a value for %s' % key} + 'msg': 'Verify that you pass a correct value for %s' % key} rconfig = RouteConfig(params['name'], params['namespace'], diff --git a/roles/lib_openshift/src/ansible/oc_atomic_container.py b/roles/lib_openshift/src/ansible/oc_atomic_container.py index 7b81760df..454d7c4b2 100644 --- a/roles/lib_openshift/src/ansible/oc_atomic_container.py +++ b/roles/lib_openshift/src/ansible/oc_atomic_container.py @@ -19,7 +19,7 @@ def _install(module, container, image, values_list): if rc != 0: return rc, out, err, False else: - changed = "Extracting" in out + changed = "Extracting" in out or "Copying blob" in out return rc, out, err, changed def _uninstall(module, name): @@ -63,7 +63,7 @@ def do_update(module, container, old_image, image, values_list): if rc != 0: module.fail_json(rc=rc, msg=err) else: - changed = "Extracting" in out + changed = "Extracting" in out or "Copying blob" in out module.exit_json(msg=out, changed=changed) diff --git a/roles/lib_openshift/src/class/oc_route.py b/roles/lib_openshift/src/class/oc_route.py index 3935525f1..3a1bd732f 100644 --- a/roles/lib_openshift/src/class/oc_route.py +++ b/roles/lib_openshift/src/class/oc_route.py @@ -68,9 +68,6 @@ class OCRoute(OpenShiftCLI): @staticmethod def get_cert_data(path, content): '''get the data for a particular value''' - if not path and not content: - return None - rval = None if path and os.path.exists(path) and os.access(path, os.R_OK): rval = open(path).read() @@ -109,14 +106,14 @@ class OCRoute(OpenShiftCLI): if params['tls_termination'] and params['tls_termination'].lower() != 'passthrough': # E501 for key, option in files.items(): - if key == 'destcacert' and params['tls_termination'] != 'reencrypt': + if not option['path'] and not option['content']: continue option['value'] = OCRoute.get_cert_data(option['path'], option['content']) # E501 if not option['value']: return {'failed': True, - 'msg': 'Verify that you pass a value for %s' % key} + 'msg': 'Verify that you pass a correct value for %s' % key} rconfig = RouteConfig(params['name'], params['namespace'], diff --git a/roles/nuage_common/defaults/main.yaml b/roles/nuage_common/defaults/main.yaml index a7803c0ee..919e3aa7b 100644 --- a/roles/nuage_common/defaults/main.yaml +++ b/roles/nuage_common/defaults/main.yaml @@ -10,5 +10,8 @@ nuage_ca_serial: "{{ nuage_ca_dir }}/nuageMonCA.serial.txt" nuage_master_mon_dir: /usr/share/nuage-openshift-monitor nuage_node_plugin_dir: /usr/share/vsp-openshift +nuage_node_cni_bin_dir: /opt/cni/bin +nuage_node_cni_netconf_dir: /etc/cni/net.d + nuage_mon_rest_server_port: "{{ nuage_openshift_monitor_rest_server_port | default('9443') }}" nuage_mon_cert_validity_period: "{{ nuage_cert_validity_period | default('3650') }}" diff --git a/roles/nuage_common/tasks/main.yml b/roles/nuage_common/tasks/main.yml new file mode 100644 index 000000000..6c8c9f8d2 --- /dev/null +++ b/roles/nuage_common/tasks/main.yml @@ -0,0 +1,27 @@ +--- +- name: Set the Nuage plugin openshift directory fact to handle Atomic host install + set_fact: + nuage_node_plugin_dir: /var/usr/share/vsp-openshift + when: openshift.common.is_atomic | bool + +- name: Set the Nuage CNI network config directory fact to handle Atomic host install + set_fact: + nuage_node_cni_netconf_dir: /var/etc/cni/net.d/ + when: openshift.common.is_atomic | bool + +- name: Set the Nuage CNI binary directory fact to handle Atomic host install + set_fact: + nuage_node_cni_bin_dir: /var/opt/cni/bin/ + when: openshift.common.is_atomic | bool + +- name: Assure CNI plugin config dir exists before daemon set install + become: yes + file: path="{{ nuage_node_plugin_dir }}" state=directory + +- name: Assure CNI netconf directory exists before daemon set install + become: yes + file: path="{{ nuage_node_cni_netconf_dir }}" state=directory + +- name: Assure CNI plugin binary directory exists before daemon set install + become: yes + file: path="{{ nuage_node_cni_bin_dir }}" state=directory diff --git a/roles/nuage_master/defaults/main.yml b/roles/nuage_master/defaults/main.yml index ffab25775..5f1d8686a 100644 --- a/roles/nuage_master/defaults/main.yml +++ b/roles/nuage_master/defaults/main.yml @@ -1,6 +1,6 @@ --- -r_nuage_master_firewall_enabled: True -r_nuage_master_use_firewalld: False +r_nuage_master_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_nuage_master_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" nuage_mon_rest_server_port: '9443' diff --git a/roles/nuage_master/handlers/main.yaml b/roles/nuage_master/handlers/main.yaml index ad7bbb111..21da6b953 100644 --- a/roles/nuage_master/handlers/main.yaml +++ b/roles/nuage_master/handlers/main.yaml @@ -1,8 +1,4 @@ --- -- name: restart nuage-openshift-monitor - become: yes - systemd: name=nuage-openshift-monitor state=restarted - - name: restart master api systemd: name={{ openshift.common.service_type }}-master-api state=restarted when: > diff --git a/roles/nuage_master/tasks/main.yaml b/roles/nuage_master/tasks/main.yaml index d0363c981..f3c487132 100644 --- a/roles/nuage_master/tasks/main.yaml +++ b/roles/nuage_master/tasks/main.yaml @@ -3,17 +3,64 @@ include: firewall.yml static: yes +- name: Set the Nuage certificate directory fact for Atomic hosts + set_fact: + cert_output_dir: /var/usr/share/nuage-openshift-monitor + when: openshift.common.is_atomic | bool + +- name: Set the Nuage kubeconfig file path fact for Atomic hosts + set_fact: + kube_config: /var/usr/share/nuage-openshift-monitor/nuage.kubeconfig + when: openshift.common.is_atomic | bool + +- name: Set the Nuage monitor yaml location fact for Atomic hosts + set_fact: + kubemon_yaml: /var/usr/share/nuage-openshift-monitor/nuage-openshift-monitor.yaml + when: openshift.common.is_atomic | bool + +- name: Set the Nuage monitor certs location fact for Atomic hosts + set_fact: + nuage_master_crt_dir: /var/usr/share/nuage-openshift-monitor/ + when: openshift.common.is_atomic | bool + +- name: Set the Nuage master config directory for daemon sets install + set_fact: + nuage_master_config_dsets_mount_dir: /var/usr/share/ + when: master_host_type == "is_atomic" + +- name: Set the Nuage node config directory for daemon sets install + set_fact: + nuage_node_config_dsets_mount_dir: /var/usr/share/ + when: slave_host_type == "is_atomic" + +- name: Set the Nuage CNI plugin binary directory for daemon sets install + set_fact: + nuage_cni_bin_dsets_mount_dir: /var/opt/cni/bin + when: openshift.common.is_atomic | bool + - name: Create directory /usr/share/nuage-openshift-monitor become: yes file: path=/usr/share/nuage-openshift-monitor state=directory + when: not openshift.common.is_atomic | bool -- name: Create the log directory +- name: Create directory /var/usr/share/nuage-openshift-monitor become: yes - file: path={{ nuage_mon_rest_server_logdir }} state=directory + file: path=/var/usr/share/nuage-openshift-monitor state=directory + when: openshift.common.is_atomic | bool + +- name: Create directory /var/usr/bin for monitor binary on atomic + become: yes + file: path=/var/usr/bin state=directory + when: openshift.common.is_atomic | bool -- name: Install Nuage Openshift Monitor +- name: Create CNI bin directory /var/opt/cni/bin become: yes - yum: name={{ nuage_openshift_rpm }} state=present + file: path=/var/opt/cni/bin state=directory + when: openshift.common.is_atomic | bool + +- name: Create the log directory + become: yes + file: path={{ nuage_mon_rest_server_logdir }} state=directory - include: serviceaccount.yml @@ -45,10 +92,32 @@ become: yes copy: src="{{ vsd_user_key_file }}" dest="{{ cert_output_dir }}/{{ vsd_user_key_file | basename }}" -- name: Create nuage-openshift-monitor.yaml +- name: Create Nuage master daemon set yaml file + become: yes + template: src=nuage-master-config-daemonset.j2 dest=/etc/nuage-master-config-daemonset.yaml owner=root mode=0644 + +- name: Create Nuage node daemon set yaml file become: yes - template: src=nuage-openshift-monitor.j2 dest=/usr/share/nuage-openshift-monitor/nuage-openshift-monitor.yaml owner=root mode=0644 + template: src=nuage-node-config-daemonset.j2 dest=/etc/nuage-node-config-daemonset.yaml owner=root mode=0644 + +- name: Add the service account to the privileged scc to have root permissions + shell: oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-infra:daemonset-controller + ignore_errors: true + when: inventory_hostname == groups.oo_first_master.0 + +- name: Spawn Nuage Master monitor daemon sets pod + shell: oc create -f /etc/nuage-master-config-daemonset.yaml + ignore_errors: true + when: inventory_hostname == groups.oo_first_master.0 + +- name: Spawn Nuage CNI daemon sets pod + shell: oc create -f /etc/nuage-node-config-daemonset.yaml + ignore_errors: true + when: inventory_hostname == groups.oo_first_master.0 + +- name: Restart daemons + command: /bin/true notify: - restart master api - restart master controllers - - restart nuage-openshift-monitor + ignore_errors: true diff --git a/roles/nuage_master/templates/nuage-master-config-daemonset.j2 b/roles/nuage_master/templates/nuage-master-config-daemonset.j2 new file mode 100755 index 000000000..612d689c2 --- /dev/null +++ b/roles/nuage_master/templates/nuage-master-config-daemonset.j2 @@ -0,0 +1,111 @@ +# This ConfigMap is used to configure Nuage VSP configuration on master nodes +kind: ConfigMap +apiVersion: v1 +metadata: + name: nuage-master-config + namespace: kube-system +data: + # This will generate the required Nuage configuration + # on master nodes + monitor_yaml_config: | + + # .kubeconfig that includes the nuage service account + kubeConfig: {{ nuage_master_crt_dir }}/nuage.kubeconfig + # name of the nuage service account, or another account with 'cluster-reader' + # permissions + # Openshift master config file + masterConfig: /etc/origin/master/master-config.yaml + # URL of the VSD Architect + vsdApiUrl: {{ vsd_api_url }} + # API version to query against. Usually "v3_2" + vspVersion: {{ vsp_version }} + # Name of the enterprise in which pods will reside + enterpriseName: {{ enterprise }} + # Name of the domain in which pods will reside + domainName: {{ domain }} + # VSD generated user certificate file location on master node + userCertificateFile: {{ nuage_master_crt_dir }}/{{ vsd_user }}.pem + # VSD generated user key file location on master node + userKeyFile: {{ nuage_master_crt_dir }}/{{ vsd_user }}-Key.pem + # Location where logs should be saved + log_dir: /var/log/nuage-openshift-monitor + # Monitor rest server parameters + # Logging level for the nuage openshift monitor + # allowed options are: 0 => INFO, 1 => WARNING, 2 => ERROR, 3 => FATAL + logLevel: 0 + # Parameters related to the nuage monitor REST server + nuageMonServer: + URL: 0.0.0.0:9443 + certificateDirectory: {{ nuage_master_crt_dir }} + # etcd config required for HA + etcdClientConfig: + ca: {{ nuage_master_crt_dir }}/nuageMonCA.crt + certFile: {{ nuage_master_crt_dir }}/nuageMonServer.crt + keyFile: {{ nuage_master_crt_dir }}/master.etcd-client.key + urls: + {% for etcd_url in openshift.master.etcd_urls %} + - {{ etcd_url }} + {% endfor %} + +--- + +# This manifest installs Nuage master node configuration on +# each Nuage master node in a cluster. +kind: DaemonSet +apiVersion: extensions/v1beta1 +metadata: + name: nuage-master-config + namespace: kube-system + labels: + k8s-app: nuage-master-config +spec: + selector: + matchLabels: + k8s-app: nuage-master-config + template: + metadata: + labels: + k8s-app: nuage-master-config + spec: + hostNetwork: true + tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule + operator: Exists + nodeSelector: + install-monitor: "true" + containers: + # This container configures Nuage Master node + - name: install-nuage-master-config + image: nuage/master:{{ nuage_monitor_container_image_version }} + ports: + - containerPort: 9443 + hostPort: 9443 + command: ["/configure-master.sh"] + args: ["ose", "{{ master_host_type }}"] + securityContext: + privileged: true + env: + # nuage-openshift-monitor.yaml config to install on each slave node. + - name: NUAGE_MASTER_VSP_CONFIG + valueFrom: + configMapKeyRef: + name: nuage-master-config + key: monitor_yaml_config + volumeMounts: + - mountPath: /var/log + name: cni-log-dir + - mountPath: {{ nuage_master_config_dsets_mount_dir }} + name: usr-share-dir + - mountPath: /etc/origin/ + name: master-config-dir + volumes: + - name: cni-log-dir + hostPath: + path: /var/log + - name: usr-share-dir + hostPath: + path: {{ nuage_master_config_dsets_mount_dir }} + - name: master-config-dir + hostPath: + path: /etc/origin/ diff --git a/roles/nuage_master/templates/nuage-node-config-daemonset.j2 b/roles/nuage_master/templates/nuage-node-config-daemonset.j2 new file mode 100755 index 000000000..02e9a1563 --- /dev/null +++ b/roles/nuage_master/templates/nuage-node-config-daemonset.j2 @@ -0,0 +1,206 @@ +# This ConfigMap is used to configure Nuage VSP configuration +kind: ConfigMap +apiVersion: v1 +metadata: + name: nuage-config + namespace: kube-system +data: + # This will generate the required Nuage vsp-openshift.yaml + # config on each slave node + plugin_yaml_config: | + clientCert: {{ nuage_node_config_dsets_mount_dir }}/vsp-openshift/client.crt + # The key to the certificate in clientCert above + clientKey: {{ nuage_node_config_dsets_mount_dir }}/vsp-openshift/client.key + # The certificate authority's certificate for the local kubelet. Usually the + # same as the CA cert used to create the client Cert/Key pair. + CACert: {{ nuage_node_config_dsets_mount_dir }}/vsp-openshift/ca.crt + # Name of the enterprise in which pods will reside + enterpriseName: {{ enterprise }} + # Name of the domain in which pods will reside + domainName: {{ domain }} + # Name of the VSD user in admin group + vsdUser: {{ vsd_user }} + # IP address and port number of master API server + masterApiServer: {{ api_server_url }} + # REST server URL + nuageMonRestServer: {{ nuage_mon_rest_server_url }} + # Bridge name for the docker bridge + dockerBridgeName: docker0 + # Certificate for connecting to the openshift monitor REST api + nuageMonClientCert: {{ nuage_node_config_dsets_mount_dir }}/vsp-openshift/nuageMonClient.crt + # Key to the certificate in restClientCert + nuageMonClientKey: {{ nuage_node_config_dsets_mount_dir }}/vsp-openshift/nuageMonClient.key + # CA certificate for verifying the master's rest server + nuageMonServerCA: {{ nuage_node_config_dsets_mount_dir }}/vsp-openshift/nuageMonCA.crt + # Nuage vport mtu size + interfaceMTU: {{ nuage_vport_mtu }} + # Logging level for the plugin + # allowed options are: "dbg", "info", "warn", "err", "emer", "off" + logLevel: 3 + + # This will generate the required Nuage CNI yaml configuration + cni_yaml_config: | + vrsendpoint: "/var/run/openvswitch/db.sock" + vrsbridge: "alubr0" + monitorinterval: 60 + cniversion: 0.2.0 + loglevel: "info" + portresolvetimer: 60 + logfilesize: 1 + vrsconnectionchecktimer: 180 + mtu: 1450 + staleentrytimeout: 600 + +--- + +# This manifest installs Nuage CNI plugins and network config on +# each worker node in Openshift cluster +kind: DaemonSet +apiVersion: extensions/v1beta1 +metadata: + name: nuage-cni-ds + namespace: kube-system + labels: + k8s-app: nuage-cni-ds +spec: + selector: + matchLabels: + k8s-app: nuage-cni-ds + template: + metadata: + labels: + k8s-app: nuage-cni-ds + spec: + hostNetwork: true + tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule + operator: Exists + containers: + # This container installs Nuage CNI binaries + # and CNI network config file on each node. + - name: install-nuage-cni + image: nuage/cni:{{ nuage_cni_container_image_version }} + command: ["/install-cni.sh"] + args: ["nuage-cni-openshift", "{{ slave_host_type }}"] + securityContext: + privileged: true + env: + # Nuage vsp-openshift.yaml config to install on each slave node. + - name: NUAGE_VSP_CONFIG + valueFrom: + configMapKeyRef: + name: nuage-config + key: plugin_yaml_config + # Nuage nuage-cni.yaml config to install on each slave node. + - name: NUAGE_CNI_YAML_CONFIG + valueFrom: + configMapKeyRef: + name: nuage-config + key: cni_yaml_config + # Nuage cluster network CIDR for iptables configuration + - name: NUAGE_CLUSTER_NW_CIDR + value: "{{ hostvars[groups.oo_first_master.0].openshift.master.sdn_cluster_network_cidr }}" + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/net.d + name: cni-net-dir + - mountPath: /etc/default + name: cni-yaml-dir + - mountPath: /var/run + name: var-run-dir + - mountPath: /var/log + name: cni-log-dir + - mountPath: {{ nuage_node_config_dsets_mount_dir }} + name: usr-share-dir + volumes: + - name: cni-bin-dir + hostPath: + path: {{ nuage_cni_bin_dsets_mount_dir }} + - name: cni-net-dir + hostPath: + path: {{ nuage_cni_netconf_dsets_mount_dir }} + - name: cni-yaml-dir + hostPath: + path: /etc/default + - name: var-run-dir + hostPath: + path: /var/run + - name: cni-log-dir + hostPath: + path: /var/log + - name: usr-share-dir + hostPath: + path: {{ nuage_node_config_dsets_mount_dir }} + +--- + +# This manifest installs Nuage VRS on +# each worker node in an Openshift cluster. +kind: DaemonSet +apiVersion: extensions/v1beta1 +metadata: + name: nuage-vrs-ds + namespace: kube-system + labels: + k8s-app: nuage-vrs-ds +spec: + selector: + matchLabels: + k8s-app: nuage-vrs-ds + updateStrategy: + type: RollingUpdate + template: + metadata: + labels: + k8s-app: nuage-vrs-ds + spec: + hostNetwork: true + tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule + operator: Exists + containers: + # This container installs Nuage VRS running as a + # container on each worker node + - name: install-nuage-vrs + image: nuage/vrs:{{ nuage_vrs_container_image_version }} + securityContext: + privileged: true + env: + # Configure parameters for VRS openvswitch file + - name: NUAGE_ACTIVE_CONTROLLER + value: "{{ vsc_active_ip }}" + - name: NUAGE_STANDBY_CONTROLLER + value: "{{ vsc_standby_ip }}" + - name: NUAGE_PLATFORM + value: '"kvm, k8s"' + - name: NUAGE_K8S_SERVICE_IPV4_SUBNET + value: '192.168.0.0\/16' + - name: NUAGE_NETWORK_UPLINK_INTF + value: "eth0" + volumeMounts: + - mountPath: /var/run + name: vrs-run-dir + - mountPath: /var/log + name: vrs-log-dir + - mountPath: /sys/module + name: sys-mod-dir + readOnly: true + - mountPath: /lib/modules + name: lib-mod-dir + readOnly: true + volumes: + - name: vrs-run-dir + hostPath: + path: /var/run + - name: vrs-log-dir + hostPath: + path: /var/log + - name: sys-mod-dir + hostPath: + path: /sys/module + - name: lib-mod-dir + hostPath: + path: /lib/modules diff --git a/roles/nuage_master/templates/nuage-openshift-monitor.j2 b/roles/nuage_master/templates/nuage-openshift-monitor.j2 deleted file mode 100644 index e077128a4..000000000 --- a/roles/nuage_master/templates/nuage-openshift-monitor.j2 +++ /dev/null @@ -1,41 +0,0 @@ -# .kubeconfig that includes the nuage service account -kubeConfig: {{ kube_config }} -# name of the nuage service account, or another account with 'cluster-reader' -# permissions -# Openshift master config file -masterConfig: {{ master_config_yaml }} -# URL of the VSD Architect -vsdApiUrl: {{ vsd_api_url }} -# API version to query against. Usually "v3_2" -vspVersion: {{ vsp_version }} -# File containing a VSP license to install. Only necessary if no license has -# been installed on the VSD Architect before, only valid for standalone vsd install -# licenseFile: "/path/to/base_vsp_license.txt" -# Name of the enterprise in which pods will reside -enterpriseName: {{ enterprise }} -# Name of the domain in which pods will reside -domainName: {{ domain }} -# VSD generated user certificate file location on master node -userCertificateFile: {{ cert_output_dir }}/{{ vsd_user_cert_file | basename }} -# VSD generated user key file location on master node -userKeyFile: {{ cert_output_dir }}/{{ vsd_user_key_file | basename }} -# Location where logs should be saved -log_dir: {{ nuage_mon_rest_server_logdir }} -# Monitor rest server parameters -# Logging level for the nuage openshift monitor -# allowed options are: 0 => INFO, 1 => WARNING, 2 => ERROR, 3 => FATAL -logLevel: {{ nuage_mon_log_level }} -# Parameters related to the nuage monitor REST server -nuageMonServer: - URL: {{ nuage_mon_rest_server_url }} - certificateDirectory: {{ cert_output_dir }} -# etcd config required for HA -etcdClientConfig: - ca: {{ openshift_master_config_dir }}/{{ "ca.crt" if (openshift.master.embedded_etcd | bool) else "master.etcd-ca.crt" }} - certFile: {{ openshift_master_config_dir }}/master.etcd-client.crt - keyFile: {{ openshift_master_config_dir }}/master.etcd-client.key - urls: -{% for etcd_url in openshift.master.etcd_urls %} - - {{ etcd_url }} -{% endfor %} - diff --git a/roles/nuage_master/vars/main.yaml b/roles/nuage_master/vars/main.yaml index 57d5d2595..114514d7c 100644 --- a/roles/nuage_master/vars/main.yaml +++ b/roles/nuage_master/vars/main.yaml @@ -22,6 +22,18 @@ nuage_mon_rest_server_host: "{{ openshift.master.cluster_hostname | default(open nuage_master_crt_dir: /usr/share/nuage-openshift-monitor nuage_service_account: system:serviceaccount:default:nuage +nuage_master_config_dsets_mount_dir: /usr/share/ +nuage_node_config_dsets_mount_dir: /usr/share/ +nuage_cni_bin_dsets_mount_dir: /opt/cni/bin +nuage_cni_netconf_dsets_mount_dir: /etc/cni/net.d +nuage_monitor_container_image_version: "{{ nuage_monitor_image_version | default('v5.1.1') }}" +nuage_vrs_container_image_version: "{{ nuage_vrs_image_version | default('v5.1.1') }}" +nuage_cni_container_image_version: "{{ nuage_cni_image_version | default('v5.1.1') }}" +api_server_url: "{{ hostvars[groups.oo_first_master.0].openshift.master.api_url }}" +nuage_vport_mtu: "{{ nuage_interface_mtu | default('1460') }}" +master_host_type: "{{ master_base_host_type | default('is_rhel_server') }}" +slave_host_type: "{{ slave_base_host_type | default('is_rhel_server') }}" + nuage_tasks: - resource_kind: cluster-role resource_name: cluster-reader diff --git a/roles/nuage_node/defaults/main.yml b/roles/nuage_node/defaults/main.yml index b3d2e3cec..9a2e34387 100644 --- a/roles/nuage_node/defaults/main.yml +++ b/roles/nuage_node/defaults/main.yml @@ -1,6 +1,6 @@ --- -r_nuage_node_firewall_enabled: True -r_nuage_node_use_firewalld: False +r_nuage_node_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_nuage_node_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" nuage_mon_rest_server_port: '9443' diff --git a/roles/nuage_node/handlers/main.yaml b/roles/nuage_node/handlers/main.yaml index 8384856ff..e68ae74bd 100644 --- a/roles/nuage_node/handlers/main.yaml +++ b/roles/nuage_node/handlers/main.yaml @@ -1,11 +1,7 @@ --- -- name: restart vrs - become: yes - systemd: name=openvswitch state=restarted - - name: restart node become: yes - systemd: name={{ openshift.common.service_type }}-node state=restarted + systemd: name={{ openshift.common.service_type }}-node daemon-reload=yes state=restarted - name: save iptable rules become: yes diff --git a/roles/nuage_node/tasks/main.yaml b/roles/nuage_node/tasks/main.yaml index 66d6ef4ca..9db9dbb6a 100644 --- a/roles/nuage_node/tasks/main.yaml +++ b/roles/nuage_node/tasks/main.yaml @@ -1,28 +1,18 @@ --- -- name: Install Nuage VRS - become: yes - yum: name={{ vrs_rpm }} state=present - -- name: Set the uplink interface - become: yes - lineinfile: dest={{ vrs_config }} regexp=^NETWORK_UPLINK_INTF line='NETWORK_UPLINK_INTF={{ uplink_interface }}' - -- name: Set the Active Controller - become: yes - lineinfile: dest={{ vrs_config }} regexp=^ACTIVE_CONTROLLER line='ACTIVE_CONTROLLER={{ vsc_active_ip }}' - -- name: Set the K8S/OSE Cluster service CIDR - become: yes - lineinfile: dest={{ vrs_config }} regexp=^K8S_SERVICE_IPV4_SUBNET line='K8S_SERVICE_IPV4_SUBNET={{ k8s_cluster_service_cidr }}' +- name: Set the Nuage plugin openshift directory fact for Atomic hosts + set_fact: + vsp_openshift_dir: /var/usr/share/vsp-openshift + when: openshift.common.is_atomic | bool -- name: Set the Standby Controller - become: yes - lineinfile: dest={{ vrs_config }} regexp=^STANDBY_CONTROLLER line='STANDBY_CONTROLLER={{ vsc_standby_ip }}' - when: vsc_standby_ip is defined +- name: Set the Nuage CNI binary directory fact for Atomic hosts + set_fact: + cni_bin_dir: /var/opt/cni/bin/ + when: openshift.common.is_atomic | bool -- name: Install plugin rpm - become: yes - yum: name={{ plugin_rpm }} state=present +- name: Set the Nuage plugin certs directory fact for Atomic hosts + set_fact: + nuage_plugin_crt_dir: /var/usr/share/vsp-openshift + when: openshift.common.is_atomic | bool - name: Assure CNI conf dir exists become: yes @@ -32,13 +22,6 @@ become: yes file: path="{{ cni_bin_dir }}" state=directory -- name: Install CNI loopback plugin - become: yes - copy: - src: "{{ k8s_cni_loopback_plugin }}" - dest: "{{ cni_bin_dir }}/{{ k8s_cni_loopback_plugin | basename }}" - mode: 0755 - - name: Copy the certificates and keys become: yes copy: src="/tmp/{{ item }}" dest="{{ vsp_openshift_dir }}/{{ item }}" @@ -50,12 +33,16 @@ - include: certificates.yml -- name: Set the vsp-openshift.yaml +- name: Add additional Docker mounts for Nuage for atomic hosts become: yes - template: src=vsp-openshift.j2 dest={{ vsp_openshift_yaml }} owner=root mode=0644 + lineinfile: dest="{{ openshift_atomic_node_config_file }}" line="{{ nuage_atomic_docker_additional_mounts }}" + when: openshift.common.is_atomic | bool + +- name: Restart node services + command: /bin/true notify: - - restart vrs - restart node + ignore_errors: true - include: iptables.yml diff --git a/roles/nuage_node/templates/vsp-openshift.j2 b/roles/nuage_node/templates/vsp-openshift.j2 deleted file mode 100644 index f6bccebc2..000000000 --- a/roles/nuage_node/templates/vsp-openshift.j2 +++ /dev/null @@ -1,29 +0,0 @@ -clientCert: {{ client_cert }} -# The key to the certificate in clientCert above -clientKey: {{ client_key }} -# The certificate authority's certificate for the local kubelet. Usually the -# same as the CA cert used to create the client Cert/Key pair. -CACert: {{ ca_cert }} -# Name of the enterprise in which pods will reside -enterpriseName: {{ enterprise }} -# Name of the domain in which pods will reside -domainName: {{ domain }} -# Name of the VSD user in admin group -vsdUser: {{ vsd_user }} -# IP address and port number of master API server -masterApiServer: {{ api_server }} -# REST server URL -nuageMonRestServer: {{ nuage_mon_rest_server_url }} -# Bridge name for the docker bridge -dockerBridgeName: {{ docker_bridge }} -# Certificate for connecting to the kubemon REST API -nuageMonClientCert: {{ rest_client_cert }} -# Key to the certificate in restClientCert -nuageMonClientKey: {{ rest_client_key }} -# CA certificate for verifying the master's rest server -nuageMonServerCA: {{ rest_server_ca_cert }} -# Nuage vport mtu size -interfaceMTU: {{ vport_mtu }} -# Logging level for the plugin -# allowed options are: "dbg", "info", "warn", "err", "emer", "off" -logLevel: {{ plugin_log_level }} diff --git a/roles/nuage_node/vars/main.yaml b/roles/nuage_node/vars/main.yaml index 4cf68411f..d8bfca62a 100644 --- a/roles/nuage_node/vars/main.yaml +++ b/roles/nuage_node/vars/main.yaml @@ -23,3 +23,5 @@ cni_conf_dir: "/etc/cni/net.d/" cni_bin_dir: "/opt/cni/bin/" nuage_plugin_crt_dir: /usr/share/vsp-openshift +openshift_atomic_node_config_file: /etc/sysconfig/{{ openshift.common.service_type }}-node +nuage_atomic_docker_additional_mounts: "DOCKER_ADDTL_BIND_MOUNTS=-v /var/usr/share/vsp-openshift:/var/usr/share/vsp-openshift -v /etc/default:/etc/default -v /var/run:/var/run -v /opt/cni/bin:/opt/cni/bin -v /etc/cni/net.d:/etc/cni/net.d" diff --git a/roles/openshift_ami_prep/defaults/main.yml b/roles/openshift_ami_prep/defaults/main.yml deleted file mode 100644 index 2ba6d8eae..000000000 --- a/roles/openshift_ami_prep/defaults/main.yml +++ /dev/null @@ -1,50 +0,0 @@ ---- - - -r_openshift_ami_prep_packages: -- atomic-openshift-master -- atomic-openshift-node -- atomic-openshift-docker-excluder -- atomic-openshift-sdn-ovs -- openvswitch -- docker -- etcd -#- pcs -- haproxy -- dnsmasq -- ntp -- logrotate -- httpd-tools -- bind -- firewalld -- libselinux-python -- conntrack-tools -- openssl -- cloud-init -- iproute -- python-dbus -- PyYAML -- yum-utils -- python2-boto -- python2-boto3 -- cloud-utils-growpart -# gluster -- glusterfs-fuse -- heketi-client -# nfs -- nfs-utils -- flannel -- bash-completion -# cockpit -- cockpit-ws -- cockpit-system -- cockpit-bridge -- cockpit-docker -# iscsi -- iscsi-initiator-utils -# ceph -- ceph-common -# systemcontainer -# - runc -# - container-selinux -# - atomic diff --git a/roles/openshift_ami_prep/tasks/main.yml b/roles/openshift_ami_prep/tasks/main.yml deleted file mode 100644 index 98f7bc0e2..000000000 --- a/roles/openshift_ami_prep/tasks/main.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -- name: install repositories - include: yum_repos.yml - static: yes - -- name: install needed rpm(s) - package: - name: "{{ item }}" - state: present - with_items: "{{ r_openshift_ami_prep_packages }}" - -- name: create the directory for node - file: - state: directory - path: "/etc/systemd/system/{{ r_openshift_ami_prep_node }}.service.d" - -- name: laydown systemd override - copy: - dest: "/etc/systemd/system/{{ r_openshift_ami_prep_node }}.service.d/override.conf" - content: | - [Unit] - After=cloud-init.service - -- name: update the sysconfig to have KUBECONFIG - lineinfile: - dest: "/etc/sysconfig/{{ r_openshift_ami_prep_node }}" - line: "KUBECONFIG=/root/csr_kubeconfig" - regexp: "^KUBECONFIG=.*" - -- name: update the ExecStart to have bootstrap - lineinfile: - dest: "/usr/lib/systemd/system/{{ r_openshift_ami_prep_node }}.service" - line: "{% raw %}ExecStart=/usr/bin/openshift start node --bootstrap --kubeconfig=${KUBECONFIG} $OPTIONS{% endraw %}" - regexp: "^ExecStart=.*" - -- name: systemctl enable origin-node - systemd: - name: "{{ item }}" - enabled: no - with_items: - - "{{ r_openshift_ami_prep_node }}.service" - - "{{ r_openshift_ami_prep_master }}.service" diff --git a/roles/openshift_ami_prep/tasks/yum_repos.yml b/roles/openshift_ami_prep/tasks/yum_repos.yml deleted file mode 100644 index c48c67ac2..000000000 --- a/roles/openshift_ami_prep/tasks/yum_repos.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: Create our install repository - yum_repository: - description: "{{ item.description | default(omit) }}" - name: "{{ item.name }}" - baseurl: "{{ item.baseurl }}" - gpgkey: "{{ item.gpgkey | default(omit)}}" - gpgcheck: "{{ item.gpgcheck | default(1) }}" - sslverify: "{{ item.sslverify | default(1) }}" - sslclientkey: "{{ item.sslclientkey | default(omit) }}" - sslclientcert: "{{ item.sslclientcert | default(omit) }}" - file: "{{ item.file }}" - enabled: "{{ item.enabled }}" - with_items: "{{ r_openshift_ami_prep_yum_repositories }}" diff --git a/roles/openshift_aws_ami_copy/tasks/main.yml b/roles/openshift_aws_ami_copy/tasks/main.yml index 15444c8d0..bcccd4042 100644 --- a/roles/openshift_aws_ami_copy/tasks/main.yml +++ b/roles/openshift_aws_ami_copy/tasks/main.yml @@ -1,7 +1,7 @@ --- - fail: msg: "{{ item }} needs to be defined" - when: "{{ item }} is not defined" + when: item is not defined with_items: - r_openshift_aws_ami_copy_src_ami - r_openshift_aws_ami_copy_name diff --git a/roles/openshift_aws_iam_kms/tasks/main.yml b/roles/openshift_aws_iam_kms/tasks/main.yml index b541b466c..32aac2666 100644 --- a/roles/openshift_aws_iam_kms/tasks/main.yml +++ b/roles/openshift_aws_iam_kms/tasks/main.yml @@ -1,7 +1,7 @@ --- - fail: msg: "{{ item.name }} needs to be defined." - when: "{{ item.cond }}" + when: item.cond | bool with_items: - name: "{{ r_openshift_aws_iam_kms_alias }}" cond: "{{ r_openshift_aws_iam_kms_alias is undefined }}" diff --git a/roles/openshift_cfme/defaults/main.yml b/roles/openshift_cfme/defaults/main.yml index 393bee1f3..b82c2e602 100644 --- a/roles/openshift_cfme/defaults/main.yml +++ b/roles/openshift_cfme/defaults/main.yml @@ -27,8 +27,6 @@ openshift_cfme_pv_data: # Tuning parameter to use more than 5 images at once from an ImageStream openshift_cfme_maxImagesBulkImportedPerRepository: 100 -# Hostname/IP of the NFS server. Currently defaults to first master -openshift_cfme_nfs_server: "{{ groups.nfs.0 }}" # TODO: Refactor '_install_app' variable. This is just for testing but # maybe in the future it should control the entire yes/no for CFME. # diff --git a/roles/openshift_cfme/tasks/nfs.yml b/roles/openshift_cfme/tasks/nfs.yml index 8db45492e..ca04628a8 100644 --- a/roles/openshift_cfme/tasks/nfs.yml +++ b/roles/openshift_cfme/tasks/nfs.yml @@ -1,6 +1,13 @@ --- # Tasks to statically provision NFS volumes # Include if not using dynamic volume provisioning + +- name: Set openshift_cfme_nfs_server fact + when: openshift_cfme_nfs_server is not defined + set_fact: + # Hostname/IP of the NFS server. Currently defaults to first master + openshift_cfme_nfs_server: "{{ oo_nfs_to_config.0 }}" + - name: Ensure the /exports/ directory exists file: path: /exports/ diff --git a/roles/openshift_cfme/templates/miq-pv-db.yaml.j2 b/roles/openshift_cfme/templates/miq-pv-db.yaml.j2 index b8c3bb277..280f3e97a 100644 --- a/roles/openshift_cfme/templates/miq-pv-db.yaml.j2 +++ b/roles/openshift_cfme/templates/miq-pv-db.yaml.j2 @@ -8,6 +8,6 @@ spec: accessModes: - ReadWriteOnce nfs: - path: /exports/miq-pv01 + path: {{ openshift_cfme_nfs_directory }}/miq-pv01 server: {{ openshift_cfme_nfs_server }} persistentVolumeReclaimPolicy: Retain diff --git a/roles/openshift_cfme/templates/miq-pv-region.yaml.j2 b/roles/openshift_cfme/templates/miq-pv-region.yaml.j2 index 7218773f0..fe80dffa5 100644 --- a/roles/openshift_cfme/templates/miq-pv-region.yaml.j2 +++ b/roles/openshift_cfme/templates/miq-pv-region.yaml.j2 @@ -8,6 +8,6 @@ spec: accessModes: - ReadWriteOnce nfs: - path: /exports/miq-pv02 + path: {{ openshift_cfme_nfs_directory }}/miq-pv02 server: {{ openshift_cfme_nfs_server }} persistentVolumeReclaimPolicy: Retain diff --git a/roles/openshift_cfme/templates/miq-pv-server.yaml.j2 b/roles/openshift_cfme/templates/miq-pv-server.yaml.j2 index 7b40b6c69..f84b67ea9 100644 --- a/roles/openshift_cfme/templates/miq-pv-server.yaml.j2 +++ b/roles/openshift_cfme/templates/miq-pv-server.yaml.j2 @@ -8,6 +8,6 @@ spec: accessModes: - ReadWriteOnce nfs: - path: /exports/miq-pv03 + path: {{ openshift_cfme_nfs_directory }}/miq-pv03 server: {{ openshift_cfme_nfs_server }} persistentVolumeReclaimPolicy: Retain diff --git a/roles/openshift_cli/meta/main.yml b/roles/openshift_cli/meta/main.yml index c1de367d9..04a1ce873 100644 --- a/roles/openshift_cli/meta/main.yml +++ b/roles/openshift_cli/meta/main.yml @@ -15,4 +15,4 @@ dependencies: - role: openshift_docker when: not skip_docker_role | default(False) | bool - role: openshift_common -- role: openshift_cli_facts +- role: openshift_facts diff --git a/roles/openshift_cli/tasks/main.yml b/roles/openshift_cli/tasks/main.yml index c716a0860..9e61805f9 100644 --- a/roles/openshift_cli/tasks/main.yml +++ b/roles/openshift_cli/tasks/main.yml @@ -1,6 +1,6 @@ --- - set_fact: - l_use_crio: "{{ openshift_docker_use_crio | default(false) }}" + l_use_crio: "{{ openshift_use_crio | default(false) }}" - name: Install clients package: name={{ openshift.common.service_type }}-clients state=present diff --git a/roles/openshift_cli_facts/meta/main.yml b/roles/openshift_cli_facts/meta/main.yml deleted file mode 100644 index 59acde215..000000000 --- a/roles/openshift_cli_facts/meta/main.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -galaxy_info: - author: Jason DeTiberus - description: OpenShift CLI Facts - company: Red Hat, Inc. - license: Apache License, Version 2.0 - min_ansible_version: 1.9 - platforms: - - name: EL - versions: - - 7 - categories: - - cloud -dependencies: -- role: openshift_facts diff --git a/roles/openshift_cli_facts/tasks/main.yml b/roles/openshift_cli_facts/tasks/main.yml deleted file mode 100644 index dd1ed8965..000000000 --- a/roles/openshift_cli_facts/tasks/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# TODO: move this to a new 'cli' role -- openshift_facts: - role: common - local_facts: - cli_image: "{{ osm_image | default(None) }}" diff --git a/roles/openshift_clock/defaults/main.yml b/roles/openshift_clock/defaults/main.yml new file mode 100644 index 000000000..a94f67199 --- /dev/null +++ b/roles/openshift_clock/defaults/main.yml @@ -0,0 +1,2 @@ +--- +openshift_clock_enabled: True diff --git a/roles/openshift_clock/meta/main.yml b/roles/openshift_clock/meta/main.yml index 3e175beb0..d1e86d826 100644 --- a/roles/openshift_clock/meta/main.yml +++ b/roles/openshift_clock/meta/main.yml @@ -11,5 +11,4 @@ galaxy_info: - 7 categories: - cloud -dependencies: -- { role: openshift_facts } +dependencies: [] diff --git a/roles/openshift_clock/tasks/main.yaml b/roles/openshift_clock/tasks/main.yaml index 3911201ea..f8b02524a 100644 --- a/roles/openshift_clock/tasks/main.yaml +++ b/roles/openshift_clock/tasks/main.yaml @@ -1,14 +1,15 @@ --- -- name: Set clock facts - openshift_facts: - role: clock - local_facts: - enabled: "{{ openshift_clock_enabled | default(None) }}" +- name: Determine if chrony is installed + command: rpm -q chrony + failed_when: false + register: chrony_installed - name: Install ntp package package: name=ntp state=present - when: openshift.clock.enabled | bool and not openshift.clock.chrony_installed | bool + when: + - openshift_clock_enabled | bool + - chrony_installed.rc != 0 - name: Start and enable ntpd/chronyd - shell: timedatectl set-ntp true - when: openshift.clock.enabled | bool + command: timedatectl set-ntp true + when: openshift_clock_enabled | bool diff --git a/roles/openshift_docker_facts/tasks/main.yml b/roles/openshift_docker_facts/tasks/main.yml index 516d7dc29..334150f63 100644 --- a/roles/openshift_docker_facts/tasks/main.yml +++ b/roles/openshift_docker_facts/tasks/main.yml @@ -17,7 +17,7 @@ hosted_registry_insecure: "{{ openshift_docker_hosted_registry_insecure | default(openshift.docker.hosted_registry_insecure | default(False)) }}" hosted_registry_network: "{{ openshift_docker_hosted_registry_network | default(None) }}" use_system_container: "{{ openshift_docker_use_system_container | default(False) }}" - use_crio: "{{ openshift_docker_use_crio | default(False) }}" + use_crio: "{{ openshift_use_crio | default(False) }}" - role: node local_facts: sdn_mtu: "{{ openshift_node_sdn_mtu | default(None) }}" diff --git a/roles/openshift_examples/files/examples/v1.5/cfme-templates/cfme-template.yaml b/roles/openshift_examples/files/examples/v1.5/cfme-templates/cfme-template.yaml index 3bc6c5813..fd57a864c 100644 --- a/roles/openshift_examples/files/examples/v1.5/cfme-templates/cfme-template.yaml +++ b/roles/openshift_examples/files/examples/v1.5/cfme-templates/cfme-template.yaml @@ -10,6 +10,12 @@ metadata: iconClass: "icon-rails" objects: - apiVersion: v1 + kind: Secret + metadata: + name: "${NAME}-secrets" + stringData: + pg-password: "${DATABASE_PASSWORD}" +- apiVersion: v1 kind: Service metadata: annotations: @@ -148,7 +154,10 @@ objects: value: "${DATABASE_USER}" - name: "POSTGRESQL_PASSWORD" - value: "${DATABASE_PASSWORD}" + valueFrom: + secretKeyRef: + name: "${NAME}-secrets" + key: "pg-password" - name: "POSTGRESQL_DATABASE" value: "${DATABASE_NAME}" @@ -345,7 +354,10 @@ objects: value: "${DATABASE_USER}" - name: "POSTGRESQL_PASSWORD" - value: "${DATABASE_PASSWORD}" + valueFrom: + secretKeyRef: + name: "${NAME}-secrets" + key: "pg-password" - name: "POSTGRESQL_DATABASE" value: "${DATABASE_NAME}" @@ -386,7 +398,8 @@ parameters: displayName: "PostgreSQL Password" required: true description: "Password for the PostgreSQL user." - value: "smartvm" + from: "[a-zA-Z0-9]{8}" + generate: expression - name: "DATABASE_NAME" required: true diff --git a/roles/openshift_examples/files/examples/v3.6/cfme-templates/cfme-template.yaml b/roles/openshift_examples/files/examples/v3.6/cfme-templates/cfme-template.yaml index 3bc6c5813..fd57a864c 100644 --- a/roles/openshift_examples/files/examples/v3.6/cfme-templates/cfme-template.yaml +++ b/roles/openshift_examples/files/examples/v3.6/cfme-templates/cfme-template.yaml @@ -10,6 +10,12 @@ metadata: iconClass: "icon-rails" objects: - apiVersion: v1 + kind: Secret + metadata: + name: "${NAME}-secrets" + stringData: + pg-password: "${DATABASE_PASSWORD}" +- apiVersion: v1 kind: Service metadata: annotations: @@ -148,7 +154,10 @@ objects: value: "${DATABASE_USER}" - name: "POSTGRESQL_PASSWORD" - value: "${DATABASE_PASSWORD}" + valueFrom: + secretKeyRef: + name: "${NAME}-secrets" + key: "pg-password" - name: "POSTGRESQL_DATABASE" value: "${DATABASE_NAME}" @@ -345,7 +354,10 @@ objects: value: "${DATABASE_USER}" - name: "POSTGRESQL_PASSWORD" - value: "${DATABASE_PASSWORD}" + valueFrom: + secretKeyRef: + name: "${NAME}-secrets" + key: "pg-password" - name: "POSTGRESQL_DATABASE" value: "${DATABASE_NAME}" @@ -386,7 +398,8 @@ parameters: displayName: "PostgreSQL Password" required: true description: "Password for the PostgreSQL user." - value: "smartvm" + from: "[a-zA-Z0-9]{8}" + generate: expression - name: "DATABASE_NAME" required: true diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py index 251d1dfb4..cf78b4a75 100755 --- a/roles/openshift_facts/library/openshift_facts.py +++ b/roles/openshift_facts/library/openshift_facts.py @@ -1909,7 +1909,6 @@ class OpenShiftFacts(object): """ known_roles = ['builddefaults', 'buildoverrides', - 'clock', 'cloudprovider', 'common', 'docker', @@ -2099,13 +2098,6 @@ class OpenShiftFacts(object): docker['service_name'] = 'docker' defaults['docker'] = docker - if 'clock' in roles: - exit_code, _, _ = module.run_command(['rpm', '-q', 'chrony']) # noqa: F405 - chrony_installed = bool(exit_code == 0) - defaults['clock'] = dict( - enabled=True, - chrony_installed=chrony_installed) - if 'cloudprovider' in roles: defaults['cloudprovider'] = dict(kind=None) diff --git a/roles/openshift_health_checker/action_plugins/openshift_health_check.py b/roles/openshift_health_checker/action_plugins/openshift_health_check.py index 05e53333d..8d35db6b5 100644 --- a/roles/openshift_health_checker/action_plugins/openshift_health_check.py +++ b/roles/openshift_health_checker/action_plugins/openshift_health_check.py @@ -1,76 +1,74 @@ """ Ansible action plugin to execute health checks in OpenShift clusters. """ -# pylint: disable=wrong-import-position,missing-docstring,invalid-name import sys import os +import traceback from collections import defaultdict +from ansible.plugins.action import ActionBase +from ansible.module_utils.six import string_types + try: from __main__ import display except ImportError: + # pylint: disable=ungrouped-imports; this is the standard way how to import + # the default display object in Ansible action plugins. from ansible.utils.display import Display display = Display() -from ansible.plugins.action import ActionBase -from ansible.module_utils.six import string_types - # Augment sys.path so that we can import checks from a directory relative to # this callback plugin. sys.path.insert(1, os.path.dirname(os.path.dirname(__file__))) +# pylint: disable=wrong-import-position; the import statement must come after +# the manipulation of sys.path. from openshift_checks import OpenShiftCheck, OpenShiftCheckException, load_checks # noqa: E402 class ActionModule(ActionBase): + """Action plugin to execute health checks.""" def run(self, tmp=None, task_vars=None): result = super(ActionModule, self).run(tmp, task_vars) task_vars = task_vars or {} - # vars are not supportably available in the callback plugin, - # so record any it will need in the result. + # callback plugins cannot read Ansible vars, but we would like + # zz_failure_summary to have access to certain values. We do so by + # storing the information we need in the result. result['playbook_context'] = task_vars.get('r_openshift_health_checker_playbook_context') - if "openshift" not in task_vars: - result["failed"] = True - result["msg"] = "'openshift' is undefined, did 'openshift_facts' run?" - return result - try: known_checks = self.load_known_checks(tmp, task_vars) args = self._task.args requested_checks = normalize(args.get('checks', [])) + + if not requested_checks: + result['failed'] = True + result['msg'] = list_known_checks(known_checks) + return result + resolved_checks = resolve_checks(requested_checks, known_checks.values()) - except OpenShiftCheckException as e: + except OpenShiftCheckException as exc: result["failed"] = True - result["msg"] = str(e) + result["msg"] = str(exc) + return result + + if "openshift" not in task_vars: + result["failed"] = True + result["msg"] = "'openshift' is undefined, did 'openshift_facts' run?" return result result["checks"] = check_results = {} user_disabled_checks = normalize(task_vars.get('openshift_disable_check', [])) - for check_name in resolved_checks: - display.banner("CHECK [{} : {}]".format(check_name, task_vars["ansible_host"])) - check = known_checks[check_name] - - if not check.is_active(): - r = dict(skipped=True, skipped_reason="Not active for this host") - elif check_name in user_disabled_checks: - r = dict(skipped=True, skipped_reason="Disabled by user request") - else: - try: - r = check.run() - except OpenShiftCheckException as e: - r = dict( - failed=True, - msg=str(e), - ) - + for name in resolved_checks: + display.banner("CHECK [{} : {}]".format(name, task_vars["ansible_host"])) + check = known_checks[name] + check_results[name] = run_check(name, check, user_disabled_checks) if check.changed: - r["changed"] = True - check_results[check_name] = r + check_results[name]["changed"] = True result["changed"] = any(r.get("changed") for r in check_results.values()) if any(r.get("failed") for r in check_results.values()): @@ -80,22 +78,55 @@ class ActionModule(ActionBase): return result def load_known_checks(self, tmp, task_vars): + """Find all existing checks and return a mapping of names to instances.""" load_checks() known_checks = {} for cls in OpenShiftCheck.subclasses(): - check_name = cls.name - if check_name in known_checks: - other_cls = known_checks[check_name].__class__ + name = cls.name + if name in known_checks: + other_cls = known_checks[name].__class__ raise OpenShiftCheckException( - "non-unique check name '{}' in: '{}.{}' and '{}.{}'".format( - check_name, - cls.__module__, cls.__name__, - other_cls.__module__, other_cls.__name__)) - known_checks[check_name] = cls(execute_module=self._execute_module, tmp=tmp, task_vars=task_vars) + "duplicate check name '{}' in: '{}' and '{}'" + "".format(name, full_class_name(cls), full_class_name(other_cls)) + ) + known_checks[name] = cls(execute_module=self._execute_module, tmp=tmp, task_vars=task_vars) return known_checks +def list_known_checks(known_checks): + """Return text listing the existing checks and tags.""" + # TODO: we could include a description of each check by taking it from a + # check class attribute (e.g., __doc__) when building the message below. + msg = ( + 'This playbook is meant to run health checks, but no checks were ' + 'requested. Set the `openshift_checks` variable to a comma-separated ' + 'list of check names or a YAML list. Available checks:\n {}' + ).format('\n '.join(sorted(known_checks))) + + tags = describe_tags(known_checks.values()) + + msg += ( + '\n\nTags can be used as a shortcut to select multiple ' + 'checks. Available tags and the checks they select:\n {}' + ).format('\n '.join(tags)) + + return msg + + +def describe_tags(check_classes): + """Return a sorted list of strings describing tags and the checks they include.""" + tag_checks = defaultdict(list) + for cls in check_classes: + for tag in cls.tags: + tag_checks[tag].append(cls.name) + tags = [ + '@{} = {}'.format(tag, ','.join(sorted(checks))) + for tag, checks in tag_checks.items() + ] + return sorted(tags) + + def resolve_checks(names, all_checks): """Returns a set of resolved check names. @@ -123,6 +154,12 @@ def resolve_checks(names, all_checks): if unknown_tag_names: msg.append('Unknown tag names: {}.'.format(', '.join(sorted(unknown_tag_names)))) msg.append('Make sure there is no typo in the playbook and no files are missing.') + # TODO: implement a "Did you mean ...?" when the input is similar to a + # valid check or tag. + msg.append('Known checks:') + msg.append(' {}'.format('\n '.join(sorted(known_check_names)))) + msg.append('Known tags:') + msg.append(' {}'.format('\n '.join(describe_tags(all_checks)))) raise OpenShiftCheckException('\n'.join(msg)) tag_to_checks = defaultdict(set) @@ -146,3 +183,32 @@ def normalize(checks): if isinstance(checks, string_types): checks = checks.split(',') return [name.strip() for name in checks if name.strip()] + + +def run_check(name, check, user_disabled_checks): + """Run a single check if enabled and return a result dict.""" + if name in user_disabled_checks: + return dict(skipped=True, skipped_reason="Disabled by user request") + + # pylint: disable=broad-except; capturing exceptions broadly is intentional, + # to isolate arbitrary failures in one check from others. + try: + is_active = check.is_active() + except Exception as exc: + reason = "Could not determine if check should be run, exception: {}".format(exc) + return dict(skipped=True, skipped_reason=reason, exception=traceback.format_exc()) + + if not is_active: + return dict(skipped=True, skipped_reason="Not active for this host") + + try: + return check.run() + except OpenShiftCheckException as exc: + return dict(failed=True, msg=str(exc)) + except Exception as exc: + return dict(failed=True, msg=str(exc), exception=traceback.format_exc()) + + +def full_class_name(cls): + """Return the name of a class prefixed with its module name.""" + return '{}.{}'.format(cls.__module__, cls.__name__) diff --git a/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py b/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py index d10200719..349655966 100644 --- a/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py +++ b/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py @@ -1,161 +1,223 @@ -""" -Ansible callback plugin to give a nicely formatted summary of failures. -""" +"""Ansible callback plugin to print a nicely formatted summary of failures. -# Reason: In several locations below we disable pylint protected-access -# for Ansible objects that do not give us any public way -# to access the full details we need to report check failures. -# Status: disabled permanently or until Ansible object has a public API. -# This does leave the code more likely to be broken by future Ansible changes. +The file / module name is prefixed with `zz_` to make this plugin be loaded last +by Ansible, thus making its output the last thing that users see. +""" -from pprint import pformat +from collections import defaultdict +import traceback from ansible.plugins.callback import CallbackBase from ansible import constants as C from ansible.utils.color import stringc +FAILED_NO_MSG = u'Failed without returning a message.' + + class CallbackModule(CallbackBase): - """ - This callback plugin stores task results and summarizes failures. - The file name is prefixed with `zz_` to make this plugin be loaded last by - Ansible, thus making its output the last thing that users see. - """ + """This callback plugin stores task results and summarizes failures.""" CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'aggregate' CALLBACK_NAME = 'failure_summary' CALLBACK_NEEDS_WHITELIST = False - _playbook_file = None def __init__(self): super(CallbackModule, self).__init__() self.__failures = [] + self.__playbook_file = '' def v2_playbook_on_start(self, playbook): super(CallbackModule, self).v2_playbook_on_start(playbook) - # re: playbook attrs see top comment # pylint: disable=protected-access - self._playbook_file = playbook._file_name + # pylint: disable=protected-access; Ansible gives us no public API to + # get the file name of the current playbook from a callback plugin. + self.__playbook_file = playbook._file_name def v2_runner_on_failed(self, result, ignore_errors=False): super(CallbackModule, self).v2_runner_on_failed(result, ignore_errors) if not ignore_errors: - self.__failures.append(dict(result=result, ignore_errors=ignore_errors)) + self.__failures.append(result) def v2_playbook_on_stats(self, stats): super(CallbackModule, self).v2_playbook_on_stats(stats) - if self.__failures: - self._print_failure_details(self.__failures) - - def _print_failure_details(self, failures): - """Print a summary of failed tasks or checks.""" - self._display.display(u'\nFailure summary:\n') - - width = len(str(len(failures))) - initial_indent_format = u' {{:>{width}}}. '.format(width=width) - initial_indent_len = len(initial_indent_format.format(0)) - subsequent_indent = u' ' * initial_indent_len - subsequent_extra_indent = u' ' * (initial_indent_len + 10) - - for i, failure in enumerate(failures, 1): - entries = _format_failure(failure) - self._display.display(u'\n{}{}'.format(initial_indent_format.format(i), entries[0])) - for entry in entries[1:]: - entry = entry.replace(u'\n', u'\n' + subsequent_extra_indent) - indented = u'{}{}'.format(subsequent_indent, entry) - self._display.display(indented) - - failed_checks = set() - playbook_context = None - # re: result attrs see top comment # pylint: disable=protected-access - for failure in failures: - # Get context from check task result since callback plugins cannot access task vars. - # NOTE: thus context is not known unless checks run. Failures prior to checks running - # don't have playbook_context in the results. But we only use it now when checks fail. - playbook_context = playbook_context or failure['result']._result.get('playbook_context') - failed_checks.update( - name - for name, result in failure['result']._result.get('checks', {}).items() - if result.get('failed') - ) - if failed_checks: - self._print_check_failure_summary(failed_checks, playbook_context) - - def _print_check_failure_summary(self, failed_checks, context): - checks = ','.join(sorted(failed_checks)) - # The purpose of specifying context is to vary the output depending on what the user was - # expecting to happen (based on which playbook they ran). The only use currently is to - # vary the message depending on whether the user was deliberately running checks or was - # trying to install/upgrade and checks are just included. Other use cases may arise. - summary = ( # default to explaining what checks are in the first place - '\n' - 'The execution of "{playbook}"\n' - 'includes checks designed to fail early if the requirements\n' - 'of the playbook are not met. One or more of these checks\n' - 'failed. To disregard these results, you may choose to\n' - 'disable failing checks by setting an Ansible variable:\n\n' - ' openshift_disable_check={checks}\n\n' - 'Failing check names are shown in the failure details above.\n' - 'Some checks may be configurable by variables if your requirements\n' - 'are different from the defaults; consult check documentation.\n' - 'Variables can be set in the inventory or passed on the\n' - 'command line using the -e flag to ansible-playbook.\n\n' - ).format(playbook=self._playbook_file, checks=checks) - if context in ['pre-install', 'health']: - summary = ( # user was expecting to run checks, less explanation needed - '\n' - 'You may choose to configure or disable failing checks by\n' - 'setting Ansible variables. To disable those above:\n\n' - ' openshift_disable_check={checks}\n\n' - 'Consult check documentation for configurable variables.\n' - 'Variables can be set in the inventory or passed on the\n' - 'command line using the -e flag to ansible-playbook.\n\n' - ).format(checks=checks) - self._display.display(summary) - - -# re: result attrs see top comment # pylint: disable=protected-access -def _format_failure(failure): + # pylint: disable=broad-except; capturing exceptions broadly is + # intentional, to isolate arbitrary failures in this callback plugin. + try: + if self.__failures: + self._display.display(failure_summary(self.__failures, self.__playbook_file)) + except Exception: + msg = stringc( + u'An error happened while generating a summary of failures:\n' + u'{}'.format(traceback.format_exc()), C.COLOR_WARN) + self._display.v(msg) + + +def failure_summary(failures, playbook): + """Return a summary of failed tasks, including details on health checks.""" + if not failures: + return u'' + + # NOTE: because we don't have access to task_vars from callback plugins, we + # store the playbook context in the task result when the + # openshift_health_check action plugin is used, and we use this context to + # customize the error message. + # pylint: disable=protected-access; Ansible gives us no sufficient public + # API on TaskResult objects. + context = next(( + context for context in + (failure._result.get('playbook_context') for failure in failures) + if context + ), None) + + failures = [failure_to_dict(failure) for failure in failures] + failures = deduplicate_failures(failures) + + summary = [u'', u'', u'Failure summary:', u''] + + width = len(str(len(failures))) + initial_indent_format = u' {{:>{width}}}. '.format(width=width) + initial_indent_len = len(initial_indent_format.format(0)) + subsequent_indent = u' ' * initial_indent_len + subsequent_extra_indent = u' ' * (initial_indent_len + 10) + + for i, failure in enumerate(failures, 1): + entries = format_failure(failure) + summary.append(u'\n{}{}'.format(initial_indent_format.format(i), entries[0])) + for entry in entries[1:]: + entry = entry.replace(u'\n', u'\n' + subsequent_extra_indent) + indented = u'{}{}'.format(subsequent_indent, entry) + summary.append(indented) + + failed_checks = set() + for failure in failures: + failed_checks.update(name for name, message in failure['checks']) + if failed_checks: + summary.append(check_failure_footer(failed_checks, context, playbook)) + + return u'\n'.join(summary) + + +def failure_to_dict(failed_task_result): + """Extract information out of a failed TaskResult into a dict. + + The intent is to transform a TaskResult object into something easier to + manipulate. TaskResult is ansible.executor.task_result.TaskResult. + """ + # pylint: disable=protected-access; Ansible gives us no sufficient public + # API on TaskResult objects. + _result = failed_task_result._result + return { + 'host': failed_task_result._host.get_name(), + 'play': play_name(failed_task_result._task), + 'task': failed_task_result.task_name, + 'msg': _result.get('msg', FAILED_NO_MSG), + 'checks': tuple( + (name, result.get('msg', FAILED_NO_MSG)) + for name, result in sorted(_result.get('checks', {}).items()) + if result.get('failed') + ), + } + + +def play_name(obj): + """Given a task or block, return the name of its parent play. + + This is loosely inspired by ansible.playbook.base.Base.dump_me. + """ + # pylint: disable=protected-access; Ansible gives us no sufficient public + # API to implement this. + if not obj: + return '' + if hasattr(obj, '_play'): + return obj._play.get_name() + return play_name(getattr(obj, '_parent')) + + +def deduplicate_failures(failures): + """Group together similar failures from different hosts. + + Returns a new list of failures such that identical failures from different + hosts are grouped together in a single entry. The relative order of failures + is preserved. + """ + groups = defaultdict(list) + for failure in failures: + group_key = tuple(sorted((key, value) for key, value in failure.items() if key != 'host')) + groups[group_key].append(failure) + result = [] + for failure in failures: + group_key = tuple(sorted((key, value) for key, value in failure.items() if key != 'host')) + if group_key not in groups: + continue + failure['host'] = tuple(sorted(g_failure['host'] for g_failure in groups.pop(group_key))) + result.append(failure) + return result + + +def format_failure(failure): """Return a list of pretty-formatted text entries describing a failure, including relevant information about it. Expect that the list of text entries will be joined by a newline separator when output to the user.""" - result = failure['result'] - host = result._host.get_name() - play = _get_play(result._task) - if play: - play = play.get_name() - task = result._task.get_name() - msg = result._result.get('msg', u'???') + host = u', '.join(failure['host']) + play = failure['play'] + task = failure['task'] + msg = failure['msg'] + checks = failure['checks'] fields = ( - (u'Host', host), + (u'Hosts', host), (u'Play', play), (u'Task', task), (u'Message', stringc(msg, C.COLOR_ERROR)), ) - if 'checks' in result._result: - fields += ((u'Details', _format_failed_checks(result._result['checks'])),) + if checks: + fields += ((u'Details', format_failed_checks(checks)),) row_format = '{:10}{}' return [row_format.format(header + u':', body) for header, body in fields] -def _format_failed_checks(checks): +def format_failed_checks(checks): """Return pretty-formatted text describing checks that failed.""" - failed_check_msgs = [] - for check, body in checks.items(): - if body.get('failed', False): # only show the failed checks - msg = body.get('msg', u"Failed without returning a message") - failed_check_msgs.append('check "%s":\n%s' % (check, msg)) - if failed_check_msgs: - return stringc("\n\n".join(failed_check_msgs), C.COLOR_ERROR) - else: # something failed but no checks will admit to it, so dump everything - return stringc(pformat(checks), C.COLOR_ERROR) - - -# This is inspired by ansible.playbook.base.Base.dump_me. -# re: play/task/block attrs see top comment # pylint: disable=protected-access -def _get_play(obj): - """Given a task or block, recursively try to find its parent play.""" - if hasattr(obj, '_play'): - return obj._play - if getattr(obj, '_parent'): - return _get_play(obj._parent) + messages = [] + for name, message in checks: + messages.append(u'check "{}":\n{}'.format(name, message)) + return stringc(u'\n\n'.join(messages), C.COLOR_ERROR) + + +def check_failure_footer(failed_checks, context, playbook): + """Return a textual explanation about checks depending on context. + + The purpose of specifying context is to vary the output depending on what + the user was expecting to happen (based on which playbook they ran). The + only use currently is to vary the message depending on whether the user was + deliberately running checks or was trying to install/upgrade and checks are + just included. Other use cases may arise. + """ + checks = ','.join(sorted(failed_checks)) + summary = [u''] + if context in ['pre-install', 'health', 'adhoc']: + # User was expecting to run checks, less explanation needed. + summary.extend([ + u'You may configure or disable checks by setting Ansible ' + u'variables. To disable those above, set:', + u' openshift_disable_check={checks}'.format(checks=checks), + u'Consult check documentation for configurable variables.', + ]) + else: + # User may not be familiar with the checks, explain what checks are in + # the first place. + summary.extend([ + u'The execution of "{playbook}" includes checks designed to fail ' + u'early if the requirements of the playbook are not met. One or ' + u'more of these checks failed. To disregard these results,' + u'explicitly disable checks by setting an Ansible variable:'.format(playbook=playbook), + u' openshift_disable_check={checks}'.format(checks=checks), + u'Failing check names are shown in the failure details above. ' + u'Some checks may be configurable by variables if your requirements ' + u'are different from the defaults; consult check documentation.', + ]) + summary.append( + u'Variables can be set in the inventory or passed on the command line ' + u'using the -e flag to ansible-playbook.' + ) + return u'\n'.join(summary) diff --git a/roles/openshift_health_checker/openshift_checks/__init__.py b/roles/openshift_health_checker/openshift_checks/__init__.py index 07ec6f7ef..02ee1d0f9 100644 --- a/roles/openshift_health_checker/openshift_checks/__init__.py +++ b/roles/openshift_health_checker/openshift_checks/__init__.py @@ -242,7 +242,7 @@ def load_checks(path=None, subpkg=""): modules = modules + load_checks(os.path.join(path, name), subpkg + "." + name) continue - if name.endswith(".py") and name not in LOADER_EXCLUDES: + if name.endswith(".py") and not name.startswith(".") and name not in LOADER_EXCLUDES: modules.append(import_module(__package__ + subpkg + "." + name[:-3])) return modules diff --git a/roles/openshift_health_checker/openshift_checks/disk_availability.py b/roles/openshift_health_checker/openshift_checks/disk_availability.py index 6d1dea9ce..f302fd14b 100644 --- a/roles/openshift_health_checker/openshift_checks/disk_availability.py +++ b/roles/openshift_health_checker/openshift_checks/disk_availability.py @@ -115,10 +115,7 @@ class DiskAvailability(OpenShiftCheck): return { 'failed': True, - 'msg': ( - 'Available disk space in "{}" ({:.1f} GB) ' - 'is below minimum recommended ({:.1f} GB)' - ).format(path, free_gb, recommended_gb) + 'msg': msg, } return {} diff --git a/roles/openshift_health_checker/openshift_checks/docker_image_availability.py b/roles/openshift_health_checker/openshift_checks/docker_image_availability.py index 85a922f86..857a80c74 100644 --- a/roles/openshift_health_checker/openshift_checks/docker_image_availability.py +++ b/roles/openshift_health_checker/openshift_checks/docker_image_availability.py @@ -168,7 +168,10 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck): registries = [registry] for registry in registries: - args = {"_raw_params": "skopeo inspect --tls-verify=false docker://{}/{}".format(registry, image)} + args = { + "_raw_params": "timeout 10 skopeo inspect --tls-verify=false " + "docker://{}/{}".format(registry, image) + } result = self.execute_module("command", args) if result.get("rc", 0) == 0 and not result.get("failed"): return True diff --git a/roles/openshift_health_checker/test/action_plugin_test.py b/roles/openshift_health_checker/test/action_plugin_test.py index f5161d6f5..c109ebd24 100644 --- a/roles/openshift_health_checker/test/action_plugin_test.py +++ b/roles/openshift_health_checker/test/action_plugin_test.py @@ -80,7 +80,8 @@ def skipped(result): None, {}, ]) -def test_action_plugin_missing_openshift_facts(plugin, task_vars): +def test_action_plugin_missing_openshift_facts(plugin, task_vars, monkeypatch): + monkeypatch.setattr('openshift_health_check.resolve_checks', lambda *args: ['fake_check']) result = plugin.run(tmp=None, task_vars=task_vars) assert failed(result, msg_has=['openshift_facts']) @@ -94,7 +95,7 @@ def test_action_plugin_cannot_load_checks_with_the_same_name(plugin, task_vars, result = plugin.run(tmp=None, task_vars=task_vars) - assert failed(result, msg_has=['unique', 'duplicate_name', 'FakeCheck']) + assert failed(result, msg_has=['duplicate', 'duplicate_name', 'FakeCheck']) def test_action_plugin_skip_non_active_checks(plugin, task_vars, monkeypatch): @@ -217,24 +218,21 @@ def test_resolve_checks_ok(names, all_checks, expected): assert resolve_checks(names, all_checks) == expected -@pytest.mark.parametrize('names,all_checks,words_in_exception,words_not_in_exception', [ +@pytest.mark.parametrize('names,all_checks,words_in_exception', [ ( ['testA', 'testB'], [], ['check', 'name', 'testA', 'testB'], - ['tag', 'group', '@'], ), ( ['@group'], [], ['tag', 'name', 'group'], - ['check', '@'], ), ( ['testA', 'testB', '@group'], [], ['check', 'name', 'testA', 'testB', 'tag', 'group'], - ['@'], ), ( ['testA', 'testB', '@group'], @@ -244,13 +242,10 @@ def test_resolve_checks_ok(names, all_checks, expected): fake_check('from_group_2', ['preflight', 'group']), ], ['check', 'name', 'testA', 'testB'], - ['tag', 'group', '@'], ), ]) -def test_resolve_checks_failure(names, all_checks, words_in_exception, words_not_in_exception): +def test_resolve_checks_failure(names, all_checks, words_in_exception): with pytest.raises(Exception) as excinfo: resolve_checks(names, all_checks) for word in words_in_exception: assert word in str(excinfo.value) - for word in words_not_in_exception: - assert word not in str(excinfo.value) diff --git a/roles/openshift_health_checker/test/conftest.py b/roles/openshift_health_checker/test/conftest.py index 3cbd65507..244a1f0fa 100644 --- a/roles/openshift_health_checker/test/conftest.py +++ b/roles/openshift_health_checker/test/conftest.py @@ -7,5 +7,6 @@ openshift_health_checker_path = os.path.dirname(os.path.dirname(__file__)) sys.path[1:1] = [ openshift_health_checker_path, os.path.join(openshift_health_checker_path, 'action_plugins'), + os.path.join(openshift_health_checker_path, 'callback_plugins'), os.path.join(openshift_health_checker_path, 'library'), ] diff --git a/roles/openshift_health_checker/test/zz_failure_summary_test.py b/roles/openshift_health_checker/test/zz_failure_summary_test.py new file mode 100644 index 000000000..0fc258133 --- /dev/null +++ b/roles/openshift_health_checker/test/zz_failure_summary_test.py @@ -0,0 +1,70 @@ +from zz_failure_summary import deduplicate_failures + +import pytest + + +@pytest.mark.parametrize('failures,deduplicated', [ + ( + [ + { + 'host': 'master1', + 'msg': 'One or more checks failed', + }, + ], + [ + { + 'host': ('master1',), + 'msg': 'One or more checks failed', + }, + ], + ), + ( + [ + { + 'host': 'master1', + 'msg': 'One or more checks failed', + }, + { + 'host': 'node1', + 'msg': 'One or more checks failed', + }, + ], + [ + { + 'host': ('master1', 'node1'), + 'msg': 'One or more checks failed', + }, + ], + ), + ( + [ + { + 'host': 'node1', + 'msg': 'One or more checks failed', + 'checks': (('test_check', 'error message'),), + }, + { + 'host': 'master2', + 'msg': 'Some error happened', + }, + { + 'host': 'master1', + 'msg': 'One or more checks failed', + 'checks': (('test_check', 'error message'),), + }, + ], + [ + { + 'host': ('master1', 'node1'), + 'msg': 'One or more checks failed', + 'checks': (('test_check', 'error message'),), + }, + { + 'host': ('master2',), + 'msg': 'Some error happened', + }, + ], + ), +]) +def test_deduplicate_failures(failures, deduplicated): + assert deduplicate_failures(failures) == deduplicated diff --git a/roles/openshift_hosted/defaults/main.yml b/roles/openshift_hosted/defaults/main.yml index f0e303e43..c26df3afa 100644 --- a/roles/openshift_hosted/defaults/main.yml +++ b/roles/openshift_hosted/defaults/main.yml @@ -1,12 +1,12 @@ --- -r_openshift_hosted_router_firewall_enabled: True -r_openshift_hosted_router_use_firewalld: False +r_openshift_hosted_router_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_openshift_hosted_router_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" -r_openshift_hosted_registry_firewall_enabled: True -r_openshift_hosted_registry_use_firewalld: False +r_openshift_hosted_registry_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_openshift_hosted_registry_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" -openshift_hosted_router_wait: True -openshift_hosted_registry_wait: True +openshift_hosted_router_wait: "{{ not openshift_master_bootstrap_enabled | default(True) }}" +openshift_hosted_registry_wait: "{{ not openshift_master_bootstrap_enabled | default(True) }}" registry_volume_claim: 'registry-claim' diff --git a/roles/openshift_hosted/tasks/registry/secure.yml b/roles/openshift_hosted/tasks/registry/secure.yml index a18e6eea9..a8a6f6fc8 100644 --- a/roles/openshift_hosted/tasks/registry/secure.yml +++ b/roles/openshift_hosted/tasks/registry/secure.yml @@ -37,6 +37,9 @@ hostnames: - "{{ docker_registry_service.results.clusterip }}" - "{{ docker_registry_route.results[0].spec.host }}" + - "{{ openshift_hosted_registry_name }}.default.svc" + - "{{ openshift_hosted_registry_name }}.default.svc.{{ openshift.common.dns_domain }}" + - "{{ openshift_hosted_registry_routehost }}" cert: "{{ docker_registry_cert_path }}" key: "{{ docker_registry_key_path }}" expire_days: "{{ openshift_hosted_registry_cert_expire_days if openshift_version | oo_version_gte_3_5_or_1_5(openshift.common.deployment_type) | bool else omit }}" diff --git a/roles/openshift_loadbalancer/defaults/main.yml b/roles/openshift_loadbalancer/defaults/main.yml index 3f6409233..41a2b12a2 100644 --- a/roles/openshift_loadbalancer/defaults/main.yml +++ b/roles/openshift_loadbalancer/defaults/main.yml @@ -1,6 +1,6 @@ --- -r_openshift_loadbalancer_firewall_enabled: True -r_openshift_loadbalancer_use_firewalld: False +r_openshift_loadbalancer_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_openshift_loadbalancer_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" haproxy_frontends: - name: main diff --git a/roles/openshift_logging/README.md b/roles/openshift_logging/README.md index 84ead3548..f283261c4 100644 --- a/roles/openshift_logging/README.md +++ b/roles/openshift_logging/README.md @@ -15,14 +15,25 @@ to the list of persisted [node labels](https://docs.openshift.org/latest/install ###Required vars: - `openshift_logging_install_logging`: When `True` the `openshift_logging` role will install Aggregated Logging. -- `openshift_logging_upgrade_logging`: When `True` the `openshift_logging` role will upgrade Aggregated Logging. -When both `openshift_logging_install_logging` and `openshift_logging_upgrade_logging` are `False` the `openshift_logging` role will uninstall Aggregated Logging. +When `openshift_logging_install_logging` is set to `False` the `openshift_logging` role will uninstall Aggregated Logging. ###Optional vars: - +- `openshift_logging_purge_logging`: When `openshift_logging_install_logging` is set to 'False' to trigger uninstalation and `openshift_logging_purge_logging` is set to 'True', it will completely and irreversibly remove all logging persistent data including PVC. Defaults to 'False'. - `openshift_logging_image_prefix`: The prefix for the logging images to use. Defaults to 'docker.io/openshift/origin-'. +- `openshift_logging_curator_image_prefix`: Setting the image prefix for Curator image. Defaults to `openshift_logging_image_prefix`. +- `openshift_logging_elasticsearch_image_prefix`: Setting the image prefix for Elasticsearch image. Defaults to `openshift_logging_image_prefix`. +- `openshift_logging_fluentd_image_prefix`: Setting the image prefix for Fluentd image. Defaults to `openshift_logging_image_prefix`. +- `openshift_logging_kibana_image_prefix`: Setting the image prefix for Kibana image. Defaults to `openshift_logging_image_prefix`. +- `openshift_logging_kibana_proxy_image_prefix`: Setting the image prefix for Kibana proxy image. Defaults to `openshift_logging_image_prefix`. +- `openshift_logging_mux_image_prefix`: Setting the image prefix for Mux image. Defaults to `openshift_logging_image_prefix`. - `openshift_logging_image_version`: The image version for the logging images to use. Defaults to 'latest'. +- `openshift_logging_curator_image_version`: Setting the image version for Curator image. Defaults to `openshift_logging_image_version`. +- `openshift_logging_elasticsearch_image_version`: Setting the image version for Elasticsearch image. Defaults to `openshift_logging_image_version`. +- `openshift_logging_fluentd_image_version`: Setting the image version for Fluentd image. Defaults to `openshift_logging_image_version`. +- `openshift_logging_kibana_image_version`: Setting the image version for Kibana image. Defaults to `openshift_logging_image_version`. +- `openshift_logging_kibana_proxy_image_version`: Setting the image version for Kibana proxy image. Defaults to `openshift_logging_image_version`. +- `openshift_logging_mux_image_version`: Setting the image version for Mux image. Defaults to `openshift_logging_image_version`. - `openshift_logging_use_ops`: If 'True', set up a second ES and Kibana cluster for infrastructure logs. Defaults to 'False'. - `openshift_logging_master_url`: The URL for the Kubernetes master, this does not need to be public facing but should be accessible from within the cluster. Defaults to 'https://kubernetes.default.svc.{{openshift.common.dns_domain}}'. - `openshift_logging_master_public_url`: The public facing URL for the Kubernetes master, this is used for Authentication redirection. Defaults to 'https://{{openshift.common.public_hostname}}:{{openshift.master.api_port}}'. diff --git a/roles/openshift_logging/defaults/main.yml b/roles/openshift_logging/defaults/main.yml index 8b0f4cb62..716f0e002 100644 --- a/roles/openshift_logging/defaults/main.yml +++ b/roles/openshift_logging/defaults/main.yml @@ -8,6 +8,7 @@ openshift_logging_labels: {} openshift_logging_label_key: "" openshift_logging_label_value: "" openshift_logging_install_logging: True +openshift_logging_purge_logging: False openshift_logging_image_pull_secret: "{{ openshift_hosted_logging_image_pull_secret | default('') }}" openshift_logging_curator_default_days: 30 @@ -84,7 +85,7 @@ openshift_logging_es_ca: /etc/fluent/keys/ca openshift_logging_es_client_cert: /etc/fluent/keys/cert openshift_logging_es_client_key: /etc/fluent/keys/key openshift_logging_es_cluster_size: "{{ openshift_hosted_logging_elasticsearch_cluster_size | default(1) }}" -openshift_logging_es_cpu_limit: null +openshift_logging_es_cpu_limit: 1000m # the logging appenders for the root loggers to write ES logs. Valid values: 'file', 'console' openshift_logging_es_log_appenders: ['file'] openshift_logging_es_memory_limit: "{{ openshift_hosted_logging_elasticsearch_instance_ram | default('8Gi') }}" @@ -125,7 +126,7 @@ openshift_logging_es_ops_ca: /etc/fluent/keys/ca openshift_logging_es_ops_client_cert: /etc/fluent/keys/cert openshift_logging_es_ops_client_key: /etc/fluent/keys/key openshift_logging_es_ops_cluster_size: "{{ openshift_hosted_logging_elasticsearch_ops_cluster_size | default(1) }}" -openshift_logging_es_ops_cpu_limit: null +openshift_logging_es_ops_cpu_limit: 1000m openshift_logging_es_ops_memory_limit: "{{ openshift_hosted_logging_elasticsearch_ops_instance_ram | default('8Gi') }}" openshift_logging_es_ops_pv_selector: "{{ openshift_hosted_loggingops_storage_labels | default('') }}" openshift_logging_es_ops_pvc_dynamic: "{{ openshift_hosted_logging_elasticsearch_ops_pvc_dynamic | default(False) }}" diff --git a/roles/openshift_logging/tasks/annotate_ops_projects.yaml b/roles/openshift_logging/tasks/annotate_ops_projects.yaml new file mode 100644 index 000000000..fcb4c94d3 --- /dev/null +++ b/roles/openshift_logging/tasks/annotate_ops_projects.yaml @@ -0,0 +1,17 @@ +--- +- oc_obj: + state: list + kind: project + name: "{{ item }}" + with_items: "{{ __default_logging_ops_projects }}" + register: __logging_ops_projects + +- name: Annotate Operations Projects + oc_edit: + kind: ns + name: "{{ item.item }}" + separator: '#' + content: + metadata#annotations#openshift.io/logging.ui.hostname: "{{ openshift_logging_kibana_ops_hostname }}" + with_items: "{{ __logging_ops_projects.results }}" + when: item.results.stderr is not defined diff --git a/roles/openshift_logging/tasks/delete_logging.yaml b/roles/openshift_logging/tasks/delete_logging.yaml index 6d023a02d..45298e345 100644 --- a/roles/openshift_logging/tasks/delete_logging.yaml +++ b/roles/openshift_logging/tasks/delete_logging.yaml @@ -14,6 +14,16 @@ - templates - ds +# return all persistent volume claims as well if purge is set +- name: delete logging pvc objects + oc_obj: + state: absent + kind: pvc + namespace: "{{ openshift_logging_namespace }}" + selector: "logging-infra" + when: + - openshift_logging_purge_logging | default(false) | bool + # delete the oauthclient - name: delete oauthclient kibana-proxy oc_obj: diff --git a/roles/openshift_logging/tasks/install_logging.yaml b/roles/openshift_logging/tasks/install_logging.yaml index d4a305fb8..a77df9986 100644 --- a/roles/openshift_logging/tasks/install_logging.yaml +++ b/roles/openshift_logging/tasks/install_logging.yaml @@ -185,8 +185,6 @@ openshift_logging_kibana_namespace: "{{ openshift_logging_namespace }}" openshift_logging_kibana_master_url: "{{ openshift_logging_master_url }}" openshift_logging_kibana_master_public_url: "{{ openshift_logging_master_public_url }}" - openshift_logging_kibana_image_prefix: "{{ openshift_logging_image_prefix }}" - openshift_logging_kibana_image_version: "{{ openshift_logging_image_version }}" openshift_logging_kibana_replicas: "{{ openshift_logging_kibana_replica_count }}" openshift_logging_kibana_es_host: "{{ openshift_logging_es_host }}" openshift_logging_kibana_es_port: "{{ openshift_logging_es_port }}" @@ -201,8 +199,6 @@ openshift_logging_kibana_namespace: "{{ openshift_logging_namespace }}" openshift_logging_kibana_master_url: "{{ openshift_logging_master_url }}" openshift_logging_kibana_master_public_url: "{{ openshift_logging_master_public_url }}" - openshift_logging_kibana_image_prefix: "{{ openshift_logging_image_prefix }}" - openshift_logging_kibana_image_version: "{{ openshift_logging_image_version }}" openshift_logging_kibana_image_pull_secret: "{{ openshift_logging_image_pull_secret }}" openshift_logging_kibana_es_host: "{{ openshift_logging_es_ops_host }}" openshift_logging_kibana_es_port: "{{ openshift_logging_es_ops_port }}" @@ -220,6 +216,7 @@ when: - openshift_logging_use_ops | bool +- include: annotate_ops_projects.yaml ## Curator - include_role: @@ -230,8 +227,6 @@ openshift_logging_curator_es_host: "{{ openshift_logging_es_host }}" openshift_logging_curator_es_port: "{{ openshift_logging_es_port }}" openshift_logging_curator_master_url: "{{ openshift_logging_master_url }}" - openshift_logging_curator_image_prefix: "{{ openshift_logging_image_prefix }}" - openshift_logging_curator_image_version: "{{ openshift_logging_image_version }}" openshift_logging_curator_image_pull_secret: "{{ openshift_logging_image_pull_secret }}" - include_role: @@ -243,8 +238,6 @@ openshift_logging_curator_es_port: "{{ openshift_logging_es_ops_port }}" openshift_logging_curator_namespace: "{{ openshift_logging_namespace }}" openshift_logging_curator_master_url: "{{ openshift_logging_master_url }}" - openshift_logging_curator_image_prefix: "{{ openshift_logging_image_prefix }}" - openshift_logging_curator_image_version: "{{ openshift_logging_image_version }}" openshift_logging_curator_image_pull_secret: "{{ openshift_logging_image_pull_secret }}" openshift_logging_curator_cpu_limit: "{{ openshift_logging_curator_ops_cpu_limit }}" openshift_logging_curator_memory_limit: "{{ openshift_logging_curator_ops_memory_limit }}" @@ -260,8 +253,6 @@ openshift_logging_mux_ops_host: "{{ ( openshift_logging_use_ops | bool ) | ternary('logging-es-ops', 'logging-es') }}" openshift_logging_mux_namespace: "{{ openshift_logging_namespace }}" openshift_logging_mux_master_url: "{{ openshift_logging_master_url }}" - openshift_logging_mux_image_prefix: "{{ openshift_logging_image_prefix }}" - openshift_logging_mux_image_version: "{{ openshift_logging_image_version }}" openshift_logging_mux_image_pull_secret: "{{ openshift_logging_image_pull_secret }}" when: - openshift_logging_use_mux | bool @@ -273,8 +264,6 @@ vars: generated_certs_dir: "{{openshift.common.config_base}}/logging" openshift_logging_fluentd_ops_host: "{{ ( openshift_logging_use_ops | bool ) | ternary('logging-es-ops', 'logging-es') }}" - openshift_logging_fluentd_image_prefix: "{{ openshift_logging_image_prefix }}" - openshift_logging_fluentd_image_version: "{{ openshift_logging_image_version }}" openshift_logging_fluentd_image_pull_secret: "{{ openshift_logging_image_pull_secret }}" openshift_logging_fluentd_master_url: "{{ openshift_logging_master_url }}" openshift_logging_fluentd_namespace: "{{ openshift_logging_namespace }}" diff --git a/roles/openshift_logging/vars/main.yaml b/roles/openshift_logging/vars/main.yaml index e561b41e2..01809fddf 100644 --- a/roles/openshift_logging/vars/main.yaml +++ b/roles/openshift_logging/vars/main.yaml @@ -6,3 +6,5 @@ es_ops_node_quorum: "{{ (openshift_logging_es_ops_cluster_size | int/2 | round(0 es_ops_recover_expected_nodes: "{{openshift_logging_es_ops_cluster_size | int}}" es_log_appenders: ['file', 'console'] + +__default_logging_ops_projects: ['default', 'openshift', 'openshift-infra', 'kube-system'] diff --git a/roles/openshift_logging_curator/defaults/main.yml b/roles/openshift_logging_curator/defaults/main.yml index 82ffb2f93..17807b644 100644 --- a/roles/openshift_logging_curator/defaults/main.yml +++ b/roles/openshift_logging_curator/defaults/main.yml @@ -1,7 +1,7 @@ --- ### General logging settings -openshift_logging_curator_image_prefix: "{{ openshift_hosted_logging_deployer_prefix | default('docker.io/openshift/origin-') }}" -openshift_logging_curator_image_version: "{{ openshift_hosted_logging_deployer_version | default('latest') }}" +openshift_logging_curator_image_prefix: "{{ openshift_logging_image_prefix | default(__openshift_logging_image_prefix) }}" +openshift_logging_curator_image_version: "{{ openshift_logging_image_version | default('latest') }}" openshift_logging_curator_image_pull_secret: "{{ openshift_hosted_logging_image_pull_secret | default('') }}" openshift_logging_curator_master_url: "https://kubernetes.default.svc.cluster.local" diff --git a/roles/openshift_logging_curator/tasks/main.yaml b/roles/openshift_logging_curator/tasks/main.yaml index 3113fb3c9..6e8fab2b5 100644 --- a/roles/openshift_logging_curator/tasks/main.yaml +++ b/roles/openshift_logging_curator/tasks/main.yaml @@ -86,7 +86,7 @@ component: "{{ curator_component }}" logging_component: curator deploy_name: "{{ curator_name }}" - image: "{{openshift_logging_image_prefix}}logging-curator:{{openshift_logging_image_version}}" + image: "{{openshift_logging_curator_image_prefix}}logging-curator:{{openshift_logging_curator_image_version}}" es_host: "{{ openshift_logging_curator_es_host }}" es_port: "{{ openshift_logging_curator_es_port }}" curator_cpu_limit: "{{ openshift_logging_curator_cpu_limit }}" diff --git a/roles/openshift_logging_elasticsearch/defaults/main.yml b/roles/openshift_logging_elasticsearch/defaults/main.yml index 0690bf114..75bd479be 100644 --- a/roles/openshift_logging_elasticsearch/defaults/main.yml +++ b/roles/openshift_logging_elasticsearch/defaults/main.yml @@ -1,7 +1,7 @@ --- ### Common settings -openshift_logging_elasticsearch_image_prefix: "{{ openshift_hosted_logging_deployer_prefix | default('docker.io/openshift/origin-') }}" -openshift_logging_elasticsearch_image_version: "{{ openshift_hosted_logging_deployer_version | default('latest') }}" +openshift_logging_elasticsearch_image_prefix: "{{ openshift_logging_image_prefix | default(__openshift_logging_image_prefix) }}" +openshift_logging_elasticsearch_image_version: "{{ openshift_logging_image_version | default('latest') }}" openshift_logging_elasticsearch_image_pull_secret: "{{ openshift_hosted_logging_image_pull_secret | default('') }}" openshift_logging_elasticsearch_namespace: logging diff --git a/roles/openshift_logging_elasticsearch/tasks/main.yaml b/roles/openshift_logging_elasticsearch/tasks/main.yaml index 28c3ffd96..1e800b1d6 100644 --- a/roles/openshift_logging_elasticsearch/tasks/main.yaml +++ b/roles/openshift_logging_elasticsearch/tasks/main.yaml @@ -229,7 +229,7 @@ dest: "{{ tempdir }}/templates/logging-es-pvc.yml" vars: obj_name: "{{ openshift_logging_elasticsearch_pvc_name }}" - size: "{{ openshift_logging_elasticsearch_pvc_size }}" + size: "{{ (openshift_logging_elasticsearch_pvc_size | trim | length == 0) | ternary('10Gi', openshift_logging_elasticsearch_pvc_size) }}" access_modes: "{{ openshift_logging_elasticsearch_pvc_access_modes | list }}" pv_selector: "{{ openshift_logging_elasticsearch_pvc_pv_selector }}" storage_class_name: "{{ openshift_logging_elasticsearch_pvc_storage_class_name | default('', true) }}" @@ -243,7 +243,7 @@ dest: "{{ tempdir }}/templates/logging-es-pvc.yml" vars: obj_name: "{{ openshift_logging_elasticsearch_pvc_name }}" - size: "{{ openshift_logging_elasticsearch_pvc_size }}" + size: "{{ (openshift_logging_elasticsearch_pvc_size | trim | length == 0) | ternary('10Gi', openshift_logging_elasticsearch_pvc_size) }}" access_modes: "{{ openshift_logging_elasticsearch_pvc_access_modes | list }}" pv_selector: "{{ openshift_logging_elasticsearch_pvc_pv_selector }}" when: @@ -277,7 +277,7 @@ component: "{{ es_component }}" logging_component: elasticsearch deploy_name: "{{ es_deploy_name }}" - image: "{{ openshift_logging_image_prefix }}logging-elasticsearch:{{ openshift_logging_image_version }}" + image: "{{ openshift_logging_elasticsearch_image_prefix }}logging-elasticsearch:{{ openshift_logging_elasticsearch_image_version }}" es_cpu_limit: "{{ openshift_logging_elasticsearch_cpu_limit }}" es_memory_limit: "{{ openshift_logging_elasticsearch_memory_limit }}" es_node_selector: "{{ openshift_logging_elasticsearch_nodeselector | default({}) }}" diff --git a/roles/openshift_logging_fluentd/defaults/main.yml b/roles/openshift_logging_fluentd/defaults/main.yml index a53bbd2df..30d3d854a 100644 --- a/roles/openshift_logging_fluentd/defaults/main.yml +++ b/roles/openshift_logging_fluentd/defaults/main.yml @@ -1,7 +1,7 @@ --- ### General logging settings -openshift_logging_fluentd_image_prefix: "{{ openshift_hosted_logging_deployer_prefix | default('docker.io/openshift/origin-') }}" -openshift_logging_fluentd_image_version: "{{ openshift_hosted_logging_deployer_version | default('latest') }}" +openshift_logging_fluentd_image_prefix: "{{ openshift_logging_image_prefix | default(__openshift_logging_image_prefix) }}" +openshift_logging_fluentd_image_version: "{{ openshift_logging_image_version | default('latest') }}" openshift_logging_fluentd_image_pull_secret: "{{ openshift_hosted_logging_image_pull_secret | default('') }}" openshift_logging_fluentd_master_url: "https://kubernetes.default.svc.{{ openshift.common.dns_domain }}" openshift_logging_fluentd_namespace: logging diff --git a/roles/openshift_logging_fluentd/templates/fluentd.j2 b/roles/openshift_logging_fluentd/templates/fluentd.j2 index 39dffba19..88e039e3f 100644 --- a/roles/openshift_logging_fluentd/templates/fluentd.j2 +++ b/roles/openshift_logging_fluentd/templates/fluentd.j2 @@ -28,7 +28,7 @@ spec: {{ fluentd_nodeselector_key }}: "{{ fluentd_nodeselector_value }}" containers: - name: "{{ daemonset_container_name }}" - image: "{{ openshift_logging_image_prefix }}{{ daemonset_name }}:{{ openshift_logging_image_version }}" + image: "{{ openshift_logging_fluentd_image_prefix }}{{ daemonset_name }}:{{ openshift_logging_fluentd_image_version }}" imagePullPolicy: Always securityContext: privileged: true diff --git a/roles/openshift_logging_kibana/defaults/main.yml b/roles/openshift_logging_kibana/defaults/main.yml index 14787a62b..ee265bb14 100644 --- a/roles/openshift_logging_kibana/defaults/main.yml +++ b/roles/openshift_logging_kibana/defaults/main.yml @@ -2,8 +2,8 @@ ### Common settings openshift_logging_kibana_master_url: "https://kubernetes.default.svc.cluster.local" openshift_logging_kibana_master_public_url: "https://kubernetes.default.svc.cluster.local" -openshift_logging_kibana_image_prefix: "{{ openshift_hosted_logging_deployer_prefix | default('docker.io/openshift/origin-') }}" -openshift_logging_kibana_image_version: "{{ openshift_hosted_logging_deployer_version | default('latest') }}" +openshift_logging_kibana_image_prefix: "{{ openshift_logging_image_prefix | default(__openshift_logging_image_prefix) }}" +openshift_logging_kibana_image_version: "{{ openshift_logging_image_version | default('latest') }}" openshift_logging_kibana_image_pull_secret: "{{ openshift_hosted_logging_image_pull_secret | default('') }}" openshift_logging_kibana_namespace: logging @@ -24,6 +24,8 @@ openshift_logging_kibana_edge_term_policy: Redirect openshift_logging_kibana_ops_deployment: false # Proxy settings +openshift_logging_kibana_proxy_image_prefix: "{{ openshift_logging_image_prefix | default(__openshift_logging_image_prefix) }}" +openshift_logging_kibana_proxy_image_version: "{{ openshift_logging_image_version | default('latest') }}" openshift_logging_kibana_proxy_debug: false openshift_logging_kibana_proxy_cpu_limit: null openshift_logging_kibana_proxy_memory_limit: 256Mi diff --git a/roles/openshift_logging_kibana/tasks/main.yaml b/roles/openshift_logging_kibana/tasks/main.yaml index 166f102f7..e17e8c1f2 100644 --- a/roles/openshift_logging_kibana/tasks/main.yaml +++ b/roles/openshift_logging_kibana/tasks/main.yaml @@ -225,8 +225,8 @@ component: "{{ kibana_component }}" logging_component: kibana deploy_name: "{{ kibana_name }}" - image: "{{ openshift_logging_image_prefix }}logging-kibana:{{ openshift_logging_image_version }}" - proxy_image: "{{ openshift_logging_image_prefix }}logging-auth-proxy:{{ openshift_logging_image_version }}" + image: "{{ openshift_logging_kibana_image_prefix }}logging-kibana:{{ openshift_logging_kibana_image_version }}" + proxy_image: "{{ openshift_logging_kibana_proxy_image_prefix }}logging-auth-proxy:{{ openshift_logging_kibana_proxy_image_version }}" es_host: "{{ openshift_logging_kibana_es_host }}" es_port: "{{ openshift_logging_kibana_es_port }}" kibana_cpu_limit: "{{ openshift_logging_kibana_cpu_limit }}" diff --git a/roles/openshift_logging_mux/defaults/main.yml b/roles/openshift_logging_mux/defaults/main.yml index 7a3da9b4c..68412aec8 100644 --- a/roles/openshift_logging_mux/defaults/main.yml +++ b/roles/openshift_logging_mux/defaults/main.yml @@ -1,7 +1,7 @@ --- ### General logging settings -openshift_logging_mux_image_prefix: "{{ openshift_hosted_logging_deployer_prefix | default('docker.io/openshift/origin-') }}" -openshift_logging_mux_image_version: "{{ openshift_hosted_logging_deployer_version | default('latest') }}" +openshift_logging_mux_image_prefix: "{{ openshift_logging_image_prefix | default(__openshift_logging_image_prefix) }}" +openshift_logging_mux_image_version: "{{ openshift_logging_image_version | default('latest') }}" openshift_logging_mux_image_pull_secret: "{{ openshift_hosted_logging_image_pull_secret | default('') }}" openshift_logging_mux_master_url: "https://kubernetes.default.svc.{{ openshift.common.dns_domain }}" openshift_logging_mux_master_public_url: "{{ openshift_hosted_logging_master_public_url | default('https://' + openshift.common.public_hostname + ':' ~ (openshift_master_api_port | default('8443', true))) }}" diff --git a/roles/openshift_logging_mux/tasks/main.yaml b/roles/openshift_logging_mux/tasks/main.yaml index 8ec93de7d..2ec863afa 100644 --- a/roles/openshift_logging_mux/tasks/main.yaml +++ b/roles/openshift_logging_mux/tasks/main.yaml @@ -165,7 +165,7 @@ component: mux logging_component: mux deploy_name: "logging-{{ component }}" - image: "{{ openshift_logging_image_prefix }}logging-fluentd:{{ openshift_logging_image_version }}" + image: "{{ openshift_logging_mux_image_prefix }}logging-fluentd:{{ openshift_logging_mux_image_version }}" es_host: "{{ openshift_logging_mux_app_host }}" es_port: "{{ openshift_logging_mux_app_port }}" ops_host: "{{ openshift_logging_mux_ops_host }}" diff --git a/roles/openshift_master/defaults/main.yml b/roles/openshift_master/defaults/main.yml index a4c178908..d70106276 100644 --- a/roles/openshift_master/defaults/main.yml +++ b/roles/openshift_master/defaults/main.yml @@ -1,6 +1,6 @@ --- -r_openshift_master_firewall_enabled: True -r_openshift_master_use_firewalld: False +r_openshift_master_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_openshift_master_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" openshift_node_ips: [] r_openshift_master_clean_install: false @@ -19,3 +19,8 @@ r_openshift_master_os_firewall_allow: - service: etcd embedded port: 4001/tcp cond: "{{ groups.oo_etcd_to_config | default([]) | length == 0 }}" + +oreg_url: '' +oreg_host: "{{ oreg_url.split('/')[0] if '.' in oreg_url.split('/')[0] else '' }}" +oreg_auth_credentials_path: "{{ openshift.common.data_dir }}/.docker" +oreg_auth_credentials_replace: False diff --git a/roles/openshift_master/tasks/main.yml b/roles/openshift_master/tasks/main.yml index b80941b48..a06defdb9 100644 --- a/roles/openshift_master/tasks/main.yml +++ b/roles/openshift_master/tasks/main.yml @@ -177,9 +177,6 @@ local_facts: no_proxy_etcd_host_ips: "{{ openshift_no_proxy_etcd_host_ips }}" -- name: Remove the legacy master service if it exists - include: clean_systemd_units.yml - - name: Install the systemd units include: systemd_units.yml @@ -232,6 +229,22 @@ - restart master controllers when: openshift_master_bootstrap_enabled | default(False) +- name: Check for credentials file for registry auth + stat: + path: "{{oreg_auth_credentials_path }}" + when: + - oreg_auth_user is defined + register: master_oreg_auth_credentials_stat + +- name: Create credentials for registry auth + command: "docker --config={{ oreg_auth_credentials_path }} login -u {{ oreg_auth_user }} -p {{ oreg_auth_password }} {{ oreg_host }}" + when: + - oreg_auth_user is defined + - (not master_oreg_auth_credentials_stat.stat.exists or oreg_auth_credentials_replace) | bool + notify: + - restart master api + - restart master controllers + - include: set_loopback_context.yml when: - openshift.common.version_gte_3_2_or_1_2 diff --git a/roles/openshift_master/tasks/systemd_units.yml b/roles/openshift_master/tasks/systemd_units.yml index 72c231e52..c480d8223 100644 --- a/roles/openshift_master/tasks/systemd_units.yml +++ b/roles/openshift_master/tasks/systemd_units.yml @@ -3,6 +3,16 @@ # playbooks. For that reason the ha_svc variables are use set_fact instead of # the vars directory on the role. +# This play may be consumed outside the role, we need to ensure that +# openshift_master_config_dir is set. +- name: Set openshift_master_config_dir if unset + set_fact: + openshift_master_config_dir: '/etc/origin/master' + when: openshift_master_config_dir is not defined + +- name: Remove the legacy master service if it exists + include: clean_systemd_units.yml + - name: Init HA Service Info set_fact: containerized_svc_dir: "/usr/lib/systemd/system" diff --git a/roles/openshift_node/defaults/main.yml b/roles/openshift_node/defaults/main.yml index 973b3a619..a7dad5b1f 100644 --- a/roles/openshift_node/defaults/main.yml +++ b/roles/openshift_node/defaults/main.yml @@ -1,6 +1,64 @@ --- -r_openshift_node_firewall_enabled: True -r_openshift_node_use_firewalld: False +r_openshift_node_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_openshift_node_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" + +openshift_service_type: "{{ openshift.common.service_type }}" + +openshift_image_tag: '' + +openshift_node_ami_prep_packages: +- "{{ openshift_service_type }}-master" +- "{{ openshift_service_type }}-node" +- "{{ openshift_service_type }}-docker-excluder" +- "{{ openshift_service_type }}-sdn-ovs" +- ansible +- openvswitch +- docker +- etcd +#- pcs +- haproxy +- dnsmasq +- ntp +- logrotate +- httpd-tools +- bind +- firewalld +- libselinux-python +- conntrack-tools +- openssl +- cloud-init +- iproute +- python-dbus +- PyYAML +- yum-utils +- python2-boto +- python2-boto3 +- cloud-utils-growpart +# gluster +- glusterfs-fuse +- heketi-client +# nfs +- nfs-utils +- flannel +- bash-completion +# cockpit +- cockpit-ws +- cockpit-system +- cockpit-bridge +- cockpit-docker +# iscsi +- iscsi-initiator-utils +# ceph +- ceph-common +# systemcontainer +# - runc +# - container-selinux +# - atomic +# +openshift_deployment_type: origin + +openshift_node_bootstrap: False + r_openshift_node_os_firewall_deny: [] r_openshift_node_os_firewall_allow: - service: Kubernetes kubelet @@ -21,3 +79,8 @@ r_openshift_node_os_firewall_allow: - service: Kubernetes service NodePort UDP port: "{{ openshift_node_port_range | default('') }}/udp" cond: "{{ openshift_node_port_range is defined }}" + +oreg_url: '' +oreg_host: "{{ oreg_url.split('/')[0] if '.' in oreg_url.split('/')[0] else '' }}" +oreg_auth_credentials_path: "{{ openshift.common.data_dir }}/.docker" +oreg_auth_credentials_replace: False diff --git a/roles/openshift_node/handlers/main.yml b/roles/openshift_node/handlers/main.yml index f2c45a4bd..14ba48aba 100644 --- a/roles/openshift_node/handlers/main.yml +++ b/roles/openshift_node/handlers/main.yml @@ -27,6 +27,7 @@ when: - (not skip_node_svc_handlers | default(False) | bool) - not (node_service_status_changed | default(false) | bool) + - not openshift_node_bootstrap - name: reload sysctl.conf command: /sbin/sysctl -p diff --git a/roles/openshift_node/meta/main.yml b/roles/openshift_node/meta/main.yml index 06373de04..3db980514 100644 --- a/roles/openshift_node/meta/main.yml +++ b/roles/openshift_node/meta/main.yml @@ -19,6 +19,7 @@ dependencies: - role: openshift_clock - role: openshift_docker - role: openshift_node_certificates + when: not openshift_node_bootstrap - role: openshift_cloud_provider - role: openshift_node_dnsmasq when: openshift.common.use_dnsmasq | bool diff --git a/roles/openshift_node/tasks/bootstrap.yml b/roles/openshift_node/tasks/bootstrap.yml new file mode 100644 index 000000000..cb1440283 --- /dev/null +++ b/roles/openshift_node/tasks/bootstrap.yml @@ -0,0 +1,55 @@ +--- +- name: install needed rpm(s) + package: + name: "{{ item }}" + state: present + with_items: "{{ openshift_node_ami_prep_packages }}" + +- name: create the directory for node + file: + state: directory + path: "/etc/systemd/system/{{ openshift_service_type }}-node.service.d" + +- name: laydown systemd override + copy: + dest: "/etc/systemd/system/{{ openshift_service_type }}-node.service.d/override.conf" + content: | + [Unit] + After=cloud-init.service + +- name: update the sysconfig to have KUBECONFIG + lineinfile: + dest: "/etc/sysconfig/{{ openshift_service_type }}-node" + line: "KUBECONFIG=/root/csr_kubeconfig" + regexp: "^KUBECONFIG=.*" + +- name: update the ExecStart to have bootstrap + lineinfile: + dest: "/usr/lib/systemd/system/{{ openshift_service_type }}-node.service" + line: "{% raw %}ExecStart=/usr/bin/openshift start node --bootstrap --kubeconfig=${KUBECONFIG} $OPTIONS{% endraw %}" + regexp: "^ExecStart=.*" + +- name: "systemctl enable {{ openshift_service_type }}-node" + systemd: + name: "{{ item }}" + enabled: no + with_items: + - "{{ openshift_service_type }}-node.service" + - "{{ openshift_service_type }}-master.service" + +- 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 + - openshift_deployment_type in ['openshift-enterprise', 'atomic-enterprise'] + with_items: + - master + - node + - .config_managed diff --git a/roles/openshift_node/tasks/config.yml b/roles/openshift_node/tasks/config.yml new file mode 100644 index 000000000..8210fd881 --- /dev/null +++ b/roles/openshift_node/tasks/config.yml @@ -0,0 +1,111 @@ +--- +- name: Install the systemd units + include: systemd_units.yml + +- name: Check for tuned package + command: rpm -q tuned + args: + warn: no + register: tuned_installed + changed_when: false + failed_when: false + +- name: Set atomic-guest tuned profile + command: "tuned-adm profile atomic-guest" + when: tuned_installed.rc == 0 and openshift.common.is_atomic | bool + +- name: Start and enable openvswitch service + systemd: + name: openvswitch.service + enabled: yes + state: started + daemon_reload: yes + when: + - openshift.common.is_containerized | bool + - openshift.common.use_openshift_sdn | default(true) | bool + register: ovs_start_result + until: not ovs_start_result | failed + retries: 3 + delay: 30 + +- set_fact: + ovs_service_status_changed: "{{ ovs_start_result | changed }}" + +- file: + dest: "{{ (openshift_node_kubelet_args|default({'config':None})).config}}" + state: directory + when: openshift_node_kubelet_args is defined and 'config' in openshift_node_kubelet_args + +# TODO: add the validate parameter when there is a validation command to run +- name: Create the Node config + template: + dest: "{{ openshift.common.config_base }}/node/node-config.yaml" + src: node.yaml.v1.j2 + backup: true + owner: root + group: root + mode: 0600 + notify: + - restart node + +- name: Configure Node Environment Variables + lineinfile: + dest: /etc/sysconfig/{{ openshift.common.service_type }}-node + regexp: "^{{ item.key }}=" + line: "{{ item.key }}={{ item.value }}" + create: true + with_dict: "{{ openshift.node.env_vars | default({}) }}" + notify: + - restart node + +# 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 +- when: openshift.common.is_containerized | bool + block: + - 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 --cacert {{ openshift.common.config_base }}/node/ca.crt + {{ openshift_node_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: Start and enable node dep + systemd: + daemon_reload: yes + name: "{{ openshift.common.service_type }}-node-dep" + enabled: yes + state: started + +- name: Start and enable node + systemd: + name: "{{ openshift.common.service_type }}-node" + enabled: yes + state: started + daemon_reload: yes + register: node_start_result + until: not node_start_result | failed + retries: 1 + delay: 30 + ignore_errors: true + +- name: Dump logs from node service if it failed + command: journalctl --no-pager -n 100 -u {{ openshift.common.service_type }}-node + when: node_start_result | failed + +- name: Abort if node failed to start + fail: + msg: Node failed to start please inspect the logs and try again + when: node_start_result | failed + +- set_fact: + node_service_status_changed: "{{ node_start_result | changed }}" diff --git a/roles/openshift_node/tasks/install.yml b/roles/openshift_node/tasks/install.yml new file mode 100644 index 000000000..9bf4ed879 --- /dev/null +++ b/roles/openshift_node/tasks/install.yml @@ -0,0 +1,33 @@ +--- +# We have to add tuned-profiles in the same transaction otherwise we run into depsolving +# problems because the rpms don't pin the version properly. This was fixed in 3.1 packaging. +- when: not openshift.common.is_containerized | bool + block: + - name: Install Node package + package: + name: "{{ openshift.common.service_type }}-node{{ openshift_pkg_version | default('') | oo_image_tag_to_rpm_version(include_dash=True) }},tuned-profiles-{{ openshift.common.service_type }}-node{{ openshift_pkg_version | default('') | oo_image_tag_to_rpm_version(include_dash=True) }}" + state: present + + - name: Install sdn-ovs package + package: + name: "{{ openshift.common.service_type }}-sdn-ovs{{ openshift_pkg_version | oo_image_tag_to_rpm_version(include_dash=True) }}" + state: present + when: + - openshift.common.use_openshift_sdn | default(true) | bool + + - name: Install conntrack-tools package + package: + name: "conntrack-tools" + state: present + +- when: + - openshift.common.is_containerized | bool + - not openshift.common.is_node_system_container | bool + block: + - name: Pre-pull node image when containerized + command: > + docker pull {{ openshift.node.node_image }}:{{ openshift_image_tag }} + register: pull_result + changed_when: "'Downloaded newer image' in pull_result.stdout" + + - include: config/install-node-docker-service-file.yml diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml index 3353a22e3..60a25dcc6 100644 --- a/roles/openshift_node/tasks/main.yml +++ b/roles/openshift_node/tasks/main.yml @@ -1,43 +1,15 @@ --- -# TODO: allow for overriding default ports where possible - fail: msg: "SELinux is disabled, This deployment type requires that SELinux is enabled." when: - (not ansible_selinux or ansible_selinux.status != 'enabled') and deployment_type in ['enterprise', 'online', 'atomic-enterprise', 'openshift-enterprise'] - - not openshift_docker_use_crio | default(false) + - not openshift_use_crio | default(false) - name: setup firewall include: firewall.yml static: yes -- name: Set node facts - openshift_facts: - role: "{{ item.role }}" - local_facts: "{{ item.local_facts }}" - with_items: - # Reset node labels to an empty dictionary. - - role: node - local_facts: - labels: {} - - role: node - local_facts: - annotations: "{{ openshift_node_annotations | default(none) }}" - debug_level: "{{ openshift_node_debug_level | default(openshift.common.debug_level) }}" - iptables_sync_period: "{{ openshift_node_iptables_sync_period | default(None) }}" - kubelet_args: "{{ openshift_node_kubelet_args | default(None) }}" - labels: "{{ lookup('oo_option', 'openshift_node_labels') | default( openshift_node_labels | default(none), true) }}" - registry_url: "{{ oreg_url_node | default(oreg_url) | default(None) }}" - schedulable: "{{ openshift_schedulable | default(openshift_scheduleable) | default(None) }}" - sdn_mtu: "{{ openshift_node_sdn_mtu | default(None) }}" - storage_plugin_deps: "{{ osn_storage_plugin_deps | default(None) }}" - set_node_ip: "{{ openshift_set_node_ip | default(None) }}" - node_image: "{{ osn_image | default(None) }}" - ovs_image: "{{ osn_ovs_image | default(None) }}" - proxy_mode: "{{ openshift_node_proxy_mode | default('iptables') }}" - local_quota_per_fsgroup: "{{ openshift_node_local_quota_per_fsgroup | default(None) }}" - dns_ip: "{{ openshift_dns_ip | default(none) | get_dns_ip(hostvars[inventory_hostname])}}" - env_vars: "{{ openshift_node_env_vars | default(None) }}" - +#### Disable SWAP ##### # https://docs.openshift.com/container-platform/3.4/admin_guide/overcommit.html#disabling-swap-memory - name: Check for swap usage command: grep "^[^#].*swap" /etc/fstab @@ -46,9 +18,10 @@ failed_when: false register: swap_result -# Disable Swap Block -- block: - +- when: + - swap_result.stdout_lines | length > 0 + - openshift_disable_swap | default(true) | bool + block: - name: Disable swap command: swapoff --all @@ -64,55 +37,17 @@ dest: /etc/fstab line: '# OpenShift-Ansible Installer disabled swap per overcommit guidelines' state: present +#### End Disable Swap Block #### - when: - - swap_result.stdout_lines | length > 0 - - openshift_disable_swap | default(true) | bool -# End Disable Swap Block - -# We have to add tuned-profiles in the same transaction otherwise we run into depsolving -# problems because the rpms don't pin the version properly. This was fixed in 3.1 packaging. -- name: Install Node package - package: - name: "{{ openshift.common.service_type }}-node{{ openshift_pkg_version | default('') | oo_image_tag_to_rpm_version(include_dash=True) }},tuned-profiles-{{ openshift.common.service_type }}-node{{ openshift_pkg_version | default('') | oo_image_tag_to_rpm_version(include_dash=True) }}" - state: present - when: not openshift.common.is_containerized | bool - -- name: Check for tuned package - command: rpm -q tuned - args: - warn: no - register: tuned_installed - changed_when: false - failed_when: false - -- name: Set atomic-guest tuned profile - command: "tuned-adm profile atomic-guest" - when: tuned_installed.rc == 0 and openshift.common.is_atomic | bool - -- name: Install sdn-ovs package - package: - name: "{{ openshift.common.service_type }}-sdn-ovs{{ openshift_pkg_version | oo_image_tag_to_rpm_version(include_dash=True) }}" - state: present - when: - - openshift.common.use_openshift_sdn | default(true) | bool - - not openshift.common.is_containerized | bool +- name: include node installer + include: install.yml - name: Restart cri-o systemd: name: cri-o enabled: yes state: restarted - when: openshift_docker_use_crio | default(false) - -- name: Install conntrack-tools package - package: - name: "conntrack-tools" - state: present - when: not openshift.common.is_containerized | bool - -- name: Install the systemd units - include: systemd_units.yml + when: openshift_use_crio | default(false) # The atomic-openshift-node service will set this parameter on # startup, but if the network service is restarted this setting is @@ -126,37 +61,26 @@ notify: - reload sysctl.conf -- name: Start and enable openvswitch service - systemd: - name: openvswitch.service - enabled: yes - state: started - daemon_reload: yes - when: - - openshift.common.is_containerized | bool - - openshift.common.use_openshift_sdn | default(true) | bool - register: ovs_start_result - until: not ovs_start_result | failed - retries: 3 - delay: 30 +- name: include bootstrap node config + include: bootstrap.yml + when: openshift_node_bootstrap -- set_fact: - ovs_service_status_changed: "{{ ovs_start_result | changed }}" +- name: include standard node config + include: config.yml + when: not openshift_node_bootstrap -- file: - dest: "{{ (openshift_node_kubelet_args|default({'config':None})).config}}" - state: directory - when: openshift_node_kubelet_args is defined and 'config' in openshift_node_kubelet_args +- name: Check for credentials file for registry auth + stat: + path: "{{oreg_auth_credentials_path }}" + when: + - oreg_auth_user is defined + register: node_oreg_auth_credentials_stat -# TODO: add the validate parameter when there is a validation command to run -- name: Create the Node config - template: - dest: "{{ openshift.common.config_base }}/node/node-config.yaml" - src: node.yaml.v1.j2 - backup: true - owner: root - group: root - mode: 0600 +- name: Create credentials for registry auth + command: "docker --config={{ oreg_auth_credentials_path }} login -u {{ oreg_auth_user }} -p {{ oreg_auth_password }} {{ oreg_host }}" + when: + - oreg_auth_user is defined + - (not node_oreg_auth_credentials_stat.stat.exists or oreg_auth_credentials_replace) | bool notify: - restart node @@ -176,16 +100,7 @@ notify: - restart node -- name: Configure Node Environment Variables - lineinfile: - dest: /etc/sysconfig/{{ openshift.common.service_type }}-node - regexp: "^{{ item.key }}=" - line: "{{ item.key }}={{ item.value }}" - create: true - with_dict: "{{ openshift.node.env_vars | default({}) }}" - notify: - - restart node - +#### Storage class plugins here #### - name: NFS storage plugin configuration include: storage_plugins/nfs.yml tags: @@ -203,55 +118,7 @@ include: storage_plugins/iscsi.yml when: "'iscsi' in openshift.node.storage_plugin_deps" -# 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 --cacert {{ openshift.common.config_base }}/node/ca.crt - {{ openshift_node_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 - -- name: Start and enable node dep - systemd: - daemon_reload: yes - name: "{{ openshift.common.service_type }}-node-dep" - enabled: yes - state: started - when: openshift.common.is_containerized | bool - - -- name: Start and enable node - systemd: - name: "{{ openshift.common.service_type }}-node" - enabled: yes - state: started - daemon_reload: yes - register: node_start_result - until: not node_start_result | failed - retries: 1 - delay: 30 - ignore_errors: true - -- name: Dump logs from node service if it failed - command: journalctl --no-pager -n 100 -u {{ openshift.common.service_type }}-node - when: node_start_result | failed - -- name: Abort if node failed to start - fail: - msg: Node failed to start please inspect the logs and try again - when: node_start_result | failed +##### END Storage ##### -- set_fact: - node_service_status_changed: "{{ node_start_result | changed }}" +- include: config/workaround-bz1331590-ovs-oom-fix.yml + when: openshift.common.use_openshift_sdn | default(true) | bool diff --git a/roles/openshift_node/tasks/openvswitch_system_container.yml b/roles/openshift_node/tasks/openvswitch_system_container.yml index dc1df9185..e09063aa5 100644 --- a/roles/openshift_node/tasks/openvswitch_system_container.yml +++ b/roles/openshift_node/tasks/openvswitch_system_container.yml @@ -1,6 +1,6 @@ --- - set_fact: - l_use_crio: "{{ openshift_docker_use_crio | default(false) }}" + l_use_crio: "{{ openshift_use_crio | default(false) }}" - set_fact: l_service_name: "cri-o" diff --git a/roles/openshift_node/tasks/systemd_units.yml b/roles/openshift_node/tasks/systemd_units.yml index b86bb1549..4687400cd 100644 --- a/roles/openshift_node/tasks/systemd_units.yml +++ b/roles/openshift_node/tasks/systemd_units.yml @@ -1,22 +1,6 @@ --- # This file is included both in the openshift_master role and in the upgrade # playbooks. - -- include: config/install-node-deps-docker-service-file.yml - when: openshift.common.is_containerized | bool - -- block: - - name: Pre-pull node image - command: > - docker pull {{ openshift.node.node_image }}:{{ openshift_image_tag }} - register: pull_result - changed_when: "'Downloaded newer image' in pull_result.stdout" - - - include: config/install-node-docker-service-file.yml - when: - - openshift.common.is_containerized | bool - - not openshift.common.is_node_system_container | bool - - name: Install Node service file template: dest: "/etc/systemd/system/{{ openshift.common.service_type }}-node.service" @@ -26,24 +10,24 @@ - reload systemd units - restart node -- include: config/install-ovs-service-env-file.yml - when: openshift.common.is_containerized | bool +- when: openshift.common.is_containerized | bool + block: + - name: include node deps docker service file + include: config/install-node-deps-docker-service-file.yml -- name: Install Node system container - include: node_system_container.yml - when: - - openshift.common.is_containerized | bool - - openshift.common.is_node_system_container | bool + - name: include ovs service environment file + include: config/install-ovs-service-env-file.yml -- name: Install OpenvSwitch system containers - include: openvswitch_system_container.yml - when: - - openshift.common.use_openshift_sdn | default(true) | bool - - openshift.common.is_containerized | bool - - openshift.common.is_openvswitch_system_container | bool + - name: Install Node system container + include: node_system_container.yml + when: + - openshift.common.is_node_system_container | bool -- include: config/workaround-bz1331590-ovs-oom-fix.yml - when: openshift.common.use_openshift_sdn | default(true) | bool + - name: Install OpenvSwitch system containers + include: openvswitch_system_container.yml + when: + - openshift.common.use_openshift_sdn | default(true) | bool + - openshift.common.is_openvswitch_system_container | bool - block: - name: Pre-pull openvswitch image diff --git a/roles/openshift_node/tasks/tuned.yml b/roles/openshift_node/tasks/tuned.yml new file mode 100644 index 000000000..425bf6a26 --- /dev/null +++ b/roles/openshift_node/tasks/tuned.yml @@ -0,0 +1,41 @@ +--- +- name: Check for tuned package + command: rpm -q tuned + args: + warn: no + register: tuned_installed + changed_when: false + failed_when: false + +- name: Tuned service setup + block: + - name: Set tuned OpenShift variables + set_fact: + openshift_tuned_guest_profile: "{{ 'atomic-guest' if openshift.common.is_atomic else 'virtual-guest' }}" + tuned_etc_directory: '/etc/tuned' + tuned_templates_source: '../templates/tuned' + + - name: Ensure directory structure exists + file: + state: directory + dest: '{{ tuned_etc_directory }}/{{ item.path }}' + with_filetree: '{{ tuned_templates_source }}' + when: item.state == 'directory' + + - name: Ensure files are populated from templates + template: + src: '{{ item.src }}' + dest: '{{ tuned_etc_directory }}/{{ item.path }}' + with_filetree: '{{ tuned_templates_source }}' + when: item.state == 'file' + + - name: Make tuned use the recommended tuned profile on restart + file: path=/etc/tuned/active_profile state=absent + + - name: Restart tuned service + systemd: + state: restarted + daemon_reload: yes + name: tuned + + when: tuned_installed.rc == 0 | bool diff --git a/roles/openshift_node/templates/node.service.j2 b/roles/openshift_node/templates/node.service.j2 index 3d0ae3bbd..0856737f6 100644 --- a/roles/openshift_node/templates/node.service.j2 +++ b/roles/openshift_node/templates/node.service.j2 @@ -8,7 +8,7 @@ Wants={{ openshift.docker.service_name }}.service Documentation=https://github.com/openshift/origin Requires=dnsmasq.service After=dnsmasq.service -{% if openshift.docker.use_crio %}Wants=cri-o.service{% endif %} +{% if openshift_use_crio|default(false) %}Wants=cri-o.service{% endif %} [Service] Type=notify diff --git a/roles/openshift_node/templates/node.yaml.v1.j2 b/roles/openshift_node/templates/node.yaml.v1.j2 index 93f8658b4..f59aa6fb4 100644 --- a/roles/openshift_node/templates/node.yaml.v1.j2 +++ b/roles/openshift_node/templates/node.yaml.v1.j2 @@ -16,13 +16,11 @@ imageConfig: latest: false kind: NodeConfig kubeletArguments: {{ openshift.node.kubelet_args | default(None) | to_padded_yaml(level=1) }} -{% if openshift.docker.use_crio | default(False) %} +{% if openshift_use_crio | default(False) %} container-runtime: - remote container-runtime-endpoint: - /var/run/crio.sock - experimental-cri: - - 'true' image-service-endpoint: - /var/run/crio.sock node-labels: diff --git a/roles/openshift_node/templates/openshift.docker.node.dep.service b/roles/openshift_node/templates/openshift.docker.node.dep.service index c4580be1f..8734e7443 100644 --- a/roles/openshift_node/templates/openshift.docker.node.dep.service +++ b/roles/openshift_node/templates/openshift.docker.node.dep.service @@ -3,7 +3,7 @@ Requires={{ openshift.docker.service_name }}.service After={{ openshift.docker.service_name }}.service PartOf={{ openshift.common.service_type }}-node.service Before={{ openshift.common.service_type }}-node.service -{% if openshift.docker.use_crio %}Wants=cri-o.service{% endif %} +{% if openshift_use_crio|default(false) %}Wants=cri-o.service{% endif %} [Service] ExecStart=/bin/bash -c "if [[ -f /usr/bin/docker-current ]]; then echo \"DOCKER_ADDTL_BIND_MOUNTS=--volume=/usr/bin/docker-current:/usr/bin/docker-current:ro --volume=/etc/sysconfig/docker:/etc/sysconfig/docker:ro\" > /etc/sysconfig/{{ openshift.common.service_type }}-node-dep; else echo \"#DOCKER_ADDTL_BIND_MOUNTS=\" > /etc/sysconfig/{{ openshift.common.service_type }}-node-dep; fi" diff --git a/roles/openshift_node_certificates/defaults/main.yml b/roles/openshift_node_certificates/defaults/main.yml index 70a38b844..455f26f30 100644 --- a/roles/openshift_node_certificates/defaults/main.yml +++ b/roles/openshift_node_certificates/defaults/main.yml @@ -1,2 +1,3 @@ --- openshift_node_cert_expire_days: 730 +openshift_ca_host: '' diff --git a/roles/openshift_node_dnsmasq/tasks/main.yml b/roles/openshift_node_dnsmasq/tasks/main.yml index d0221a94b..9bbaafc29 100644 --- a/roles/openshift_node_dnsmasq/tasks/main.yml +++ b/roles/openshift_node_dnsmasq/tasks/main.yml @@ -14,6 +14,17 @@ package: name=dnsmasq state=installed when: not openshift.common.is_atomic | bool +- name: ensure origin/node directory exists + file: + state: directory + path: "{{ item }}" + owner: root + group: root + mode: '0700' + with_items: + - /etc/origin + - /etc/origin/node + # this file is copied to /etc/dnsmasq.d/ when the node starts and is removed # when the node stops. A dbus-message is sent to dnsmasq to add the same entries # so that dnsmasq doesn't need to be restarted. Once we can use dnsmasq 2.77 or diff --git a/roles/openshift_prometheus/README.md b/roles/openshift_prometheus/README.md new file mode 100644 index 000000000..c5a44bffb --- /dev/null +++ b/roles/openshift_prometheus/README.md @@ -0,0 +1,95 @@ +OpenShift Prometheus +==================== + +OpenShift Prometheus Installation + +Requirements +------------ + + +Role Variables +-------------- + +For default values, see [`defaults/main.yaml`](defaults/main.yaml). + +- `openshift_prometheus_state`: present - install/update. absent - uninstall. + +- `openshift_prometheus_namespace`: project (i.e. namespace) where the components will be + deployed. + +- `openshift_prometheus_replicas`: The number of replicas for prometheus deployment. + +- `openshift_prometheus_node_selector`: Selector for the nodes prometheus will be deployed on. + +- `openshift_prometheus_image_<COMPONENT>`: specify image for the component + +## Storage related variables +Each prometheus component (prometheus, alertmanager, alert-buffer, oauth-proxy) can set pv claim by setting corresponding role variable: +``` +openshift_prometheus_<COMPONENT>_storage_type: <VALUE> +openshift_prometheus_<COMPONENT>_pvc_(name|size|access_modes|pv_selector): <VALUE> +``` +e.g +``` +openshift_prometheus_storage_type: pvc +openshift_prometheus_alertmanager_pvc_name: alertmanager +openshift_prometheus_alertbuffer_pvc_size: 10G +openshift_prometheus_pvc_access_modes: [ReadWriteOnce] +``` + +## Additional Alert Rules file variable +An external file with alert rules can be added by setting path to additional rules variable: +``` +openshift_prometheus_additional_rules_file: <PATH> +``` + +File content should be in prometheus alert rules format. +Following example sets rule to fire an alert when one of the cluster nodes is down: + +``` +groups: +- name: example-rules + interval: 30s # defaults to global interval + rules: + - alert: Node Down + expr: up{job="kubernetes-nodes"} == 0 + annotations: + miqTarget: "ContainerNode" + severity: "HIGH" + message: "{{ '{{' }}{{ '$labels.instance' }}{{ '}}' }} is down" +``` + + +## Additional variables to control resource limits +Each prometheus component (prometheus, alertmanager, alert-buffer, oauth-proxy) can specify a cpu and memory limits and requests by setting +the corresponding role variable: +``` +openshift_prometheus_<COMPONENT>_(limits|requests)_(memory|cpu): <VALUE> +``` +e.g +``` +openshift_prometheus_alertmanager_limits_memory: 1Gi +openshift_prometheus_oath_proxy_requests_cpu: 100 +``` + +Dependencies +------------ + +openshift_facts + + +Example Playbook +---------------- + +``` +- name: Configure openshift-prometheus + hosts: oo_first_master + roles: + - role: openshift_prometheus +``` + +License +------- + +Apache License, Version 2.0 + diff --git a/roles/openshift_prometheus/defaults/main.yaml b/roles/openshift_prometheus/defaults/main.yaml new file mode 100644 index 000000000..18d6a1645 --- /dev/null +++ b/roles/openshift_prometheus/defaults/main.yaml @@ -0,0 +1,74 @@ +--- +# defaults file for openshift_prometheus +openshift_prometheus_state: present + +openshift_prometheus_namespace: prometheus + +openshift_prometheus_replicas: 1 +openshift_prometheus_node_selector: {"region":"infra"} + +# images +openshift_prometheus_image_proxy: "openshift/oauth-proxy:v1.0.0" +openshift_prometheus_image_prometheus: "openshift/prometheus:v2.0.0-dev" +openshift_prometheus_image_alertmanager: "openshift/prometheus-alertmanager:dev" +openshift_prometheus_image_alertbuffer: "ilackarms/message-buffer" + +# additional prometheus rules file +openshift_prometheus_additional_rules_file: null + +# All the required exports +openshift_prometheus_pv_exports: + - prometheus + - prometheus-alertmanager + - prometheus-alertbuffer +# PV template files and their created object names +openshift_prometheus_pv_data: + - pv_name: prometheus + pv_template: prom-pv-server.yml + pv_label: Prometheus Server PV + - pv_name: prometheus-alertmanager + pv_template: prom-pv-alertmanager.yml + pv_label: Prometheus Alertmanager PV + - pv_name: prometheus-alertbuffer + pv_template: prom-pv-alertbuffer.yml + pv_label: Prometheus Alert Buffer PV + +# Hostname/IP of the NFS server. Currently defaults to first master +openshift_prometheus_nfs_server: "{{ groups.nfs.0 }}" + +# storage +openshift_prometheus_storage_type: pvc +openshift_prometheus_pvc_name: prometheus +openshift_prometheus_pvc_size: 10G +openshift_prometheus_pvc_access_modes: [ReadWriteOnce] +openshift_prometheus_pvc_pv_selector: {} + +openshift_prometheus_alertmanager_storage_type: pvc +openshift_prometheus_alertmanager_pvc_name: prometheus-alertmanager +openshift_prometheus_alertmanager_pvc_size: 10G +openshift_prometheus_alertmanager_pvc_access_modes: [ReadWriteOnce] +openshift_prometheus_alertmanager_pvc_pv_selector: {} + +openshift_prometheus_alertbuffer_storage_type: pvc +openshift_prometheus_alertbuffer_pvc_name: prometheus-alertbuffer +openshift_prometheus_alertbuffer_pvc_size: 10G +openshift_prometheus_alertbuffer_pvc_access_modes: [ReadWriteOnce] +openshift_prometheus_alertbuffer_pvc_pv_selector: {} + +# container resources +openshift_prometheus_cpu_limit: null +openshift_prometheus_memory_limit: null +openshift_prometheus_cpu_requests: null +openshift_prometheus_memory_requests: null +openshift_prometheus_alertmanager_cpu_limit: null +openshift_prometheus_alertmanager_memory_limit: null +openshift_prometheus_alertmanager_cpu_requests: null +openshift_prometheus_alertmanager_memory_requests: null +openshift_prometheus_alertbuffer_cpu_limit: null +openshift_prometheus_alertbuffer_memory_limit: null +openshift_prometheus_alertbuffer_cpu_requests: null +openshift_prometheus_alertbuffer_memory_requests: null +openshift_prometheus_oauth_proxy_cpu_limit: null +openshift_prometheus_oauth_proxy_memory_limit: null +openshift_prometheus_oauth_proxy_cpu_requests: null +openshift_prometheus_oauth_proxy_memory_requests: null diff --git a/roles/openshift_prometheus/files/openshift_prometheus.exports b/roles/openshift_prometheus/files/openshift_prometheus.exports new file mode 100644 index 000000000..3ccedb1fd --- /dev/null +++ b/roles/openshift_prometheus/files/openshift_prometheus.exports @@ -0,0 +1,3 @@ +/exports/prometheus *(rw,no_root_squash,no_wdelay) +/exports/prometheus-alertmanager *(rw,no_root_squash,no_wdelay) +/exports/prometheus-alertbuffer *(rw,no_root_squash,no_wdelay) diff --git a/roles/openshift_prometheus/meta/main.yaml b/roles/openshift_prometheus/meta/main.yaml new file mode 100644 index 000000000..33188bb7e --- /dev/null +++ b/roles/openshift_prometheus/meta/main.yaml @@ -0,0 +1,19 @@ +--- +galaxy_info: + author: OpenShift Development <dev@lists.openshift.redhat.com> + description: Deploy OpenShift prometheus integration for the cluster + company: Red Hat, Inc. + license: license (Apache) + min_ansible_version: 2.2 + platforms: + - name: EL + versions: + - 7 + - name: Fedora + versions: + - all + categories: + - openshift +dependencies: +- { role: lib_openshift } +- { role: openshift_facts } diff --git a/roles/openshift_prometheus/tasks/create_pvs.yaml b/roles/openshift_prometheus/tasks/create_pvs.yaml new file mode 100644 index 000000000..4e79da05f --- /dev/null +++ b/roles/openshift_prometheus/tasks/create_pvs.yaml @@ -0,0 +1,36 @@ +--- +# Check for existance and then conditionally: +# - evaluate templates +# - PVs +# +# These tasks idempotently create required Prometheus PV objects. Do not +# call this file directly. This file is intended to be ran as an +# include that has a 'with_items' attached to it. Hence the use below +# of variables like "{{ item.pv_label }}" + +- name: "Check if the {{ item.pv_label }} template has been created already" + oc_obj: + namespace: "{{ openshift_prometheus_namespace }}" + state: list + kind: pv + name: "{{ item.pv_name }}" + register: prom_pv_check + +# Skip all of this if the PV already exists +- block: + - name: "Ensure the {{ item.pv_label }} template is evaluated" + template: + src: "{{ item.pv_template }}.j2" + dest: "{{ tempdir }}/templates/{{ item.pv_template }}" + + - name: "Ensure {{ item.pv_label }} is created" + oc_obj: + namespace: "{{ openshift_prometheus_namespace }}" + kind: pv + name: "{{ item.pv_name }}" + state: present + delete_after: True + files: + - "{{ tempdir }}/templates/{{ item.pv_template }}" + when: + - not prom_pv_check.results.results.0 diff --git a/roles/openshift_prometheus/tasks/install_prometheus.yaml b/roles/openshift_prometheus/tasks/install_prometheus.yaml new file mode 100644 index 000000000..93bdda3e8 --- /dev/null +++ b/roles/openshift_prometheus/tasks/install_prometheus.yaml @@ -0,0 +1,241 @@ +--- + +# namespace +- name: Add prometheus project + oc_project: + state: "{{ state }}" + name: "{{ openshift_prometheus_namespace }}" + node_selector: "{{ openshift_prometheus_node_selector | oo_selector_to_string_list() }}" + description: Prometheus + +# secrets +- name: Set alert and prometheus secrets + oc_secret: + state: "{{ state }}" + name: "{{ item }}-proxy" + namespace: "{{ openshift_prometheus_namespace }}" + contents: + - path: session_secret + data: "{{ 43 | oo_random_word }}=" + with_items: + - prometheus + - alerts + +# serviceaccount +- name: create prometheus serviceaccount + oc_serviceaccount: + state: "{{ state }}" + name: prometheus + namespace: "{{ openshift_prometheus_namespace }}" + # TODO add annotations when supproted + # annotations: + # serviceaccounts.openshift.io/oauth-redirectreference.prom: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"prometheus"}}' + # serviceaccounts.openshift.io/oauth-redirectreference.alerts: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"alerts"}}' + + secrets: + - prometheus-secrets + changed_when: no + +# TODO remove this when annotations are supported by oc_serviceaccount +- name: annotate serviceaccount + command: > + {{ openshift.common.client_binary }} annotate --overwrite -n {{ openshift_prometheus_namespace }} + serviceaccount prometheus + serviceaccounts.openshift.io/oauth-redirectreference.prom='{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"prometheus"}}' + serviceaccounts.openshift.io/oauth-redirectreference.alerts='{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"alerts"}}' + + +# create clusterrolebinding for prometheus serviceaccount +- name: Set cluster-reader permissions for prometheus + oc_adm_policy_user: + state: "{{ state }}" + namespace: "{{ openshift_prometheus_namespace }}" + resource_kind: cluster-role + resource_name: cluster-reader + user: "system:serviceaccount:{{ openshift_prometheus_namespace }}:prometheus" + + +###################################################################### +# NFS +# In the case that we are not running on a cloud provider, volumes must be statically provisioned + +- include: nfs.yaml + when: not (openshift_cloudprovider_kind is defined and (openshift_cloudprovider_kind == 'aws' or openshift_cloudprovider_kind == 'gce')) + + +# create prometheus and alerts services +# TODO join into 1 task with loop +- name: Create prometheus service + oc_service: + state: "{{ state }}" + name: "{{ item.name }}" + namespace: "{{ openshift_prometheus_namespace }}" + selector: + app: prometheus + labels: + name: "{{ item.name }}" + # TODO add annotations when supported + # annotations: + # service.alpha.openshift.io/serving-cert-secret-name: "{{item.name}}-tls" + ports: + - port: 443 + targetPort: 8443 + with_items: + - name: prometheus + +- name: Create alerts service + oc_service: + state: "{{ state }}" + name: "{{ item.name }}" + namespace: "{{ openshift_prometheus_namespace }}" + selector: + app: prometheus + labels: + name: "{{ item.name }}" + # TODO add annotations when supported + # annotations: + # service.alpha.openshift.io/serving-cert-secret-name: "{{item.name}}-tls" + ports: + - port: 443 + targetPort: 9443 + with_items: + - name: alerts + + +# Annotate services with secret name +# TODO remove this when annotations are supported by oc_service +- name: annotate prometheus service + command: > + {{ openshift.common.client_binary }} annotate --overwrite -n {{ openshift_prometheus_namespace }} + service prometheus 'service.alpha.openshift.io/serving-cert-secret-name=prometheus-tls' + +- name: annotate alerts service + command: > + {{ openshift.common.client_binary }} annotate --overwrite -n {{ openshift_prometheus_namespace }} + service alerts 'service.alpha.openshift.io/serving-cert-secret-name=prometheus-alerts-tls' + +# create prometheus and alerts routes +- name: create prometheus and alerts routes + oc_route: + state: "{{ state }}" + name: "{{ item.name }}" + namespace: "{{ openshift_prometheus_namespace }}" + service_name: "{{ item.name }}" + tls_termination: reencrypt + with_items: + - name: prometheus + - name: alerts + +# Storage +- name: create prometheus pvc + oc_pvc: + namespace: "{{ openshift_prometheus_namespace }}" + name: "{{ openshift_prometheus_pvc_name }}" + access_modes: "{{ openshift_prometheus_pvc_access_modes }}" + volume_capacity: "{{ openshift_prometheus_pvc_size }}" + selector: "{{ openshift_prometheus_pvc_pv_selector }}" + +- name: create alertmanager pvc + oc_pvc: + namespace: "{{ openshift_prometheus_namespace }}" + name: "{{ openshift_prometheus_alertmanager_pvc_name }}" + access_modes: "{{ openshift_prometheus_alertmanager_pvc_access_modes }}" + volume_capacity: "{{ openshift_prometheus_alertmanager_pvc_size }}" + selector: "{{ openshift_prometheus_alertmanager_pvc_pv_selector }}" + +- name: create alertbuffer pvc + oc_pvc: + namespace: "{{ openshift_prometheus_namespace }}" + name: "{{ openshift_prometheus_alertbuffer_pvc_name }}" + access_modes: "{{ openshift_prometheus_alertbuffer_pvc_access_modes }}" + volume_capacity: "{{ openshift_prometheus_alertbuffer_pvc_size }}" + selector: "{{ openshift_prometheus_alertbuffer_pvc_pv_selector }}" + +# create prometheus deployment +- name: Set prometheus deployment template + template: + src: prometheus_deployment.j2 + dest: "{{ tempdir }}/templates/prometheus.yaml" + vars: + namespace: "{{ openshift_prometheus_namespace }}" + prom_replicas: "{{ openshift_prometheus_replicas }}" + +- name: Set prometheus deployment + oc_obj: + state: "{{ state }}" + name: "prometheus" + namespace: "{{ openshift_prometheus_namespace }}" + kind: deployment + files: + - "{{ tempdir }}/templates/prometheus.yaml" + delete_after: true + +# prometheus configmap +# Copy the additional rules file if it is defined +- name: Copy additional rules file to host + copy: + src: "{{ openshift_prometheus_additional_rules_file }}" + dest: "{{ tempdir }}/prometheus.additional.rules" + when: + - openshift_prometheus_additional_rules_file is defined + - openshift_prometheus_additional_rules_file is not none + - openshift_prometheus_additional_rules_file | trim | length > 0 + +- stat: + path: "{{ tempdir }}/prometheus.additional.rules" + register: additional_rules_stat + +# The kubernetes version impacts the prometheus scraping endpoint +# so gathering it before constructing the configmap +- name: get oc version + oc_version: + register: oc_version + +- set_fact: + kubernetes_version: "{{ oc_version.results.kubernetes_short | float }}" + +- template: + src: prometheus.yml.j2 + dest: "{{ tempdir }}/prometheus.yml" + changed_when: no + +- template: + src: prometheus.rules.j2 + dest: "{{ tempdir }}/prometheus.rules" + changed_when: no + +# In prometheus configmap create "additional.rules" section if file exists +- name: Set prometheus configmap + oc_configmap: + state: "{{ state }}" + name: "prometheus" + namespace: "{{ openshift_prometheus_namespace }}" + from_file: + prometheus.rules: "{{ tempdir }}/prometheus.rules" + prometheus.additional.rules: "{{ tempdir }}/prometheus.additional.rules" + prometheus.yml: "{{ tempdir }}/prometheus.yml" + when: additional_rules_stat.stat.exists == True + +- name: Set prometheus configmap + oc_configmap: + state: "{{ state }}" + name: "prometheus" + namespace: "{{ openshift_prometheus_namespace }}" + from_file: + prometheus.rules: "{{ tempdir }}/prometheus.rules" + prometheus.yml: "{{ tempdir }}/prometheus.yml" + when: additional_rules_stat.stat.exists == False + +# alertmanager configmap +- template: + src: alertmanager.yml.j2 + dest: "{{ tempdir }}/alertmanager.yml" + changed_when: no + +- name: Set alertmanager configmap + oc_configmap: + state: "{{ state }}" + name: "prometheus-alerts" + namespace: "{{ openshift_prometheus_namespace }}" + from_file: + alertmanager.yml: "{{ tempdir }}/alertmanager.yml" diff --git a/roles/openshift_prometheus/tasks/main.yaml b/roles/openshift_prometheus/tasks/main.yaml new file mode 100644 index 000000000..523a64334 --- /dev/null +++ b/roles/openshift_prometheus/tasks/main.yaml @@ -0,0 +1,26 @@ +--- + +- name: Create temp directory for doing work in on target + command: mktemp -td openshift-prometheus-ansible-XXXXXX + register: mktemp + changed_when: False + +- set_fact: + tempdir: "{{ mktemp.stdout }}" + +- name: Create templates subdirectory + file: + state: directory + path: "{{ tempdir }}/templates" + mode: 0755 + changed_when: False + +- include: install_prometheus.yaml + vars: + state: "{{ openshift_prometheus_state }}" + +- name: Delete temp directory + file: + name: "{{ tempdir }}" + state: absent + changed_when: False diff --git a/roles/openshift_prometheus/tasks/nfs.yaml b/roles/openshift_prometheus/tasks/nfs.yaml new file mode 100644 index 000000000..0b45f2cee --- /dev/null +++ b/roles/openshift_prometheus/tasks/nfs.yaml @@ -0,0 +1,44 @@ +--- +# Tasks to statically provision NFS volumes +# Include if not using dynamic volume provisioning +- name: Ensure the /exports/ directory exists + file: + path: /exports/ + state: directory + mode: 0755 + owner: root + group: root + +- name: Ensure the prom-pv0X export directories exist + file: + path: "/exports/{{ item }}" + state: directory + mode: 0777 + owner: nfsnobody + group: nfsnobody + with_items: "{{ openshift_prometheus_pv_exports }}" + +- name: Ensure the NFS exports for Prometheus PVs exist + copy: + src: openshift_prometheus.exports + dest: /etc/exports.d/openshift_prometheus.exports + register: nfs_exports_updated + +- name: Ensure the NFS export table is refreshed if exports were added + command: exportfs -ar + when: + - nfs_exports_updated.changed + + +###################################################################### +# Create the required Prometheus PVs. Check out these online docs if you +# need a refresher on includes looping with items: +# * http://docs.ansible.com/ansible/playbooks_loops.html#loops-and-includes-in-2-0 +# * http://stackoverflow.com/a/35128533 +# +# TODO: Handle the case where a PV template is updated in +# openshift-ansible and the change needs to be landed on the managed +# cluster. + +- include: create_pvs.yaml + with_items: "{{ openshift_prometheus_pv_data }}" diff --git a/roles/openshift_prometheus/templates/alertmanager.yml.j2 b/roles/openshift_prometheus/templates/alertmanager.yml.j2 new file mode 100644 index 000000000..6c432a3d0 --- /dev/null +++ b/roles/openshift_prometheus/templates/alertmanager.yml.j2 @@ -0,0 +1,20 @@ +global: + +# The root route on which each incoming alert enters. +route: + # default route if none match + receiver: alert-buffer-wh + + # The labels by which incoming alerts are grouped together. For example, + # multiple alerts coming in for cluster=A and alertname=LatencyHigh would + # be batched into a single group. + # TODO: + group_by: [] + + # All the above attributes are inherited by all child routes and can + # overwritten on each. + +receivers: +- name: alert-buffer-wh + webhook_configs: + - url: http://localhost:9099/topics/alerts diff --git a/roles/openshift_prometheus/templates/prom-pv-alertbuffer.yml.j2 b/roles/openshift_prometheus/templates/prom-pv-alertbuffer.yml.j2 new file mode 100644 index 000000000..55a5e19c3 --- /dev/null +++ b/roles/openshift_prometheus/templates/prom-pv-alertbuffer.yml.j2 @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: prometheus-alertbuffer + labels: + storage: prometheus-alertbuffer +spec: + capacity: + storage: 15Gi + accessModes: + - ReadWriteOnce + nfs: + path: /exports/prometheus-alertbuffer + server: {{ openshift_prometheus_nfs_server }} + persistentVolumeReclaimPolicy: Retain diff --git a/roles/openshift_prometheus/templates/prom-pv-alertmanager.yml.j2 b/roles/openshift_prometheus/templates/prom-pv-alertmanager.yml.j2 new file mode 100644 index 000000000..4ee518735 --- /dev/null +++ b/roles/openshift_prometheus/templates/prom-pv-alertmanager.yml.j2 @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: prometheus-alertmanager + labels: + storage: prometheus-alertmanager +spec: + capacity: + storage: 15Gi + accessModes: + - ReadWriteOnce + nfs: + path: /exports/prometheus-alertmanager + server: {{ openshift_prometheus_nfs_server }} + persistentVolumeReclaimPolicy: Retain diff --git a/roles/openshift_prometheus/templates/prom-pv-server.yml.j2 b/roles/openshift_prometheus/templates/prom-pv-server.yml.j2 new file mode 100644 index 000000000..933bf0f60 --- /dev/null +++ b/roles/openshift_prometheus/templates/prom-pv-server.yml.j2 @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: prometheus + labels: + storage: prometheus +spec: + capacity: + storage: 15Gi + accessModes: + - ReadWriteOnce + nfs: + path: /exports/prometheus + server: {{ openshift_prometheus_nfs_server }} + persistentVolumeReclaimPolicy: Retain diff --git a/roles/openshift_prometheus/templates/prometheus.rules.j2 b/roles/openshift_prometheus/templates/prometheus.rules.j2 new file mode 100644 index 000000000..e861dc127 --- /dev/null +++ b/roles/openshift_prometheus/templates/prometheus.rules.j2 @@ -0,0 +1,4 @@ +groups: +- name: example-rules + interval: 30s # defaults to global interval + rules: diff --git a/roles/openshift_prometheus/templates/prometheus.yml.j2 b/roles/openshift_prometheus/templates/prometheus.yml.j2 new file mode 100644 index 000000000..63430f834 --- /dev/null +++ b/roles/openshift_prometheus/templates/prometheus.yml.j2 @@ -0,0 +1,174 @@ +rule_files: + - 'prometheus.rules' +{% if openshift_prometheus_additional_rules_file is defined and openshift_prometheus_additional_rules_file is not none %} + - 'prometheus.additional.rules' +{% endif %} + + + +# A scrape configuration for running Prometheus on a Kubernetes cluster. +# This uses separate scrape configs for cluster components (i.e. API server, node) +# and services to allow each to use different authentication configs. +# +# Kubernetes labels will be added as Prometheus labels on metrics via the +# `labelmap` relabeling action. + +# Scrape config for API servers. +# +# Kubernetes exposes API servers as endpoints to the default/kubernetes +# service so this uses `endpoints` role and uses relabelling to only keep +# the endpoints associated with the default/kubernetes service using the +# default named port `https`. This works for single API server deployments as +# well as HA API server deployments. +scrape_configs: +- job_name: 'kubernetes-apiservers' + + kubernetes_sd_configs: + - role: endpoints + + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + # Keep only the default/kubernetes service endpoints for the https port. This + # will add targets for each API server which Kubernetes adds an endpoint to + # the default/kubernetes service. + relabel_configs: + - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] + action: keep + regex: default;kubernetes;https + +# Scrape config for nodes. +# +# Each node exposes a /metrics endpoint that contains operational metrics for +# the Kubelet and other components. +- job_name: 'kubernetes-nodes' + + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + kubernetes_sd_configs: + - role: node + + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + +# Scrape config for controllers. +# +# Each master node exposes a /metrics endpoint on :8444 that contains operational metrics for +# the controllers. +# +# TODO: move this to a pure endpoints based metrics gatherer when controllers are exposed via +# endpoints. +- job_name: 'kubernetes-controllers' + + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + kubernetes_sd_configs: + - role: endpoints + + # Keep only the default/kubernetes service endpoints for the https port, and then + # set the port to 8444. This is the default configuration for the controllers on OpenShift + # masters. + relabel_configs: + - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] + action: keep + regex: default;kubernetes;https + - source_labels: [__address__] + action: replace + target_label: __address__ + regex: (.+)(?::\d+) + replacement: $1:8444 + +# Scrape config for cAdvisor. +# +# Beginning in Kube 1.7, each node exposes a /metrics/cadvisor endpoint that +# reports container metrics for each running pod. Scrape those by default. +- job_name: 'kubernetes-cadvisor' + + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + +{% if kubernetes_version | float() >= 1.7 | float() %} + metrics_path: /metrics/cadvisor +{% else %} + metrics_path: /metrics +{% endif %} + + kubernetes_sd_configs: + - role: node + + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + +# Scrape config for service endpoints. +# +# The relabeling allows the actual service scrape endpoint to be configured +# via the following annotations: +# +# * `prometheus.io/scrape`: Only scrape services that have a value of `true` +# * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need +# to set this to `https` & most likely set the `tls_config` of the scrape config. +# * `prometheus.io/path`: If the metrics path is not `/metrics` override this. +# * `prometheus.io/port`: If the metrics are exposed on a different port to the +# service then set this appropriately. +- job_name: 'kubernetes-service-endpoints' + + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + # TODO: this should be per target + insecure_skip_verify: true + + kubernetes_sd_configs: + - role: endpoints + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: replace + target_label: __scheme__ + regex: (https?) + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: (.+)(?::\d+);(\d+) + replacement: $1:$2 + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_username] + action: replace + target_label: __basic_auth_username__ + regex: (.+) + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_password] + action: replace + target_label: __basic_auth_password__ + regex: (.+) + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_service_name] + action: replace + target_label: kubernetes_name + +alerting: + alertmanagers: + - scheme: http + static_configs: + - targets: + - "localhost:9093" diff --git a/roles/openshift_prometheus/templates/prometheus_deployment.j2 b/roles/openshift_prometheus/templates/prometheus_deployment.j2 new file mode 100644 index 000000000..98c117f19 --- /dev/null +++ b/roles/openshift_prometheus/templates/prometheus_deployment.j2 @@ -0,0 +1,240 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: prometheus + namespace: {{ namespace }} + labels: + app: prometheus +spec: + replicas: {{ prom_replicas|default(1) }} + selector: + provider: openshift + matchLabels: + app: prometheus + template: + metadata: + name: prometheus + labels: + app: prometheus + spec: + serviceAccountName: prometheus +{% if openshift_prometheus_node_selector is iterable and openshift_prometheus_node_selector | length > 0 %} + nodeSelector: +{% for key, value in openshift_prometheus_node_selector.iteritems() %} + {{key}}: "{{value}}" +{% endfor %} +{% endif %} + containers: + # Deploy Prometheus behind an oauth proxy + - name: prom-proxy + image: "{{ openshift_prometheus_image_proxy }}" + imagePullPolicy: IfNotPresent + resources: + requests: +{% if openshift_prometheus_oauth_proxy_memory_requests is defined and openshift_prometheus_oauth_proxy_memory_requests is not none %} + memory: "{{openshift_prometheus_oauth_proxy_memory_requests}}" +{% endif %} +{% if openshift_prometheus_oauth_proxy_cpu_requests is defined and openshift_prometheus_oauth_proxy_cpu_requests is not none %} + cpu: "{{openshift_prometheus_oauth_proxy_cpu_requests}}" +{% endif %} + limits: +{% if openshift_prometheus_memory_requests_limit_proxy is defined and openshift_prometheus_oauth_proxy_memory_limit is not none %} + memory: "{{openshift_prometheus_oauth_proxy_memory_limit}}" +{% endif %} +{% if openshift_prometheus_oauth_proxy_cpu_limit is defined and openshift_prometheus_oauth_proxy_cpu_limit is not none %} + cpu: "{{openshift_prometheus_oauth_proxy_cpu_limit}}" +{% endif %} + ports: + - containerPort: 8443 + name: web + args: + - -provider=openshift + - -https-address=:8443 + - -http-address= + - -email-domain=* + - -upstream=http://localhost:9090 + - -client-id=system:serviceaccount:{{ namespace }}:prometheus + - '-openshift-sar={"resource": "namespaces", "verb": "get", "resourceName": "{{ namespace }}", "namespace": "{{ namespace }}"}' + - '-openshift-delegate-urls={"/": {"resource": "namespaces", "verb": "get", "resourceName": "{{ namespace }}", "namespace": "{{ namespace }}"}}' + - -tls-cert=/etc/tls/private/tls.crt + - -tls-key=/etc/tls/private/tls.key + - -client-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token + - -cookie-secret-file=/etc/proxy/secrets/session_secret + - -skip-auth-regex=^/metrics + volumeMounts: + - mountPath: /etc/tls/private + name: prometheus-tls + - mountPath: /etc/proxy/secrets + name: prometheus-secrets + - mountPath: /prometheus + name: prometheus-data + + - name: prometheus + args: + - --storage.tsdb.retention=6h + - --config.file=/etc/prometheus/prometheus.yml + - --web.listen-address=localhost:9090 + image: "{{ openshift_prometheus_image_prometheus }}" + imagePullPolicy: IfNotPresent + resources: + requests: +{% if openshift_prometheus_memory_requests is defined and openshift_prometheus_memory_requests is not none %} + memory: "{{openshift_prometheus_memory_requests}}" +{% endif %} +{% if openshift_prometheus_cpu_requests is defined and openshift_prometheus_cpu_requests is not none %} + cpu: "{{openshift_prometheus_cpu_requests}}" +{% endif %} + limits: +{% if openshift_prometheus_memory_limit is defined and openshift_prometheus_memory_limit is not none %} + memory: "{{ openshift_prometheus_memory_limit }}" +{% endif %} +{% if openshift_prometheus_cpu_limit is defined and openshift_prometheus_cpu_limit is not none %} + cpu: "{{openshift_prometheus_cpu_limit}}" +{% endif %} + + volumeMounts: + - mountPath: /etc/prometheus + name: prometheus-config + - mountPath: /prometheus + name: prometheus-data + + # Deploy alertmanager behind prometheus-alert-buffer behind an oauth proxy + - name: alerts-proxy + image: "{{ openshift_prometheus_image_proxy }}" + imagePullPolicy: IfNotPresent + resources: + requests: +{% if openshift_prometheus_oauth_proxy_memory_requests is defined and openshift_prometheus_oauth_proxy_memory_requests is not none %} + memory: "{{openshift_prometheus_oauth_proxy_memory_requests}}" +{% endif %} +{% if openshift_prometheus_oauth_proxy_cpu_requests is defined and openshift_prometheus_oauth_proxy_cpu_requests is not none %} + cpu: "{{openshift_prometheus_oauth_proxy_cpu_requests}}" +{% endif %} + limits: +{% if openshift_prometheus_oauth_proxy_memory_limit is defined and openshift_prometheus_oauth_proxy_memory_limit is not none %} + memory: "{{openshift_prometheus_oauth_proxy_memory_limit}}" +{% endif %} +{% if openshift_prometheus_oauth_proxy_cpu_limit is defined and openshift_prometheus_oauth_proxy_cpu_limit is not none %} + cpu: "{{openshift_prometheus_oauth_proxy_cpu_limit}}" +{% endif %} + ports: + - containerPort: 9443 + name: web + args: + - -provider=openshift + - -https-address=:9443 + - -http-address= + - -email-domain=* + - -upstream=http://localhost:9099 + - -client-id=system:serviceaccount:{{ namespace }}:prometheus + - '-openshift-sar={"resource": "namespaces", "verb": "get", "resourceName": "{{ namespace }}", "namespace": "{{ namespace }}"}' + - '-openshift-delegate-urls={"/": {"resource": "namespaces", "verb": "get", "resourceName": "{{ namespace }}", "namespace": "{{ namespace }}"}}' + - -tls-cert=/etc/tls/private/tls.crt + - -tls-key=/etc/tls/private/tls.key + - -client-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token + - -cookie-secret-file=/etc/proxy/secrets/session_secret + volumeMounts: + - mountPath: /etc/tls/private + name: alerts-tls + - mountPath: /etc/proxy/secrets + name: alerts-secrets + + - name: alert-buffer + args: + - --storage-path=/alert-buffer/messages.db + image: "{{ openshift_prometheus_image_alertbuffer }}" + imagePullPolicy: IfNotPresent + resources: + requests: +{% if openshift_prometheus_alertbuffer_memory_requests is defined and openshift_prometheus_alertbuffer_memory_requests is not none %} + memory: "{{openshift_prometheus_alertbuffer_memory_requests}}" +{% endif %} +{% if openshift_prometheus_alertbuffer_cpu_requests is defined and openshift_prometheus_alertbuffer_cpu_requests is not none %} + cpu: "{{openshift_prometheus_alertbuffer_cpu_requests}}" +{% endif %} + limits: +{% if openshift_prometheus_alertbuffer_memory_limit is defined and openshift_prometheus_alertbuffer_memory_limit is not none %} + memory: "{{openshift_prometheus_alertbuffer_memory_limit}}" +{% endif %} +{% if openshift_prometheus_alertbuffer_cpu_limit is defined and openshift_prometheus_alertbuffer_cpu_limit is not none %} + cpu: "{{openshift_prometheus_alertbuffer_cpu_limit}}" +{% endif %} + volumeMounts: + - mountPath: /alert-buffer + name: alert-buffer-data + ports: + - containerPort: 9099 + name: alert-buf + + - name: alertmanager + args: + - -config.file=/etc/alertmanager/alertmanager.yml + image: "{{ openshift_prometheus_image_alertmanager }}" + imagePullPolicy: IfNotPresent + resources: + requests: +{% if openshift_prometheus_alertmanager_memory_requests is defined and openshift_prometheus_alertmanager_memory_requests is not none %} + memory: "{{openshift_prometheus_alertmanager_memory_requests}}" +{% endif %} +{% if openshift_prometheus_alertmanager_cpu_requests is defined and openshift_prometheus_alertmanager_cpu_requests is not none %} + cpu: "{{openshift_prometheus_alertmanager_cpu_requests}}" +{% endif %} + limits: +{% if openshift_prometheus_alertmanager_memory_limit is defined and openshift_prometheus_alertmanager_memory_limit is not none %} + memory: "{{openshift_prometheus_alertmanager_memory_limit}}" +{% endif %} +{% if openshift_prometheus_alertmanager_cpu_limit is defined and openshift_prometheus_alertmanager_cpu_limit is not none %} + cpu: "{{openshift_prometheus_alertmanager_cpu_limit}}" +{% endif %} + ports: + - containerPort: 9093 + name: web + volumeMounts: + - mountPath: /etc/alertmanager + name: alertmanager-config + - mountPath: /alertmanager + name: alertmanager-data + + restartPolicy: Always + volumes: + - name: prometheus-config + configMap: + defaultMode: 420 + name: prometheus + - name: prometheus-secrets + secret: + secretName: prometheus-proxy + - name: prometheus-tls + secret: + secretName: prometheus-tls + - name: prometheus-data +{% if openshift_prometheus_storage_type == 'pvc' %} + persistentVolumeClaim: + claimName: {{ openshift_prometheus_pvc_name }} +{% else %} + emptydir: {} +{% endif %} + - name: alertmanager-config + configMap: + defaultMode: 420 + name: prometheus-alerts + - name: alerts-secrets + secret: + secretName: alerts-proxy + - name: alerts-tls + secret: + secretName: prometheus-alerts-tls + - name: alertmanager-data +{% if openshift_prometheus_alertmanager_storage_type == 'pvc' %} + persistentVolumeClaim: + claimName: {{ openshift_prometheus_alertmanager_pvc_name }} +{% else %} + emptydir: {} +{% endif %} + - name: alert-buffer-data +{% if openshift_prometheus_alertbuffer_storage_type == 'pvc' %} + persistentVolumeClaim: + claimName: {{ openshift_prometheus_alertbuffer_pvc_name }} +{% else %} + emptydir: {} +{% endif %} diff --git a/roles/openshift_prometheus/tests/inventory b/roles/openshift_prometheus/tests/inventory new file mode 100644 index 000000000..878877b07 --- /dev/null +++ b/roles/openshift_prometheus/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/openshift_prometheus/tests/test.yaml b/roles/openshift_prometheus/tests/test.yaml new file mode 100644 index 000000000..37baf573c --- /dev/null +++ b/roles/openshift_prometheus/tests/test.yaml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - openshift_prometheus diff --git a/roles/openshift_repos/tasks/main.yaml b/roles/openshift_repos/tasks/main.yaml index 7458db87e..f972c0fd9 100644 --- a/roles/openshift_repos/tasks/main.yaml +++ b/roles/openshift_repos/tasks/main.yaml @@ -6,23 +6,24 @@ - when: not ostree_booted.stat.exists block: + # TODO: This needs to be removed and placed into a role - name: Ensure libselinux-python is installed package: name=libselinux-python state=present - name: Create any additional repos that are defined - template: - src: yum_repo.j2 - dest: /etc/yum.repos.d/openshift_additional.repo - when: - - openshift_additional_repos | length > 0 - notify: refresh cache - - - name: Remove the additional repos if no longer defined - file: - dest: /etc/yum.repos.d/openshift_additional.repo - state: absent - when: - - openshift_additional_repos | length == 0 + yum_repository: + description: "{{ item.description | default(item.name | default(item.id)) }}" + name: "{{ item.name | default(item.id) }}" + baseurl: "{{ item.baseurl }}" + gpgkey: "{{ item.gpgkey | default(omit)}}" + gpgcheck: "{{ item.gpgcheck | default(1) }}" + sslverify: "{{ item.sslverify | default(1) }}" + sslclientkey: "{{ item.sslclientkey | default(omit) }}" + sslclientcert: "{{ item.sslclientcert | default(omit) }}" + file: "{{ item.name }}" + enabled: "{{ item.enabled | default('no')}}" + with_items: "{{ openshift_additional_repos }}" + when: openshift_additional_repos | length > 0 notify: refresh cache # Singleton block diff --git a/roles/openshift_repos/templates/yum_repo.j2 b/roles/openshift_repos/templates/yum_repo.j2 deleted file mode 100644 index ef2cd6603..000000000 --- a/roles/openshift_repos/templates/yum_repo.j2 +++ /dev/null @@ -1,14 +0,0 @@ -{% for repo in openshift_additional_repos %} -[{{ repo.id }}] -name={{ repo.name | default(repo.id) }} -baseurl={{ repo.baseurl }} -{% set enable_repo = repo.enabled | default(1) %} -enabled={{ 1 if ( enable_repo == 1 or enable_repo == True ) else 0 }} -{% set enable_gpg_check = repo.gpgcheck | default(1) %} -gpgcheck={{ 1 if ( enable_gpg_check == 1 or enable_gpg_check == True ) else 0 }} -{% for key, value in repo.iteritems() %} -{% if key not in ['id', 'name', 'baseurl', 'enabled', 'gpgcheck'] and value is defined %} -{{ key }}={{ value }} -{% endif %} -{% endfor %} -{% endfor %} diff --git a/roles/openshift_service_catalog/tasks/install.yml b/roles/openshift_service_catalog/tasks/install.yml index 686857d94..64f94347b 100644 --- a/roles/openshift_service_catalog/tasks/install.yml +++ b/roles/openshift_service_catalog/tasks/install.yml @@ -168,19 +168,19 @@ - "{{ mktemp.stdout }}/service_catalog_api_server.yml" delete_after: yes -- template: - src: api_server_service.j2 - dest: "{{ mktemp.stdout }}/service_catalog_api_service.yml" - - name: Set Service Catalog API Server service - oc_obj: - state: present - namespace: "kube-service-catalog" - kind: service + oc_service: name: apiserver - files: - - "{{ mktemp.stdout }}/service_catalog_api_service.yml" - delete_after: yes + namespace: kube-service-catalog + state: present + ports: + - name: secure + port: 443 + protocol: TCP + targetPort: 6443 + selector: + app: apiserver + session_affinity: None - template: src: api_server_route.j2 @@ -216,19 +216,19 @@ - "{{ mktemp.stdout }}/controller_manager.yml" delete_after: yes -- template: - src: controller_manager_service.j2 - dest: "{{ mktemp.stdout }}/controller_manager_service.yml" - - name: Set Controller Manager service - oc_obj: - state: present - namespace: "kube-service-catalog" - kind: service + oc_service: name: controller-manager - files: - - "{{ mktemp.stdout }}/controller_manager_service.yml" - delete_after: yes + namespace: kube-service-catalog + state: present + ports: + - port: 6443 + protocol: TCP + targetPort: 6443 + selector: + app: controller-manager + session_affinity: None + service_type: ClusterIP - include: start_api_server.yml diff --git a/roles/openshift_service_catalog/templates/api_server_service.j2 b/roles/openshift_service_catalog/templates/api_server_service.j2 deleted file mode 100644 index bae337201..000000000 --- a/roles/openshift_service_catalog/templates/api_server_service.j2 +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: apiserver -spec: - ports: - - name: secure - port: 443 - protocol: TCP - targetPort: 6443 - selector: - app: apiserver - sessionAffinity: None diff --git a/roles/openshift_service_catalog/templates/controller_manager_service.j2 b/roles/openshift_service_catalog/templates/controller_manager_service.j2 deleted file mode 100644 index 2bac645fc..000000000 --- a/roles/openshift_service_catalog/templates/controller_manager_service.j2 +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: controller-manager -spec: - ports: - - port: 6443 - protocol: TCP - targetPort: 6443 - selector: - app: controller-manager - sessionAffinity: None - type: ClusterIP diff --git a/roles/openshift_storage_glusterfs/defaults/main.yml b/roles/openshift_storage_glusterfs/defaults/main.yml index a5887465e..0b3d3aef1 100644 --- a/roles/openshift_storage_glusterfs/defaults/main.yml +++ b/roles/openshift_storage_glusterfs/defaults/main.yml @@ -52,8 +52,8 @@ openshift_storage_glusterfs_registry_heketi_ssh_port: "{{ openshift_storage_glus openshift_storage_glusterfs_registry_heketi_ssh_user: "{{ openshift_storage_glusterfs_heketi_ssh_user }}" openshift_storage_glusterfs_registry_heketi_ssh_sudo: "{{ openshift_storage_glusterfs_heketi_ssh_sudo }}" openshift_storage_glusterfs_registry_heketi_ssh_keyfile: "{{ openshift_storage_glusterfs_heketi_ssh_keyfile | default(omit) }}" -r_openshift_master_firewall_enabled: True -r_openshift_master_use_firewalld: False +r_openshift_storage_glusterfs_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_openshift_storage_glusterfs_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" r_openshift_storage_glusterfs_os_firewall_deny: [] r_openshift_storage_glusterfs_os_firewall_allow: - service: glusterfs_sshd diff --git a/roles/openshift_storage_nfs/defaults/main.yml b/roles/openshift_storage_nfs/defaults/main.yml index 4a2bc6141..e7e0b331b 100644 --- a/roles/openshift_storage_nfs/defaults/main.yml +++ b/roles/openshift_storage_nfs/defaults/main.yml @@ -1,6 +1,6 @@ --- -r_openshift_storage_nfs_firewall_enabled: True -r_openshift_storage_nfs_use_firewalld: False +r_openshift_storage_nfs_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_openshift_storage_nfs_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" r_openshift_storage_nfs_os_firewall_deny: [] r_openshift_storage_nfs_os_firewall_allow: diff --git a/roles/openshift_version/tasks/main.yml b/roles/openshift_version/tasks/main.yml index a6b8a40c8..c0ea00f34 100644 --- a/roles/openshift_version/tasks/main.yml +++ b/roles/openshift_version/tasks/main.yml @@ -60,13 +60,16 @@ # It also allows for optional trailing data which: # - must start with a dash # - may contain numbers + # - may containe dots (https://github.com/openshift/openshift-ansible/issues/5192) + # - name: (Enterprise) Verify openshift_image_tag is valid when: openshift.common.deployment_type == 'openshift-enterprise' assert: that: - - "{{ openshift_image_tag|match('(^v\\d+\\.\\d+[\\.\\d+]*(-\\d+)?$)') }}" + - "{{ openshift_image_tag|match('(^v\\d+\\.\\d+(\\.\\d+)*(-\\d+(\\.\\d+)*)?$)') }}" msg: |- - openshift_image_tag must be in the format v#.#[.#[.#]]. Examples: v1.2, v3.4.1, v3.5.1.3, v1.2-1, v1.2.3-4 + openshift_image_tag must be in the format v#.#[.#[.#]]. Examples: v1.2, v3.4.1, v3.5.1.3, + v3.5.1.3.4, v1.2-1, v1.2.3-4, v1.2.3-4.5, v1.2.3-4.5.6 You specified openshift_image_tag={{ openshift_image_tag }} # Make sure we copy this to a fact if given a var: diff --git a/roles/openshift_version/tasks/set_version_containerized.yml b/roles/openshift_version/tasks/set_version_containerized.yml index 4d9f72f01..a2a579e9d 100644 --- a/roles/openshift_version/tasks/set_version_containerized.yml +++ b/roles/openshift_version/tasks/set_version_containerized.yml @@ -1,6 +1,6 @@ --- - set_fact: - l_use_crio: "{{ openshift_docker_use_crio | default(false) }}" + l_use_crio: "{{ openshift_use_crio | default(false) }}" - name: Set containerized version to configure if openshift_image_tag specified set_fact: diff --git a/roles/os_firewall/defaults/main.yml b/roles/os_firewall/defaults/main.yml index f96a80f1c..2cae94411 100644 --- a/roles/os_firewall/defaults/main.yml +++ b/roles/os_firewall/defaults/main.yml @@ -2,4 +2,4 @@ os_firewall_enabled: True # firewalld is not supported on Atomic Host # https://bugzilla.redhat.com/show_bug.cgi?id=1403331 -os_firewall_use_firewalld: "{{ False }}" +os_firewall_use_firewalld: False |