From 18306e3401818cfd9723b6813987308f584c6ea3 Mon Sep 17 00:00:00 2001 From: Jan Chaloupka Date: Wed, 20 Sep 2017 11:56:19 +0200 Subject: consolidate etcd_common role --- .../redeploy-certificates/etcd-ca.yml | 93 ++----- .../redeploy-certificates/etcd.yml | 90 +++---- .../openshift-cluster/upgrades/etcd/backup.yml | 15 +- .../openshift-cluster/upgrades/etcd/main.yml | 5 +- playbooks/common/openshift-etcd/migrate.yml | 15 +- roles/etcd/defaults/main.yaml | 75 +++++- roles/etcd/library/delegated_serial_command.py | 274 +++++++++++++++++++++ roles/etcd/meta/main.yml | 1 - roles/etcd/tasks/auxiliary/drop_etcdctl.yml | 12 + roles/etcd/tasks/backup.yml | 2 + roles/etcd/tasks/backup/backup.yml | 101 ++++++++ roles/etcd/tasks/backup_ca_certificates.yml | 2 + roles/etcd/tasks/backup_generated_certificates.yml | 2 + roles/etcd/tasks/backup_server_certificates.yml | 2 + roles/etcd/tasks/ca.yml | 2 +- roles/etcd/tasks/ca/deploy.yml | 78 ------ .../tasks/certificates/backup_ca_certificates.yml | 12 + .../certificates/backup_generated_certificates.yml | 13 + .../certificates/backup_server_certificates.yml | 11 + roles/etcd/tasks/certificates/deploy_ca.yml | 78 ++++++ roles/etcd/tasks/certificates/distribute_ca.yml | 47 ++++ .../fetch_client_certificates_from_ca.yml | 138 +++++++++++ .../fetch_server_certificates_from_ca.yml | 234 ++++++++++++++++++ .../tasks/certificates/remove_ca_certificates.yml | 5 + .../certificates/remove_generated_certificates.yml | 5 + .../certificates/retrieve_ca_certificates.yml | 8 + roles/etcd/tasks/client_certificates.yml | 2 +- .../tasks/client_certificates/fetch_from_ca.yml | 138 ----------- roles/etcd/tasks/distribute_ca | 2 + roles/etcd/tasks/drop_etcdctl.yml | 2 + roles/etcd/tasks/main.yml | 5 +- roles/etcd/tasks/remove_ca_certificates.yml | 2 + roles/etcd/tasks/remove_generated_certificates.yml | 2 + roles/etcd/tasks/retrieve_ca_certificates.yml | 2 + roles/etcd/tasks/server_certificates.yml | 6 +- .../tasks/server_certificates/fetch_from_ca.yml | 238 ------------------ roles/etcd/templates/etcdctl.sh.j2 | 12 + roles/etcd_common/README.md | 53 ---- roles/etcd_common/defaults/main.yml | 78 ------ .../library/delegated_serial_command.py | 274 --------------------- roles/etcd_common/meta/main.yml | 15 -- roles/etcd_common/tasks/backup.yml | 101 -------- roles/etcd_common/tasks/drop_etcdctl.yml | 12 - roles/etcd_common/tasks/main.yml | 9 - roles/etcd_common/tasks/noop.yml | 4 - roles/etcd_common/templates/etcdctl.sh.j2 | 12 - roles/etcd_common/vars/main.yml | 4 - 47 files changed, 1121 insertions(+), 1172 deletions(-) create mode 100755 roles/etcd/library/delegated_serial_command.py create mode 100644 roles/etcd/tasks/auxiliary/drop_etcdctl.yml create mode 100644 roles/etcd/tasks/backup.yml create mode 100644 roles/etcd/tasks/backup/backup.yml create mode 100644 roles/etcd/tasks/backup_ca_certificates.yml create mode 100644 roles/etcd/tasks/backup_generated_certificates.yml create mode 100644 roles/etcd/tasks/backup_server_certificates.yml delete mode 100644 roles/etcd/tasks/ca/deploy.yml create mode 100644 roles/etcd/tasks/certificates/backup_ca_certificates.yml create mode 100644 roles/etcd/tasks/certificates/backup_generated_certificates.yml create mode 100644 roles/etcd/tasks/certificates/backup_server_certificates.yml create mode 100644 roles/etcd/tasks/certificates/deploy_ca.yml create mode 100644 roles/etcd/tasks/certificates/distribute_ca.yml create mode 100644 roles/etcd/tasks/certificates/fetch_client_certificates_from_ca.yml create mode 100644 roles/etcd/tasks/certificates/fetch_server_certificates_from_ca.yml create mode 100644 roles/etcd/tasks/certificates/remove_ca_certificates.yml create mode 100644 roles/etcd/tasks/certificates/remove_generated_certificates.yml create mode 100644 roles/etcd/tasks/certificates/retrieve_ca_certificates.yml delete mode 100644 roles/etcd/tasks/client_certificates/fetch_from_ca.yml create mode 100644 roles/etcd/tasks/distribute_ca create mode 100644 roles/etcd/tasks/drop_etcdctl.yml create mode 100644 roles/etcd/tasks/remove_ca_certificates.yml create mode 100644 roles/etcd/tasks/remove_generated_certificates.yml create mode 100644 roles/etcd/tasks/retrieve_ca_certificates.yml delete mode 100644 roles/etcd/tasks/server_certificates/fetch_from_ca.yml create mode 100644 roles/etcd/templates/etcdctl.sh.j2 delete mode 100644 roles/etcd_common/README.md delete mode 100644 roles/etcd_common/defaults/main.yml delete mode 100755 roles/etcd_common/library/delegated_serial_command.py delete mode 100644 roles/etcd_common/meta/main.yml delete mode 100644 roles/etcd_common/tasks/backup.yml delete mode 100644 roles/etcd_common/tasks/drop_etcdctl.yml delete mode 100644 roles/etcd_common/tasks/main.yml delete mode 100644 roles/etcd_common/tasks/noop.yml delete mode 100644 roles/etcd_common/templates/etcdctl.sh.j2 delete mode 100644 roles/etcd_common/vars/main.yml diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/etcd-ca.yml b/playbooks/common/openshift-cluster/redeploy-certificates/etcd-ca.yml index 3a8e32ed1..3da22bce6 100644 --- a/playbooks/common/openshift-cluster/redeploy-certificates/etcd-ca.yml +++ b/playbooks/common/openshift-cluster/redeploy-certificates/etcd-ca.yml @@ -13,26 +13,13 @@ - name: Backup existing etcd CA certificate directories hosts: oo_etcd_to_config - roles: - - role: etcd_common - r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" tasks: - - name: Determine if CA certificate directory exists - stat: - path: "{{ etcd_ca_dir }}" - register: etcd_ca_certs_dir_stat - - name: Backup generated etcd certificates - command: > - tar -czf {{ etcd_conf_dir }}/etcd-ca-certificate-backup-{{ ansible_date_time.epoch }}.tgz - {{ etcd_ca_dir }} - args: - warn: no - when: etcd_ca_certs_dir_stat.stat.exists | bool - - name: Remove CA certificate directory - file: - path: "{{ etcd_ca_dir }}" - state: absent - when: etcd_ca_certs_dir_stat.stat.exists | bool + - include_role: + name: etcd + tasks_from: backup_ca_certificates + - include_role: + name: etcd + tasks_from: remove_ca_certificates - name: Generate new etcd CA hosts: oo_first_etcd @@ -62,52 +49,14 @@ - name: Distribute etcd CA to etcd hosts hosts: oo_etcd_to_config - vars: - etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" - roles: - - role: etcd_common - r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" tasks: - - name: Create a tarball of the etcd ca certs - command: > - tar -czvf {{ etcd_conf_dir }}/{{ etcd_ca_name }}.tgz - -C {{ etcd_ca_dir }} . - args: - creates: "{{ etcd_conf_dir }}/{{ etcd_ca_name }}.tgz" - warn: no - delegate_to: "{{ etcd_ca_host }}" - run_once: true - - name: Retrieve etcd ca cert tarball - fetch: - src: "{{ etcd_conf_dir }}/{{ etcd_ca_name }}.tgz" - dest: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}/" - flat: yes - fail_on_missing: yes - validate_checksum: yes - delegate_to: "{{ etcd_ca_host }}" - run_once: true - - name: Ensure ca directory exists - file: - path: "{{ etcd_ca_dir }}" - state: directory - - name: Unarchive etcd ca cert tarballs - unarchive: - src: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}/{{ etcd_ca_name }}.tgz" - dest: "{{ etcd_ca_dir }}" - - name: Read current etcd CA - slurp: - src: "{{ etcd_conf_dir }}/ca.crt" - register: g_current_etcd_ca_output - - name: Read new etcd CA - slurp: - src: "{{ etcd_ca_dir }}/ca.crt" - register: g_new_etcd_ca_output - - copy: - content: "{{ (g_new_etcd_ca_output.content|b64decode) + (g_current_etcd_ca_output.content|b64decode) }}" - dest: "{{ item }}/ca.crt" - with_items: - - "{{ etcd_conf_dir }}" - - "{{ etcd_ca_dir }}" + - include_role: + name: etcd + tasks_from: distribute_ca + vars: + r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" + etcd_sync_cert_dir: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}" + etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" - include: ../../openshift-etcd/restart.yml # Do not restart etcd when etcd certificates were previously expired. @@ -118,17 +67,13 @@ - name: Retrieve etcd CA certificate hosts: oo_first_etcd - roles: - - role: etcd_common - r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" tasks: - - name: Retrieve etcd CA certificate - fetch: - src: "{{ etcd_conf_dir }}/ca.crt" - dest: "{{ hostvars['localhost'].g_etcd_mktemp.stdout }}/" - flat: yes - fail_on_missing: yes - validate_checksum: yes + - include_role: + name: etcd + tasks_from: retrieve_ca_certificates + vars: + etcd_sync_cert_dir: hostvars['localhost'].g_etcd_mktemp.stdout + r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" - name: Distribute etcd CA to masters hosts: oo_masters_to_config diff --git a/playbooks/common/openshift-cluster/redeploy-certificates/etcd.yml b/playbooks/common/openshift-cluster/redeploy-certificates/etcd.yml index 16f0edb06..48a5a13ac 100644 --- a/playbooks/common/openshift-cluster/redeploy-certificates/etcd.yml +++ b/playbooks/common/openshift-cluster/redeploy-certificates/etcd.yml @@ -2,73 +2,53 @@ - name: Backup and remove generated etcd certificates hosts: oo_first_etcd any_errors_fatal: true - roles: - - role: etcd_common - r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" - post_tasks: - - name: Determine if generated etcd certificates exist - stat: - path: "{{ etcd_conf_dir }}/generated_certs" - register: etcd_generated_certs_dir_stat - - name: Backup generated etcd certificates - command: > - tar -czf {{ etcd_conf_dir }}/etcd-generated-certificate-backup-{{ ansible_date_time.epoch }}.tgz - {{ etcd_conf_dir }}/generated_certs - args: - warn: no - when: etcd_generated_certs_dir_stat.stat.exists | bool - - name: Remove generated etcd certificates - file: - path: "{{ item }}" - state: absent - with_items: - - "{{ etcd_conf_dir }}/generated_certs" + tasks: + - include_role: + name: etcd + tasks_from: backup_generated_certificates + - include_role: + name: etcd + tasks_from: remove_generated_certificates - name: Backup and removed deployed etcd certificates hosts: oo_etcd_to_config any_errors_fatal: true - roles: - - role: etcd_common + tasks: + - include_role: + name: etcd + tasks_from: backup_server_certificates + vars: r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" - post_tasks: - - name: Backup etcd certificates - command: > - tar -czvf /etc/etcd/etcd-server-certificate-backup-{{ ansible_date_time.epoch }}.tgz - {{ etcd_conf_dir }}/ca.crt - {{ etcd_conf_dir }}/server.crt - {{ etcd_conf_dir }}/server.key - {{ etcd_conf_dir }}/peer.crt - {{ etcd_conf_dir }}/peer.key - args: - warn: no - name: Redeploy etcd certificates hosts: oo_etcd_to_config any_errors_fatal: true + roles: + - role: openshift_etcd_facts tasks: - - include_role: - name: etcd - tasks_from: server_certificates - vars: - etcd_certificates_redeploy: true - etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" - etcd_peers: "{{ groups.oo_etcd_to_config | default([], true) }}" - etcd_certificates_etcd_hosts: "{{ groups.oo_etcd_to_config | default([], true) }}" - openshift_ca_host: "{{ groups.oo_first_master.0 }}" - r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" + - include_role: + name: etcd + tasks_from: server_certificates + vars: + etcd_certificates_redeploy: true + etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" + etcd_peers: "{{ groups.oo_etcd_to_config | default([], true) }}" + etcd_certificates_etcd_hosts: "{{ groups.oo_etcd_to_config | default([], true) }}" + openshift_ca_host: "{{ groups.oo_first_master.0 }}" + r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" - name: Redeploy etcd client certificates for masters hosts: oo_masters_to_config any_errors_fatal: true roles: - - role: openshift_etcd_facts - - role: openshift_etcd_client_certificates - etcd_certificates_redeploy: true - etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" - etcd_cert_subdir: "openshift-master-{{ openshift.common.hostname }}" - etcd_cert_config_dir: "{{ openshift.common.config_base }}/master" - etcd_cert_prefix: "master.etcd-" - openshift_ca_host: "{{ groups.oo_first_master.0 }}" - openshift_master_count: "{{ openshift.master.master_count | default(groups.oo_masters | length) }}" - r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" - when: groups.oo_etcd_to_config is defined and groups.oo_etcd_to_config + - role: openshift_etcd_facts + - role: openshift_etcd_client_certificates + etcd_certificates_redeploy: true + etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}" + etcd_cert_subdir: "openshift-master-{{ openshift.common.hostname }}" + etcd_cert_config_dir: "{{ openshift.common.config_base }}/master" + etcd_cert_prefix: "master.etcd-" + openshift_ca_host: "{{ groups.oo_first_master.0 }}" + openshift_master_count: "{{ openshift.master.master_count | default(groups.oo_masters | length) }}" + r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" + when: groups.oo_etcd_to_config is defined and groups.oo_etcd_to_config diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/backup.yml b/playbooks/common/openshift-cluster/upgrades/etcd/backup.yml index 2cc6c9019..6420998d2 100644 --- a/playbooks/common/openshift-cluster/upgrades/etcd/backup.yml +++ b/playbooks/common/openshift-cluster/upgrades/etcd/backup.yml @@ -3,12 +3,15 @@ hosts: oo_etcd_hosts_to_backup roles: - role: openshift_etcd_facts - - role: etcd_common - r_etcd_common_action: backup - r_etcd_common_backup_tag: etcd_backup_tag - r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" - r_etcd_common_embedded_etcd: "{{ groups.oo_etcd_to_config | default([]) | length == 0 }}" - r_etcd_common_backup_sufix_name: "{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}" + post_tasks: + - include_role: + name: etcd + tasks_from: backup + vars: + r_etcd_common_backup_tag: etcd_backup_tag + r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" + r_etcd_common_embedded_etcd: "{{ groups.oo_etcd_to_config | default([]) | length == 0 }}" + r_etcd_common_backup_sufix_name: "{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}" - name: Gate on etcd backup hosts: localhost diff --git a/playbooks/common/openshift-cluster/upgrades/etcd/main.yml b/playbooks/common/openshift-cluster/upgrades/etcd/main.yml index 64abc54e7..5c8467a4e 100644 --- a/playbooks/common/openshift-cluster/upgrades/etcd/main.yml +++ b/playbooks/common/openshift-cluster/upgrades/etcd/main.yml @@ -15,9 +15,8 @@ hosts: oo_etcd_hosts_to_upgrade tasks: - include_role: - name: etcd_common - vars: - r_etcd_common_action: drop_etcdctl + name: etcd + tasks_from: drop_etcdctl - name: Perform etcd upgrade include: ./upgrade.yml diff --git a/playbooks/common/openshift-etcd/migrate.yml b/playbooks/common/openshift-etcd/migrate.yml index 06e0607bd..b8d404e26 100644 --- a/playbooks/common/openshift-etcd/migrate.yml +++ b/playbooks/common/openshift-etcd/migrate.yml @@ -30,12 +30,15 @@ gather_facts: no roles: - role: openshift_facts - - role: etcd_common - r_etcd_common_action: backup - r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" - r_etcd_common_backup_tag: pre-migration - r_etcd_common_embedded_etcd: "{{ groups.oo_etcd_to_config | default([]) | length == 0 }}" - r_etcd_common_backup_sufix_name: "{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}" + post_tasks: + - include_role: + name: etcd + tasks_from: backup + vars: + r_etcd_common_etcd_runtime: "{{ openshift.common.etcd_runtime }}" + r_etcd_common_backup_tag: pre-migration + r_etcd_common_embedded_etcd: "{{ groups.oo_etcd_to_config | default([]) | length == 0 }}" + r_etcd_common_backup_sufix_name: "{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}" - name: Gate on etcd backup hosts: localhost diff --git a/roles/etcd/defaults/main.yaml b/roles/etcd/defaults/main.yaml index 3cc2bbb18..36808241f 100644 --- a/roles/etcd/defaults/main.yaml +++ b/roles/etcd/defaults/main.yaml @@ -1,6 +1,66 @@ --- -r_etcd_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" -r_etcd_use_firewalld: "{{ os_firewall_use_firewalld | default(Falsel) }}" +r_etcd_common_backup_tag: '' +r_etcd_common_backup_sufix_name: '' + +# runc, docker, host +r_etcd_common_etcd_runtime: "docker" +r_etcd_common_embedded_etcd: false + +# etcd run on a host => use etcdctl command directly +# etcd run as a docker container => use docker exec +# etcd run as a runc container => use runc exec +r_etcd_common_etcdctl_command: "{{ 'etcdctl' if r_etcd_common_etcd_runtime == 'host' or r_etcd_common_embedded_etcd | bool else 'docker exec etcd_container etcdctl' if r_etcd_common_etcd_runtime == 'docker' else 'runc exec etcd etcdctl' }}" + +# etcd server vars +etcd_conf_dir: '/etc/etcd' +r_etcd_common_system_container_host_dir: /var/lib/etcd/etcd.etcd +etcd_system_container_conf_dir: /var/lib/etcd/etc +etcd_conf_file: "{{ etcd_conf_dir }}/etcd.conf" +etcd_ca_file: "{{ etcd_conf_dir }}/ca.crt" +etcd_cert_file: "{{ etcd_conf_dir }}/server.crt" +etcd_key_file: "{{ etcd_conf_dir }}/server.key" +etcd_peer_ca_file: "{{ etcd_conf_dir }}/ca.crt" +etcd_peer_cert_file: "{{ etcd_conf_dir }}/peer.crt" +etcd_peer_key_file: "{{ etcd_conf_dir }}/peer.key" + +# etcd ca vars +etcd_ca_dir: "{{ etcd_conf_dir}}/ca" +etcd_generated_certs_dir: "{{ etcd_conf_dir }}/generated_certs" +etcd_ca_cert: "{{ etcd_ca_dir }}/ca.crt" +etcd_ca_key: "{{ etcd_ca_dir }}/ca.key" +etcd_openssl_conf: "{{ etcd_ca_dir }}/openssl.cnf" +etcd_ca_name: etcd_ca +etcd_req_ext: etcd_v3_req +etcd_ca_exts_peer: etcd_v3_ca_peer +etcd_ca_exts_server: etcd_v3_ca_server +etcd_ca_exts_self: etcd_v3_ca_self +etcd_ca_exts_client: etcd_v3_ca_client +etcd_ca_crl_dir: "{{ etcd_ca_dir }}/crl" +etcd_ca_new_certs_dir: "{{ etcd_ca_dir }}/certs" +etcd_ca_db: "{{ etcd_ca_dir }}/index.txt" +etcd_ca_serial: "{{ etcd_ca_dir }}/serial" +etcd_ca_crl_number: "{{ etcd_ca_dir }}/crlnumber" +etcd_ca_default_days: 1825 + +r_etcd_common_master_peer_cert_file: /etc/origin/master/master.etcd-client.crt +r_etcd_common_master_peer_key_file: /etc/origin/master/master.etcd-client.key +r_etcd_common_master_peer_ca_file: /etc/origin/master/master.etcd-ca.crt + +# etcd server & certificate vars +etcd_hostname: "{{ inventory_hostname }}" +etcd_ip: "{{ ansible_default_ipv4.address }}" +etcd_is_atomic: False +etcd_is_containerized: False +etcd_is_thirdparty: False + +# etcd dir vars +etcd_data_dir: "{{ '/var/lib/origin/openshift.local.etcd' if r_etcd_common_embedded_etcd | bool else '/var/lib/etcd/' if r_etcd_common_etcd_runtime != 'runc' else '/var/lib/etcd/etcd.etcd/' }}" + +# etcd ports and protocols +etcd_client_port: 2379 +etcd_peer_port: 2380 +etcd_url_scheme: http +etcd_peer_url_scheme: http etcd_initial_cluster_state: new etcd_initial_cluster_token: etcd-cluster-1 @@ -10,8 +70,15 @@ etcd_listen_peer_urls: "{{ etcd_peer_url_scheme }}://{{ etcd_ip }}:{{ etcd_peer_ etcd_advertise_client_urls: "{{ etcd_url_scheme }}://{{ etcd_ip }}:{{ etcd_client_port }}" etcd_listen_client_urls: "{{ etcd_url_scheme }}://{{ etcd_ip }}:{{ etcd_client_port }}" -etcd_client_port: 2379 -etcd_peer_port: 2380 +etcd_peer: 127.0.0.1 +etcdctlv2: "etcdctl --cert-file {{ etcd_peer_cert_file }} --key-file {{ etcd_peer_key_file }} --ca-file {{ etcd_peer_ca_file }} -C https://{{ etcd_peer }}:{{ etcd_client_port }}" + +etcd_service: "{{ 'etcd_container' if r_etcd_common_etcd_runtime == 'docker' else 'etcd' }}" +# Location of the service file is fixed and not meant to be changed +etcd_service_file: "/etc/systemd/system/{{ etcd_service }}.service" + +r_etcd_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_etcd_use_firewalld: "{{ os_firewall_use_firewalld | default(Falsel) }}" etcd_systemd_dir: "/etc/systemd/system/{{ etcd_service }}.service.d" r_etcd_os_firewall_deny: [] diff --git a/roles/etcd/library/delegated_serial_command.py b/roles/etcd/library/delegated_serial_command.py new file mode 100755 index 000000000..0cab1ca88 --- /dev/null +++ b/roles/etcd/library/delegated_serial_command.py @@ -0,0 +1,274 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2012, Michael DeHaan , and others +# (c) 2016, Andrew Butcher +# +# This module is derrived from the Ansible command module. +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + + +# pylint: disable=unused-wildcard-import,wildcard-import,unused-import,redefined-builtin + +''' delegated_serial_command ''' + +import datetime +import errno +import glob +import shlex +import os +import fcntl +import time + +DOCUMENTATION = ''' +--- +module: delegated_serial_command +short_description: Executes a command on a remote node +version_added: historical +description: + - The M(command) module takes the command name followed by a list + of space-delimited arguments. + - The given command will be executed on all selected nodes. It + will not be processed through the shell, so variables like + C($HOME) and operations like C("<"), C(">"), C("|"), and C("&") + will not work (use the M(shell) module if you need these + features). + - Creates and maintains a lockfile such that this module will + wait for other invocations to proceed. +options: + command: + description: + - the command to run + required: true + default: null + creates: + description: + - a filename or (since 2.0) glob pattern, when it already + exists, this step will B(not) be run. + required: no + default: null + removes: + description: + - a filename or (since 2.0) glob pattern, when it does not + exist, this step will B(not) be run. + version_added: "0.8" + required: no + default: null + chdir: + description: + - cd into this directory before running the command + version_added: "0.6" + required: false + default: null + executable: + description: + - change the shell used to execute the command. Should be an + absolute path to the executable. + required: false + default: null + version_added: "0.9" + warn: + version_added: "1.8" + default: yes + description: + - if command warnings are on in ansible.cfg, do not warn about + this particular line if set to no/false. + required: false + lockfile: + default: yes + description: + - the lockfile that will be created + timeout: + default: yes + description: + - time in milliseconds to wait to obtain the lock +notes: + - If you want to run a command through the shell (say you are using C(<), + C(>), C(|), etc), you actually want the M(shell) module instead. The + M(command) module is much more secure as it's not affected by the user's + environment. + - " C(creates), C(removes), and C(chdir) can be specified after + the command. For instance, if you only want to run a command if + a certain file does not exist, use this." +author: + - Ansible Core Team + - Michael DeHaan + - Andrew Butcher +''' + +EXAMPLES = ''' +# Example from Ansible Playbooks. +- delegated_serial_command: + command: /sbin/shutdown -t now + +# Run the command if the specified file does not exist. +- delegated_serial_command: + command: /usr/bin/make_database.sh arg1 arg2 + creates: /path/to/database +''' + +# Dict of options and their defaults +OPTIONS = {'chdir': None, + 'creates': None, + 'command': None, + 'executable': None, + 'NO_LOG': None, + 'removes': None, + 'warn': True, + 'lockfile': None, + 'timeout': None} + + +def check_command(commandline): + ''' Check provided command ''' + arguments = {'chown': 'owner', 'chmod': 'mode', 'chgrp': 'group', + 'ln': 'state=link', 'mkdir': 'state=directory', + 'rmdir': 'state=absent', 'rm': 'state=absent', 'touch': 'state=touch'} + commands = {'git': 'git', 'hg': 'hg', 'curl': 'get_url or uri', 'wget': 'get_url or uri', + 'svn': 'subversion', 'service': 'service', + 'mount': 'mount', 'rpm': 'yum, dnf or zypper', 'yum': 'yum', 'apt-get': 'apt', + 'tar': 'unarchive', 'unzip': 'unarchive', 'sed': 'template or lineinfile', + 'rsync': 'synchronize', 'dnf': 'dnf', 'zypper': 'zypper'} + become = ['sudo', 'su', 'pbrun', 'pfexec', 'runas'] + warnings = list() + command = os.path.basename(commandline.split()[0]) + # pylint: disable=line-too-long + if command in arguments: + warnings.append("Consider using file module with {0} rather than running {1}".format(arguments[command], command)) + if command in commands: + warnings.append("Consider using {0} module rather than running {1}".format(commands[command], command)) + if command in become: + warnings.append( + "Consider using 'become', 'become_method', and 'become_user' rather than running {0}".format(command,)) + return warnings + + +# pylint: disable=too-many-statements,too-many-branches,too-many-locals +def main(): + ''' Main module function ''' + module = AnsibleModule( # noqa: F405 + argument_spec=dict( + _uses_shell=dict(type='bool', default=False), + command=dict(required=True), + chdir=dict(), + executable=dict(), + creates=dict(), + removes=dict(), + warn=dict(type='bool', default=True), + lockfile=dict(default='/tmp/delegated_serial_command.lock'), + timeout=dict(type='int', default=30) + ) + ) + + shell = module.params['_uses_shell'] + chdir = module.params['chdir'] + executable = module.params['executable'] + command = module.params['command'] + creates = module.params['creates'] + removes = module.params['removes'] + warn = module.params['warn'] + lockfile = module.params['lockfile'] + timeout = module.params['timeout'] + + if command.strip() == '': + module.fail_json(rc=256, msg="no command given") + + iterated = 0 + lockfd = open(lockfile, 'w+') + while iterated < timeout: + try: + fcntl.flock(lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB) + break + # pylint: disable=invalid-name + except IOError as e: + if e.errno != errno.EAGAIN: + module.fail_json(msg="I/O Error {0}: {1}".format(e.errno, e.strerror)) + else: + iterated += 1 + time.sleep(0.1) + + if chdir: + chdir = os.path.abspath(os.path.expanduser(chdir)) + os.chdir(chdir) + + if creates: + # do not run the command if the line contains creates=filename + # and the filename already exists. This allows idempotence + # of command executions. + path = os.path.expanduser(creates) + if glob.glob(path): + module.exit_json( + cmd=command, + stdout="skipped, since %s exists" % path, + changed=False, + stderr=False, + rc=0 + ) + + if removes: + # do not run the command if the line contains removes=filename + # and the filename does not exist. This allows idempotence + # of command executions. + path = os.path.expanduser(removes) + if not glob.glob(path): + module.exit_json( + cmd=command, + stdout="skipped, since %s does not exist" % path, + changed=False, + stderr=False, + rc=0 + ) + + warnings = list() + if warn: + warnings = check_command(command) + + if not shell: + command = shlex.split(command) + startd = datetime.datetime.now() + + # pylint: disable=invalid-name + rc, out, err = module.run_command(command, executable=executable, use_unsafe_shell=shell) + + fcntl.flock(lockfd, fcntl.LOCK_UN) + lockfd.close() + + endd = datetime.datetime.now() + delta = endd - startd + + if out is None: + out = '' + if err is None: + err = '' + + module.exit_json( + cmd=command, + stdout=out.rstrip("\r\n"), + stderr=err.rstrip("\r\n"), + rc=rc, + start=str(startd), + end=str(endd), + delta=str(delta), + changed=True, + warnings=warnings, + iterated=iterated + ) + + +# import module snippets +# pylint: disable=wrong-import-position +from ansible.module_utils.basic import * # noqa: F402,F403 + +main() diff --git a/roles/etcd/meta/main.yml b/roles/etcd/meta/main.yml index 537c01c0e..879ca4f4e 100644 --- a/roles/etcd/meta/main.yml +++ b/roles/etcd/meta/main.yml @@ -19,4 +19,3 @@ dependencies: - role: lib_openshift - role: lib_os_firewall - role: lib_utils -- role: etcd_common diff --git a/roles/etcd/tasks/auxiliary/drop_etcdctl.yml b/roles/etcd/tasks/auxiliary/drop_etcdctl.yml new file mode 100644 index 000000000..6cb456677 --- /dev/null +++ b/roles/etcd/tasks/auxiliary/drop_etcdctl.yml @@ -0,0 +1,12 @@ +--- +- name: Install etcd for etcdctl + package: name=etcd{{ '-' + etcd_version if etcd_version is defined else '' }} state=present + when: not openshift.common.is_atomic | bool + +- name: Configure etcd profile.d alises + template: + dest: "/etc/profile.d/etcdctl.sh" + src: etcdctl.sh.j2 + mode: 0755 + owner: root + group: root diff --git a/roles/etcd/tasks/backup.yml b/roles/etcd/tasks/backup.yml new file mode 100644 index 000000000..c0538e596 --- /dev/null +++ b/roles/etcd/tasks/backup.yml @@ -0,0 +1,2 @@ +--- +- include: backup/backup.yml diff --git a/roles/etcd/tasks/backup/backup.yml b/roles/etcd/tasks/backup/backup.yml new file mode 100644 index 000000000..42d27c081 --- /dev/null +++ b/roles/etcd/tasks/backup/backup.yml @@ -0,0 +1,101 @@ +--- +# set the etcd backup directory name here in case the tag or sufix consists of dynamic value that changes over time +# e.g. openshift-backup-{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }} value will change every second so if the date changes +# right after setting l_etcd_incontainer_backup_dir and before l_etcd_backup_dir facts, the backup directory name is different +- set_fact: + l_backup_dir_name: "openshift-backup-{{ r_etcd_common_backup_tag }}{{ r_etcd_common_backup_sufix_name }}" + +- set_fact: + l_etcd_data_dir: "{{ etcd_data_dir }}{{ '/etcd.etcd' if r_etcd_common_etcd_runtime == 'runc' else '' }}" + +- set_fact: + l_etcd_incontainer_data_dir: "{{ etcd_data_dir }}" + +- set_fact: + l_etcd_incontainer_backup_dir: "{{ l_etcd_incontainer_data_dir }}/{{ l_backup_dir_name }}" + +- set_fact: + l_etcd_backup_dir: "{{ l_etcd_data_dir }}/{{ l_backup_dir_name }}" + +# TODO: replace shell module with command and update later checks +- name: Check available disk space for etcd backup + shell: df --output=avail -k {{ l_etcd_data_dir }} | tail -n 1 + register: l_avail_disk + # AUDIT:changed_when: `false` because we are only inspecting + # state, not manipulating anything + changed_when: false + +# TODO: replace shell module with command and update later checks +- name: Check current etcd disk usage + shell: du --exclude='*openshift-backup*' -k {{ l_etcd_data_dir }} | tail -n 1 | cut -f1 + register: l_etcd_disk_usage + # AUDIT:changed_when: `false` because we are only inspecting + # state, not manipulating anything + changed_when: false + +- name: Abort if insufficient disk space for etcd backup + fail: + msg: > + {{ l_etcd_disk_usage.stdout|int*2 }} Kb disk space required for etcd backup, + {{ l_avail_disk.stdout }} Kb available. + when: l_etcd_disk_usage.stdout|int*2 > l_avail_disk.stdout|int + +# For non containerized and non embedded we should have the correct version of +# etcd installed already. So don't do anything. +# +# For containerized installs we now exec into etcd_container +# +# For embedded non containerized we need to ensure we have the latest version +# etcd on the host. +- name: Detecting Atomic Host Operating System + stat: + path: /run/ostree-booted + register: l_ostree_booted + +- name: Install latest etcd for embedded + package: + name: etcd + state: latest + when: + - r_etcd_common_embedded_etcd | bool + - not l_ostree_booted.stat.exists | bool + +- name: Check selinux label of '{{ l_etcd_data_dir }}' + command: > + stat -c '%C' {{ l_etcd_data_dir }} + register: l_etcd_selinux_labels + +- debug: + msg: "{{ l_etcd_selinux_labels }}" + +- name: Make sure the '{{ l_etcd_data_dir }}' has the proper label + command: > + chcon -t svirt_sandbox_file_t "{{ l_etcd_data_dir }}" + when: + - l_etcd_selinux_labels.rc == 0 + - "'svirt_sandbox_file_t' not in l_etcd_selinux_labels.stdout" + +- name: Generate etcd backup + command: > + {{ r_etcd_common_etcdctl_command }} backup --data-dir={{ l_etcd_incontainer_data_dir }} + --backup-dir={{ l_etcd_incontainer_backup_dir }} + +# According to the docs change you can simply copy snap/db +# https://github.com/openshift/openshift-docs/commit/b38042de02d9780842dce95cfa0ef45d53b58bc6 +- name: Check for v3 data store + stat: + path: "{{ l_etcd_data_dir }}/member/snap/db" + register: l_v3_db + +- name: Copy etcd v3 data store + command: > + cp -a {{ l_etcd_data_dir }}/member/snap/db + {{ l_etcd_backup_dir }}/member/snap/ + when: l_v3_db.stat.exists + +- set_fact: + r_etcd_common_backup_complete: True + +- name: Display location of etcd backup + debug: + msg: "Etcd backup created in {{ l_etcd_backup_dir }}" diff --git a/roles/etcd/tasks/backup_ca_certificates.yml b/roles/etcd/tasks/backup_ca_certificates.yml new file mode 100644 index 000000000..a41b032f3 --- /dev/null +++ b/roles/etcd/tasks/backup_ca_certificates.yml @@ -0,0 +1,2 @@ +--- +- include: certificates/backup_ca_certificates.yml diff --git a/roles/etcd/tasks/backup_generated_certificates.yml b/roles/etcd/tasks/backup_generated_certificates.yml new file mode 100644 index 000000000..8cf2a10cc --- /dev/null +++ b/roles/etcd/tasks/backup_generated_certificates.yml @@ -0,0 +1,2 @@ +--- +- include: certificates/backup_generated_certificates.yml diff --git a/roles/etcd/tasks/backup_server_certificates.yml b/roles/etcd/tasks/backup_server_certificates.yml new file mode 100644 index 000000000..267ffeb4d --- /dev/null +++ b/roles/etcd/tasks/backup_server_certificates.yml @@ -0,0 +1,2 @@ +--- +- include: certificates/backup_server_certificates.yml diff --git a/roles/etcd/tasks/ca.yml b/roles/etcd/tasks/ca.yml index 7cda49069..cca1e9ad7 100644 --- a/roles/etcd/tasks/ca.yml +++ b/roles/etcd/tasks/ca.yml @@ -1,2 +1,2 @@ --- -- include: ca/deploy.yml +- include: certificates/deploy_ca.yml diff --git a/roles/etcd/tasks/ca/deploy.yml b/roles/etcd/tasks/ca/deploy.yml deleted file mode 100644 index 3d32290a2..000000000 --- a/roles/etcd/tasks/ca/deploy.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- -- name: Install openssl - package: - name: openssl - state: present - when: not etcd_is_atomic | bool - delegate_to: "{{ etcd_ca_host }}" - run_once: true - -- file: - path: "{{ item }}" - state: directory - mode: 0700 - owner: root - group: root - with_items: - - "{{ etcd_ca_new_certs_dir }}" - - "{{ etcd_ca_crl_dir }}" - - "{{ etcd_ca_dir }}/fragments" - delegate_to: "{{ etcd_ca_host }}" - run_once: true - -- command: cp /etc/pki/tls/openssl.cnf ./ - args: - chdir: "{{ etcd_ca_dir }}/fragments" - creates: "{{ etcd_ca_dir }}/fragments/openssl.cnf" - delegate_to: "{{ etcd_ca_host }}" - run_once: true - -- template: - dest: "{{ etcd_ca_dir }}/fragments/openssl_append.cnf" - src: openssl_append.j2 - backup: true - delegate_to: "{{ etcd_ca_host }}" - run_once: true - -- assemble: - src: "{{ etcd_ca_dir }}/fragments" - dest: "{{ etcd_openssl_conf }}" - delegate_to: "{{ etcd_ca_host }}" - run_once: true - -- name: Check etcd_ca_db exist - stat: path="{{ etcd_ca_db }}" - register: etcd_ca_db_check - changed_when: false - delegate_to: "{{ etcd_ca_host }}" - run_once: true - -- name: Touch etcd_ca_db file - file: - path: "{{ etcd_ca_db }}" - state: touch - when: etcd_ca_db_check.stat.isreg is not defined - delegate_to: "{{ etcd_ca_host }}" - run_once: true - -- copy: - dest: "{{ etcd_ca_serial }}" - content: "01" - force: no - delegate_to: "{{ etcd_ca_host }}" - run_once: true - -- name: Create etcd CA certificate - command: > - openssl req -config {{ etcd_openssl_conf }} -newkey rsa:4096 - -keyout {{ etcd_ca_key }} -new -out {{ etcd_ca_cert }} - -x509 -extensions {{ etcd_ca_exts_self }} -batch -nodes - -days {{ etcd_ca_default_days }} - -subj /CN=etcd-signer@{{ ansible_date_time.epoch }} - args: - chdir: "{{ etcd_ca_dir }}" - creates: "{{ etcd_ca_cert }}" - environment: - SAN: 'etcd-signer' - delegate_to: "{{ etcd_ca_host }}" - run_once: true diff --git a/roles/etcd/tasks/certificates/backup_ca_certificates.yml b/roles/etcd/tasks/certificates/backup_ca_certificates.yml new file mode 100644 index 000000000..f60eb82ef --- /dev/null +++ b/roles/etcd/tasks/certificates/backup_ca_certificates.yml @@ -0,0 +1,12 @@ +--- +- name: Determine if CA certificate directory exists + stat: + path: "{{ etcd_ca_dir }}" + register: etcd_ca_certs_dir_stat +- name: Backup generated etcd certificates + command: > + tar -czf {{ etcd_conf_dir }}/etcd-ca-certificate-backup-{{ ansible_date_time.epoch }}.tgz + {{ etcd_ca_dir }} + args: + warn: no + when: etcd_ca_certs_dir_stat.stat.exists | bool diff --git a/roles/etcd/tasks/certificates/backup_generated_certificates.yml b/roles/etcd/tasks/certificates/backup_generated_certificates.yml new file mode 100644 index 000000000..6a24cfcb3 --- /dev/null +++ b/roles/etcd/tasks/certificates/backup_generated_certificates.yml @@ -0,0 +1,13 @@ +--- +- name: Determine if generated etcd certificates exist + stat: + path: "{{ etcd_conf_dir }}/generated_certs" + register: etcd_generated_certs_dir_stat + +- name: Backup generated etcd certificates + command: > + tar -czf {{ etcd_conf_dir }}/etcd-generated-certificate-backup-{{ ansible_date_time.epoch }}.tgz + {{ etcd_conf_dir }}/generated_certs + args: + warn: no + when: etcd_generated_certs_dir_stat.stat.exists | bool diff --git a/roles/etcd/tasks/certificates/backup_server_certificates.yml b/roles/etcd/tasks/certificates/backup_server_certificates.yml new file mode 100644 index 000000000..8e6cc6965 --- /dev/null +++ b/roles/etcd/tasks/certificates/backup_server_certificates.yml @@ -0,0 +1,11 @@ +--- +- name: Backup etcd certificates + command: > + tar -czvf /etc/etcd/etcd-server-certificate-backup-{{ ansible_date_time.epoch }}.tgz + {{ etcd_conf_dir }}/ca.crt + {{ etcd_conf_dir }}/server.crt + {{ etcd_conf_dir }}/server.key + {{ etcd_conf_dir }}/peer.crt + {{ etcd_conf_dir }}/peer.key + args: + warn: no diff --git a/roles/etcd/tasks/certificates/deploy_ca.yml b/roles/etcd/tasks/certificates/deploy_ca.yml new file mode 100644 index 000000000..3d32290a2 --- /dev/null +++ b/roles/etcd/tasks/certificates/deploy_ca.yml @@ -0,0 +1,78 @@ +--- +- name: Install openssl + package: + name: openssl + state: present + when: not etcd_is_atomic | bool + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- file: + path: "{{ item }}" + state: directory + mode: 0700 + owner: root + group: root + with_items: + - "{{ etcd_ca_new_certs_dir }}" + - "{{ etcd_ca_crl_dir }}" + - "{{ etcd_ca_dir }}/fragments" + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- command: cp /etc/pki/tls/openssl.cnf ./ + args: + chdir: "{{ etcd_ca_dir }}/fragments" + creates: "{{ etcd_ca_dir }}/fragments/openssl.cnf" + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- template: + dest: "{{ etcd_ca_dir }}/fragments/openssl_append.cnf" + src: openssl_append.j2 + backup: true + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- assemble: + src: "{{ etcd_ca_dir }}/fragments" + dest: "{{ etcd_openssl_conf }}" + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- name: Check etcd_ca_db exist + stat: path="{{ etcd_ca_db }}" + register: etcd_ca_db_check + changed_when: false + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- name: Touch etcd_ca_db file + file: + path: "{{ etcd_ca_db }}" + state: touch + when: etcd_ca_db_check.stat.isreg is not defined + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- copy: + dest: "{{ etcd_ca_serial }}" + content: "01" + force: no + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- name: Create etcd CA certificate + command: > + openssl req -config {{ etcd_openssl_conf }} -newkey rsa:4096 + -keyout {{ etcd_ca_key }} -new -out {{ etcd_ca_cert }} + -x509 -extensions {{ etcd_ca_exts_self }} -batch -nodes + -days {{ etcd_ca_default_days }} + -subj /CN=etcd-signer@{{ ansible_date_time.epoch }} + args: + chdir: "{{ etcd_ca_dir }}" + creates: "{{ etcd_ca_cert }}" + environment: + SAN: 'etcd-signer' + delegate_to: "{{ etcd_ca_host }}" + run_once: true diff --git a/roles/etcd/tasks/certificates/distribute_ca.yml b/roles/etcd/tasks/certificates/distribute_ca.yml new file mode 100644 index 000000000..632ac15dd --- /dev/null +++ b/roles/etcd/tasks/certificates/distribute_ca.yml @@ -0,0 +1,47 @@ +--- +- name: Create a tarball of the etcd ca certs + command: > + tar -czvf {{ etcd_conf_dir }}/{{ etcd_ca_name }}.tgz + -C {{ etcd_ca_dir }} . + args: + creates: "{{ etcd_conf_dir }}/{{ etcd_ca_name }}.tgz" + warn: no + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- name: Retrieve etcd ca cert tarball + fetch: + src: "{{ etcd_conf_dir }}/{{ etcd_ca_name }}.tgz" + dest: "{{ etcd_sync_cert_dir }}/" + flat: yes + fail_on_missing: yes + validate_checksum: yes + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- name: Ensure ca directory exists + file: + path: "{{ etcd_ca_dir }}" + state: directory + +- name: Unarchive etcd ca cert tarballs + unarchive: + src: "{{ etcd_sync_cert_dir }}/{{ etcd_ca_name }}.tgz" + dest: "{{ etcd_ca_dir }}" + +- name: Read current etcd CA + slurp: + src: "{{ etcd_conf_dir }}/ca.crt" + register: g_current_etcd_ca_output + +- name: Read new etcd CA + slurp: + src: "{{ etcd_ca_dir }}/ca.crt" + register: g_new_etcd_ca_output + +- copy: + content: "{{ (g_new_etcd_ca_output.content|b64decode) + (g_current_etcd_ca_output.content|b64decode) }}" + dest: "{{ item }}/ca.crt" + with_items: + - "{{ etcd_conf_dir }}" + - "{{ etcd_ca_dir }}" diff --git a/roles/etcd/tasks/certificates/fetch_client_certificates_from_ca.yml b/roles/etcd/tasks/certificates/fetch_client_certificates_from_ca.yml new file mode 100644 index 000000000..119071a72 --- /dev/null +++ b/roles/etcd/tasks/certificates/fetch_client_certificates_from_ca.yml @@ -0,0 +1,138 @@ +--- +- name: Ensure CA certificate exists on etcd_ca_host + stat: + path: "{{ etcd_ca_cert }}" + register: g_ca_cert_stat_result + delegate_to: "{{ etcd_ca_host }}" + run_once: true + +- fail: + msg: > + CA certificate {{ etcd_ca_cert }} doesn't exist on CA host + {{ etcd_ca_host }}. Apply 'etcd_ca' action from `etcd` role to + {{ etcd_ca_host }}. + when: not g_ca_cert_stat_result.stat.exists | bool + run_once: true + +- name: Check status of external etcd certificatees + stat: + path: "{{ etcd_cert_config_dir }}/{{ item }}" + with_items: + - "{{ etcd_cert_prefix }}client.crt" + - "{{ etcd_cert_prefix }}client.key" + - "{{ etcd_cert_prefix }}ca.crt" + register: g_external_etcd_cert_stat_result + when: not etcd_certificates_redeploy | default(false) | bool + +- set_fact: + etcd_client_certs_missing: "{{ true if etcd_certificates_redeploy | default(false) | bool + else (False in (g_external_etcd_cert_stat_result.results + | default({}) + | oo_collect(attribute='stat.exists') + | list)) }}" + +- name: Ensure generated_certs directory present + file: + path: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" + state: directory + mode: 0700 + when: etcd_client_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Create the client csr + command: > + openssl req -new -keyout {{ etcd_cert_prefix }}client.key + -config {{ etcd_openssl_conf }} + -out {{ etcd_cert_prefix }}client.csr + -reqexts {{ etcd_req_ext }} -batch -nodes + -subj /CN={{ etcd_hostname }} + args: + chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" + creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' + ~ etcd_cert_prefix ~ 'client.csr' }}" + environment: + SAN: "IP:{{ etcd_ip }},DNS:{{ etcd_hostname }}" + when: etcd_client_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +# Certificates must be signed serially in order to avoid competing +# for the serial file. +- name: Sign and create the client crt + delegated_serial_command: + command: > + openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }} + -out {{ etcd_cert_prefix }}client.crt + -in {{ etcd_cert_prefix }}client.csr + -batch + chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" + creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' + ~ etcd_cert_prefix ~ 'client.crt' }}" + environment: + SAN: "IP:{{ etcd_ip }}" + when: etcd_client_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- file: + src: "{{ etcd_ca_cert }}" + dest: "{{ etcd_generated_certs_dir}}/{{ etcd_cert_subdir }}/{{ etcd_cert_prefix }}ca.crt" + state: hard + when: etcd_client_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Create local temp directory for syncing certs + local_action: command mktemp -d /tmp/etcd_certificates-XXXXXXX + register: g_etcd_client_mktemp + changed_when: False + when: etcd_client_certs_missing | bool + become: no + +- name: Create a tarball of the etcd certs + command: > + tar -czvf {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz + -C {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }} . + args: + creates: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" + # Disables the following warning: + # Consider using unarchive module rather than running tar + warn: no + when: etcd_client_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Retrieve the etcd cert tarballs + fetch: + src: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" + dest: "{{ g_etcd_client_mktemp.stdout }}/" + flat: yes + fail_on_missing: yes + validate_checksum: yes + when: etcd_client_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Ensure certificate directory exists + file: + path: "{{ etcd_cert_config_dir }}" + state: directory + when: etcd_client_certs_missing | bool + +- name: Unarchive etcd cert tarballs + unarchive: + src: "{{ g_etcd_client_mktemp.stdout }}/{{ etcd_cert_subdir }}.tgz" + dest: "{{ etcd_cert_config_dir }}" + when: etcd_client_certs_missing | bool + +- file: + path: "{{ etcd_cert_config_dir }}/{{ item }}" + owner: root + group: root + mode: 0600 + with_items: + - "{{ etcd_cert_prefix }}client.crt" + - "{{ etcd_cert_prefix }}client.key" + - "{{ etcd_cert_prefix }}ca.crt" + when: etcd_client_certs_missing | bool + +- name: Delete temporary directory + local_action: file path="{{ g_etcd_client_mktemp.stdout }}" state=absent + changed_when: False + when: etcd_client_certs_missing | bool + become: no diff --git a/roles/etcd/tasks/certificates/fetch_server_certificates_from_ca.yml b/roles/etcd/tasks/certificates/fetch_server_certificates_from_ca.yml new file mode 100644 index 000000000..26492fb3c --- /dev/null +++ b/roles/etcd/tasks/certificates/fetch_server_certificates_from_ca.yml @@ -0,0 +1,234 @@ +--- +- name: Install etcd + package: + name: "etcd{{ '-' + etcd_version if etcd_version is defined else '' }}" + state: present + when: not etcd_is_containerized | bool + +- name: Check status of etcd certificates + stat: + path: "{{ item }}" + with_items: + - "{{ etcd_cert_config_dir }}/{{ etcd_cert_prefix }}server.crt" + - "{{ etcd_cert_config_dir }}/{{ etcd_cert_prefix }}peer.crt" + - "{{ etcd_cert_config_dir }}/{{ etcd_cert_prefix }}ca.crt" + - "{{ etcd_system_container_cert_config_dir }}/{{ etcd_cert_prefix }}server.crt" + - "{{ etcd_system_container_cert_config_dir }}/{{ etcd_cert_prefix }}peer.crt" + - "{{ etcd_system_container_cert_config_dir }}/{{ etcd_cert_prefix }}ca.crt" + register: g_etcd_server_cert_stat_result + when: not etcd_certificates_redeploy | default(false) | bool + +- set_fact: + etcd_server_certs_missing: "{{ true if etcd_certificates_redeploy | default(false) | bool + else (False in (g_etcd_server_cert_stat_result.results + | default({}) + | oo_collect(attribute='stat.exists') + | list)) }}" + +- name: Ensure generated_certs directory present + file: + path: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" + state: directory + mode: 0700 + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Create the server csr + command: > + openssl req -new -keyout {{ etcd_cert_prefix }}server.key + -config {{ etcd_openssl_conf }} + -out {{ etcd_cert_prefix }}server.csr + -reqexts {{ etcd_req_ext }} -batch -nodes + -subj /CN={{ etcd_hostname }} + args: + chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" + creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' + ~ etcd_cert_prefix ~ 'server.csr' }}" + environment: + SAN: "IP:{{ etcd_ip }},DNS:{{ etcd_hostname }}" + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +# Certificates must be signed serially in order to avoid competing +# for the serial file. +- name: Sign and create the server crt + delegated_serial_command: + command: > + openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }} + -out {{ etcd_cert_prefix }}server.crt + -in {{ etcd_cert_prefix }}server.csr + -extensions {{ etcd_ca_exts_server }} -batch + chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" + creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' + ~ etcd_cert_prefix ~ 'server.crt' }}" + environment: + SAN: "IP:{{ etcd_ip }}" + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Create the peer csr + command: > + openssl req -new -keyout {{ etcd_cert_prefix }}peer.key + -config {{ etcd_openssl_conf }} + -out {{ etcd_cert_prefix }}peer.csr + -reqexts {{ etcd_req_ext }} -batch -nodes + -subj /CN={{ etcd_hostname }} + args: + chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" + creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' + ~ etcd_cert_prefix ~ 'peer.csr' }}" + environment: + SAN: "IP:{{ etcd_ip }},DNS:{{ etcd_hostname }}" + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +# Certificates must be signed serially in order to avoid competing +# for the serial file. +- name: Sign and create the peer crt + delegated_serial_command: + command: > + openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }} + -out {{ etcd_cert_prefix }}peer.crt + -in {{ etcd_cert_prefix }}peer.csr + -extensions {{ etcd_ca_exts_peer }} -batch + chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" + creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' + ~ etcd_cert_prefix ~ 'peer.crt' }}" + environment: + SAN: "IP:{{ etcd_ip }}" + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- file: + src: "{{ etcd_ca_cert }}" + dest: "{{ etcd_generated_certs_dir}}/{{ etcd_cert_subdir }}/{{ etcd_cert_prefix }}ca.crt" + state: hard + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Create local temp directory for syncing certs + local_action: command mktemp -d /tmp/etcd_certificates-XXXXXXX + become: no + register: g_etcd_server_mktemp + changed_when: False + when: etcd_server_certs_missing | bool + +- name: Create a tarball of the etcd certs + command: > + tar -czvf {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz + -C {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }} . + args: + creates: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" + # Disables the following warning: + # Consider using unarchive module rather than running tar + warn: no + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Retrieve etcd cert tarball + fetch: + src: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" + dest: "{{ g_etcd_server_mktemp.stdout }}/" + flat: yes + fail_on_missing: yes + validate_checksum: yes + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Ensure certificate directory exists + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ etcd_cert_config_dir }}" + - "{{ etcd_system_container_cert_config_dir }}" + when: etcd_server_certs_missing | bool + +- name: Unarchive cert tarball + unarchive: + src: "{{ g_etcd_server_mktemp.stdout }}/{{ etcd_cert_subdir }}.tgz" + dest: "{{ etcd_cert_config_dir }}" + when: etcd_server_certs_missing | bool + +- name: Create a tarball of the etcd ca certs + command: > + tar -czvf {{ etcd_generated_certs_dir }}/{{ etcd_ca_name }}.tgz + -C {{ etcd_ca_dir }} . + args: + creates: "{{ etcd_generated_certs_dir }}/{{ etcd_ca_name }}.tgz" + warn: no + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Retrieve etcd ca cert tarball + fetch: + src: "{{ etcd_generated_certs_dir }}/{{ etcd_ca_name }}.tgz" + dest: "{{ g_etcd_server_mktemp.stdout }}/" + flat: yes + fail_on_missing: yes + validate_checksum: yes + when: etcd_server_certs_missing | bool + delegate_to: "{{ etcd_ca_host }}" + +- name: Ensure ca directory exists + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ etcd_ca_dir }}" + - "{{ etcd_system_container_cert_config_dir }}/ca" + when: etcd_server_certs_missing | bool + +- name: Unarchive cert tarball for the system container + unarchive: + src: "{{ g_etcd_server_mktemp.stdout }}/{{ etcd_cert_subdir }}.tgz" + dest: "{{ etcd_system_container_cert_config_dir }}" + when: + - etcd_server_certs_missing | bool + - r_etcd_common_etcd_runtime == 'runc' + +- name: Unarchive etcd ca cert tarballs for the system container + unarchive: + src: "{{ g_etcd_server_mktemp.stdout }}/{{ etcd_ca_name }}.tgz" + dest: "{{ etcd_system_container_cert_config_dir }}/ca" + when: + - etcd_server_certs_missing | bool + - r_etcd_common_etcd_runtime == 'runc' + +- name: Delete temporary directory + local_action: file path="{{ g_etcd_server_mktemp.stdout }}" state=absent + become: no + changed_when: False + when: etcd_server_certs_missing | bool + +- name: Validate permissions on certificate files + file: + path: "{{ item }}" + mode: 0600 + owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" + group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" + when: etcd_url_scheme == 'https' + with_items: + - "{{ etcd_ca_file }}" + - "{{ etcd_cert_file }}" + - "{{ etcd_key_file }}" + +- name: Validate permissions on peer certificate files + file: + path: "{{ item }}" + mode: 0600 + owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" + group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" + when: etcd_peer_url_scheme == 'https' + with_items: + - "{{ etcd_peer_ca_file }}" + - "{{ etcd_peer_cert_file }}" + - "{{ etcd_peer_key_file }}" + +- name: Validate permissions on the config dir + file: + path: "{{ etcd_conf_dir }}" + state: directory + owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" + group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" + mode: 0700 diff --git a/roles/etcd/tasks/certificates/remove_ca_certificates.yml b/roles/etcd/tasks/certificates/remove_ca_certificates.yml new file mode 100644 index 000000000..4a86eb60d --- /dev/null +++ b/roles/etcd/tasks/certificates/remove_ca_certificates.yml @@ -0,0 +1,5 @@ +--- +- name: Remove CA certificate directory + file: + path: "{{ etcd_ca_dir }}" + state: absent diff --git a/roles/etcd/tasks/certificates/remove_generated_certificates.yml b/roles/etcd/tasks/certificates/remove_generated_certificates.yml new file mode 100644 index 000000000..993b18de2 --- /dev/null +++ b/roles/etcd/tasks/certificates/remove_generated_certificates.yml @@ -0,0 +1,5 @@ +--- +- name: Remove generated etcd certificates + file: + path: "{{ etcd_conf_dir }}/generated_certs" + state: absent diff --git a/roles/etcd/tasks/certificates/retrieve_ca_certificates.yml b/roles/etcd/tasks/certificates/retrieve_ca_certificates.yml new file mode 100644 index 000000000..70b5c6523 --- /dev/null +++ b/roles/etcd/tasks/certificates/retrieve_ca_certificates.yml @@ -0,0 +1,8 @@ +--- +- name: Retrieve etcd CA certificate + fetch: + src: "{{ etcd_conf_dir }}/ca.crt" + dest: "{{ etcd_sync_cert_dir }}/" + flat: yes + fail_on_missing: yes + validate_checksum: yes diff --git a/roles/etcd/tasks/client_certificates.yml b/roles/etcd/tasks/client_certificates.yml index 2e9c078b9..2f4108a0d 100644 --- a/roles/etcd/tasks/client_certificates.yml +++ b/roles/etcd/tasks/client_certificates.yml @@ -1,2 +1,2 @@ --- -- include: client_certificates/fetch_from_ca.yml +- include: certificates/fetch_client_certificates_from_ca.yml diff --git a/roles/etcd/tasks/client_certificates/fetch_from_ca.yml b/roles/etcd/tasks/client_certificates/fetch_from_ca.yml deleted file mode 100644 index 119071a72..000000000 --- a/roles/etcd/tasks/client_certificates/fetch_from_ca.yml +++ /dev/null @@ -1,138 +0,0 @@ ---- -- name: Ensure CA certificate exists on etcd_ca_host - stat: - path: "{{ etcd_ca_cert }}" - register: g_ca_cert_stat_result - delegate_to: "{{ etcd_ca_host }}" - run_once: true - -- fail: - msg: > - CA certificate {{ etcd_ca_cert }} doesn't exist on CA host - {{ etcd_ca_host }}. Apply 'etcd_ca' action from `etcd` role to - {{ etcd_ca_host }}. - when: not g_ca_cert_stat_result.stat.exists | bool - run_once: true - -- name: Check status of external etcd certificatees - stat: - path: "{{ etcd_cert_config_dir }}/{{ item }}" - with_items: - - "{{ etcd_cert_prefix }}client.crt" - - "{{ etcd_cert_prefix }}client.key" - - "{{ etcd_cert_prefix }}ca.crt" - register: g_external_etcd_cert_stat_result - when: not etcd_certificates_redeploy | default(false) | bool - -- set_fact: - etcd_client_certs_missing: "{{ true if etcd_certificates_redeploy | default(false) | bool - else (False in (g_external_etcd_cert_stat_result.results - | default({}) - | oo_collect(attribute='stat.exists') - | list)) }}" - -- name: Ensure generated_certs directory present - file: - path: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" - state: directory - mode: 0700 - when: etcd_client_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Create the client csr - command: > - openssl req -new -keyout {{ etcd_cert_prefix }}client.key - -config {{ etcd_openssl_conf }} - -out {{ etcd_cert_prefix }}client.csr - -reqexts {{ etcd_req_ext }} -batch -nodes - -subj /CN={{ etcd_hostname }} - args: - chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" - creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' - ~ etcd_cert_prefix ~ 'client.csr' }}" - environment: - SAN: "IP:{{ etcd_ip }},DNS:{{ etcd_hostname }}" - when: etcd_client_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -# Certificates must be signed serially in order to avoid competing -# for the serial file. -- name: Sign and create the client crt - delegated_serial_command: - command: > - openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }} - -out {{ etcd_cert_prefix }}client.crt - -in {{ etcd_cert_prefix }}client.csr - -batch - chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" - creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' - ~ etcd_cert_prefix ~ 'client.crt' }}" - environment: - SAN: "IP:{{ etcd_ip }}" - when: etcd_client_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- file: - src: "{{ etcd_ca_cert }}" - dest: "{{ etcd_generated_certs_dir}}/{{ etcd_cert_subdir }}/{{ etcd_cert_prefix }}ca.crt" - state: hard - when: etcd_client_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Create local temp directory for syncing certs - local_action: command mktemp -d /tmp/etcd_certificates-XXXXXXX - register: g_etcd_client_mktemp - changed_when: False - when: etcd_client_certs_missing | bool - become: no - -- name: Create a tarball of the etcd certs - command: > - tar -czvf {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz - -C {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }} . - args: - creates: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" - # Disables the following warning: - # Consider using unarchive module rather than running tar - warn: no - when: etcd_client_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Retrieve the etcd cert tarballs - fetch: - src: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" - dest: "{{ g_etcd_client_mktemp.stdout }}/" - flat: yes - fail_on_missing: yes - validate_checksum: yes - when: etcd_client_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Ensure certificate directory exists - file: - path: "{{ etcd_cert_config_dir }}" - state: directory - when: etcd_client_certs_missing | bool - -- name: Unarchive etcd cert tarballs - unarchive: - src: "{{ g_etcd_client_mktemp.stdout }}/{{ etcd_cert_subdir }}.tgz" - dest: "{{ etcd_cert_config_dir }}" - when: etcd_client_certs_missing | bool - -- file: - path: "{{ etcd_cert_config_dir }}/{{ item }}" - owner: root - group: root - mode: 0600 - with_items: - - "{{ etcd_cert_prefix }}client.crt" - - "{{ etcd_cert_prefix }}client.key" - - "{{ etcd_cert_prefix }}ca.crt" - when: etcd_client_certs_missing | bool - -- name: Delete temporary directory - local_action: file path="{{ g_etcd_client_mktemp.stdout }}" state=absent - changed_when: False - when: etcd_client_certs_missing | bool - become: no diff --git a/roles/etcd/tasks/distribute_ca b/roles/etcd/tasks/distribute_ca new file mode 100644 index 000000000..040c5f7af --- /dev/null +++ b/roles/etcd/tasks/distribute_ca @@ -0,0 +1,2 @@ +--- +- include: certificates/distribute_ca.yml diff --git a/roles/etcd/tasks/drop_etcdctl.yml b/roles/etcd/tasks/drop_etcdctl.yml new file mode 100644 index 000000000..4c1f609f7 --- /dev/null +++ b/roles/etcd/tasks/drop_etcdctl.yml @@ -0,0 +1,2 @@ +--- +- include: auxiliary/drop_etcdctl.yml diff --git a/roles/etcd/tasks/main.yml b/roles/etcd/tasks/main.yml index 870c11ad4..f643d292d 100644 --- a/roles/etcd/tasks/main.yml +++ b/roles/etcd/tasks/main.yml @@ -16,10 +16,7 @@ package: name=etcd{{ '-' + etcd_version if etcd_version is defined else '' }} state=present when: not etcd_is_containerized | bool -- include_role: - name: etcd_common - vars: - r_etcd_common_action: drop_etcdctl +- include: drop_etcdctl.yml when: - openshift_etcd_etcdctl_profile | default(true) | bool diff --git a/roles/etcd/tasks/remove_ca_certificates.yml b/roles/etcd/tasks/remove_ca_certificates.yml new file mode 100644 index 000000000..36df1a1cc --- /dev/null +++ b/roles/etcd/tasks/remove_ca_certificates.yml @@ -0,0 +1,2 @@ +--- +- include: certificates/remove_ca_certificates.yml diff --git a/roles/etcd/tasks/remove_generated_certificates.yml b/roles/etcd/tasks/remove_generated_certificates.yml new file mode 100644 index 000000000..b10a4b32d --- /dev/null +++ b/roles/etcd/tasks/remove_generated_certificates.yml @@ -0,0 +1,2 @@ +--- +- include: certificates/remove_generated_certificates.yml diff --git a/roles/etcd/tasks/retrieve_ca_certificates.yml b/roles/etcd/tasks/retrieve_ca_certificates.yml new file mode 100644 index 000000000..bd6c4ec85 --- /dev/null +++ b/roles/etcd/tasks/retrieve_ca_certificates.yml @@ -0,0 +1,2 @@ +--- +- include: certificates/retrieve_ca_certificates.yml diff --git a/roles/etcd/tasks/server_certificates.yml b/roles/etcd/tasks/server_certificates.yml index f0ba58b6e..ae26079f9 100644 --- a/roles/etcd/tasks/server_certificates.yml +++ b/roles/etcd/tasks/server_certificates.yml @@ -1,2 +1,6 @@ --- -- include: server_certificates/fetch_from_ca.yml +- include: ca.yml + when: + - etcd_ca_setup | default(True) | bool + +- include: certificates/fetch_server_certificates_from_ca.yml diff --git a/roles/etcd/tasks/server_certificates/fetch_from_ca.yml b/roles/etcd/tasks/server_certificates/fetch_from_ca.yml deleted file mode 100644 index 064fe1952..000000000 --- a/roles/etcd/tasks/server_certificates/fetch_from_ca.yml +++ /dev/null @@ -1,238 +0,0 @@ ---- -- include: ../ca/deploy.yml - when: - - etcd_ca_setup | default(True) | bool - -- name: Install etcd - package: - name: "etcd{{ '-' + etcd_version if etcd_version is defined else '' }}" - state: present - when: not etcd_is_containerized | bool - -- name: Check status of etcd certificates - stat: - path: "{{ item }}" - with_items: - - "{{ etcd_cert_config_dir }}/{{ etcd_cert_prefix }}server.crt" - - "{{ etcd_cert_config_dir }}/{{ etcd_cert_prefix }}peer.crt" - - "{{ etcd_cert_config_dir }}/{{ etcd_cert_prefix }}ca.crt" - - "{{ etcd_system_container_cert_config_dir }}/{{ etcd_cert_prefix }}server.crt" - - "{{ etcd_system_container_cert_config_dir }}/{{ etcd_cert_prefix }}peer.crt" - - "{{ etcd_system_container_cert_config_dir }}/{{ etcd_cert_prefix }}ca.crt" - register: g_etcd_server_cert_stat_result - when: not etcd_certificates_redeploy | default(false) | bool - -- set_fact: - etcd_server_certs_missing: "{{ true if etcd_certificates_redeploy | default(false) | bool - else (False in (g_etcd_server_cert_stat_result.results - | default({}) - | oo_collect(attribute='stat.exists') - | list)) }}" - -- name: Ensure generated_certs directory present - file: - path: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" - state: directory - mode: 0700 - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Create the server csr - command: > - openssl req -new -keyout {{ etcd_cert_prefix }}server.key - -config {{ etcd_openssl_conf }} - -out {{ etcd_cert_prefix }}server.csr - -reqexts {{ etcd_req_ext }} -batch -nodes - -subj /CN={{ etcd_hostname }} - args: - chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" - creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' - ~ etcd_cert_prefix ~ 'server.csr' }}" - environment: - SAN: "IP:{{ etcd_ip }},DNS:{{ etcd_hostname }}" - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -# Certificates must be signed serially in order to avoid competing -# for the serial file. -- name: Sign and create the server crt - delegated_serial_command: - command: > - openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }} - -out {{ etcd_cert_prefix }}server.crt - -in {{ etcd_cert_prefix }}server.csr - -extensions {{ etcd_ca_exts_server }} -batch - chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" - creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' - ~ etcd_cert_prefix ~ 'server.crt' }}" - environment: - SAN: "IP:{{ etcd_ip }}" - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Create the peer csr - command: > - openssl req -new -keyout {{ etcd_cert_prefix }}peer.key - -config {{ etcd_openssl_conf }} - -out {{ etcd_cert_prefix }}peer.csr - -reqexts {{ etcd_req_ext }} -batch -nodes - -subj /CN={{ etcd_hostname }} - args: - chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" - creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' - ~ etcd_cert_prefix ~ 'peer.csr' }}" - environment: - SAN: "IP:{{ etcd_ip }},DNS:{{ etcd_hostname }}" - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -# Certificates must be signed serially in order to avoid competing -# for the serial file. -- name: Sign and create the peer crt - delegated_serial_command: - command: > - openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }} - -out {{ etcd_cert_prefix }}peer.crt - -in {{ etcd_cert_prefix }}peer.csr - -extensions {{ etcd_ca_exts_peer }} -batch - chdir: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}" - creates: "{{ etcd_generated_certs_dir ~ '/' ~ etcd_cert_subdir ~ '/' - ~ etcd_cert_prefix ~ 'peer.crt' }}" - environment: - SAN: "IP:{{ etcd_ip }}" - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- file: - src: "{{ etcd_ca_cert }}" - dest: "{{ etcd_generated_certs_dir}}/{{ etcd_cert_subdir }}/{{ etcd_cert_prefix }}ca.crt" - state: hard - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Create local temp directory for syncing certs - local_action: command mktemp -d /tmp/etcd_certificates-XXXXXXX - become: no - register: g_etcd_server_mktemp - changed_when: False - when: etcd_server_certs_missing | bool - -- name: Create a tarball of the etcd certs - command: > - tar -czvf {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz - -C {{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }} . - args: - creates: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" - # Disables the following warning: - # Consider using unarchive module rather than running tar - warn: no - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Retrieve etcd cert tarball - fetch: - src: "{{ etcd_generated_certs_dir }}/{{ etcd_cert_subdir }}.tgz" - dest: "{{ g_etcd_server_mktemp.stdout }}/" - flat: yes - fail_on_missing: yes - validate_checksum: yes - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Ensure certificate directory exists - file: - path: "{{ item }}" - state: directory - with_items: - - "{{ etcd_cert_config_dir }}" - - "{{ etcd_system_container_cert_config_dir }}" - when: etcd_server_certs_missing | bool - -- name: Unarchive cert tarball - unarchive: - src: "{{ g_etcd_server_mktemp.stdout }}/{{ etcd_cert_subdir }}.tgz" - dest: "{{ etcd_cert_config_dir }}" - when: etcd_server_certs_missing | bool - -- name: Create a tarball of the etcd ca certs - command: > - tar -czvf {{ etcd_generated_certs_dir }}/{{ etcd_ca_name }}.tgz - -C {{ etcd_ca_dir }} . - args: - creates: "{{ etcd_generated_certs_dir }}/{{ etcd_ca_name }}.tgz" - warn: no - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Retrieve etcd ca cert tarball - fetch: - src: "{{ etcd_generated_certs_dir }}/{{ etcd_ca_name }}.tgz" - dest: "{{ g_etcd_server_mktemp.stdout }}/" - flat: yes - fail_on_missing: yes - validate_checksum: yes - when: etcd_server_certs_missing | bool - delegate_to: "{{ etcd_ca_host }}" - -- name: Ensure ca directory exists - file: - path: "{{ item }}" - state: directory - with_items: - - "{{ etcd_ca_dir }}" - - "{{ etcd_system_container_cert_config_dir }}/ca" - when: etcd_server_certs_missing | bool - -- name: Unarchive cert tarball for the system container - unarchive: - src: "{{ g_etcd_server_mktemp.stdout }}/{{ etcd_cert_subdir }}.tgz" - dest: "{{ etcd_system_container_cert_config_dir }}" - when: - - etcd_server_certs_missing | bool - - r_etcd_common_etcd_runtime == 'runc' - -- name: Unarchive etcd ca cert tarballs for the system container - unarchive: - src: "{{ g_etcd_server_mktemp.stdout }}/{{ etcd_ca_name }}.tgz" - dest: "{{ etcd_system_container_cert_config_dir }}/ca" - when: - - etcd_server_certs_missing | bool - - r_etcd_common_etcd_runtime == 'runc' - -- name: Delete temporary directory - local_action: file path="{{ g_etcd_server_mktemp.stdout }}" state=absent - become: no - changed_when: False - when: etcd_server_certs_missing | bool - -- name: Validate permissions on certificate files - file: - path: "{{ item }}" - mode: 0600 - owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" - group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" - when: etcd_url_scheme == 'https' - with_items: - - "{{ etcd_ca_file }}" - - "{{ etcd_cert_file }}" - - "{{ etcd_key_file }}" - -- name: Validate permissions on peer certificate files - file: - path: "{{ item }}" - mode: 0600 - owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" - group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" - when: etcd_peer_url_scheme == 'https' - with_items: - - "{{ etcd_peer_ca_file }}" - - "{{ etcd_peer_cert_file }}" - - "{{ etcd_peer_key_file }}" - -- name: Validate permissions on the config dir - file: - path: "{{ etcd_conf_dir }}" - state: directory - owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" - group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" - mode: 0700 diff --git a/roles/etcd/templates/etcdctl.sh.j2 b/roles/etcd/templates/etcdctl.sh.j2 new file mode 100644 index 000000000..ac7d9c72f --- /dev/null +++ b/roles/etcd/templates/etcdctl.sh.j2 @@ -0,0 +1,12 @@ +#!/bin/bash +# Sets up handy aliases for etcd, need etcdctl2 and etcdctl3 because +# command flags are different between the two. Should work on stand +# alone etcd hosts and master + etcd hosts too because we use the peer keys. +etcdctl2() { + /usr/bin/etcdctl --cert-file {{ etcd_peer_cert_file }} --key-file {{ etcd_peer_key_file }} --ca-file {{ etcd_peer_ca_file }} -C https://`hostname`:2379 ${@} + +} + +etcdctl3() { + ETCDCTL_API=3 /usr/bin/etcdctl --cert {{ etcd_peer_cert_file }} --key {{ etcd_peer_key_file }} --cacert {{ etcd_peer_ca_file }} --endpoints https://`hostname`:2379 ${@} +} diff --git a/roles/etcd_common/README.md b/roles/etcd_common/README.md deleted file mode 100644 index d1c3a6602..000000000 --- a/roles/etcd_common/README.md +++ /dev/null @@ -1,53 +0,0 @@ -etcd_common -======================== - -Common resources for dependent etcd roles. E.g. default variables for: -* config directories -* certificates -* ports -* other settings - -Or `delegated_serial_command` ansible module for executing a command on a remote node. E.g. - -```yaml -- delegated_serial_command: - command: /usr/bin/make_database.sh arg1 arg2 - creates: /path/to/database -``` - -Or etcdctl.yml playbook for installation of `etcdctl` aliases on a node (see example). - -Dependencies ------------- - -openshift-repos - -Example Playbook ----------------- - -**Drop etcdctl aliases** - -```yaml -- include_role: - name: etcd_common - tasks_from: etcdctl -``` - -**Get access to common variables** - -```yaml -# meta.yml of etcd -... -dependencies: -- { role: etcd_common } -``` - -License -------- - -Apache License Version 2.0 - -Author Information ------------------- - -Jason DeTiberus (jdetiber@redhat.com) diff --git a/roles/etcd_common/defaults/main.yml b/roles/etcd_common/defaults/main.yml deleted file mode 100644 index 6705e1ac5..000000000 --- a/roles/etcd_common/defaults/main.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- -# Default action when calling this role -r_etcd_common_action: noop -r_etcd_common_backup_tag: '' -r_etcd_common_backup_sufix_name: '' - -# runc, docker, host -r_etcd_common_etcd_runtime: "docker" -r_etcd_common_embedded_etcd: false - -# etcd run on a host => use etcdctl command directly -# etcd run as a docker container => use docker exec -# etcd run as a runc container => use runc exec -r_etcd_common_etcdctl_command: "{{ 'etcdctl' if r_etcd_common_etcd_runtime == 'host' or r_etcd_common_embedded_etcd | bool else 'docker exec etcd_container etcdctl' if r_etcd_common_etcd_runtime == 'docker' else 'runc exec etcd etcdctl' }}" - -# etcd server vars -etcd_conf_dir: '/etc/etcd' -r_etcd_common_system_container_host_dir: /var/lib/etcd/etcd.etcd -etcd_system_container_conf_dir: /var/lib/etcd/etc -etcd_conf_file: "{{ etcd_conf_dir }}/etcd.conf" -etcd_ca_file: "{{ etcd_conf_dir }}/ca.crt" -etcd_cert_file: "{{ etcd_conf_dir }}/server.crt" -etcd_key_file: "{{ etcd_conf_dir }}/server.key" -etcd_peer_ca_file: "{{ etcd_conf_dir }}/ca.crt" -etcd_peer_cert_file: "{{ etcd_conf_dir }}/peer.crt" -etcd_peer_key_file: "{{ etcd_conf_dir }}/peer.key" - -# etcd ca vars -etcd_ca_dir: "{{ etcd_conf_dir}}/ca" -etcd_generated_certs_dir: "{{ etcd_conf_dir }}/generated_certs" -etcd_ca_cert: "{{ etcd_ca_dir }}/ca.crt" -etcd_ca_key: "{{ etcd_ca_dir }}/ca.key" -etcd_openssl_conf: "{{ etcd_ca_dir }}/openssl.cnf" -etcd_ca_name: etcd_ca -etcd_req_ext: etcd_v3_req -etcd_ca_exts_peer: etcd_v3_ca_peer -etcd_ca_exts_server: etcd_v3_ca_server -etcd_ca_exts_self: etcd_v3_ca_self -etcd_ca_exts_client: etcd_v3_ca_client -etcd_ca_crl_dir: "{{ etcd_ca_dir }}/crl" -etcd_ca_new_certs_dir: "{{ etcd_ca_dir }}/certs" -etcd_ca_db: "{{ etcd_ca_dir }}/index.txt" -etcd_ca_serial: "{{ etcd_ca_dir }}/serial" -etcd_ca_crl_number: "{{ etcd_ca_dir }}/crlnumber" -etcd_ca_default_days: 1825 - -r_etcd_common_master_peer_cert_file: /etc/origin/master/master.etcd-client.crt -r_etcd_common_master_peer_key_file: /etc/origin/master/master.etcd-client.key -r_etcd_common_master_peer_ca_file: /etc/origin/master/master.etcd-ca.crt - -# etcd server & certificate vars -etcd_hostname: "{{ inventory_hostname }}" -etcd_ip: "{{ ansible_default_ipv4.address }}" -etcd_is_atomic: False -etcd_is_containerized: False -etcd_is_thirdparty: False - -# etcd dir vars -etcd_data_dir: "{{ '/var/lib/origin/openshift.local.etcd' if r_etcd_common_embedded_etcd | bool else '/var/lib/etcd/' if r_etcd_common_etcd_runtime != 'runc' else '/var/lib/etcd/etcd.etcd/' }}" - -# etcd ports and protocols -etcd_client_port: 2379 -etcd_peer_port: 2380 -etcd_url_scheme: http -etcd_peer_url_scheme: http - -etcd_initial_cluster_state: new -etcd_initial_cluster_token: etcd-cluster-1 - -etcd_initial_advertise_peer_urls: "{{ etcd_peer_url_scheme }}://{{ etcd_ip }}:{{ etcd_peer_port }}" -etcd_listen_peer_urls: "{{ etcd_peer_url_scheme }}://{{ etcd_ip }}:{{ etcd_peer_port }}" -etcd_advertise_client_urls: "{{ etcd_url_scheme }}://{{ etcd_ip }}:{{ etcd_client_port }}" -etcd_listen_client_urls: "{{ etcd_url_scheme }}://{{ etcd_ip }}:{{ etcd_client_port }}" - -etcd_systemd_dir: "/etc/systemd/system/{{ etcd_service }}.service.d" - -# etcd_peer needs to be set by a role caller -etcdctlv2: "etcdctl --cert-file {{ etcd_peer_cert_file }} --key-file {{ etcd_peer_key_file }} --ca-file {{ etcd_peer_ca_file }} -C https://{{ etcd_peer }}:{{ etcd_client_port }}" diff --git a/roles/etcd_common/library/delegated_serial_command.py b/roles/etcd_common/library/delegated_serial_command.py deleted file mode 100755 index 0cab1ca88..000000000 --- a/roles/etcd_common/library/delegated_serial_command.py +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2012, Michael DeHaan , and others -# (c) 2016, Andrew Butcher -# -# This module is derrived from the Ansible command module. -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - - -# pylint: disable=unused-wildcard-import,wildcard-import,unused-import,redefined-builtin - -''' delegated_serial_command ''' - -import datetime -import errno -import glob -import shlex -import os -import fcntl -import time - -DOCUMENTATION = ''' ---- -module: delegated_serial_command -short_description: Executes a command on a remote node -version_added: historical -description: - - The M(command) module takes the command name followed by a list - of space-delimited arguments. - - The given command will be executed on all selected nodes. It - will not be processed through the shell, so variables like - C($HOME) and operations like C("<"), C(">"), C("|"), and C("&") - will not work (use the M(shell) module if you need these - features). - - Creates and maintains a lockfile such that this module will - wait for other invocations to proceed. -options: - command: - description: - - the command to run - required: true - default: null - creates: - description: - - a filename or (since 2.0) glob pattern, when it already - exists, this step will B(not) be run. - required: no - default: null - removes: - description: - - a filename or (since 2.0) glob pattern, when it does not - exist, this step will B(not) be run. - version_added: "0.8" - required: no - default: null - chdir: - description: - - cd into this directory before running the command - version_added: "0.6" - required: false - default: null - executable: - description: - - change the shell used to execute the command. Should be an - absolute path to the executable. - required: false - default: null - version_added: "0.9" - warn: - version_added: "1.8" - default: yes - description: - - if command warnings are on in ansible.cfg, do not warn about - this particular line if set to no/false. - required: false - lockfile: - default: yes - description: - - the lockfile that will be created - timeout: - default: yes - description: - - time in milliseconds to wait to obtain the lock -notes: - - If you want to run a command through the shell (say you are using C(<), - C(>), C(|), etc), you actually want the M(shell) module instead. The - M(command) module is much more secure as it's not affected by the user's - environment. - - " C(creates), C(removes), and C(chdir) can be specified after - the command. For instance, if you only want to run a command if - a certain file does not exist, use this." -author: - - Ansible Core Team - - Michael DeHaan - - Andrew Butcher -''' - -EXAMPLES = ''' -# Example from Ansible Playbooks. -- delegated_serial_command: - command: /sbin/shutdown -t now - -# Run the command if the specified file does not exist. -- delegated_serial_command: - command: /usr/bin/make_database.sh arg1 arg2 - creates: /path/to/database -''' - -# Dict of options and their defaults -OPTIONS = {'chdir': None, - 'creates': None, - 'command': None, - 'executable': None, - 'NO_LOG': None, - 'removes': None, - 'warn': True, - 'lockfile': None, - 'timeout': None} - - -def check_command(commandline): - ''' Check provided command ''' - arguments = {'chown': 'owner', 'chmod': 'mode', 'chgrp': 'group', - 'ln': 'state=link', 'mkdir': 'state=directory', - 'rmdir': 'state=absent', 'rm': 'state=absent', 'touch': 'state=touch'} - commands = {'git': 'git', 'hg': 'hg', 'curl': 'get_url or uri', 'wget': 'get_url or uri', - 'svn': 'subversion', 'service': 'service', - 'mount': 'mount', 'rpm': 'yum, dnf or zypper', 'yum': 'yum', 'apt-get': 'apt', - 'tar': 'unarchive', 'unzip': 'unarchive', 'sed': 'template or lineinfile', - 'rsync': 'synchronize', 'dnf': 'dnf', 'zypper': 'zypper'} - become = ['sudo', 'su', 'pbrun', 'pfexec', 'runas'] - warnings = list() - command = os.path.basename(commandline.split()[0]) - # pylint: disable=line-too-long - if command in arguments: - warnings.append("Consider using file module with {0} rather than running {1}".format(arguments[command], command)) - if command in commands: - warnings.append("Consider using {0} module rather than running {1}".format(commands[command], command)) - if command in become: - warnings.append( - "Consider using 'become', 'become_method', and 'become_user' rather than running {0}".format(command,)) - return warnings - - -# pylint: disable=too-many-statements,too-many-branches,too-many-locals -def main(): - ''' Main module function ''' - module = AnsibleModule( # noqa: F405 - argument_spec=dict( - _uses_shell=dict(type='bool', default=False), - command=dict(required=True), - chdir=dict(), - executable=dict(), - creates=dict(), - removes=dict(), - warn=dict(type='bool', default=True), - lockfile=dict(default='/tmp/delegated_serial_command.lock'), - timeout=dict(type='int', default=30) - ) - ) - - shell = module.params['_uses_shell'] - chdir = module.params['chdir'] - executable = module.params['executable'] - command = module.params['command'] - creates = module.params['creates'] - removes = module.params['removes'] - warn = module.params['warn'] - lockfile = module.params['lockfile'] - timeout = module.params['timeout'] - - if command.strip() == '': - module.fail_json(rc=256, msg="no command given") - - iterated = 0 - lockfd = open(lockfile, 'w+') - while iterated < timeout: - try: - fcntl.flock(lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB) - break - # pylint: disable=invalid-name - except IOError as e: - if e.errno != errno.EAGAIN: - module.fail_json(msg="I/O Error {0}: {1}".format(e.errno, e.strerror)) - else: - iterated += 1 - time.sleep(0.1) - - if chdir: - chdir = os.path.abspath(os.path.expanduser(chdir)) - os.chdir(chdir) - - if creates: - # do not run the command if the line contains creates=filename - # and the filename already exists. This allows idempotence - # of command executions. - path = os.path.expanduser(creates) - if glob.glob(path): - module.exit_json( - cmd=command, - stdout="skipped, since %s exists" % path, - changed=False, - stderr=False, - rc=0 - ) - - if removes: - # do not run the command if the line contains removes=filename - # and the filename does not exist. This allows idempotence - # of command executions. - path = os.path.expanduser(removes) - if not glob.glob(path): - module.exit_json( - cmd=command, - stdout="skipped, since %s does not exist" % path, - changed=False, - stderr=False, - rc=0 - ) - - warnings = list() - if warn: - warnings = check_command(command) - - if not shell: - command = shlex.split(command) - startd = datetime.datetime.now() - - # pylint: disable=invalid-name - rc, out, err = module.run_command(command, executable=executable, use_unsafe_shell=shell) - - fcntl.flock(lockfd, fcntl.LOCK_UN) - lockfd.close() - - endd = datetime.datetime.now() - delta = endd - startd - - if out is None: - out = '' - if err is None: - err = '' - - module.exit_json( - cmd=command, - stdout=out.rstrip("\r\n"), - stderr=err.rstrip("\r\n"), - rc=rc, - start=str(startd), - end=str(endd), - delta=str(delta), - changed=True, - warnings=warnings, - iterated=iterated - ) - - -# import module snippets -# pylint: disable=wrong-import-position -from ansible.module_utils.basic import * # noqa: F402,F403 - -main() diff --git a/roles/etcd_common/meta/main.yml b/roles/etcd_common/meta/main.yml deleted file mode 100644 index dfb1c7a2c..000000000 --- a/roles/etcd_common/meta/main.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -galaxy_info: - author: Jason DeTiberus - description: - company: Red Hat, Inc. - license: Apache License, Version 2.0 - min_ansible_version: 1.9 - platforms: - - name: EL - versions: - - 7 - categories: - - cloud - - system -dependencies: [] diff --git a/roles/etcd_common/tasks/backup.yml b/roles/etcd_common/tasks/backup.yml deleted file mode 100644 index 42d27c081..000000000 --- a/roles/etcd_common/tasks/backup.yml +++ /dev/null @@ -1,101 +0,0 @@ ---- -# set the etcd backup directory name here in case the tag or sufix consists of dynamic value that changes over time -# e.g. openshift-backup-{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }} value will change every second so if the date changes -# right after setting l_etcd_incontainer_backup_dir and before l_etcd_backup_dir facts, the backup directory name is different -- set_fact: - l_backup_dir_name: "openshift-backup-{{ r_etcd_common_backup_tag }}{{ r_etcd_common_backup_sufix_name }}" - -- set_fact: - l_etcd_data_dir: "{{ etcd_data_dir }}{{ '/etcd.etcd' if r_etcd_common_etcd_runtime == 'runc' else '' }}" - -- set_fact: - l_etcd_incontainer_data_dir: "{{ etcd_data_dir }}" - -- set_fact: - l_etcd_incontainer_backup_dir: "{{ l_etcd_incontainer_data_dir }}/{{ l_backup_dir_name }}" - -- set_fact: - l_etcd_backup_dir: "{{ l_etcd_data_dir }}/{{ l_backup_dir_name }}" - -# TODO: replace shell module with command and update later checks -- name: Check available disk space for etcd backup - shell: df --output=avail -k {{ l_etcd_data_dir }} | tail -n 1 - register: l_avail_disk - # AUDIT:changed_when: `false` because we are only inspecting - # state, not manipulating anything - changed_when: false - -# TODO: replace shell module with command and update later checks -- name: Check current etcd disk usage - shell: du --exclude='*openshift-backup*' -k {{ l_etcd_data_dir }} | tail -n 1 | cut -f1 - register: l_etcd_disk_usage - # AUDIT:changed_when: `false` because we are only inspecting - # state, not manipulating anything - changed_when: false - -- name: Abort if insufficient disk space for etcd backup - fail: - msg: > - {{ l_etcd_disk_usage.stdout|int*2 }} Kb disk space required for etcd backup, - {{ l_avail_disk.stdout }} Kb available. - when: l_etcd_disk_usage.stdout|int*2 > l_avail_disk.stdout|int - -# For non containerized and non embedded we should have the correct version of -# etcd installed already. So don't do anything. -# -# For containerized installs we now exec into etcd_container -# -# For embedded non containerized we need to ensure we have the latest version -# etcd on the host. -- name: Detecting Atomic Host Operating System - stat: - path: /run/ostree-booted - register: l_ostree_booted - -- name: Install latest etcd for embedded - package: - name: etcd - state: latest - when: - - r_etcd_common_embedded_etcd | bool - - not l_ostree_booted.stat.exists | bool - -- name: Check selinux label of '{{ l_etcd_data_dir }}' - command: > - stat -c '%C' {{ l_etcd_data_dir }} - register: l_etcd_selinux_labels - -- debug: - msg: "{{ l_etcd_selinux_labels }}" - -- name: Make sure the '{{ l_etcd_data_dir }}' has the proper label - command: > - chcon -t svirt_sandbox_file_t "{{ l_etcd_data_dir }}" - when: - - l_etcd_selinux_labels.rc == 0 - - "'svirt_sandbox_file_t' not in l_etcd_selinux_labels.stdout" - -- name: Generate etcd backup - command: > - {{ r_etcd_common_etcdctl_command }} backup --data-dir={{ l_etcd_incontainer_data_dir }} - --backup-dir={{ l_etcd_incontainer_backup_dir }} - -# According to the docs change you can simply copy snap/db -# https://github.com/openshift/openshift-docs/commit/b38042de02d9780842dce95cfa0ef45d53b58bc6 -- name: Check for v3 data store - stat: - path: "{{ l_etcd_data_dir }}/member/snap/db" - register: l_v3_db - -- name: Copy etcd v3 data store - command: > - cp -a {{ l_etcd_data_dir }}/member/snap/db - {{ l_etcd_backup_dir }}/member/snap/ - when: l_v3_db.stat.exists - -- set_fact: - r_etcd_common_backup_complete: True - -- name: Display location of etcd backup - debug: - msg: "Etcd backup created in {{ l_etcd_backup_dir }}" diff --git a/roles/etcd_common/tasks/drop_etcdctl.yml b/roles/etcd_common/tasks/drop_etcdctl.yml deleted file mode 100644 index 6cb456677..000000000 --- a/roles/etcd_common/tasks/drop_etcdctl.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- -- name: Install etcd for etcdctl - package: name=etcd{{ '-' + etcd_version if etcd_version is defined else '' }} state=present - when: not openshift.common.is_atomic | bool - -- name: Configure etcd profile.d alises - template: - dest: "/etc/profile.d/etcdctl.sh" - src: etcdctl.sh.j2 - mode: 0755 - owner: root - group: root diff --git a/roles/etcd_common/tasks/main.yml b/roles/etcd_common/tasks/main.yml deleted file mode 100644 index 6ed87e6c7..000000000 --- a/roles/etcd_common/tasks/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: Fail if invalid r_etcd_common_action provided - fail: - msg: "etcd_common role can only be called with 'noop' or 'backup' or 'drop_etcdctl'" - when: r_etcd_common_action not in ['noop', 'backup', 'drop_etcdctl'] - -- name: Include main action task file - include: "{{ r_etcd_common_action }}.yml" - when: r_etcd_common_action != "noop" diff --git a/roles/etcd_common/tasks/noop.yml b/roles/etcd_common/tasks/noop.yml deleted file mode 100644 index a88d78235..000000000 --- a/roles/etcd_common/tasks/noop.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -# This is file is here because the usage of tags, specifically `pre_upgrade` -# breaks the functionality of this role. -# See https://bugzilla.redhat.com/show_bug.cgi?id=1464025 diff --git a/roles/etcd_common/templates/etcdctl.sh.j2 b/roles/etcd_common/templates/etcdctl.sh.j2 deleted file mode 100644 index ac7d9c72f..000000000 --- a/roles/etcd_common/templates/etcdctl.sh.j2 +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -# Sets up handy aliases for etcd, need etcdctl2 and etcdctl3 because -# command flags are different between the two. Should work on stand -# alone etcd hosts and master + etcd hosts too because we use the peer keys. -etcdctl2() { - /usr/bin/etcdctl --cert-file {{ etcd_peer_cert_file }} --key-file {{ etcd_peer_key_file }} --ca-file {{ etcd_peer_ca_file }} -C https://`hostname`:2379 ${@} - -} - -etcdctl3() { - ETCDCTL_API=3 /usr/bin/etcdctl --cert {{ etcd_peer_cert_file }} --key {{ etcd_peer_key_file }} --cacert {{ etcd_peer_ca_file }} --endpoints https://`hostname`:2379 ${@} -} diff --git a/roles/etcd_common/vars/main.yml b/roles/etcd_common/vars/main.yml deleted file mode 100644 index 00d697776..000000000 --- a/roles/etcd_common/vars/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -etcd_service: "{{ 'etcd_container' if r_etcd_common_etcd_runtime == 'docker' else 'etcd' }}" -# Location of the service file is fixed and not meant to be changed -etcd_service_file: "/etc/systemd/system/{{ etcd_service }}.service" -- cgit v1.2.1