From fb2481aac771199853a47f064b62b9079d35cc87 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Mon, 6 May 2024 13:17:57 +0200 Subject: [PATCH] feat: Allow creating encrypted Stratis Pools with Clevis/Tang Tang server configuration or TPM2 can now be used when creating an encrypted Stratis Pool. Related: RHEL-31854 --- README.md | 15 ++++++++++++++ library/blivet.py | 28 +++++++++++++++++++++++++- tests/tests_stratis.yml | 37 +++++++++++++++++++++++++++++++++++ tests/verify-pool-stratis.yml | 15 +++++++++++++- 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 658dad1a..5398d30c 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,21 @@ keys: This integer specifies the LUKS version to use. +- `encryption_clevis_pin` + + For Stratis pools, the clevis method that should be used to encrypt the created pool. + Accepted values are: `tang` and `tpm2` + +- `encryption_tang_url` + + When creating a Stratis pool encrypted via NBDE using a tang server, + specifies the URL of the server. + +- `encryption_tang_thumbprint` + + When creating a Stratis pool encrypted via NBDE using a tang server, + specifies the thumbprint of the server. + ### `storage_volumes` The `storage_volumes` variable is a list of volumes to manage. Each volume has the following diff --git a/library/blivet.py b/library/blivet.py index e44ac759..24f17396 100644 --- a/library/blivet.py +++ b/library/blivet.py @@ -51,6 +51,15 @@ encryption_password: description: encryption_password type: str + encryption_clevis_pin: + description: encryption_clevis_pin + type: str + encryption_tang_url: + description: encryption_tang_url + type: str + encryption_tang_thumbprint: + description: encryption_tang_thumbprint + type: str name: description: name type: str @@ -1907,6 +1916,12 @@ def _update_from_device(self, param_name): self._pool['disks'] = [d.name for d in self._device.disks] elif param_name == 'encryption': self._pool['encryption'] = self._device.encrypted + elif param_name == 'encryption_clevis_pin': + self._pool['encryption_clevis_pin'] = self._device._clevis.pin + elif param_name == 'encryption_tang_url': + self._pool['encryption_tang_url'] = self._device._clevis.tang_url + elif param_name == 'encryption_tang_thumbprint': + self._pool['encryption_tang_thumbprint'] = self._device._clevis.tang_thumbprint else: return False @@ -1961,11 +1976,19 @@ def _create(self): if not self._device: members = self._create_members() try: + if self._spec_dict['encryption'] and self._spec_dict['encryption_clevis_pin']: + clevis_config = devices.stratis.StratisClevisConfig(pin=self._spec_dict['encryption_clevis_pin'], + tang_url=self._spec_dict['encryption_tang_url'], + tang_thumbprint=self._spec_dict['encryption_tang_thumbprint']) + else: + clevis_config = None + pool_device = self._blivet.new_stratis_pool(name=self._pool['name'], parents=members, encrypted=self._spec_dict['encryption'], passphrase=self._spec_dict.get('encryption_password') or None, - key_file=self._spec_dict.get('encryption_key') or None) + key_file=self._spec_dict.get('encryption_key') or None, + clevis=clevis_config) except Exception as e: raise BlivetAnsibleError("failed to set up pool '%s': %s" % (self._pool['name'], str(e))) @@ -2291,6 +2314,9 @@ def run_module(): encryption_key_size=dict(type='int'), encryption_luks_version=dict(type='str'), encryption_password=dict(type='str', no_log=True), + encryption_clevis_pin=dict(type='str'), + encryption_tang_url=dict(type='str'), + encryption_tang_thumbprint=dict(type='str'), name=dict(type='str'), raid_level=dict(type='str'), raid_device_count=dict(type='int'), diff --git a/tests/tests_stratis.yml b/tests/tests_stratis.yml index c38ea291..79333507 100644 --- a/tests/tests_stratis.yml +++ b/tests/tests_stratis.yml @@ -208,3 +208,40 @@ - name: Verify role results include_tasks: verify-role-results.yml + + - name: Setup Tang server on localhost for testing + ansible.builtin.include_role: + name: linux-system-roles.nbde_server + vars: + nbde_server_manage_firewall: true + nbde_server_manage_selinux: true + nbde_server_port: 7500 + + - name: Create encrypted Stratis pool with Clevis/Tang + include_role: + name: linux-system-roles.storage + vars: + storage_pools: + - name: foo + disks: "{{ unused_disks[0] }}" + type: stratis + encryption: true + encryption_password: yabbadabbadoo + encryption_clevis_pin: tang + encryption_tang_url: localhost:7500 + + - name: Verify role results + include_tasks: verify-role-results.yml + + - name: Clean up + include_role: + name: linux-system-roles.storage + vars: + storage_pools: + - name: foo + disks: "{{ unused_disks[0] }}" + type: stratis + state: absent + + - name: Verify role results + include_tasks: verify-role-results.yml diff --git a/tests/verify-pool-stratis.yml b/tests/verify-pool-stratis.yml index 8efae163..7f380171 100644 --- a/tests/verify-pool-stratis.yml +++ b/tests/verify-pool-stratis.yml @@ -26,13 +26,26 @@ - name: Verify that encryption is correctly set assert: that: storage_test_pool.name in - _stratis_pool_info[0]['blockdevs']['datadevs'][0]['key_description'] + _stratis_pool_info.pools[0]['blockdevs']['datadevs'][0]['key_description'] msg: >- Stratis pool '{{ storage_test_pool.name }}' is not encrypted when: - storage_test_pool.state == 'present' - storage_test_pool.encryption + - name: Verify that Clevis/Tang encryption is correctly set + assert: + that: + _stratis_pool_info.pools[0]['blockdevs']['datadevs'][0]['clevis_pin'] == 'tang' and + _stratis_pool_info.pools[0]['blockdevs']['datadevs'][0]['clevis_config']['url'] == + storage_test_pool.encryption_tang_url + msg: >- + Stratis pool '{{ storage_test_pool.name }}' Clevis is not correctly configured + when: + - storage_test_pool.state == 'present' + - storage_test_pool.encryption + - storage_test_pool.encryption_clevis_pin == 'tang' + - name: Reset variable used by test set_fact: storage_test_stratis_report: null