From ed4aee2bb1594f50663cfcad4860913040f5c64c Mon Sep 17 00:00:00 2001 From: Michele Azzolari Date: Fri, 7 Jun 2019 17:55:35 +0200 Subject: [PATCH 1/8] CI: Add wrapper to execute molecule --- .travis.yml | 2 +- runMolecule.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100755 runMolecule.sh diff --git a/.travis.yml b/.travis.yml index f1497fe..68c1c6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ before_script: - cd ansible-$ROLE_NAME script: - - molecule --debug test --all + - ./runMolecule.sh notifications: webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/runMolecule.sh b/runMolecule.sh new file mode 100755 index 0000000..684388e --- /dev/null +++ b/runMolecule.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +SCENARIOS="default signature" + +MUST_FAIL="" + +function has_right_to_fail { + for i in ${MUST_FAIL}; do + if [ "${MOLECULE_DISTRO}:${1}" = "${i}" ]; then + return 1 + fi + done + return 0 +} + +for scenario in ${SCENARIOS}; do + molecule test -s ${scenario} + RETURN_SCENARIO=$? + has_right_to_fail ${scenario} + RIGHT_TO_FAIL=$? + if [ ${RETURN_SCENARIO} -gt 0 ] && [ ${RIGHT_TO_FAIL} -eq 0 ]; then + exit ${RETURN_SCENARIO} + fi; + + if [ ${RETURN_SCENARIO} -eq 0 ] && [ ${RIGHT_TO_FAIL} -eq 1 ]; then + echo "${MOLECULE_DISTRO} on ${scenario} must fail" + exit 1; + fi +done From a75d5a7b089ea4502b4694068bdc04a8d016cd29 Mon Sep 17 00:00:00 2001 From: Michele Azzolari Date: Fri, 7 Jun 2019 17:59:46 +0200 Subject: [PATCH 2/8] CI: refactor tests, factorisation of common pre_task --- molecule/default/playbook.yml | 25 ++-------------------- molecule/default/tests/test_default.py | 9 +++++++- molecule/resources/playbooks/pre-tasks.yml | 24 +++++++++++++++++++++ molecule/signature/Dockerfile.j2 | 14 ------------ molecule/signature/INSTALL.rst | 22 ------------------- molecule/signature/playbook.yml | 24 ++------------------- 6 files changed, 36 insertions(+), 82 deletions(-) create mode 100644 molecule/resources/playbooks/pre-tasks.yml delete mode 100644 molecule/signature/Dockerfile.j2 delete mode 100644 molecule/signature/INSTALL.rst diff --git a/molecule/default/playbook.yml b/molecule/default/playbook.yml index c26b078..7012f73 100644 --- a/molecule/default/playbook.yml +++ b/molecule/default/playbook.yml @@ -5,29 +5,8 @@ - theo_url: https://theo.example.com - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP pre_tasks: - - name: Update apt cache - apt: - update_cache: yes - cache_valid_time: 600 - when: ansible_os_family == 'Debian' - - - name: Ensure sshd is installed - package: - name: - - openssh-server - state: present - - - name: Ensure sshd service is started - service: - name: ssh - state: started - when: ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04' - - - name: Ensure sshd service is started - service: - name: sshd - state: started - when: not (ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04') + - name: Import common tasks + import_tasks: ../resources/playbooks/pre-tasks.yml roles: - role: ansible-theo-agent diff --git a/molecule/default/tests/test_default.py b/molecule/default/tests/test_default.py index 2d93234..b362b7f 100644 --- a/molecule/default/tests/test_default.py +++ b/molecule/default/tests/test_default.py @@ -37,6 +37,13 @@ def test_theo_config_file(host): assert line in conf +def test_theo_cache_dir(host): + f = host.file('/var/cache/theo-agent') + assert f.exists + assert f.user == 'theo-agent' + assert f.group == 'root' + + def test_sshd_config(host): distro = os.getenv('MOLECULE_DISTRO', 'centos7') if distro == 'centos6': @@ -63,7 +70,7 @@ def test_sshd_config(host): if line not in configlines: errors.append(line) - if(len(errors)): + if len(errors): print('Failed test_sshd_config, missing line(s)') for error in errors: print(error) diff --git a/molecule/resources/playbooks/pre-tasks.yml b/molecule/resources/playbooks/pre-tasks.yml new file mode 100644 index 0000000..86a9522 --- /dev/null +++ b/molecule/resources/playbooks/pre-tasks.yml @@ -0,0 +1,24 @@ +--- +- name: Update apt cache + apt: + update_cache: yes + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + +- name: Ensure sshd is installed + package: + name: + - openssh-server + state: present + +- name: Ensure sshd service is started + service: + name: ssh + state: started + when: ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04' + +- name: Ensure sshd service is started + service: + name: sshd + state: started + when: not (ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04') diff --git a/molecule/signature/Dockerfile.j2 b/molecule/signature/Dockerfile.j2 deleted file mode 100644 index e6aa95d..0000000 --- a/molecule/signature/Dockerfile.j2 +++ /dev/null @@ -1,14 +0,0 @@ -# Molecule managed - -{% if item.registry is defined %} -FROM {{ item.registry.url }}/{{ item.image }} -{% else %} -FROM {{ item.image }} -{% endif %} - -RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \ - elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash && dnf clean all; \ - elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ - elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml && zypper clean -a; \ - elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ - elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi diff --git a/molecule/signature/INSTALL.rst b/molecule/signature/INSTALL.rst deleted file mode 100644 index 6a44bde..0000000 --- a/molecule/signature/INSTALL.rst +++ /dev/null @@ -1,22 +0,0 @@ -******* -Docker driver installation guide -******* - -Requirements -============ - -* Docker Engine - -Install -======= - -Please refer to the `Virtual environment`_ documentation for installation best -practices. If not using a virtual environment, please consider passing the -widely recommended `'--user' flag`_ when invoking ``pip``. - -.. _Virtual environment: https://virtualenv.pypa.io/en/latest/ -.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site - -.. code-block:: bash - - $ pip install 'molecule[docker]' diff --git a/molecule/signature/playbook.yml b/molecule/signature/playbook.yml index ca8d099..1f0ae09 100644 --- a/molecule/signature/playbook.yml +++ b/molecule/signature/playbook.yml @@ -21,29 +21,9 @@ JK85kX7Atut+tgWgwuwT5vcCAwEAAQ== -----END PUBLIC KEY----- pre_tasks: - - name: Update apt cache - apt: - update_cache: yes - cache_valid_time: 600 - when: ansible_os_family == 'Debian' + - name: Import common tasks + import_tasks: ../resources/playbooks/pre-tasks.yml - - name: Ensure sshd is installed - package: - name: - - openssh-server - state: present - - - name: Ensure sshd service is started - service: - name: ssh - state: started - when: ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04' - - - name: Ensure sshd service is started - service: - name: sshd - state: started - when: not (ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04') roles: - role: ansible-theo-agent From 8417312be52497977fa1a73568c56e90d2c17577 Mon Sep 17 00:00:00 2001 From: Michele Azzolari Date: Fri, 7 Jun 2019 18:00:46 +0200 Subject: [PATCH 3/8] CI: add new scenario 'custom-bin-file' --- molecule/custom-bin-file/molecule.yml | 23 ++++++ molecule/custom-bin-file/playbook.yml | 30 ++++++++ .../custom-bin-file/tests/test_default.py | 70 +++++++++++++++++++ runMolecule.sh | 2 +- 4 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 molecule/custom-bin-file/molecule.yml create mode 100644 molecule/custom-bin-file/playbook.yml create mode 100644 molecule/custom-bin-file/tests/test_default.py diff --git a/molecule/custom-bin-file/molecule.yml b/molecule/custom-bin-file/molecule.yml new file mode 100644 index 0000000..858e2e8 --- /dev/null +++ b/molecule/custom-bin-file/molecule.yml @@ -0,0 +1,23 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint +verifier: + name: testinfra + lint: + name: flake8 diff --git a/molecule/custom-bin-file/playbook.yml b/molecule/custom-bin-file/playbook.yml new file mode 100644 index 0000000..e1298c2 --- /dev/null +++ b/molecule/custom-bin-file/playbook.yml @@ -0,0 +1,30 @@ +--- +- name: Converge + hosts: all + vars: + - theo_url: https://theo.example.com + - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_agent_path: /usr/local/bin/theo + - theo_agent_verify_signature: true + - theo_agent_public_key: | + -----BEGIN PUBLIC KEY----- + MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwVhHEBTVqEpBOpguARtg + //WyDBEoCT2F2OjnHB6fxJ9oopYJZB2Y4jj5cxo1O41r65XmMRT4lqeHWS6Iovde + kzlJ0bH91gl7/iNziUMN4ONiIR0SU3PiBGQ0XKq6rUxpsOhe+tFPfBQYhkkAiQeG + WC1GYQynYjZ/MTEDIPnd5YjSl0agzm7BMRujEcjWyYqEBuZjtDqP6AICz8nkFo9i + CWBONYbCujDl+1sei3WUfeGcUdGiPNwQGU/TW4sfcRWQzayw3XQEl3ERNRMihVsb + in2529O4+JMKdKn22mzTmWsraP/ZakVeti0VtpGZEe1YSTW8+SCz7DnTadnuUZAO + 5JFVTmFcbF7/d/H0atKVVAeTC5nqYNeDrW4jtIQalUZeaHrBkWK7i/yxDYFlC2AW + ZEu4IQZtGfNJCaZFuYSiN96yzlnMWRp1nUGaBxoax4K8rBwX8EWxT4EAyN1mtan0 + ZQITjiZTqDvnhr8iSIvn9hy3942GYi3upOsBeqfb90vzS7BAmoplyWPS0D+UWweB + +sjv96Gtb4BFpc96qwptLCnVFFOVlq0bq0u1FN6sZ4RApl2IaSJV9JGsJjeeJowh + GCK9sSDVI5XY3wy6UYMo9SZQGIglyRPrnd3R82O277lAyOVC/NNp1vq5WH/Mi1Mu + JK85kX7Atut+tgWgwuwT5vcCAwEAAQ== + -----END PUBLIC KEY----- + pre_tasks: + - name: Import common tasks + import_tasks: ../resources/playbooks/pre-tasks.yml + + + roles: + - role: ansible-theo-agent diff --git a/molecule/custom-bin-file/tests/test_default.py b/molecule/custom-bin-file/tests/test_default.py new file mode 100644 index 0000000..20cea08 --- /dev/null +++ b/molecule/custom-bin-file/tests/test_default.py @@ -0,0 +1,70 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_theo_binary_file(host): + f = host.file('/usr/local/bin/theo') + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + + +def test_sshd_config(host): + distro = os.getenv('MOLECULE_DISTRO', 'centos7') + if distro == 'centos6': + expected = get_sshd_config_centos6() + elif distro == 'debian8': + expected = get_sshd_config_pre_v69() + elif distro == 'ubuntu1404': + expected = get_sshd_config_pre_v69() + else: + expected = get_sshd_config_v69() + f = host.file('/etc/ssh/sshd_config') + config = f.content + configlines = [] + for line in config.splitlines(): + if not line.startswith(b'#'): + configlines.append(line) + ''' + I don't want to use something like: + assert set(expected).issubset(configlines) + Because there's no detail of the missing line(s) + ''' + errors = [] + for line in expected: + if line not in configlines: + errors.append(line) + + if len(errors): + print('Failed test_sshd_config, missing line(s)') + for error in errors: + print(error) + assert False + + +def get_sshd_config_centos6(): + return [ + b'AuthorizedKeysCommandRunAs theo-agent', + b'AuthorizedKeysCommand /usr/local/bin/theo', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] + + +def get_sshd_config_pre_v69(): + return [ + b'AuthorizedKeysCommandUser theo-agent', + b'AuthorizedKeysCommand /usr/local/bin/theo', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] + + +def get_sshd_config_v69(): + return [ + b'AuthorizedKeysCommandUser theo-agent', + b'AuthorizedKeysCommand /usr/local/bin/theo -fingerprint %f %u', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] diff --git a/runMolecule.sh b/runMolecule.sh index 684388e..1e31dbc 100755 --- a/runMolecule.sh +++ b/runMolecule.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -SCENARIOS="default signature" +SCENARIOS="default signature custom-bin-file" MUST_FAIL="" From aff9cf9181666d9b05b0c81fc254144b72777967 Mon Sep 17 00:00:00 2001 From: Michele Azzolari Date: Fri, 7 Jun 2019 18:01:37 +0200 Subject: [PATCH 4/8] CI: add new scenario 'custom-config-file' --- molecule/custom-config-file/molecule.yml | 23 +++++ molecule/custom-config-file/playbook.yml | 31 ++++++ .../custom-config-file/tests/test_default.py | 95 +++++++++++++++++++ runMolecule.sh | 4 +- 4 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 molecule/custom-config-file/molecule.yml create mode 100644 molecule/custom-config-file/playbook.yml create mode 100644 molecule/custom-config-file/tests/test_default.py diff --git a/molecule/custom-config-file/molecule.yml b/molecule/custom-config-file/molecule.yml new file mode 100644 index 0000000..858e2e8 --- /dev/null +++ b/molecule/custom-config-file/molecule.yml @@ -0,0 +1,23 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint +verifier: + name: testinfra + lint: + name: flake8 diff --git a/molecule/custom-config-file/playbook.yml b/molecule/custom-config-file/playbook.yml new file mode 100644 index 0000000..3792bf1 --- /dev/null +++ b/molecule/custom-config-file/playbook.yml @@ -0,0 +1,31 @@ +--- +- name: Converge + hosts: all + vars: + - theo_url: https://theo.example.com + - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_agent_config_dir: /var/lib/theo + - theo_agent_config_path: /var/lib/theo/theo.yml + - theo_agent_verify_signature: true + - theo_agent_public_key: | + -----BEGIN PUBLIC KEY----- + MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwVhHEBTVqEpBOpguARtg + //WyDBEoCT2F2OjnHB6fxJ9oopYJZB2Y4jj5cxo1O41r65XmMRT4lqeHWS6Iovde + kzlJ0bH91gl7/iNziUMN4ONiIR0SU3PiBGQ0XKq6rUxpsOhe+tFPfBQYhkkAiQeG + WC1GYQynYjZ/MTEDIPnd5YjSl0agzm7BMRujEcjWyYqEBuZjtDqP6AICz8nkFo9i + CWBONYbCujDl+1sei3WUfeGcUdGiPNwQGU/TW4sfcRWQzayw3XQEl3ERNRMihVsb + in2529O4+JMKdKn22mzTmWsraP/ZakVeti0VtpGZEe1YSTW8+SCz7DnTadnuUZAO + 5JFVTmFcbF7/d/H0atKVVAeTC5nqYNeDrW4jtIQalUZeaHrBkWK7i/yxDYFlC2AW + ZEu4IQZtGfNJCaZFuYSiN96yzlnMWRp1nUGaBxoax4K8rBwX8EWxT4EAyN1mtan0 + ZQITjiZTqDvnhr8iSIvn9hy3942GYi3upOsBeqfb90vzS7BAmoplyWPS0D+UWweB + +sjv96Gtb4BFpc96qwptLCnVFFOVlq0bq0u1FN6sZ4RApl2IaSJV9JGsJjeeJowh + GCK9sSDVI5XY3wy6UYMo9SZQGIglyRPrnd3R82O277lAyOVC/NNp1vq5WH/Mi1Mu + JK85kX7Atut+tgWgwuwT5vcCAwEAAQ== + -----END PUBLIC KEY----- + pre_tasks: + - name: Import common tasks + import_tasks: ../resources/playbooks/pre-tasks.yml + + + roles: + - role: ansible-theo-agent diff --git a/molecule/custom-config-file/tests/test_default.py b/molecule/custom-config-file/tests/test_default.py new file mode 100644 index 0000000..8e960e0 --- /dev/null +++ b/molecule/custom-config-file/tests/test_default.py @@ -0,0 +1,95 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_theo_binary_file(host): + f = host.file('/usr/sbin/theo-agent') + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + + +def test_theo_config_file(host): + f = host.file('/var/lib/theo/theo.yml') + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + conf = f.content + ''' + url: https://theo.example.com + token: \ + zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + cachedir: /var/cache/theo-agent + verify: True + public_key: /var/lib/theo/public.pem + ''' + expected = [ + b'url: https://theo.example.com', + b'token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp' + b'+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP', + b'cachedir: /var/cache/theo-agent', + b'verify: True', + b'public_key: /var/lib/theo/public.pem' + ] + for line in expected: + assert line in conf + + +def test_theo_public_key_file(host): + f = host.file('/var/lib/theo/public.pem') + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + + +def test_sshd_config(host): + distro = os.getenv('MOLECULE_DISTRO', 'centos7') + if distro == 'debian8': + expected = get_sshd_config_pre_v69() + elif distro == 'ubuntu1404': + expected = get_sshd_config_pre_v69() + else: + expected = get_sshd_config_v69() + f = host.file('/etc/ssh/sshd_config') + config = f.content + configlines = [] + for line in config.splitlines(): + if not line.startswith(b'#'): + configlines.append(line) + ''' + I don't want to use something like: + assert set(expected).issubset(configlines) + Because there's no detail of the missing line(s) + ''' + errors = [] + for line in expected: + if line not in configlines: + errors.append(line) + + if len(errors): + print('Failed test_sshd_config, missing line(s)') + for error in errors: + print(error) + assert False + + +def get_sshd_config_pre_v69(): + return [ + b'AuthorizedKeysCommandUser theo-agent', + b'AuthorizedKeysCommand /usr/sbin/theo-agent ' + b'-config-file /var/lib/theo/theo.yml %u', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] + + +def get_sshd_config_v69(): + return [ + b'AuthorizedKeysCommandUser theo-agent', + b'AuthorizedKeysCommand /usr/sbin/theo-agent ' + b'-config-file /var/lib/theo/theo.yml -fingerprint %f %u', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] diff --git a/runMolecule.sh b/runMolecule.sh index 1e31dbc..99507b5 100755 --- a/runMolecule.sh +++ b/runMolecule.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -SCENARIOS="default signature custom-bin-file" +SCENARIOS="default signature custom-bin-file custom-config-file" -MUST_FAIL="" +MUST_FAIL="centos6:custom-config-file" function has_right_to_fail { for i in ${MUST_FAIL}; do From d833afa2d08e2c5e7ea732146182de70e092fe76 Mon Sep 17 00:00:00 2001 From: Michele Azzolari Date: Fri, 7 Jun 2019 18:02:13 +0200 Subject: [PATCH 5/8] CI: add new scenario 'custom-config-dir' --- molecule/custom-config-dir/molecule.yml | 23 +++++ molecule/custom-config-dir/playbook.yml | 30 ++++++ .../custom-config-dir/tests/test_default.py | 95 +++++++++++++++++++ runMolecule.sh | 4 +- 4 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 molecule/custom-config-dir/molecule.yml create mode 100644 molecule/custom-config-dir/playbook.yml create mode 100644 molecule/custom-config-dir/tests/test_default.py diff --git a/molecule/custom-config-dir/molecule.yml b/molecule/custom-config-dir/molecule.yml new file mode 100644 index 0000000..858e2e8 --- /dev/null +++ b/molecule/custom-config-dir/molecule.yml @@ -0,0 +1,23 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint +verifier: + name: testinfra + lint: + name: flake8 diff --git a/molecule/custom-config-dir/playbook.yml b/molecule/custom-config-dir/playbook.yml new file mode 100644 index 0000000..06b4efc --- /dev/null +++ b/molecule/custom-config-dir/playbook.yml @@ -0,0 +1,30 @@ +--- +- name: Converge + hosts: all + vars: + - theo_url: https://theo.example.com + - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_agent_config_dir: /var/lib/theo + - theo_agent_verify_signature: true + - theo_agent_public_key: | + -----BEGIN PUBLIC KEY----- + MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwVhHEBTVqEpBOpguARtg + //WyDBEoCT2F2OjnHB6fxJ9oopYJZB2Y4jj5cxo1O41r65XmMRT4lqeHWS6Iovde + kzlJ0bH91gl7/iNziUMN4ONiIR0SU3PiBGQ0XKq6rUxpsOhe+tFPfBQYhkkAiQeG + WC1GYQynYjZ/MTEDIPnd5YjSl0agzm7BMRujEcjWyYqEBuZjtDqP6AICz8nkFo9i + CWBONYbCujDl+1sei3WUfeGcUdGiPNwQGU/TW4sfcRWQzayw3XQEl3ERNRMihVsb + in2529O4+JMKdKn22mzTmWsraP/ZakVeti0VtpGZEe1YSTW8+SCz7DnTadnuUZAO + 5JFVTmFcbF7/d/H0atKVVAeTC5nqYNeDrW4jtIQalUZeaHrBkWK7i/yxDYFlC2AW + ZEu4IQZtGfNJCaZFuYSiN96yzlnMWRp1nUGaBxoax4K8rBwX8EWxT4EAyN1mtan0 + ZQITjiZTqDvnhr8iSIvn9hy3942GYi3upOsBeqfb90vzS7BAmoplyWPS0D+UWweB + +sjv96Gtb4BFpc96qwptLCnVFFOVlq0bq0u1FN6sZ4RApl2IaSJV9JGsJjeeJowh + GCK9sSDVI5XY3wy6UYMo9SZQGIglyRPrnd3R82O277lAyOVC/NNp1vq5WH/Mi1Mu + JK85kX7Atut+tgWgwuwT5vcCAwEAAQ== + -----END PUBLIC KEY----- + pre_tasks: + - name: Import common tasks + import_tasks: ../resources/playbooks/pre-tasks.yml + + + roles: + - role: ansible-theo-agent diff --git a/molecule/custom-config-dir/tests/test_default.py b/molecule/custom-config-dir/tests/test_default.py new file mode 100644 index 0000000..660b851 --- /dev/null +++ b/molecule/custom-config-dir/tests/test_default.py @@ -0,0 +1,95 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_theo_binary_file(host): + f = host.file('/usr/sbin/theo-agent') + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + + +def test_theo_config_file(host): + f = host.file('/var/lib/theo/config.yml') + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + conf = f.content + ''' + url: https://theo.example.com + token: \ + zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + cachedir: /var/cache/theo-agent + verify: True + public_key: /var/lib/theo/public.pem + ''' + expected = [ + b'url: https://theo.example.com', + b'token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp' + b'+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP', + b'cachedir: /var/cache/theo-agent', + b'verify: True', + b'public_key: /var/lib/theo/public.pem' + ] + for line in expected: + assert line in conf + + +def test_theo_public_key_file(host): + f = host.file('/var/lib/theo/public.pem') + assert f.exists + assert f.user == 'root' + assert f.group == 'root' + + +def test_sshd_config(host): + distro = os.getenv('MOLECULE_DISTRO', 'centos7') + if distro == 'debian8': + expected = get_sshd_config_pre_v69() + elif distro == 'ubuntu1404': + expected = get_sshd_config_pre_v69() + else: + expected = get_sshd_config_v69() + f = host.file('/etc/ssh/sshd_config') + config = f.content + configlines = [] + for line in config.splitlines(): + if not line.startswith(b'#'): + configlines.append(line) + ''' + I don't want to use something like: + assert set(expected).issubset(configlines) + Because there's no detail of the missing line(s) + ''' + errors = [] + for line in expected: + if line not in configlines: + errors.append(line) + + if len(errors): + print('Failed test_sshd_config, missing line(s)') + for error in errors: + print(error) + assert False + + +def get_sshd_config_pre_v69(): + return [ + b'AuthorizedKeysCommandUser theo-agent', + b'AuthorizedKeysCommand /usr/sbin/theo-agent ' + b'-config-file /var/lib/theo/config.yml %u', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] + + +def get_sshd_config_v69(): + return [ + b'AuthorizedKeysCommandUser theo-agent', + b'AuthorizedKeysCommand /usr/sbin/theo-agent ' + b'-config-file /var/lib/theo/config.yml -fingerprint %f %u', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] diff --git a/runMolecule.sh b/runMolecule.sh index 99507b5..1f421f2 100755 --- a/runMolecule.sh +++ b/runMolecule.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -SCENARIOS="default signature custom-bin-file custom-config-file" +SCENARIOS="default signature custom-bin-file custom-config-file custom-config-dir" -MUST_FAIL="centos6:custom-config-file" +MUST_FAIL="centos6:custom-config-file centos6:custom-config-dir" function has_right_to_fail { for i in ${MUST_FAIL}; do From 936cbd393a58e647b6ac9882f0dfb0ae0bf3b3b5 Mon Sep 17 00:00:00 2001 From: Michele Azzolari Date: Fri, 7 Jun 2019 18:03:00 +0200 Subject: [PATCH 6/8] CI: add new scenario 'custom-all' --- molecule/custom-all/molecule.yml | 23 +++++ molecule/custom-all/playbook.yml | 34 +++++++ molecule/custom-all/tests/test_default.py | 108 ++++++++++++++++++++++ runMolecule.sh | 4 +- 4 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 molecule/custom-all/molecule.yml create mode 100644 molecule/custom-all/playbook.yml create mode 100644 molecule/custom-all/tests/test_default.py diff --git a/molecule/custom-all/molecule.yml b/molecule/custom-all/molecule.yml new file mode 100644 index 0000000..858e2e8 --- /dev/null +++ b/molecule/custom-all/molecule.yml @@ -0,0 +1,23 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint +verifier: + name: testinfra + lint: + name: flake8 diff --git a/molecule/custom-all/playbook.yml b/molecule/custom-all/playbook.yml new file mode 100644 index 0000000..a6d8cb0 --- /dev/null +++ b/molecule/custom-all/playbook.yml @@ -0,0 +1,34 @@ +--- +- name: Converge + hosts: all + vars: + - theo_url: https://theo.example.com + - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_agent_path: /usr/local/bin/theo + - theo_agent_user: theo + - theo_agent_cache_dir: /var/cache/theo + - theo_agent_config_dir: /var/lib/theo + - theo_agent_config_path: /var/lib/theo/theo.yml + - theo_agent_verify_signature: true + - theo_agent_public_key: | + -----BEGIN PUBLIC KEY----- + MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwVhHEBTVqEpBOpguARtg + //WyDBEoCT2F2OjnHB6fxJ9oopYJZB2Y4jj5cxo1O41r65XmMRT4lqeHWS6Iovde + kzlJ0bH91gl7/iNziUMN4ONiIR0SU3PiBGQ0XKq6rUxpsOhe+tFPfBQYhkkAiQeG + WC1GYQynYjZ/MTEDIPnd5YjSl0agzm7BMRujEcjWyYqEBuZjtDqP6AICz8nkFo9i + CWBONYbCujDl+1sei3WUfeGcUdGiPNwQGU/TW4sfcRWQzayw3XQEl3ERNRMihVsb + in2529O4+JMKdKn22mzTmWsraP/ZakVeti0VtpGZEe1YSTW8+SCz7DnTadnuUZAO + 5JFVTmFcbF7/d/H0atKVVAeTC5nqYNeDrW4jtIQalUZeaHrBkWK7i/yxDYFlC2AW + ZEu4IQZtGfNJCaZFuYSiN96yzlnMWRp1nUGaBxoax4K8rBwX8EWxT4EAyN1mtan0 + ZQITjiZTqDvnhr8iSIvn9hy3942GYi3upOsBeqfb90vzS7BAmoplyWPS0D+UWweB + +sjv96Gtb4BFpc96qwptLCnVFFOVlq0bq0u1FN6sZ4RApl2IaSJV9JGsJjeeJowh + GCK9sSDVI5XY3wy6UYMo9SZQGIglyRPrnd3R82O277lAyOVC/NNp1vq5WH/Mi1Mu + JK85kX7Atut+tgWgwuwT5vcCAwEAAQ== + -----END PUBLIC KEY----- + pre_tasks: + - name: Import common tasks + import_tasks: ../resources/playbooks/pre-tasks.yml + + + roles: + - role: ansible-theo-agent diff --git a/molecule/custom-all/tests/test_default.py b/molecule/custom-all/tests/test_default.py new file mode 100644 index 0000000..9c4ee85 --- /dev/null +++ b/molecule/custom-all/tests/test_default.py @@ -0,0 +1,108 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_theo_binary_file(host): + f = host.file('/usr/local/bin/theo') + assert f.exists + assert f.is_file + assert f.user == 'root' + assert f.group == 'root' + print("{} vs {}".format(f.mode, oct(f.mode))) + assert oct(f.mode) == '0o755' + + +def test_theo_cache_dir(host): + f = host.file('/var/cache/theo') + assert f.exists + assert f.is_directory + assert f.user == 'theo' + assert f.group == 'root' + + +def test_theo_config_file(host): + f = host.file('/var/lib/theo/theo.yml') + assert f.exists + assert f.is_file + assert f.user == 'root' + assert f.group == 'root' + conf = f.content + ''' + url: https://theo.example.com + token: \ + zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + cachedir: /var/cache/theo + verify: True + public_key: /var/lib/theo/public.pem + ''' + expected = [ + b'url: https://theo.example.com', + b'token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp' + b'+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP', + b'cachedir: /var/cache/theo', + b'verify: True', + b'public_key: /var/lib/theo/public.pem' + ] + for line in expected: + assert line in conf + + +def test_theo_public_key_file(host): + f = host.file('/var/lib/theo/public.pem') + assert f.exists + assert f.is_file + assert f.user == 'root' + assert f.group == 'root' + + +def test_sshd_config(host): + distro = os.getenv('MOLECULE_DISTRO', 'centos7') + if distro == 'debian8': + expected = get_sshd_config_pre_v69() + elif distro == 'ubuntu1404': + expected = get_sshd_config_pre_v69() + else: + expected = get_sshd_config_v69() + f = host.file('/etc/ssh/sshd_config') + config = f.content + configlines = [] + for line in config.splitlines(): + if not line.startswith(b'#'): + configlines.append(line) + ''' + I don't want to use something like: + assert set(expected).issubset(configlines) + Because there's no detail of the missing line(s) + ''' + errors = [] + for line in expected: + if line not in configlines: + errors.append(line) + + if len(errors): + print('Failed test_sshd_config, missing line(s)') + for error in errors: + print(error) + assert False + + +def get_sshd_config_pre_v69(): + return [ + b'AuthorizedKeysCommandUser theo', + b'AuthorizedKeysCommand /usr/local/bin/theo ' + b'-config-file /var/lib/theo/theo.yml %u', + b'AuthorizedKeysFile /var/cache/theo/%u' + ] + + +def get_sshd_config_v69(): + return [ + b'AuthorizedKeysCommandUser theo', + b'AuthorizedKeysCommand /usr/local/bin/theo ' + b'-config-file /var/lib/theo/theo.yml -fingerprint %f %u', + b'AuthorizedKeysFile /var/cache/theo/%u' + ] diff --git a/runMolecule.sh b/runMolecule.sh index 1f421f2..749f9f6 100755 --- a/runMolecule.sh +++ b/runMolecule.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -SCENARIOS="default signature custom-bin-file custom-config-file custom-config-dir" +SCENARIOS="default signature custom-bin-file custom-config-file custom-config-dir custom-all" -MUST_FAIL="centos6:custom-config-file centos6:custom-config-dir" +MUST_FAIL="centos6:custom-config-file centos6:custom-config-dir centos6:custom-all" function has_right_to_fail { for i in ${MUST_FAIL}; do From 936b2b8022299ae23a5f14702ab8d502f9502801 Mon Sep 17 00:00:00 2001 From: Michele Azzolari Date: Thu, 1 Aug 2019 10:08:49 +0200 Subject: [PATCH 7/8] CI: add comment to runMolecule.sh --- runMolecule.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runMolecule.sh b/runMolecule.sh index 749f9f6..79d352b 100755 --- a/runMolecule.sh +++ b/runMolecule.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash +# This script wraps molecule test to handle "controlled" failures +# Add distro:scenario to MUST_FAIL var if the test is supposed to fail SCENARIOS="default signature custom-bin-file custom-config-file custom-config-dir custom-all" +# List of tests that must fail, in the form distro:scenario MUST_FAIL="centos6:custom-config-file centos6:custom-config-dir centos6:custom-all" function has_right_to_fail { From 9fb320d1131ab95cb78ba82fbe98ac5c07a42dbc Mon Sep 17 00:00:00 2001 From: Michele Azzolari Date: Thu, 1 Aug 2019 10:32:24 +0200 Subject: [PATCH 8/8] CI: yaml files: - add double quotes around URLs and other possible critical strings - remove empty lines between keys --- molecule/custom-all/playbook.yml | 6 ++---- molecule/custom-bin-file/playbook.yml | 6 ++---- molecule/custom-config-dir/playbook.yml | 6 ++---- molecule/custom-config-file/playbook.yml | 6 ++---- molecule/default/playbook.yml | 5 ++--- molecule/signature/playbook.yml | 6 ++---- 6 files changed, 12 insertions(+), 23 deletions(-) diff --git a/molecule/custom-all/playbook.yml b/molecule/custom-all/playbook.yml index a6d8cb0..b8f2947 100644 --- a/molecule/custom-all/playbook.yml +++ b/molecule/custom-all/playbook.yml @@ -2,8 +2,8 @@ - name: Converge hosts: all vars: - - theo_url: https://theo.example.com - - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_url: "https://theo.example.com" + - theo_client_token: "zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP" - theo_agent_path: /usr/local/bin/theo - theo_agent_user: theo - theo_agent_cache_dir: /var/cache/theo @@ -28,7 +28,5 @@ pre_tasks: - name: Import common tasks import_tasks: ../resources/playbooks/pre-tasks.yml - - roles: - role: ansible-theo-agent diff --git a/molecule/custom-bin-file/playbook.yml b/molecule/custom-bin-file/playbook.yml index e1298c2..048efdc 100644 --- a/molecule/custom-bin-file/playbook.yml +++ b/molecule/custom-bin-file/playbook.yml @@ -2,8 +2,8 @@ - name: Converge hosts: all vars: - - theo_url: https://theo.example.com - - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_url: "https://theo.example.com" + - theo_client_token: "zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP" - theo_agent_path: /usr/local/bin/theo - theo_agent_verify_signature: true - theo_agent_public_key: | @@ -24,7 +24,5 @@ pre_tasks: - name: Import common tasks import_tasks: ../resources/playbooks/pre-tasks.yml - - roles: - role: ansible-theo-agent diff --git a/molecule/custom-config-dir/playbook.yml b/molecule/custom-config-dir/playbook.yml index 06b4efc..bd38abb 100644 --- a/molecule/custom-config-dir/playbook.yml +++ b/molecule/custom-config-dir/playbook.yml @@ -2,8 +2,8 @@ - name: Converge hosts: all vars: - - theo_url: https://theo.example.com - - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_url: "https://theo.example.com" + - theo_client_token: "zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP" - theo_agent_config_dir: /var/lib/theo - theo_agent_verify_signature: true - theo_agent_public_key: | @@ -24,7 +24,5 @@ pre_tasks: - name: Import common tasks import_tasks: ../resources/playbooks/pre-tasks.yml - - roles: - role: ansible-theo-agent diff --git a/molecule/custom-config-file/playbook.yml b/molecule/custom-config-file/playbook.yml index 3792bf1..52be6da 100644 --- a/molecule/custom-config-file/playbook.yml +++ b/molecule/custom-config-file/playbook.yml @@ -2,8 +2,8 @@ - name: Converge hosts: all vars: - - theo_url: https://theo.example.com - - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_url: "https://theo.example.com" + - theo_client_token: "zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP" - theo_agent_config_dir: /var/lib/theo - theo_agent_config_path: /var/lib/theo/theo.yml - theo_agent_verify_signature: true @@ -25,7 +25,5 @@ pre_tasks: - name: Import common tasks import_tasks: ../resources/playbooks/pre-tasks.yml - - roles: - role: ansible-theo-agent diff --git a/molecule/default/playbook.yml b/molecule/default/playbook.yml index 7012f73..0ee1bce 100644 --- a/molecule/default/playbook.yml +++ b/molecule/default/playbook.yml @@ -2,11 +2,10 @@ - name: Converge hosts: all vars: - - theo_url: https://theo.example.com - - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_url: "https://theo.example.com" + - theo_client_token: "zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP" pre_tasks: - name: Import common tasks import_tasks: ../resources/playbooks/pre-tasks.yml - roles: - role: ansible-theo-agent diff --git a/molecule/signature/playbook.yml b/molecule/signature/playbook.yml index 1f0ae09..5523ef5 100644 --- a/molecule/signature/playbook.yml +++ b/molecule/signature/playbook.yml @@ -2,8 +2,8 @@ - name: Converge hosts: all vars: - - theo_url: https://theo.example.com - - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_url: "https://theo.example.com" + - theo_client_token: "zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP" - theo_agent_verify_signature: true - theo_agent_public_key: | -----BEGIN PUBLIC KEY----- @@ -23,7 +23,5 @@ pre_tasks: - name: Import common tasks import_tasks: ../resources/playbooks/pre-tasks.yml - - roles: - role: ansible-theo-agent