-
Notifications
You must be signed in to change notification settings - Fork 37
Add molecule tests to certificates role #548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| --- | ||
| dependency: | ||
| name: galaxy | ||
| options: | ||
| requirements-file: ${MOLECULE_PROJECT_DIRECTORY}/../../requirements.yml | ||
|
|
||
| driver: | ||
| name: podman | ||
|
|
||
| platforms: | ||
| - name: quadlet | ||
| image: registry.access.redhat.com/ubi9/ubi | ||
| volumes: | ||
| - "${MOLECULE_PROJECT_DIRECTORY}/../../../:/vagrant:Z" | ||
| tmpfs: | ||
| /tmp: exec | ||
| /run: rw,noexec,nosuid,nodev | ||
|
|
||
| provisioner: | ||
| name: ansible | ||
| env: | ||
| ANSIBLE_COLLECTIONS_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../../../build/collections/foremanctl | ||
| ANSIBLE_COLLECTIONS_SCAN_SYS_PATH: "false" | ||
| inventory: | ||
| group_vars: | ||
| all: | ||
| certificates_ca_password: molecule-test-password | ||
| config_options: | ||
| defaults: | ||
| roles_path: ${MOLECULE_PROJECT_DIRECTORY}/.. | ||
|
|
||
| verifier: | ||
| name: ansible | ||
|
|
||
| scenario: | ||
| test_sequence: | ||
| - cleanup | ||
| - destroy | ||
| - syntax | ||
| - create | ||
| - converge | ||
| - idempotence | ||
| - verify | ||
| - cleanup | ||
| - destroy | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ jinja2 | |
| paramiko | ||
| passlib | ||
| ruff | ||
| molecule>=24.0.0 | ||
| pytest-testinfra | ||
| pytest-durations | ||
| python-dateutil | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| [pytest] | ||
| testpaths = tests | ||
| # Ignore molecule scenario directories during normal test discovery | ||
| norecursedirs = molecule .molecule build .venv .git .ansible .vagrant | ||
| markers = | ||
| molecule: Molecule role tests (run with pytest --molecule) | ||
| iop: tests requiring IOP to be enabled |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| - name: Set certificate hostnames from VM FQDN | ||
| ansible.builtin.set_fact: | ||
| certificates_hostnames: | ||
| - "{{ ansible_facts['fqdn'] }}" | ||
| - localhost |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| --- | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can tests with molecule be written in pytest or do they have to be written in Ansible?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently molecule supports ansible and testinfra verifiers.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. testinfra verifiers are pytest based right?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes I think so. |
||
| - name: Read internal CA certificate subject | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl x509 -in {{ certificates_ca_directory_certs }}/ca.crt | ||
| -noout -subject | ||
| register: certificates_internal_ca_subject | ||
| changed_when: false | ||
|
|
||
| - name: Read custom server CA certificate subject | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl x509 -in {{ certificates_ca_directory_certs }}/server-ca.crt | ||
| -noout -subject | ||
| register: certificates_server_ca_subject | ||
| changed_when: false | ||
|
|
||
| - name: Verify custom server CA differs from internal CA | ||
| ansible.builtin.assert: | ||
| that: | ||
| - certificates_internal_ca_subject.stdout != certificates_server_ca_subject.stdout | ||
| fail_msg: Custom server CA should have a different subject than the internal CA | ||
|
|
||
| - name: Read server certificate issuer | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl x509 -in {{ certificates_ca_directory_certs }}/{{ certificates_test_hostname }}.crt | ||
| -noout -issuer | ||
| register: certificates_server_issuer | ||
| changed_when: false | ||
|
|
||
| - name: Verify server certificate is issued by custom server CA | ||
| ansible.builtin.assert: | ||
| that: | ||
| - certificates_server_issuer.stdout == certificates_server_ca_subject.stdout.replace('subject=', 'issuer=') | ||
| fail_msg: Server certificate should be issued by the custom server CA | ||
|
|
||
| - name: Read client certificate issuer | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl x509 -in {{ certificates_ca_directory_certs }}/{{ certificates_test_hostname }}-client.crt | ||
| -noout -issuer | ||
| register: certificates_client_issuer | ||
| changed_when: false | ||
|
|
||
| - name: Verify client certificate is issued by internal CA | ||
| ansible.builtin.assert: | ||
| that: | ||
| - certificates_client_issuer.stdout == certificates_internal_ca_subject.stdout.replace('subject=', 'issuer=') | ||
| fail_msg: Client certificate should be issued by the internal CA | ||
|
|
||
| - name: Read localhost certificate issuer | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl x509 -in {{ certificates_ca_directory_certs }}/localhost.crt | ||
| -noout -issuer | ||
| register: certificates_localhost_issuer | ||
| changed_when: false | ||
|
|
||
| - name: Verify localhost certificate is issued by internal CA | ||
| ansible.builtin.assert: | ||
| that: | ||
| - certificates_localhost_issuer.stdout == certificates_internal_ca_subject.stdout.replace('subject=', 'issuer=') | ||
| fail_msg: Localhost certificate should be issued by the internal CA | ||
|
|
||
| - name: Verify server certificate chains to CA bundle | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl verify -CAfile {{ certificates_ca_directory_certs }}/ca-bundle.crt | ||
| {{ certificates_ca_directory_certs }}/{{ certificates_test_hostname }}.crt | ||
| register: certificates_server_verify | ||
| changed_when: false | ||
| failed_when: "'OK' not in certificates_server_verify.stdout" | ||
|
|
||
| - name: Verify client certificate chains to internal CA | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl verify -CAfile {{ certificates_ca_directory_certs }}/ca.crt | ||
| {{ certificates_ca_directory_certs }}/{{ certificates_test_hostname }}-client.crt | ||
| register: certificates_client_verify | ||
| changed_when: false | ||
| failed_when: "'OK' not in certificates_client_verify.stdout" | ||
|
|
||
| - name: Verify localhost server certificate chains to internal CA | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl verify -CAfile {{ certificates_ca_directory_certs }}/ca.crt | ||
| {{ certificates_ca_directory_certs }}/localhost.crt | ||
| register: certificates_localhost_verify | ||
| changed_when: false | ||
| failed_when: "'OK' not in certificates_localhost_verify.stdout" | ||
|
|
||
| - name: List CA bundle certificate subjects | ||
| ansible.builtin.shell: | | ||
| set -o pipefail | ||
| awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/' {{ certificates_ca_directory_certs }}/ca-bundle.crt \ | ||
| | openssl crl2pkcs7 -nocrl -certfile /dev/stdin \ | ||
| | openssl pkcs7 -print_certs -noout -text \ | ||
| | grep 'Subject:' | ||
| args: | ||
| executable: /bin/bash | ||
| register: certificates_bundle_subjects | ||
| changed_when: false | ||
|
|
||
| - name: Verify CA bundle contains internal and custom server CAs | ||
| ansible.builtin.assert: | ||
| that: | ||
| - certificates_internal_ca_subject.stdout.split('=', 1)[1] in certificates_bundle_subjects.stdout | ||
| - certificates_server_ca_subject.stdout.split('=', 1)[1] in certificates_bundle_subjects.stdout | ||
| - certificates_bundle_subjects.stdout | regex_findall('Subject:') | length == 2 | ||
| fail_msg: CA bundle should contain exactly the internal CA and custom server CA | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| --- | ||
| - name: Verify CA certificate subject | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl x509 -in {{ certificates_ca_directory_certs }}/ca.crt | ||
| -noout -subject | ||
| register: certificates_ca_subject | ||
| changed_when: false | ||
| failed_when: "'Foreman Self-signed CA' not in certificates_ca_subject.stdout" | ||
|
|
||
| - name: Verify server certificate chains to CA | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl verify -CAfile {{ certificates_ca_directory_certs }}/ca.crt | ||
| {{ certificates_ca_directory_certs }}/{{ certificates_test_hostname }}.crt | ||
| register: certificates_server_verify | ||
| changed_when: false | ||
| failed_when: "'OK' not in certificates_server_verify.stdout" | ||
|
|
||
| - name: Verify client certificate chains to CA | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl verify -CAfile {{ certificates_ca_directory_certs }}/ca.crt | ||
| {{ certificates_ca_directory_certs }}/{{ certificates_test_hostname }}-client.crt | ||
| register: certificates_client_verify | ||
| changed_when: false | ||
| failed_when: "'OK' not in certificates_client_verify.stdout" | ||
|
|
||
| - name: Verify localhost server certificate chains to CA | ||
| ansible.builtin.command: | ||
| cmd: >- | ||
| openssl verify -CAfile {{ certificates_ca_directory_certs }}/ca.crt | ||
| {{ certificates_ca_directory_certs }}/localhost.crt | ||
| register: certificates_localhost_verify | ||
| changed_when: false | ||
| failed_when: "'OK' not in certificates_localhost_verify.stdout" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| - name: Check expected certificate files exist | ||
| ansible.builtin.stat: | ||
| path: "{{ item }}" | ||
| register: certificates_file_stats | ||
| failed_when: not certificates_file_stats.stat.exists | ||
| loop: "{{ certificates_expected_files }}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| --- | ||
| certificates_test_hostname: "{{ ansible_facts['fqdn'] }}" | ||
| certificates_ca_directory_certs: "{{ certificates_ca_directory }}/certs" | ||
| certificates_ca_directory_keys: "{{ certificates_ca_directory }}/private" | ||
| certificates_expected_files: | ||
| - "{{ certificates_ca_directory_certs }}/ca.crt" | ||
| - "{{ certificates_ca_directory_certs }}/server-ca.crt" | ||
| - "{{ certificates_ca_directory_certs }}/ca-bundle.crt" | ||
| - "{{ certificates_ca_directory_keys }}/ca.key" | ||
| - "{{ certificates_ca_directory_certs }}/{{ certificates_test_hostname }}.crt" | ||
| - "{{ certificates_ca_directory_keys }}/{{ certificates_test_hostname }}.key" | ||
| - "{{ certificates_ca_directory_certs }}/{{ certificates_test_hostname }}-client.crt" | ||
| - "{{ certificates_ca_directory_keys }}/{{ certificates_test_hostname }}-client.key" | ||
| - "{{ certificates_ca_directory_certs }}/localhost.crt" | ||
| - "{{ certificates_ca_directory_keys }}/localhost.key" | ||
| - "{{ certificates_ca_directory_certs }}/localhost-client.crt" | ||
| - "{{ certificates_ca_directory_keys }}/localhost-client.key" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| --- | ||
| - name: Converge | ||
| hosts: quadlet | ||
| become: true | ||
| vars: | ||
| molecule_custom_source_directory: /vagrant/tests/fixtures/foreman-certificate-check/certs/ | ||
| pre_tasks: | ||
| - ansible.builtin.import_tasks: ../common/tasks/set_hostnames.yml | ||
|
|
||
| - name: Set custom server certificate paths | ||
| ansible.builtin.set_fact: | ||
| certificates_custom_server_certificate: "{{ molecule_custom_source_directory }}foreman.example.com.crt" | ||
| certificates_custom_server_key: "{{ molecule_custom_source_directory }}foreman.example.com.key" | ||
| certificates_custom_server_ca_certificate: "{{ molecule_custom_source_directory }}ca.crt" | ||
|
|
||
| roles: | ||
| - role: certificates |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| provisioner: | ||
| inventory: | ||
| group_vars: | ||
| all: | ||
| certificates_source: custom_server | ||
| certificates_ca_directory: /var/lib/foremanctl/molecule-certs-custom |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| - name: Verify | ||
| hosts: quadlet | ||
| gather_facts: true | ||
| vars_files: | ||
| - ../common/vars/verify.yml | ||
| tasks: | ||
| - ansible.builtin.import_tasks: ../common/tasks/verify_invariant.yml | ||
| - ansible.builtin.import_tasks: ../common/tasks/verify_custom_server.yml |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| --- | ||
| - name: Converge | ||
| hosts: quadlet | ||
| become: true | ||
| pre_tasks: | ||
| - ansible.builtin.import_tasks: ../common/tasks/set_hostnames.yml | ||
| roles: | ||
| - role: certificates |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| provisioner: | ||
| inventory: | ||
| group_vars: | ||
| all: | ||
| certificates_ca_directory: /var/lib/foremanctl/molecule-certs |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| - name: Verify | ||
| hosts: quadlet | ||
| gather_facts: true | ||
| vars_files: | ||
| - ../common/vars/verify.yml | ||
| tasks: | ||
| - ansible.builtin.import_tasks: ../common/tasks/verify_invariant.yml | ||
| - ansible.builtin.import_tasks: ../common/tasks/verify_default.yml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this mounting things at
/vagrant? this should run in a container, right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because I was lazy when switched between drivers. I need the sources mounted into the container to do things like copying the custom certificates: https://github.com/theforeman/foremanctl/pull/548/changes#diff-8e0370b95ab38b1aa4d27ac77915e805f1832f8adba342ef74dda35f550660a1R6.
Since I was lazy to change the folder names, and if I use vagrant as the driver, I have synced the folder structure between the drivers.