diff --git a/README.md b/README.md index 614ce5c..e8f39ac 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,34 @@ Note that this functionality requires at least Cockpit version 257, i.e. RHEL ### Generate a new certificate -For generating a new certificate for Cockpit it is recommended to use the [linux-system-roles.certificate role](https://github.com/linux-system-roles/certificate/). If your machines are joined to a FreeIPA domain, or you use certmonger in a different mode already, generate a certificate with: +For generating a new certificate for Cockpit it is recommended to set the +`cockpit_certificates` variable. The value of `cockpit_certificates` is passed +on to the `certificate_requests` variable of the `certificate` role called +internally in the `cockpit` role and it generates the private key and certificate. +For the supported parameters of `cockpit_certificates`, see the +[`certificate_requests` role documentation section](https://github.com/linux-system-roles/certificate/#certificate_requests). + +When you set `cockpit_certificates`, you must not set `cockpit_private_key` +and `cockpit_cert` variables because they are ignored. + +This example installs Cockpit with an IdM-issued web server certificate +assuming your machines are joined to a FreeIPA domain. + +```yaml + - name: Install cockpit with Cockpit web server certificate + include_role: + name: linux-system-roles.cockpit + vars: + cockpit_certificates: + - name: monger-cockpit + dns: ['localhost', 'www.example.com'] + ca: ipa + group: cockpit-ws +``` + +Note: Generating a new certificate using the [linux-system-roles.certificate role](https://github.com/linux-system-roles/certificate/) in the playbook remains supported. + +This example also installs Cockpit with an IdM-issued web server certificate. ```yaml # This step is only necessary for Cockpit version < 255; in particular on RHEL/CentOS 8 @@ -166,9 +193,13 @@ For generating a new certificate for Cockpit it is recommended to use the [linux group: cockpit-ws ``` -You can also use `ca: self-sign` or `ca: local` depending on your certmonger usage, see the [linux-system-roles.certificate documentation](https://github.com/linux-system-roles/certificate/#cas-and-providers) for details. +NOTE: The `certificate` role, unless using IPA and joining the systems to an IPA domain, +creates self-signed certificates, so you will need to explicitly configure trust, +which is not currently supported by the system roles. To use `ca: self-sign` or +`ca: local`, depending on your certmonger usage, see the +[linux-system-roles.certificate documentation](https://github.com/linux-system-roles/certificate/#cas-and-providers) for details. -Note that this does *not* work on RHEL/CentOS 7. +NOTE: This creating a self-signed certificate is not supported on RHEL/CentOS-7. ## Example Playbooks The most simple example. diff --git a/defaults/main.yml b/defaults/main.yml index 5fccdb0..04f8651 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -23,3 +23,6 @@ cockpit_manage_firewall: no # If yes, manage the cockpit ports using the selinux role. cockpit_manage_selinux: no + +# pass to the certificate_requests variable of the certificate role. +cockpit_certificates: [] diff --git a/tasks/main.yml b/tasks/main.yml index aee7476..faa3835 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -79,6 +79,31 @@ when: cockpit_config is defined notify: restart cockpit +- name: Create certificates + when: + - cockpit_certificates | length > 0 + - ansible_facts['os_family'] == 'RedHat' + block: + - name: Check the OS version for self-sign + when: + - (ansible_facts['distribution_version'] | int == 7 and + cockpit_certificates.0.ca == 'self-sign') + fail: + msg: >- + Creating a self-signed certificate is not supported on + {{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_version'] }} + + - name: Create certificates using the certificate role + include_role: + name: fedora.linux_system_roles.certificate + vars: + certificate_requests: "{{ cockpit_certificates }}" + + - name: Set cockpit_cert and cockpit_private_key + set_fact: + cockpit_cert: "/etc/pki/tls/certs/{{ cockpit_certificates.0.name }}.crt" + cockpit_private_key: "/etc/pki/tls/private/{{ cockpit_certificates.0.name }}.key" + - name: Link to configured existing certificate file: src: "{{ cockpit_cert }}" diff --git a/tests/tests_certificate.yml b/tests/tests_certificate_external.yml similarity index 100% rename from tests/tests_certificate.yml rename to tests/tests_certificate_external.yml diff --git a/tests/tests_certificate_internal.yml b/tests/tests_certificate_internal.yml new file mode 100644 index 0000000..cef391c --- /dev/null +++ b/tests/tests_certificate_internal.yml @@ -0,0 +1,74 @@ +--- +- name: Test the cockpit role calling the certificate role internally + hosts: all + tasks: + - name: tests + vars: + cert_name: cockpit_cert + block: + - name: Install cockpit using the certificate role to create a certificate + block: + - name: Install cockpit with cockpit_certificates request + vars: + cockpit_packages: minimal + cockpit_certificates: + - name: "{{ cert_name }}" + dns: ['localhost', 'www.example.com'] + ca: self-sign + group: cockpit-ws + include_role: + name: linux-system-roles.cockpit + rescue: + - name: Check the error message + vars: + expected: >- + Creating a self-signed certificate is not supported on + {{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_version'] }} + assert: + that: ansible_failed_result.msg == expected + when: + - ansible_facts['os_family'] == 'RedHat' + - ansible_facts['distribution_version'] | int == 7 + + - name: Verify self-signed certmonger certificate created by the certificate role + when: + - ansible_facts['os_family'] == 'RedHat' + - ansible_facts['distribution_version'] | int > 7 + block: + - name: Collect installed package versions + package_facts: + + # Validate installation + - name: test - cockpit works with TLS and expected certificate + command: + cmd: curl --cacert "/etc/pki/tls/certs/{{ cert_name }}.crt" https://localhost:9090 + # ansible 2.11's uri module has ca_path, but that's still too new for us + warn: false + changed_when: false + + - name: test - get certmonger tracking status + command: getcert list --tracking-only -f "/etc/pki/tls/certs/{{ cert_name }}.crt" + register: result + changed_when: false + + - name: test - ensure certificate generation succeeded + assert: + that: "'status: MONITORING' in result.stdout" + + - name: test - clean up tracked certificate + command: getcert stop-tracking -f "/etc/pki/tls/certs/{{ cert_name }}.crt" + changed_when: false + + always: + - name: test - clean up generated certificate + file: + path: "/etc/pki/tls/certs/{{ cert_name }}.crt" + state: absent + + - name: test - clean up generated private key + file: + path: "/etc/pki/tls/private/{{ cert_name }}.key" + state: absent + + - name: test - generic cleanup + include_tasks: tasks/cleanup.yml