diff --git a/changelogs/fragments/52408-luks-device.yaml b/changelogs/fragments/52408-luks-device.yaml new file mode 100644 index 0000000000..3ab3b8d6a3 --- /dev/null +++ b/changelogs/fragments/52408-luks-device.yaml @@ -0,0 +1,2 @@ +minor_changes: + - luks_device - accept ``passphrase``, ``new_passphrase`` and ``remove_passphrase``. diff --git a/lib/ansible/modules/crypto/luks_device.py b/lib/ansible/modules/crypto/luks_device.py index d5a2190471..3b895db757 100644 --- a/lib/ansible/modules/crypto/luks_device.py +++ b/lib/ansible/modules/crypto/luks_device.py @@ -20,7 +20,7 @@ version_added: "2.8" description: - "Module manages L(LUKS,https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup) on given device. Supports creating, destroying, opening and closing of - LUKS container and adding or removing new keys." + LUKS container and adding or removing new keys and passphrases." options: device: @@ -34,19 +34,22 @@ options: - "Desired state of the LUKS container. Based on its value creates, destroys, opens or closes the LUKS container on a given device." - "I(present) will create LUKS container unless already present. - Requires I(device) and I(keyfile) options to be provided." + Requires I(device) and either I(keyfile) or I(passphrase) options + to be provided." - "I(absent) will remove existing LUKS container if it exists. Requires I(device) or I(name) to be specified." - "I(opened) will unlock the LUKS container. If it does not exist it will be created first. - Requires I(device) and I(keyfile) to be specified. Use - the I(name) option to set the name of the opened container. - Otherwise the name will be generated automatically and returned - as a part of the result." + Requires I(device) and either I(keyfile) or I(passphrase) + to be specified. Use the I(name) option to set the name of + the opened container. Otherwise the name will be + generated automatically and returned as a part of the + result." - "I(closed) will lock the LUKS container. However if the container does not exist it will be created. - Requires I(device) and I(keyfile) options to be provided. If - container does already exist I(device) or I(name) will suffice." + Requires I(device) and either I(keyfile) or I(passphrase) + options to be provided. If container does already exist + I(device) or I(name) will suffice." type: str default: present choices: [present, absent, opened, closed] @@ -58,12 +61,19 @@ options: type: str keyfile: description: - - "Used to unlock the container and needed for most - of the operations. Parameter value is the path - to the keyfile with the passphrase." + - "Used to unlock the container. Either a I(keyfile) or a + I(passphrase) is needed for most of the operations. Parameter + value is the path to the keyfile with the passphrase." - "BEWARE that working with keyfiles in plaintext is dangerous. Make sure that they are protected." type: path + passphrase: + description: + - "Used to unlock the container. Either a I(passphrase) or a + I(keyfile) is needed for most of the operations. Parameter + value is a string with the passphrase." + type: str + version_added: '2.10' keysize: description: - "Sets the key size only if LUKS container does not exist." @@ -72,27 +82,50 @@ options: new_keyfile: description: - "Adds additional key to given container on I(device). - Needs I(keyfile) option for authorization. LUKS container - supports up to 8 keys. Parameter value is the path - to the keyfile with the passphrase." - - "NOTE that adding additional keys is I(not idempotent). + Needs I(keyfile) or I(passphrase) option for authorization. + LUKS container supports up to 8 keyslots. Parameter value + is the path to the keyfile with the passphrase." + - "NOTE that adding additional keys is *not idempotent*. A new keyslot will be used even if another keyslot already exists for this keyfile." - "BEWARE that working with keyfiles in plaintext is dangerous. Make sure that they are protected." type: path + new_passphrase: + description: + - "Adds additional passphrase to given container on I(device). + Needs I(keyfile) or I(passphrase) option for authorization. LUKS + container supports up to 8 keyslots. Parameter value is a string + with the new passphrase." + - "NOTE that adding additional passphrase is *not idempotent*. A + new keyslot will be used even if another keyslot already exists + for this passphrase." + type: str + version_added: '2.10' remove_keyfile: description: - "Removes given key from the container on I(device). Does not remove the keyfile from filesystem. Parameter value is the path to the keyfile with the passphrase." - - "NOTE that removing keys is I(not idempotent). Trying to remove + - "NOTE that removing keys is *not idempotent*. Trying to remove a key which no longer exists results in an error." - "NOTE that to remove the last key from a LUKS container, the I(force_remove_last_key) option must be set to C(yes)." - "BEWARE that working with keyfiles in plaintext is dangerous. Make sure that they are protected." type: path + remove_passphrase: + description: + - "Removes given passphrase from the container on I(device). + Parameter value is a string with the passphrase to remove." + - "NOTE that removing passphrases is I(not + idempotent). Trying to remove a passphrase which no longer + exists results in an error." + - "NOTE that to remove the last keyslot from a LUKS + container, the I(force_remove_last_key) option must be set + to C(yes)." + type: str + version_added: '2.10' force_remove_last_key: description: - "If set to C(yes), allows removing the last key from a container." @@ -143,6 +176,12 @@ EXAMPLES = ''' state: "present" keyfile: "/vault/keyfile" +- name: create LUKS container with a passphrase + luks_device: + device: "/dev/loop0" + state: "present" + passphrase: "foo" + - name: (create and) open the LUKS container; name it "mycrypt" luks_device: device: "/dev/loop0" @@ -174,11 +213,22 @@ EXAMPLES = ''' keyfile: "/vault/keyfile" new_keyfile: "/vault/keyfile2" -- name: remove existing key from the LUKS container +- name: add new passphrase to the LUKS container + luks_device: + device: "/dev/loop0" + keyfile: "/vault/keyfile" + new_passphrase: "foo" + +- name: remove existing keyfile from the LUKS container luks_device: device: "/dev/loop0" remove_keyfile: "/vault/keyfile2" +- name: remove existing passphrase from the LUKS container + luks_device: + device: "/dev/loop0" + remove_passphrase: "foo" + - name: completely remove the LUKS container and its contents luks_device: device: "/dev/loop0" @@ -246,8 +296,8 @@ class Handler(object): self._module = module self._lsblk_bin = self._module.get_bin_path('lsblk', True) - def _run_command(self, command): - return self._module.run_command(command) + def _run_command(self, command, data=None): + return self._module.run_command(command, data=data) def get_device_by_uuid(self, uuid): ''' Returns the device that holds UUID passed by user @@ -330,7 +380,7 @@ class CryptHandler(Handler): result = self._run_command([self._cryptsetup_bin, 'isLuks', device]) return result[RETURN_CODE] == 0 - def run_luks_create(self, device, keyfile, keysize): + def run_luks_create(self, device, keyfile, passphrase, keysize): # create a new luks container; use batch mode to auto confirm luks_type = self._module.params['type'] label = self._module.params['label'] @@ -346,16 +396,22 @@ class CryptHandler(Handler): args = [self._cryptsetup_bin, 'luksFormat'] args.extend(options) - args.extend(['-q', device, keyfile]) + args.extend(['-q', device]) + if keyfile: + args.append(keyfile) - result = self._run_command(args) + result = self._run_command(args, data=passphrase) if result[RETURN_CODE] != 0: raise ValueError('Error while creating LUKS on %s: %s' % (device, result[STDERR])) - def run_luks_open(self, device, keyfile, name): - result = self._run_command([self._cryptsetup_bin, '--key-file', keyfile, - 'open', '--type', 'luks', device, name]) + def run_luks_open(self, device, keyfile, passphrase, name): + args = [self._cryptsetup_bin] + if keyfile: + args.extend(['--key-file', keyfile]) + args.extend(['open', '--type', 'luks', device, name]) + + result = self._run_command(args, data=passphrase) if result[RETURN_CODE] != 0: raise ValueError('Error while opening LUKS container on %s: %s' % (device, result[STDERR])) @@ -376,17 +432,32 @@ class CryptHandler(Handler): raise ValueError('Error while wiping luks container %s: %s' % (device, result[STDERR])) - def run_luks_add_key(self, device, keyfile, new_keyfile): - ''' Add new key to given 'device'; authentication done using 'keyfile' - Raises ValueError when command fails + def run_luks_add_key(self, device, keyfile, passphrase, new_keyfile, + new_passphrase): + ''' Add new key from a keyfile or passphrase to given 'device'; + authentication done using 'keyfile' or 'passphrase'. + Raises ValueError when command fails. ''' - result = self._run_command([self._cryptsetup_bin, 'luksAddKey', device, - new_keyfile, '--key-file', keyfile]) + data = [] + args = [self._cryptsetup_bin, 'luksAddKey', device] + + if keyfile: + args.extend(['--key-file', keyfile]) + else: + data.append(passphrase) + + if new_keyfile: + args.append(new_keyfile) + else: + data.extend([new_passphrase, new_passphrase]) + + result = self._run_command(args, data='\n'.join(data) or None) if result[RETURN_CODE] != 0: - raise ValueError('Error while adding new LUKS key to %s: %s' + raise ValueError('Error while adding new LUKS keyslot to %s: %s' % (device, result[STDERR])) - def run_luks_remove_key(self, device, keyfile, force_remove_last_key=False): + def run_luks_remove_key(self, device, keyfile, passphrase, + force_remove_last_key=False): ''' Remove key from given device Raises ValueError when command fails ''' @@ -420,8 +491,10 @@ class CryptHandler(Handler): "To be able to remove a key, please set " "`force_remove_last_key` to `yes`." % device) - result = self._run_command([self._cryptsetup_bin, 'luksRemoveKey', device, - '-q', '--key-file', keyfile]) + args = [self._cryptsetup_bin, 'luksRemoveKey', device, '-q'] + if keyfile: + args.extend(['--key-file', keyfile]) + result = self._run_command(args, data=passphrase) if result[RETURN_CODE] != 0: raise ValueError('Error while removing LUKS key from %s: %s' % (device, result[STDERR])) @@ -451,7 +524,8 @@ class ConditionsHandler(Handler): def luks_create(self): return (self.device is not None and - self._module.params['keyfile'] is not None and + (self._module.params['keyfile'] is not None or + self._module.params['passphrase'] is not None) and self._module.params['state'] in ('present', 'opened', 'closed') and @@ -487,7 +561,8 @@ class ConditionsHandler(Handler): return name def luks_open(self): - if (self._module.params['keyfile'] is None or + if ((self._module.params['keyfile'] is None and + self._module.params['passphrase'] is None) or self.device is None or self._module.params['state'] != 'opened'): # conditions for open not fulfilled @@ -520,8 +595,10 @@ class ConditionsHandler(Handler): def luks_add_key(self): if (self.device is None or - self._module.params['keyfile'] is None or - self._module.params['new_keyfile'] is None): + (self._module.params['keyfile'] is None and + self._module.params['passphrase'] is None) or + (self._module.params['new_keyfile'] is None and + self._module.params['new_passphrase'] is None)): # conditions for adding a key not fulfilled return False @@ -533,7 +610,8 @@ class ConditionsHandler(Handler): def luks_remove_key(self): if (self.device is None or - self._module.params['remove_keyfile'] is None): + (self._module.params['remove_keyfile'] is None and + self._module.params['remove_passphrase'] is None)): # conditions for removing a key not fulfilled return False @@ -558,6 +636,9 @@ def run_module(): keyfile=dict(type='path'), new_keyfile=dict(type='path'), remove_keyfile=dict(type='path'), + passphrase=dict(type='str', no_log=True), + new_passphrase=dict(type='str', no_log=True), + remove_passphrase=dict(type='str', no_log=True), force_remove_last_key=dict(type='bool', default=False), keysize=dict(type='int'), label=dict(type='str'), @@ -565,6 +646,12 @@ def run_module(): type=dict(type='str', choices=['luks1', 'luks2']), ) + mutually_exclusive = [ + ('keyfile', 'passphrase'), + ('new_keyfile', 'new_passphrase'), + ('remove_keyfile', 'remove_passphrase') + ] + # seed the result dict in the object result = dict( changed=False, @@ -572,7 +659,8 @@ def run_module(): ) module = AnsibleModule(argument_spec=module_args, - supports_check_mode=True) + supports_check_mode=True, + mutually_exclusive=mutually_exclusive) if module.params['device'] is not None: try: @@ -599,6 +687,7 @@ def run_module(): try: crypt.run_luks_create(conditions.device, module.params['keyfile'], + module.params['passphrase'], module.params['keysize']) except ValueError as e: module.fail_json(msg="luks_device error: %s" % e) @@ -623,6 +712,7 @@ def run_module(): try: crypt.run_luks_open(conditions.device, module.params['keyfile'], + module.params['passphrase'], name) except ValueError as e: module.fail_json(msg="luks_device error: %s" % e) @@ -657,7 +747,9 @@ def run_module(): try: crypt.run_luks_add_key(conditions.device, module.params['keyfile'], - module.params['new_keyfile']) + module.params['passphrase'], + module.params['new_keyfile'], + module.params['new_passphrase']) except ValueError as e: module.fail_json(msg="luks_device error: %s" % e) result['changed'] = True @@ -671,6 +763,7 @@ def run_module(): last_key = module.params['force_remove_last_key'] crypt.run_luks_remove_key(conditions.device, module.params['remove_keyfile'], + module.params['remove_passphrase'], force_remove_last_key=last_key) except ValueError as e: module.fail_json(msg="luks_device error: %s" % e) diff --git a/test/integration/targets/luks_device/tasks/main.yml b/test/integration/targets/luks_device/tasks/main.yml index 9793704581..d3ca75b637 100644 --- a/test/integration/targets/luks_device/tasks/main.yml +++ b/test/integration/targets/luks_device/tasks/main.yml @@ -15,6 +15,9 @@ register: cryptfile_device_output - set_fact: cryptfile_device: "{{ cryptfile_device_output.stdout_lines[1] }}" + cryptfile_passphrase1: "uNiJ9vKG2mUOEWDiQVuBHJlfMHE" + cryptfile_passphrase2: "HW4Ak2HtE2vvne0qjJMPTtmbV4M" + cryptfile_passphrase3: "qQJqsjabO9pItV792k90VvX84MM" - block: - include_tasks: run-test.yml with_fileglob: diff --git a/test/integration/targets/luks_device/tasks/tests/key-management.yml b/test/integration/targets/luks_device/tasks/tests/key-management.yml index 1866a46dbc..b89d505fa6 100644 --- a/test/integration/targets/luks_device/tasks/tests/key-management.yml +++ b/test/integration/targets/luks_device/tasks/tests/key-management.yml @@ -23,6 +23,7 @@ luks_device: device: "{{ cryptfile_device }}" state: closed + become: yes - name: Try to open with keyfile2 luks_device: @@ -61,9 +62,11 @@ luks_device: device: "{{ cryptfile_device }}" state: closed + become: yes - name: Dump LUKS header command: "cryptsetup luksDump {{ cryptfile_device }}" + become: yes - name: Remove access from keyfile1 luks_device: @@ -102,9 +105,11 @@ luks_device: device: "{{ cryptfile_device }}" state: closed + become: yes - name: Dump LUKS header command: "cryptsetup luksDump {{ cryptfile_device }}" + become: yes - name: Remove access from keyfile2 luks_device: @@ -137,6 +142,7 @@ luks_device: device: "{{ cryptfile_device }}" state: closed + become: yes - name: Remove access from keyfile2 luks_device: diff --git a/test/integration/targets/luks_device/tasks/tests/options.yml b/test/integration/targets/luks_device/tasks/tests/options.yml index 31d16d3b8d..afee6667d6 100644 --- a/test/integration/targets/luks_device/tasks/tests/options.yml +++ b/test/integration/targets/luks_device/tasks/tests/options.yml @@ -23,9 +23,19 @@ keysize: 512 become: yes register: create_idem_with_diff_keysize +- name: Create with ambiguous arguments + luks_device: + device: "{{ cryptfile_device }}" + state: present + keyfile: "{{ role_path }}/files/keyfile1" + passphrase: "{{ cryptfile_passphrase1 }}" + ignore_errors: yes + become: yes + register: create_with_ambiguous - assert: that: - create_with_keysize is changed - create_idem_with_keysize is not changed - create_idem_with_diff_keysize is not changed + - create_with_ambiguous is failed diff --git a/test/integration/targets/luks_device/tasks/tests/passphrase.yml b/test/integration/targets/luks_device/tasks/tests/passphrase.yml new file mode 100644 index 0000000000..560915252f --- /dev/null +++ b/test/integration/targets/luks_device/tasks/tests/passphrase.yml @@ -0,0 +1,181 @@ +--- +- name: Create with passphrase1 + luks_device: + device: "{{ cryptfile_device }}" + state: closed + passphrase: "{{ cryptfile_passphrase1 }}" + become: yes + +- name: Open with passphrase1 + luks_device: + device: "{{ cryptfile_device }}" + state: opened + passphrase: "{{ cryptfile_passphrase1 }}" + become: yes + ignore_errors: yes + register: open_try +- assert: + that: + - open_try is not failed +- name: Close + luks_device: + device: "{{ cryptfile_device }}" + state: closed + become: yes + +- name: Give access with ambiguous new_ arguments + luks_device: + device: "{{ cryptfile_device }}" + state: closed + passphrase: "{{ cryptfile_passphrase1 }}" + new_passphrase: "{{ cryptfile_passphrase2 }}" + new_keyfile: "{{ role_path }}/files/keyfile1" + become: yes + ignore_errors: yes + register: new_try +- assert: + that: + - new_try is failed + +- name: Try to open with passphrase2 + luks_device: + device: "{{ cryptfile_device }}" + state: opened + passphrase: "{{ cryptfile_passphrase2 }}" + become: yes + ignore_errors: yes + register: open_try +- assert: + that: + - open_try is failed + +- name: Give access to passphrase2 + luks_device: + device: "{{ cryptfile_device }}" + state: closed + passphrase: "{{ cryptfile_passphrase1 }}" + new_passphrase: "{{ cryptfile_passphrase2 }}" + become: yes + +- name: Open with passphrase2 + luks_device: + device: "{{ cryptfile_device }}" + state: opened + passphrase: "{{ cryptfile_passphrase2 }}" + become: yes + ignore_errors: yes + register: open_try +- assert: + that: + - open_try is not failed +- name: Close + luks_device: + device: "{{ cryptfile_device }}" + state: closed + become: yes + +- name: Try to open with keyfile1 + luks_device: + device: "{{ cryptfile_device }}" + state: opened + keyfile: "{{ role_path }}/files/keyfile1" + become: yes + ignore_errors: yes + register: open_try +- assert: + that: + - open_try is failed + +- name: Give access to keyfile1 from passphrase1 + luks_device: + device: "{{ cryptfile_device }}" + state: closed + passphrase: "{{ cryptfile_passphrase1 }}" + new_keyfile: "{{ role_path }}/files/keyfile1" + become: yes + +- name: Remove access with ambiguous remove_ arguments + luks_device: + device: "{{ cryptfile_device }}" + state: closed + remove_keyfile: "{{ role_path }}/files/keyfile1" + remove_passphrase: "{{ cryptfile_passphrase1 }}" + become: yes + ignore_errors: yes + register: remove_try +- assert: + that: + - remove_try is failed + +- name: Open with keyfile1 + luks_device: + device: "{{ cryptfile_device }}" + state: opened + keyfile: "{{ role_path }}/files/keyfile1" + become: yes + ignore_errors: yes + register: open_try +- assert: + that: + - open_try is not failed +- name: Close + luks_device: + device: "{{ cryptfile_device }}" + state: closed + become: yes + +- name: Remove access for passphrase1 + luks_device: + device: "{{ cryptfile_device }}" + state: closed + remove_passphrase: "{{ cryptfile_passphrase1 }}" + become: yes + +- name: Try to open with passphrase1 + luks_device: + device: "{{ cryptfile_device }}" + state: opened + passphrase: "{{ cryptfile_passphrase1 }}" + become: yes + ignore_errors: yes + register: open_try +- assert: + that: + - open_try is failed + +- name: Try to open with passphrase3 + luks_device: + device: "{{ cryptfile_device }}" + state: opened + passphrase: "{{ cryptfile_passphrase3 }}" + become: yes + ignore_errors: yes + register: open_try +- assert: + that: + - open_try is failed + +- name: Give access to passphrase3 from keyfile1 + luks_device: + device: "{{ cryptfile_device }}" + state: closed + keyfile: "{{ role_path }}/files/keyfile1" + new_passphrase: "{{ cryptfile_passphrase3 }}" + become: yes + +- name: Open with passphrase3 + luks_device: + device: "{{ cryptfile_device }}" + state: opened + passphrase: "{{ cryptfile_passphrase3 }}" + become: yes + ignore_errors: yes + register: open_try +- assert: + that: + - open_try is not failed +- name: Close + luks_device: + device: "{{ cryptfile_device }}" + state: closed + become: yes diff --git a/test/units/modules/crypto/test_luks_device.py b/test/units/modules/crypto/test_luks_device.py index 025b0d1a3c..e6449814a0 100644 --- a/test/units/modules/crypto/test_luks_device.py +++ b/test/units/modules/crypto/test_luks_device.py @@ -64,16 +64,24 @@ def test_run_luks_remove(monkeypatch): # ===== ConditionsHandler methods data and tests ===== -# device, key, state, is_luks, label, expected +# device, key, passphrase, state, is_luks, label, expected LUKS_CREATE_DATA = ( - ("dummy", "key", "present", False, None, True), - (None, "key", "present", False, None, False), - (None, "key", "present", False, "labelName", True), - ("dummy", None, "present", False, None, False), - ("dummy", "key", "absent", False, None, False), - ("dummy", "key", "opened", True, None, False), - ("dummy", "key", "closed", True, None, False), - ("dummy", "key", "present", True, None, False)) + ("dummy", "key", None, "present", False, None, True), + (None, "key", None, "present", False, None, False), + (None, "key", None, "present", False, "labelName", True), + ("dummy", None, None, "present", False, None, False), + ("dummy", "key", None, "absent", False, None, False), + ("dummy", "key", None, "opened", True, None, False), + ("dummy", "key", None, "closed", True, None, False), + ("dummy", "key", None, "present", True, None, False), + ("dummy", None, "foo", "present", False, None, True), + (None, None, "bar", "present", False, None, False), + (None, None, "baz", "present", False, "labelName", True), + ("dummy", None, None, "present", False, None, False), + ("dummy", None, "quz", "absent", False, None, False), + ("dummy", None, "qux", "opened", True, None, False), + ("dummy", None, "quux", "closed", True, None, False), + ("dummy", None, "corge", "present", True, None, False)) # device, state, is_luks, expected LUKS_REMOVE_DATA = ( @@ -82,16 +90,24 @@ LUKS_REMOVE_DATA = ( ("dummy", "present", True, False), ("dummy", "absent", False, False)) -# device, key, state, name, name_by_dev, expected +# device, key, passphrase, state, name, name_by_dev, expected LUKS_OPEN_DATA = ( - ("dummy", "key", "present", "name", None, False), - ("dummy", "key", "absent", "name", None, False), - ("dummy", "key", "closed", "name", None, False), - ("dummy", "key", "opened", "name", None, True), - (None, "key", "opened", "name", None, False), - ("dummy", None, "opened", "name", None, False), - ("dummy", "key", "opened", "name", "name", False), - ("dummy", "key", "opened", "beer", "name", "exception")) + ("dummy", "key", None, "present", "name", None, False), + ("dummy", "key", None, "absent", "name", None, False), + ("dummy", "key", None, "closed", "name", None, False), + ("dummy", "key", None, "opened", "name", None, True), + (None, "key", None, "opened", "name", None, False), + ("dummy", None, None, "opened", "name", None, False), + ("dummy", "key", None, "opened", "name", "name", False), + ("dummy", "key", None, "opened", "beer", "name", "exception"), + ("dummy", None, "foo", "present", "name", None, False), + ("dummy", None, "bar", "absent", "name", None, False), + ("dummy", None, "baz", "closed", "name", None, False), + ("dummy", None, "qux", "opened", "name", None, True), + (None, None, "quux", "opened", "name", None, False), + ("dummy", None, None, "opened", "name", None, False), + ("dummy", None, "quuz", "opened", "name", "name", False), + ("dummy", None, "corge", "opened", "beer", "name", "exception")) # device, dev_by_name, name, name_by_dev, state, label, expected LUKS_CLOSE_DATA = ( @@ -103,33 +119,50 @@ LUKS_CLOSE_DATA = ( ("dummy", "dummy", None, "name", "closed", None, True), (None, "dummy", None, "name", "closed", None, False)) -# device, key, new_key, state, label, expected +# device, key, passphrase, new_key, new_passphrase, state, label, expected LUKS_ADD_KEY_DATA = ( - ("dummy", "key", "new_key", "present", None, True), - (None, "key", "new_key", "present", "labelName", True), - (None, "key", "new_key", "present", None, False), - ("dummy", None, "new_key", "present", None, False), - ("dummy", "key", None, "present", None, False), - ("dummy", "key", "new_key", "absent", None, "exception")) + ("dummy", "key", None, "new_key", None, "present", None, True), + (None, "key", None, "new_key", None, "present", "labelName", True), + (None, "key", None, "new_key", None, "present", None, False), + ("dummy", None, None, "new_key", None, "present", None, False), + ("dummy", "key", None, None, None, "present", None, False), + ("dummy", "key", None, "new_key", None, "absent", None, "exception"), + ("dummy", None, "pass", "new_key", None, "present", None, True), + (None, None, "pass", "new_key", None, "present", "labelName", True), + ("dummy", "key", None, None, "new_pass", "present", None, True), + (None, "key", None, None, "new_pass", "present", "labelName", True), + (None, "key", None, None, "new_pass", "present", None, False), + ("dummy", None, None, None, "new_pass", "present", None, False), + ("dummy", "key", None, None, None, "present", None, False), + ("dummy", "key", None, None, "new_pass", "absent", None, "exception"), + ("dummy", None, "pass", None, "new_pass", "present", None, True), + (None, None, "pass", None, "new_pass", "present", "labelName", True)) -# device, remove_key, state, label, expected +# device, remove_key, remove_passphrase, state, label, expected LUKS_REMOVE_KEY_DATA = ( - ("dummy", "key", "present", None, True), - (None, "key", "present", None, False), - (None, "key", "present", "labelName", True), - ("dummy", None, "present", None, False), - ("dummy", "key", "absent", None, "exception")) + ("dummy", "key", None, "present", None, True), + (None, "key", None, "present", None, False), + (None, "key", None, "present", "labelName", True), + ("dummy", None, None, "present", None, False), + ("dummy", "key", None, "absent", None, "exception"), + ("dummy", None, "foo", "present", None, True), + (None, None, "foo", "present", None, False), + (None, None, "foo", "present", "labelName", True), + ("dummy", None, None, "present", None, False), + ("dummy", None, "foo", "absent", None, "exception")) -@pytest.mark.parametrize("device, keyfile, state, is_luks, label, expected", - ((d[0], d[1], d[2], d[3], d[4], d[5]) +@pytest.mark.parametrize("device, keyfile, passphrase, state, is_luks, " + + "label, expected", + ((d[0], d[1], d[2], d[3], d[4], d[5], d[6]) for d in LUKS_CREATE_DATA)) -def test_luks_create(device, keyfile, state, is_luks, label, expected, - monkeypatch): +def test_luks_create(device, keyfile, passphrase, state, is_luks, label, + expected, monkeypatch): module = DummyModule() module.params["device"] = device module.params["keyfile"] = keyfile + module.params["passphrase"] = passphrase module.params["state"] = state module.params["label"] = label @@ -165,15 +198,16 @@ def test_luks_remove(device, state, is_luks, expected, monkeypatch): assert expected == "exception" -@pytest.mark.parametrize("device, keyfile, state, name, " +@pytest.mark.parametrize("device, keyfile, passphrase, state, name, " "name_by_dev, expected", - ((d[0], d[1], d[2], d[3], d[4], d[5]) + ((d[0], d[1], d[2], d[3], d[4], d[5], d[6]) for d in LUKS_OPEN_DATA)) -def test_luks_open(device, keyfile, state, name, name_by_dev, +def test_luks_open(device, keyfile, passphrase, state, name, name_by_dev, expected, monkeypatch): module = DummyModule() module.params["device"] = device module.params["keyfile"] = keyfile + module.params["passphrase"] = passphrase module.params["state"] = state module.params["name"] = name @@ -219,14 +253,18 @@ def test_luks_close(device, dev_by_name, name, name_by_dev, state, assert expected == "exception" -@pytest.mark.parametrize("device, keyfile, new_keyfile, state, label, expected", - ((d[0], d[1], d[2], d[3], d[4], d[5]) +@pytest.mark.parametrize("device, keyfile, passphrase, new_keyfile, " + + "new_passphrase, state, label, expected", + ((d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]) for d in LUKS_ADD_KEY_DATA)) -def test_luks_add_key(device, keyfile, new_keyfile, state, label, expected, monkeypatch): +def test_luks_add_key(device, keyfile, passphrase, new_keyfile, new_passphrase, + state, label, expected, monkeypatch): module = DummyModule() module.params["device"] = device module.params["keyfile"] = keyfile + module.params["passphrase"] = passphrase module.params["new_keyfile"] = new_keyfile + module.params["new_passphrase"] = new_passphrase module.params["state"] = state module.params["label"] = label @@ -240,14 +278,17 @@ def test_luks_add_key(device, keyfile, new_keyfile, state, label, expected, monk assert expected == "exception" -@pytest.mark.parametrize("device, remove_keyfile, state, label, expected", - ((d[0], d[1], d[2], d[3], d[4]) +@pytest.mark.parametrize("device, remove_keyfile, remove_passphrase, state, " + + "label, expected", + ((d[0], d[1], d[2], d[3], d[4], d[5]) for d in LUKS_REMOVE_KEY_DATA)) -def test_luks_remove_key(device, remove_keyfile, state, label, expected, monkeypatch): +def test_luks_remove_key(device, remove_keyfile, remove_passphrase, state, + label, expected, monkeypatch): module = DummyModule() module.params["device"] = device module.params["remove_keyfile"] = remove_keyfile + module.params["remove_passphrase"] = remove_passphrase module.params["state"] = state module.params["label"] = label