diff --git a/README-vault.md b/README-vault.md index db700783e0390f5859610fa7e1997524195244ef..61f684147030b6918bc48505a65823c37b4862c3 100644 --- a/README-vault.md +++ b/README-vault.md @@ -41,7 +41,7 @@ Example inventory file ipaserver.test.local ``` -Example playbook to make sure vault is present: +Example playbook to make sure vault is present (by default, vault type is `symmetric`): ```yaml --- @@ -53,8 +53,7 @@ Example playbook to make sure vault is present: - ipavault: ipaadmin_password: SomeADMINpassword name: symvault - username: admin - vault_password: MyVaultPassword123 + password: SomeVAULTpassword description: A standard private vault. ``` @@ -124,13 +123,31 @@ Example playbook to make sure vault data is present in a symmetric vault: ipaadmin_password: SomeADMINpassword name: symvault username: admin - vault_password: MyVaultPassword123 - vault_data: > + password: SomeVAULTpassword + data: > Data archived. More data archived. action: member ``` +Example playbook to retrieve vault data from a symmetric vault: + +```yaml +--- +- name: Playbook to handle vaults + hosts: ipaserver + become: true + + tasks: + - ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: admin + password: SomeVAULTpassword + retrieve: true + action: member +``` + Example playbook to make sure vault data is absent in a symmetric vault: ```yaml @@ -144,7 +161,7 @@ Example playbook to make sure vault data is absent in a symmetric vault: ipaadmin_password: SomeADMINpassword name: symvault username: admin - vault_password: MyVaultPassword123 + password: SomeVAULTpassword action: member state: absent ``` @@ -178,8 +195,12 @@ Variable | Description | Required `name` \| `cn` | The list of vault name strings. | yes `description` | The vault description string. | no `nomembers` | Suppress processing of membership attributes. (bool) | no -`vault_public_key` \| `ipavaultpublickey` | Vault public key. | no -`vault_salt` \| `ipavaultsalt` | Vault salt. | no +`password ` \| `vault_password` \| `ipavaultpassword` | Vault password. | no +`public_key ` \| `vault_public_key` \| `ipavaultpublickey` | Base64 encoded vault public key. | no +`public_key_file` \| `vault_public_key_file` | Path to file with public key. | no +`private_key `\| `vault_private_key` | Base64 encoded vault private key. Used only to retrieve data. | no +`private_key_file` \| `vault_private_key_file` | Path to file with private key. | no +`salt` \| `vault_salt` \| `ipavaultsalt` | Vault salt. | no `vault_type` \| `ipavaulttype` | Vault types are based on security level. It can be one of `standard`, `symmetric` or `asymmetric`, default: `symmetric` | no `user` \| `username` | Any user can own one or more user vaults. | no `service` | Any service can own one or more service vaults. | no @@ -187,7 +208,10 @@ Variable | Description | Required `users` | Users that are members of the vault. | no `groups` | Groups that are member of the vault. | no `services` | Services that are member of the vault. | no -`vault_data` \| `ipavaultdata` | Data to be stored in the vault. | no +`data` \|`vault_data` \| `ipavaultdata` | Data to be stored in the vault. | no +`in` \| `datafile_in` | Path to file with data to be stored in the vault. | no +`out` \| `datafile_out` | Path to file to store data retrieved from the vault. | no +`retrieve` | If set to True, retrieve data stored in the vault. (bool) | no `action` | Work on vault or member level. It can be on of `member` or `vault` and defaults to `vault`. | no `state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | no diff --git a/playbooks/vault/change-password-symmetric-vault.yml b/playbooks/vault/change-password-symmetric-vault.yml new file mode 100644 index 0000000000000000000000000000000000000000..3871f45dd676e3d29c5f11d85fa74b3488a953bd --- /dev/null +++ b/playbooks/vault/change-password-symmetric-vault.yml @@ -0,0 +1,18 @@ +--- +- name: Playbook to change password of symmetric vault. + hosts: ipaserver + become: yes + gather_facts: no + + tasks: + - name: Create vault. + ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + password: SomeVAULTpassword + - name: Change vault passord. + ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + password: SomeVAULTpassword + new_password: SomeNEWpassword diff --git a/playbooks/vault/data-archive-in-symmetric-vault.yml b/playbooks/vault/data-archive-in-symmetric-vault.yml index f94e9d87abacdc74bea596322c3deee1e8060be0..3d4ae99fa91b904028e993d8b88ae0dc2a852c84 100644 --- a/playbooks/vault/data-archive-in-symmetric-vault.yml +++ b/playbooks/vault/data-archive-in-symmetric-vault.yml @@ -9,6 +9,6 @@ ipaadmin_password: SomeADMINpassword name: symvault username: admin - vault_password: MyVaultPassword123 + vault_password: SomeVAULTpassword vault_data: The world of π is half rounded. action: member diff --git a/playbooks/vault/ensure-symetric-vault-is-present.yml b/playbooks/vault/ensure-symetric-vault-is-present.yml index 949f60e27abb2cea12e7f196e6e3a331b602dd2f..2418ced822e52148ba18e260566ae931fd1da6da 100644 --- a/playbooks/vault/ensure-symetric-vault-is-present.yml +++ b/playbooks/vault/ensure-symetric-vault-is-present.yml @@ -9,5 +9,4 @@ ipaadmin_password: SomeADMINpassword name: symvault username: admin - vault_password: MyVaultPassword123 - vault_type: symmetric + vault_password: SomeVAULTpassword diff --git a/playbooks/vault/password.txt b/playbooks/vault/password.txt new file mode 100644 index 0000000000000000000000000000000000000000..989cadd48bbba919ffa6d0947c54c92e28c58e73 --- /dev/null +++ b/playbooks/vault/password.txt @@ -0,0 +1 @@ +SomeVAULTpassword diff --git a/playbooks/vault/private.pem b/playbooks/vault/private.pem new file mode 100644 index 0000000000000000000000000000000000000000..0ac895b9252a4293d19fe59f7ac4764745188609 --- /dev/null +++ b/playbooks/vault/private.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEArM5/f6dd/YIm/a9eoGVTW8jobEgrf9PXRA3aHsA7kJo6fB18 +HD4+RVUwx/lqlkPYbUi9bXV/rJAkUwAEDOnJeqXESZ+gVCVmigRzmKWK2ad9agmY +SiqyyNxFIJvZAo0dG4CAWjYK27tLg4Ih6oGsZIDG+WVES5W89K+L0bwVjq4tshhe +DMO57unvmIKEmaBE0ewPfvkdZh5k8Gts9H4fh0fGk5tbIYa0bhwMUpL+WHOm6nbd ++n7BbaVc820TgZDO/rSYtnuXaIc6Wx0U9LXZkUmk3apMnzknNaTqguAQdTn79G8P +qrGqmyWd/E1cH2b5jzIxiGo8psL5sxWVY7WJdwIDAQABAoIBAA6e9iit14UAgx4J +vX7is9fbOtcWkB+jo94NMfxSFXgZpIMl139oQMqK97KjxsHqAaDVe7mMLH5EP96J +7M3O5g4rgl0cVWtpMrDQyZsLvqDFzBWxtCHqVPAruumUZhsSJ3lROQro8ag/w5bf +5tC5ogVq4+rsB4hBphgp1jGrsUM+E8O7DXXFH68F8WgBi725WvcjnbI9irkb0Gcq +1bCPJwN3fA1i2VWiRwVYWbNTWnDoNM9ZdYYxK0kuUkD+QtreycWPf9V49lvUi1Vp +FVNmBUDvGK3K1MwbgXRwOXhacY7Ptjkdvaeb2Qcu5RjTkruGhzUYsOP3p/cw+wKV +vzQqceECgYEA5Wz7V2SlRa2r//z+ETQkJfENJ0KDnCb0pMClCQh3jTNPA6DbhiMk +FTkcoNbqcpTiVSlvhh6TKscSgqYQUjQ/OqyG7SkjKVjQ72j5beQLxiLTtUyj1OmP +Xh9cWJXx8iQ+45cPon+kMOAIiTwiB3mmFRfQjIGve1DPUo9J+NZ4XdECgYEAwNKg +OdGYxxKtCrXVz1mdg6PDlV8qh7nxxZbPch+aMIQl1+oTCgSiw8oOYEd8g0HOdV6t +1G+IWhvPxiiWy3/AE0QhgoKk2GUsSjWSMLcJbaUzDoEHFjTLjecRlqdzo7qxRXqB +meN4L5WJYKnLC482K7hvufS+uo5fB5qwPmt13McCgYAe4TVPRP+tyjttYCr+O8tl +w/UmRKCcQu4Iwtkzxwz4V2CaN2t0uYQgyygcSfESbRGtrr8RCUp7poHKTfnCZr/f +8NrUTwYpiYfNwY5ZCSnAiG2AaIlgnfMrEwOF9OC028YPMgTrtUxvO6hKeGqIIQqG +qkbqsoXhDjZpgVnOgWeAEQKBgGuiZ0w/IqAlXbC31fUb2iBMfvXXnJ8M/dfFGmFj +IKfqbFF9WUljUxQlqya1YNzIFB5STohiBeP+2FmN+Lb5xdc7VdVLZgdhWnrGMqe8 +1Kd+6uQyxCjyKZo5nQjSymtf4GqfOs8TOdieCYSK40u9koiPONa9tuXeaU+OWslN +JQqrAoGBAJ3MKOvsnQzuZVP2vz0ZqLwIE3XjRiFGveVpizq4hwOVeuNsV08JvA0t +pueNIy9klPScFc9OUdiZWkEX09BwJkVIrOHotuSB8AStO5UAntNnuyWLJEFC4Uq4 +GpB8lbj9jkxSKaU7X3Gac23K9JL8euLh7E7rPuZRYa6mYN4nbKqu +-----END RSA PRIVATE KEY----- diff --git a/playbooks/vault/public.pem b/playbooks/vault/public.pem new file mode 100644 index 0000000000000000000000000000000000000000..d8a9f71bf194a0ce9ca48ca54d7cb9e8477e2434 --- /dev/null +++ b/playbooks/vault/public.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArM5/f6dd/YIm/a9eoGVT +W8jobEgrf9PXRA3aHsA7kJo6fB18HD4+RVUwx/lqlkPYbUi9bXV/rJAkUwAEDOnJ +eqXESZ+gVCVmigRzmKWK2ad9agmYSiqyyNxFIJvZAo0dG4CAWjYK27tLg4Ih6oGs +ZIDG+WVES5W89K+L0bwVjq4tshheDMO57unvmIKEmaBE0ewPfvkdZh5k8Gts9H4f +h0fGk5tbIYa0bhwMUpL+WHOm6nbd+n7BbaVc820TgZDO/rSYtnuXaIc6Wx0U9LXZ +kUmk3apMnzknNaTqguAQdTn79G8PqrGqmyWd/E1cH2b5jzIxiGo8psL5sxWVY7WJ +dwIDAQAB +-----END PUBLIC KEY----- diff --git a/playbooks/vault/retrive-data-asymmetric-vault.yml b/playbooks/vault/retrive-data-asymmetric-vault.yml new file mode 100644 index 0000000000000000000000000000000000000000..420acc78f206d444e3b0d07d438608f8befe6c87 --- /dev/null +++ b/playbooks/vault/retrive-data-asymmetric-vault.yml @@ -0,0 +1,19 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: True + + tasks: + - name: Retrieve data from assymetric vault with a private key file. + ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: admin + private_key_file: private.pem + retrieve: True + register: result + - debug: + msg: "Data: {{ result.data }}" + - debug: + msg: "Decoded Data: {{ result.data | b64decode }}" diff --git a/playbooks/vault/retrive-data-symmetric-vault.yml b/playbooks/vault/retrive-data-symmetric-vault.yml new file mode 100644 index 0000000000000000000000000000000000000000..0ac1337291e91f9661b17f2e9c05a8d5a3cc3898 --- /dev/null +++ b/playbooks/vault/retrive-data-symmetric-vault.yml @@ -0,0 +1,18 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: True + + tasks: + - name: Retrieve data from symmetric vault. + ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: admin + password: SomeVAULTpassword + retrieve: yes + action: member + register: result + - debug: + msg: "{{ result.data | b64decode }}" diff --git a/playbooks/vault/vault-is-present-with-password-file.yml b/playbooks/vault/vault-is-present-with-password-file.yml new file mode 100644 index 0000000000000000000000000000000000000000..b552ac66584d26859718c6a262a60abcb5dfe674 --- /dev/null +++ b/playbooks/vault/vault-is-present-with-password-file.yml @@ -0,0 +1,22 @@ +--- +- name: Tests + hosts: ipaserver + become: true + gather_facts: True + + tasks: + - copy: + src: "{{ playbook_dir }}/password.txt" + dest: "{{ ansible_env.HOME }}/password.txt" + owner: "{{ ansible_user }}" + group: "{{ ansible_user }}" + mode: 0600 + - ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: admin + vault_type: symmetric + vault_password_file: "{{ ansible_env.HOME }}/password.txt" + - file: + path: "{{ ansible_env.HOME }}/password.txt" + state: absent diff --git a/playbooks/vault/vault-is-present-with-public-key-file.yml b/playbooks/vault/vault-is-present-with-public-key-file.yml new file mode 100644 index 0000000000000000000000000000000000000000..2420f83668ec7b489b47ddeb240c2b44bf611a4a --- /dev/null +++ b/playbooks/vault/vault-is-present-with-public-key-file.yml @@ -0,0 +1,27 @@ +--- +# +# Example keys for this playbook were generated with the commands: +# $ openssl genrsa -out private.pem 2048 +# $ openssl rsa -in private.pem -pubout > public.pem +# +- name: Tests + hosts: ipaserver + become: true + gather_facts: True + + tasks: + - copy: + src: "{{ playbook_dir }}/public.pem" + dest: "{{ ansible_env.HOME }}/public.pem" + owner: "{{ ansible_user }}" + group: "{{ ansible_user }}" + mode: 0600 + - ipavault: + ipaadmin_password: SomeADMINpassword + name: asymvault + username: admin + vault_type: asymmetric + vault_public_key_file: "{{ ansible_env.HOME }}/public.pem" + - file: + path: "{{ ansible_env.HOME }}/public.pem" + state: absent diff --git a/plugins/modules/ipauser.py b/plugins/modules/ipauser.py index 6c48a2ffc805f5723ee1b37e570e38e60697f890..c7ea3f9366f9f6f1636e1d4776aee18e5584c216 100644 --- a/plugins/modules/ipauser.py +++ b/plugins/modules/ipauser.py @@ -1427,7 +1427,6 @@ def main(): temp_kdestroy(ccache_dir, ccache_name) # Done - ansible_module.exit_json(changed=changed, user=exit_args) diff --git a/plugins/modules/ipavault.py b/plugins/modules/ipavault.py index 593544e29aa52f5447e6a28b536b0b133025d8f2..dc59d4bedd00b54505b69200a57e3bec845627fd 100644 --- a/plugins/modules/ipavault.py +++ b/plugins/modules/ipavault.py @@ -45,21 +45,41 @@ options: description: description: The vault description required: false - vault_public_key: - description: Base64 encoded public key. + public_key: + description: Base64 encode public key. required: false - type: list - aliases: ["ipavaultpublickey"] - vault_salt: - description: Vault salt. + type: string + aliases: ["ipavaultpublickey", "vault_public_key"] + public_key_file: + description: Path to file with public key. required: false - type: list - aliases: ["ipavaultsalt"] - vault_password: + type: string + aliases: ["vault_public_key_file"] + private_key: + description: Base64 encode private key. + required: false + type: string + aliases: ["ipavaultprivatekey", "vault_private_key"] + private_key_file: + description: Path to file with private key. + required: false + type: string + aliases: ["vault_private_key_file"] + password: description: password to be used on symmetric vault. required: false type: string - aliases: ["ipavaultpassword"] + aliases: ["ipavaultpassword", "vault_password"] + password_file: + description: file with password to be used on symmetric vault. + required: false + type: string + aliases: ["ipavaultpassword", "vault_password"] + salt: + description: Vault salt. + required: false + type: list + aliases: ["ipavaultsalt", "vault_salt"] vault_type: description: Vault types are based on security level. required: true @@ -79,11 +99,6 @@ options: description: Vault is shared. required: false type: boolean - vault_data: - description: Data to be stored in the vault. - required: false - type: string - aliases: ["ipavaultdata"] owners: description: Users that are owners of the container. required: false @@ -100,6 +115,25 @@ options: description: Services that are member of the container. required: false type: list + data: + description: Data to be stored in the vault. + required: false + type: string + aliases: ["ipavaultdata", "vault_data"] + in: + description: Path to file with data to be stored in the vault. + required: false + type: string + aliases: ["datafile_in"] + out: + description: Path to file to store data retrieved from the vault. + required: false + type: string + aliases: ["datafile_out"] + retrieve: + description: If set to True, retrieve data stored in the vault. + required: false + type: bool action: description: Work on vault or member level. default: vault @@ -118,9 +152,9 @@ EXAMPLES = """ ipaadmin_password: SomeADMINpassword name: symvault username: admin - vault_password: MyVaultPassword123 - vault_salt: MTIzNDU2Nzg5MAo= vault_type: symmetric + password: SomeVAULTpassword + salt: MTIzNDU2Nzg5MAo= # Ensure group ipausers is a vault member. - ipavault: @@ -182,12 +216,24 @@ EXAMPLES = """ ipaadmin_password: SomeADMINpassword name: symvault username: admin - vault_password: MyVaultPassword123 - vault_data: > + password: SomeVAULTpassword + data: > Data archived. More data archived. action: member +# Retrieve data archived from a symmetric vault +- ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: admin + password: SomeVAULTpassword + retrieve: yes + action: member + register: result +- debug: + msg: "{{ result.data | b64decode }}" + # Ensure vault symvault is absent - ipavault: ipaadmin_password: SomeADMINpassword @@ -202,7 +248,7 @@ EXAMPLES = """ username: user01 description: An asymmetric vault vault_type: asymmetric - vault_public_key: + public_key: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi 9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM @@ -215,11 +261,20 @@ EXAMPLES = """ ipaadmin_password: SomeADMINpassword name: asymvault username: admin - vault_data: > + data: > Data archived. More data archived. action: member +# Retrive data archived in an asymmetric vault +- ipavault: + ipaadmin_password: SomeADMINpassword + name: asymvault + username: admin + retrieve: yes + private_key: + + # Ensure asymmetric vault is absent. - ipavault: ipaadmin_password: SomeADMINpassword @@ -233,6 +288,7 @@ RETURN = """ """ import os +from base64 import b64encode, b64decode from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ temp_kdestroy, valid_creds, api_connect, api_command, \ @@ -265,7 +321,8 @@ def find_vault(module, name, username, service, shared): def gen_args(description, username, service, shared, vault_type, salt, - public_key, vault_data): + password, password_file, public_key, public_key_file, vault_data, + datafile_in, datafile_out): _args = {} if description is not None: @@ -281,9 +338,11 @@ def gen_args(description, username, service, shared, vault_type, salt, if salt is not None: _args['ipavaultsalt'] = salt if public_key is not None: - _args['ipavaultpublickey'] = public_key - if vault_data is not None: - _args['data'] = vault_data.encode('utf-8') + _args['ipavaultpublickey'] = b64decode(public_key.encode('utf-8')) + if public_key_file is not None: + with open(public_key_file, 'r') as keyfile: + keydata = keyfile.read() + _args['ipavaultpublickey'] = keydata.strip().encode('utf-8') return _args @@ -306,7 +365,8 @@ def gen_member_args(args, users, groups, services): return _args -def data_storage_args(args, data, password): +def data_storage_args(args, data, password, password_file, private_key, + private_key_file, retrieve, datafile_in, datafile_out): _args = {} if 'username' in args: @@ -318,55 +378,117 @@ def data_storage_args(args, data, password): if password is not None: _args['password'] = password + if password_file is not None: + _args['password_file'] = password_file + + if private_key is not None: + _args['private_key'] = private_key + if private_key_file is not None: + _args['private_key_file'] = private_key_file + + if datafile_in is not None: + _args['in'] = datafile_in + else: + if data is None: + _args['data'] = b'' + else: + _args['data'] = data.encode('utf-8') - _args['data'] = data + if datafile_out is not None: + _args['out'] = datafile_out + + if private_key_file is not None: + _args['private_key_file'] = private_key_file return _args def check_parameters(module, state, action, description, username, service, shared, users, groups, services, owners, ownergroups, - ownerservices, vault_type, salt, password, public_key, - vault_data): + ownerservices, vault_type, salt, password, password_file, + public_key, public_key_file, private_key, + private_key_file, retrieve, vault_data, datafile_in, + datafile_out): invalid = [] if state == "present": + if salt is not None: + if vault_type is not None and vault_type != "symmetric": + module.fail_json( + msg="Attribute `salt` can only be used with `symmetric` " + "vaults.") + if not any([password, password_file]): + module.fail_json( + msg="Value of `salt` can only modified by providing " + "vault password.") if action == "member": - invalid = ['description', 'public_key', 'salt'] + invalid = ['description'] - for param in invalid: - if vars()[param] is not None: + if not retrieve: + if datafile_out is not None: module.fail_json( - msg="Argument '%s' can not be used with action '%s'" % - (param, action)) + msg="Retrieve must be enabled to use datafile_out.") + + if any([private_key, private_key_file]): + module.fail_json( + msg="Attributes private_key and private_key_file can only " + "be used when retrieving data from asymmetric vaults.") + else: + check = ['description', 'salt', 'datafile_in', 'users', 'groups', + 'owners', 'ownergroups', 'public_key', 'public_key_file', + 'vault_data'] + + for arg in check: + if vars()[arg] is not None: + module.fail_json( + msg="`%s` cannot be used with `retrieve`." % arg) elif state == "absent": - invalid = ['description', 'salt'] + invalid = ['description', 'salt', 'vault_type', 'private_key', + 'private_key_file', 'retrieve', 'datafile_in', + 'datafile_out', 'vault_data'] if action == "vault": invalid.extend(['users', 'groups', 'services', 'owners', 'ownergroups', 'ownerservices', 'password', - 'public_key']) + 'password_file', 'public_key', 'public_key_file']) - for arg in invalid: - if vars()[arg] is not None: - module.fail_json( - msg="Argument '%s' can not be used with action '%s'" % - (arg, state)) + for arg in invalid: + if vars()[arg] is not None: + module.fail_json( + msg="Argument '%s' can not be used with state '%s', " + "action '%s'" % (arg, state, action)) -def check_encryption_params(module, state, vault_type, password, public_key, - vault_data, res_find): +def check_encryption_params(module, state, vault_type, salt, password, + password_file, public_key, public_key_file, + private_key, private_key_file, retrieve, + vault_data, datafile_in, datafile_out, res_find): + vault_type_invalid = [] if state == "present": - if vault_type == "symmetric": - if password is None \ - and (vault_data is not None or res_find is None): + if vault_type == "standard": + vault_type_invalid = ['public_key', 'public_key_file', 'password', + 'password_file', 'salt'] + + if vault_type is None or vault_type == "symmetric": + vault_type_invalid = ['public_key', 'public_key_file', + 'private_key', 'private_key_file'] + if not any([password, password_file]): module.fail_json( - msg="Vault password required for symmetric vault.") + msg="Symmetric vault requires password or password_file " + "to store data.") if vault_type == "asymmetric": - if public_key is None and res_find is None: + vault_type_invalid = ['password', 'password_file'] + if not any([public_key, public_key_file]) and res_find is None: module.fail_json( - msg="Public Key required for asymmetric vault.") + msg="Assymmetric vault requires public_key " + "or public_key_file to store data.") + + for param in vault_type_invalid: + if vars()[param] is not None: + module.fail_json( + msg="Argument '%s' cannot be used with vault type '%s'" % + (param, vault_type or 'symmetric')) def main(): @@ -379,16 +501,24 @@ def main(): name=dict(type="list", aliases=["cn"], default=None, required=True), - # present - description=dict(required=False, type="str", default=None), vault_type=dict(type="str", aliases=["ipavaulttype"], default=None, required=False, choices=["standard", "symmetric", "asymmetric"]), vault_public_key=dict(type="str", required=False, default=None, - aliases=['ipavaultpublickey']), + aliases=['ipavaultpublickey', 'public_key']), + vault_public_key_file=dict(type="str", required=False, + default=None, + aliases=['public_key_file']), + vault_private_key=dict( + type="str", required=False, default=None, no_log=True, + aliases=['ipavaultprivatekey', 'private_key']), + vault_private_key_file=dict(type="str", required=False, + default=None, + aliases=['private_key_file']), + retrieve=dict(type="bool", required=False, default=None), vault_salt=dict(type="str", required=False, default=None, - aliases=['ipavaultsalt']), + aliases=['ipavaultsalt', 'salt']), username=dict(type="str", required=False, default=None, aliases=['user']), service=dict(type="str", required=False, default=None), @@ -402,10 +532,16 @@ def main(): ownergroups=dict(required=False, type='list', default=None), ownerservices=dict(required=False, type='list', default=None), vault_data=dict(type="str", required=False, default=None, - aliases=['ipavaultdata']), + no_log=True, aliases=['ipavaultdata', 'data']), + datafile_in=dict(type="str", required=False, default=None, + aliases=['in']), + datafile_out=dict(type="str", required=False, default=None, + aliases=['out']), vault_password=dict(type="str", required=False, default=None, - no_log=True, aliases=['ipavaultpassword']), - + aliases=['ipavaultpassword', 'password'], + no_log=True), + vault_password_file=dict(type="str", required=False, default=None, + no_log=False, aliases=['password_file']), # state action=dict(type="str", default="vault", choices=["vault", "data", "member"]), @@ -413,7 +549,10 @@ def main(): choices=["present", "absent"]), ), supports_check_mode=True, - mutually_exclusive=[['username', 'service', 'shared']], + mutually_exclusive=[['username', 'service', 'shared'], + ['datafile_in', 'vault_data'], + ['vault_password', 'vault_password_file'], + ['vault_public_key', 'vault_public_key_file']], ) ansible_module._ansible_debug = True @@ -441,12 +580,22 @@ def main(): vault_type = module_params_get(ansible_module, "vault_type") salt = module_params_get(ansible_module, "vault_salt") password = module_params_get(ansible_module, "vault_password") + password_file = module_params_get(ansible_module, "vault_password_file") public_key = module_params_get(ansible_module, "vault_public_key") + public_key_file = module_params_get(ansible_module, + "vault_public_key_file") + private_key = module_params_get(ansible_module, "vault_private_key") + private_key_file = module_params_get(ansible_module, + "vault_private_key_file") vault_data = module_params_get(ansible_module, "vault_data") + datafile_in = module_params_get(ansible_module, "datafile_in") + datafile_out = module_params_get(ansible_module, "datafile_out") + + retrieve = module_params_get(ansible_module, "retrieve") + action = module_params_get(ansible_module, "action") - # state state = module_params_get(ansible_module, "state") # Check parameters @@ -466,7 +615,9 @@ def main(): check_parameters(ansible_module, state, action, description, username, service, shared, users, groups, services, owners, ownergroups, ownerservices, vault_type, salt, password, - public_key, vault_data) + password_file, public_key, public_key_file, private_key, + private_key_file, retrieve, vault_data, datafile_in, + datafile_out) # Init changed = False @@ -492,7 +643,10 @@ def main(): # Generate args args = gen_args(description, username, service, shared, vault_type, - salt, public_key, vault_data) + salt, password, password_file, public_key, + public_key_file, vault_data, datafile_in, + datafile_out) + pwdargs = None # Set default vault_type if needed. if vault_type is None and vault_data is not None: @@ -503,8 +657,11 @@ def main(): args['ipavaulttype'] = vault_type = "symmetric" # verify data encription args - check_encryption_params(ansible_module, state, vault_type, - password, public_key, vault_data, res_find) + check_encryption_params(ansible_module, state, vault_type, salt, + password, password_file, public_key, + public_key_file, private_key, + private_key_file, retrieve, vault_data, + datafile_in, datafile_out, res_find) # Create command if state == "present": @@ -518,16 +675,13 @@ def main(): if not compare_args_ipa(ansible_module, args, res_find): commands.append([name, "vault_mod_internal", args]) + else: - if 'ipavaultsault' not in args: - args['ipavaultsalt'] = os.urandom(32) commands.append([name, "vault_add_internal", args]) - # archive empty data to set password - pwdargs = data_storage_args( - args, args.get('data', ''), password) - commands.append([name, "vault_archive", pwdargs]) + if vault_type != 'standard' and vault_data is None: + vault_data = '' - # Set res_find to empty dict for next step # noqa + # Set res_find to empty dict for next steps res_find = {} # Generate adittion and removal lists @@ -576,6 +730,10 @@ def main(): commands.append( [name, 'vault_remove_owner', owner_del_args]) + if vault_type == 'symmetric' \ + and 'ipavaultsalt' not in args: + args['ipavaultsalt'] = os.urandom(32) + elif action in "member": # Add users and groups if any([users, groups, services]): @@ -587,10 +745,16 @@ def main(): ownerservices) commands.append([name, 'vault_add_owner', owner_args]) - if vault_data is not None: - data_args = data_storage_args( - args, args.get('data', ''), password) - commands.append([name, 'vault_archive', data_args]) + pwdargs = data_storage_args( + args, vault_data, password, password_file, + private_key, private_key_file, retrieve, datafile_in, + datafile_out) + if any([vault_data, datafile_in]): + commands.append([name, "vault_archive", pwdargs]) + if retrieve: + if 'data' in pwdargs: + del pwdargs['data'] + commands.append([name, "vault_retrieve", pwdargs]) elif state == "absent": if 'ipavaulttype' in args: @@ -629,6 +793,9 @@ def main(): if command == 'vault_archive': changed = 'Archived data into' in result['summary'] + elif command == 'vault_retrieve': + exit_args['data'] = b64encode(result['result']['data']) + changed = False else: if "completed" in result: if result["completed"] > 0: diff --git a/tests/vault/in.txt b/tests/vault/in.txt new file mode 100644 index 0000000000000000000000000000000000000000..61ef922b612ad103dc685b33fb7c2d160b9dc97a --- /dev/null +++ b/tests/vault/in.txt @@ -0,0 +1 @@ +Another World. \ No newline at end of file diff --git a/tests/vault/password.txt b/tests/vault/password.txt new file mode 100644 index 0000000000000000000000000000000000000000..989cadd48bbba919ffa6d0947c54c92e28c58e73 --- /dev/null +++ b/tests/vault/password.txt @@ -0,0 +1 @@ +SomeVAULTpassword diff --git a/tests/vault/private.pem b/tests/vault/private.pem new file mode 100644 index 0000000000000000000000000000000000000000..0ac895b9252a4293d19fe59f7ac4764745188609 --- /dev/null +++ b/tests/vault/private.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEArM5/f6dd/YIm/a9eoGVTW8jobEgrf9PXRA3aHsA7kJo6fB18 +HD4+RVUwx/lqlkPYbUi9bXV/rJAkUwAEDOnJeqXESZ+gVCVmigRzmKWK2ad9agmY +SiqyyNxFIJvZAo0dG4CAWjYK27tLg4Ih6oGsZIDG+WVES5W89K+L0bwVjq4tshhe +DMO57unvmIKEmaBE0ewPfvkdZh5k8Gts9H4fh0fGk5tbIYa0bhwMUpL+WHOm6nbd ++n7BbaVc820TgZDO/rSYtnuXaIc6Wx0U9LXZkUmk3apMnzknNaTqguAQdTn79G8P +qrGqmyWd/E1cH2b5jzIxiGo8psL5sxWVY7WJdwIDAQABAoIBAA6e9iit14UAgx4J +vX7is9fbOtcWkB+jo94NMfxSFXgZpIMl139oQMqK97KjxsHqAaDVe7mMLH5EP96J +7M3O5g4rgl0cVWtpMrDQyZsLvqDFzBWxtCHqVPAruumUZhsSJ3lROQro8ag/w5bf +5tC5ogVq4+rsB4hBphgp1jGrsUM+E8O7DXXFH68F8WgBi725WvcjnbI9irkb0Gcq +1bCPJwN3fA1i2VWiRwVYWbNTWnDoNM9ZdYYxK0kuUkD+QtreycWPf9V49lvUi1Vp +FVNmBUDvGK3K1MwbgXRwOXhacY7Ptjkdvaeb2Qcu5RjTkruGhzUYsOP3p/cw+wKV +vzQqceECgYEA5Wz7V2SlRa2r//z+ETQkJfENJ0KDnCb0pMClCQh3jTNPA6DbhiMk +FTkcoNbqcpTiVSlvhh6TKscSgqYQUjQ/OqyG7SkjKVjQ72j5beQLxiLTtUyj1OmP +Xh9cWJXx8iQ+45cPon+kMOAIiTwiB3mmFRfQjIGve1DPUo9J+NZ4XdECgYEAwNKg +OdGYxxKtCrXVz1mdg6PDlV8qh7nxxZbPch+aMIQl1+oTCgSiw8oOYEd8g0HOdV6t +1G+IWhvPxiiWy3/AE0QhgoKk2GUsSjWSMLcJbaUzDoEHFjTLjecRlqdzo7qxRXqB +meN4L5WJYKnLC482K7hvufS+uo5fB5qwPmt13McCgYAe4TVPRP+tyjttYCr+O8tl +w/UmRKCcQu4Iwtkzxwz4V2CaN2t0uYQgyygcSfESbRGtrr8RCUp7poHKTfnCZr/f +8NrUTwYpiYfNwY5ZCSnAiG2AaIlgnfMrEwOF9OC028YPMgTrtUxvO6hKeGqIIQqG +qkbqsoXhDjZpgVnOgWeAEQKBgGuiZ0w/IqAlXbC31fUb2iBMfvXXnJ8M/dfFGmFj +IKfqbFF9WUljUxQlqya1YNzIFB5STohiBeP+2FmN+Lb5xdc7VdVLZgdhWnrGMqe8 +1Kd+6uQyxCjyKZo5nQjSymtf4GqfOs8TOdieCYSK40u9koiPONa9tuXeaU+OWslN +JQqrAoGBAJ3MKOvsnQzuZVP2vz0ZqLwIE3XjRiFGveVpizq4hwOVeuNsV08JvA0t +pueNIy9klPScFc9OUdiZWkEX09BwJkVIrOHotuSB8AStO5UAntNnuyWLJEFC4Uq4 +GpB8lbj9jkxSKaU7X3Gac23K9JL8euLh7E7rPuZRYa6mYN4nbKqu +-----END RSA PRIVATE KEY----- diff --git a/tests/vault/public.pem b/tests/vault/public.pem new file mode 100644 index 0000000000000000000000000000000000000000..d8a9f71bf194a0ce9ca48ca54d7cb9e8477e2434 --- /dev/null +++ b/tests/vault/public.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArM5/f6dd/YIm/a9eoGVT +W8jobEgrf9PXRA3aHsA7kJo6fB18HD4+RVUwx/lqlkPYbUi9bXV/rJAkUwAEDOnJ +eqXESZ+gVCVmigRzmKWK2ad9agmYSiqyyNxFIJvZAo0dG4CAWjYK27tLg4Ih6oGs +ZIDG+WVES5W89K+L0bwVjq4tshheDMO57unvmIKEmaBE0ewPfvkdZh5k8Gts9H4f +h0fGk5tbIYa0bhwMUpL+WHOm6nbd+n7BbaVc820TgZDO/rSYtnuXaIc6Wx0U9LXZ +kUmk3apMnzknNaTqguAQdTn79G8PqrGqmyWd/E1cH2b5jzIxiGo8psL5sxWVY7WJ +dwIDAQAB +-----END PUBLIC KEY----- diff --git a/tests/vault/test_vault.yml b/tests/vault/test_vault.yml index 16a2e17e5e9508456414cef730e3ac005d78daab..c0af27007f1a211573f729af8aff50cf243a95a0 100644 --- a/tests/vault/test_vault.yml +++ b/tests/vault/test_vault.yml @@ -3,10 +3,31 @@ - name: Test vault hosts: ipaserver become: true - gather_facts: false + # Need to gather facts for ansible_env. + gather_facts: true tasks: + - name: Copy password file to target host. + copy: + src: "{{ playbook_dir }}/password.txt" + dest: "{{ ansible_env.HOME }}/password.txt" + + - name: Copy public key file to target host. + copy: + src: "{{ playbook_dir }}/public.pem" + dest: "{{ ansible_env.HOME }}/public.pem" + + - name: Copy private key file to target host. + copy: + src: "{{ playbook_dir }}/private.pem" + dest: "{{ ansible_env.HOME }}/private.pem" + + - name: Copy input data file to target host. + copy: + src: "{{ playbook_dir }}/in.txt" + dest: "{{ ansible_env.HOME }}/in.txt" + - name: Ensure user vaults are absent ipavault: ipaadmin_password: SomeADMINpassword @@ -118,7 +139,7 @@ ipaadmin_password: SomeADMINpassword name: symvault username: user01 - vault_password: MyVaultPassword123 + vault_password: SomeVAULTpassword vault_type: symmetric register: result failed_when: not result.changed @@ -128,7 +149,7 @@ ipaadmin_password: SomeADMINpassword name: symvault username: user01 - vault_password: MyVaultPassword123 + vault_password: SomeVAULTpassword vault_type: symmetric register: result failed_when: result.changed @@ -138,9 +159,8 @@ ipaadmin_password: SomeADMINpassword name: symvault username: user01 - vault_password: MyVaultPassword123 + vault_password: SomeVAULTpassword vault_data: Hello World. - action: member register: result failed_when: not result.changed @@ -149,9 +169,8 @@ ipaadmin_password: SomeADMINpassword name: symvault username: user01 - vault_password: MyVaultPassword123 + vault_password: SomeVAULTpassword vault_data: The world of π is half rounded. - action: member register: result failed_when: not result.changed @@ -173,19 +192,113 @@ register: result failed_when: result.changed + - name: Ensure symmetric vault is present + ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: user01 + vault_password: SomeVAULTpassword + vault_type: symmetric + register: result + failed_when: not result.changed + + - name: Ensure symmetric vault is present, with a different password + ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: user01 + vault_password: SomeOtherVAULTpassword + vault_type: symmetric + register: result + failed_when: result.changed + + - name: Ensure symmetric vault is absent + ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: user01 + state: absent + register: result + failed_when: not result.changed + + + - name: Ensure symmetric vault is present, with password from file. + ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: user01 + vault_password_file: "{{ ansible_env.HOME }}/password.txt" + vault_type: symmetric + register: result + failed_when: not result.changed + + - name: Ensure symmetric vault is present, with password from file, again. + ipavault: + ipaadmin_password: SomeADMINpassword + name: symvault + username: user01 + vault_password_file: password.txt + vault_type: symmetric + register: result + failed_when: result.changed + + - name: Ensure asymmetric vault is present, with public key file. + ipavault: + ipaadmin_password: SomeADMINpassword + name: asymvault + username: admin + description: An asymmetric private vault. + public_key_file: "{{ ansible_env.HOME }}/public.pem" + vault_type: asymmetric + register: result + failed_when: not result.changed + + - name: Ensure asymmetric vault is present, with public key file, again. + ipavault: + ipaadmin_password: SomeADMINpassword + name: asymvault + username: admin + description: An asymmetric private vault. + public_key_file: "{{ ansible_env.HOME }}/public.pem" + vault_type: asymmetric + register: result + failed_when: result.changed + + - name: Archive data in asymmetric vault. + ipavault: + ipaadmin_password: SomeADMINpassword + name: asymvault + username: admin + vault_data: Hello World. + register: result + failed_when: not result.changed + + - name: Ensure asymmetric vault is absent. + ipavault: + ipaadmin_password: SomeADMINpassword + name: asymvault + username: admin + state: absent + register: result + failed_when: not result.changed + + - name: Ensure asymmetric vault is absent, again. + ipavault: + ipaadmin_password: SomeADMINpassword + name: asymvault + username: admin + state: absent + register: result + failed_when: result.changed + - name: Ensure asymmetric vault is present. ipavault: ipaadmin_password: SomeADMINpassword name: asymvault username: user01 - description: A symmetric private vault. + description: An asymmetric private vault. vault_public_key: - LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR - HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi - 9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM - 295VTFEMnFOZERYeGtSaFFETXBiUEVSWWlHbE1jbzdhN0hIVDk1bGNQbmhObVFkb3VGdHlV - bFBUVS96V1kKZldYWTBOeU1UbUtoeFRseUV3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVk - tLS0tLQo= + LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFyTTUvZjZkZC9ZSW0vYTllb0dWVApXOGpvYkVncmY5UFhSQTNhSHNBN2tKbzZmQjE4SEQ0K1JWVXd4L2xxbGtQWWJVaTliWFYvckpBa1V3QUVET25KCmVxWEVTWitnVkNWbWlnUnptS1dLMmFkOWFnbVlTaXF5eU54RklKdlpBbzBkRzRDQVdqWUsyN3RMZzRJaDZvR3MKWklERytXVkVTNVc4OUsrTDBid1ZqcTR0c2hoZURNTzU3dW52bUlLRW1hQkUwZXdQZnZrZFpoNWs4R3RzOUg0ZgpoMGZHazV0YklZYTBiaHdNVXBMK1dIT202bmJkK243QmJhVmM4MjBUZ1pETy9yU1l0bnVYYUljNld4MFU5TFhaCmtVbWszYXBNbnprbk5hVHFndUFRZFRuNzlHOFBxckdxbXlXZC9FMWNIMmI1anpJeGlHbzhwc0w1c3hXVlk3V0oKZHdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg== vault_type: asymmetric register: result failed_when: not result.changed @@ -195,13 +308,9 @@ ipaadmin_password: SomeADMINpassword name: asymvault username: user01 + description: An asymmetric private vault. vault_public_key: - LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR - HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi - 9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM - 295VTFEMnFOZERYeGtSaFFETXBiUEVSWWlHbE1jbzdhN0hIVDk1bGNQbmhObVFkb3VGdHlV - bFBUVS96V1kKZldYWTBOeU1UbUtoeFRseUV3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVk - tLS0tLQo= + LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFyTTUvZjZkZC9ZSW0vYTllb0dWVApXOGpvYkVncmY5UFhSQTNhSHNBN2tKbzZmQjE4SEQ0K1JWVXd4L2xxbGtQWWJVaTliWFYvckpBa1V3QUVET25KCmVxWEVTWitnVkNWbWlnUnptS1dLMmFkOWFnbVlTaXF5eU54RklKdlpBbzBkRzRDQVdqWUsyN3RMZzRJaDZvR3MKWklERytXVkVTNVc4OUsrTDBid1ZqcTR0c2hoZURNTzU3dW52bUlLRW1hQkUwZXdQZnZrZFpoNWs4R3RzOUg0ZgpoMGZHazV0YklZYTBiaHdNVXBMK1dIT202bmJkK243QmJhVmM4MjBUZ1pETy9yU1l0bnVYYUljNld4MFU5TFhaCmtVbWszYXBNbnprbk5hVHFndUFRZFRuNzlHOFBxckdxbXlXZC9FMWNIMmI1anpJeGlHbzhwc0w1c3hXVlk3V0oKZHdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg== vault_type: asymmetric register: result failed_when: result.changed @@ -212,10 +321,32 @@ name: asymvault username: user01 vault_data: Hello World. - action: member register: result failed_when: not result.changed + - name: Retrieve data from asymmetric vault. + ipavault: + ipaadmin_password: SomeADMINpassword + name: asymvault + username: user01 + vault_type: asymmetric + retrieve: true + private_key: + LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBck01L2Y2ZGQvWUltL2E5ZW9HVlRXOGpvYkVncmY5UFhSQTNhSHNBN2tKbzZmQjE4CkhENCtSVlV3eC9scWxrUFliVWk5YlhWL3JKQWtVd0FFRE9uSmVxWEVTWitnVkNWbWlnUnptS1dLMmFkOWFnbVkKU2lxeXlOeEZJSnZaQW8wZEc0Q0FXallLMjd0TGc0SWg2b0dzWklERytXVkVTNVc4OUsrTDBid1ZqcTR0c2hoZQpETU81N3Vudm1JS0VtYUJFMGV3UGZ2a2RaaDVrOEd0czlINGZoMGZHazV0YklZYTBiaHdNVXBMK1dIT202bmJkCituN0JiYVZjODIwVGdaRE8vclNZdG51WGFJYzZXeDBVOUxYWmtVbWszYXBNbnprbk5hVHFndUFRZFRuNzlHOFAKcXJHcW15V2QvRTFjSDJiNWp6SXhpR284cHNMNXN4V1ZZN1dKZHdJREFRQUJBb0lCQUE2ZTlpaXQxNFVBZ3g0Sgp2WDdpczlmYk90Y1drQitqbzk0Tk1meFNGWGdacElNbDEzOW9RTXFLOTdLanhzSHFBYURWZTdtTUxINUVQOTZKCjdNM081ZzRyZ2wwY1ZXdHBNckRReVpzTHZxREZ6Qld4dENIcVZQQXJ1dW1VWmhzU0ozbFJPUXJvOGFnL3c1YmYKNXRDNW9nVnE0K3JzQjRoQnBoZ3Axakdyc1VNK0U4TzdEWFhGSDY4RjhXZ0JpNzI1V3Zjam5iSTlpcmtiMEdjcQoxYkNQSndOM2ZBMWkyVldpUndWWVdiTlRXbkRvTk05WmRZWXhLMGt1VWtEK1F0cmV5Y1dQZjlWNDlsdlVpMVZwCkZWTm1CVUR2R0szSzFNd2JnWFJ3T1hoYWNZN1B0amtkdmFlYjJRY3U1UmpUa3J1R2h6VVlzT1AzcC9jdyt3S1YKdnpRcWNlRUNnWUVBNVd6N1YyU2xSYTJyLy96K0VUUWtKZkVOSjBLRG5DYjBwTUNsQ1FoM2pUTlBBNkRiaGlNawpGVGtjb05icWNwVGlWU2x2aGg2VEtzY1NncVlRVWpRL09xeUc3U2tqS1ZqUTcyajViZVFMeGlMVHRVeWoxT21QClhoOWNXSlh4OGlRKzQ1Y1BvbitrTU9BSWlUd2lCM21tRlJmUWpJR3ZlMURQVW85SitOWjRYZEVDZ1lFQXdOS2cKT2RHWXh4S3RDclhWejFtZGc2UERsVjhxaDdueHhaYlBjaCthTUlRbDErb1RDZ1NpdzhvT1lFZDhnMEhPZFY2dAoxRytJV2h2UHhpaVd5My9BRTBRaGdvS2syR1VzU2pXU01MY0piYVV6RG9FSEZqVExqZWNSbHFkem83cXhSWHFCCm1lTjRMNVdKWUtuTEM0ODJLN2h2dWZTK3VvNWZCNXF3UG10MTNNY0NnWUFlNFRWUFJQK3R5anR0WUNyK084dGwKdy9VbVJLQ2NRdTRJd3Rrenh3ejRWMkNhTjJ0MHVZUWd5eWdjU2ZFU2JSR3RycjhSQ1VwN3BvSEtUZm5DWnIvZgo4TnJVVHdZcGlZZk53WTVaQ1NuQWlHMkFhSWxnbmZNckV3T0Y5T0MwMjhZUE1nVHJ0VXh2TzZoS2VHcUlJUXFHCnFrYnFzb1hoRGpacGdWbk9nV2VBRVFLQmdHdWlaMHcvSXFBbFhiQzMxZlViMmlCTWZ2WFhuSjhNL2RmRkdtRmoKSUtmcWJGRjlXVWxqVXhRbHF5YTFZTnpJRkI1U1RvaGlCZVArMkZtTitMYjV4ZGM3VmRWTFpnZGhXbnJHTXFlOAoxS2QrNnVReXhDanlLWm81blFqU3ltdGY0R3FmT3M4VE9kaWVDWVNLNDB1OWtvaVBPTmE5dHVYZWFVK09Xc2xOCkpRcXJBb0dCQUozTUtPdnNuUXp1WlZQMnZ6MFpxTHdJRTNYalJpRkd2ZVZwaXpxNGh3T1ZldU5zVjA4SnZBMHQKcHVlTkl5OWtsUFNjRmM5T1VkaVpXa0VYMDlCd0prVklyT0hvdHVTQjhBU3RPNVVBbnRObnV5V0xKRUZDNFVxNApHcEI4bGJqOWpreFNLYVU3WDNHYWMyM0s5Skw4ZXVMaDdFN3JQdVpSWWE2bVlONG5iS3F1Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== + register: result + failed_when: result.data | b64decode != 'Hello World.' or result.changed + + - name: Retrieve data from asymmetric vault, with private key file. + ipavault: + ipaadmin_password: SomeADMINpassword + name: asymvault + username: user01 + vault_type: asymmetric + retrieve: true + private_key_file: "{{ ansible_env.HOME }}/private.pem" + register: result + failed_when: result.data | b64decode != 'Hello World.' or result.changed + - name: Ensure asymmetric vault is absent. ipavault: ipaadmin_password: SomeADMINpassword @@ -260,10 +391,44 @@ name: stdvault username: user01 vault_data: Hello World. - action: member register: result failed_when: not result.changed + - name: Retrieve data from standard vault. + ipavault: + ipaadmin_password: SomeADMINpassword + name: stdvault + username: user01 + retrieve: yes + out: "{{ ansible_env.HOME }}/data.txt" + register: result + failed_when: result.changed + + - name: Verify retrieved data. + slurp: + src: "{{ ansible_env.HOME }}/data.txt" + register: slurpfile + failed_when: slurpfile['content'] | b64decode != 'Hello World.' + + - name: Archive data in standard vault. + ipavault: + ipaadmin_password: SomeADMINpassword + name: stdvault + username: user01 + in: "{{ ansible_env.HOME }}/in.txt" + register: result + failed_when: not result.changed + + - name: Retrieve data from standard vault. + ipavault: + ipaadmin_password: SomeADMINpassword + name: stdvault + username: user01 + vault_type: standard + retrieve: true + register: result + failed_when: result.data | b64decode != 'Another World.' or result.changed + - name: Ensure standard vault member user is present. ipavault: ipaadmin_password: SomeADMINpassword @@ -454,7 +619,7 @@ ipaadmin_password: SomeADMINpassword name: sharedvault shared: True - ipavaultpassword: MyVaultPassword123 + ipavaultpassword: SomeVAULTpassword register: result failed_when: not result.changed @@ -471,7 +636,7 @@ ipavault: ipaadmin_password: SomeADMINpassword name: svcvault - ipavaultpassword: MyVaultPassword123 + ipavaultpassword: SomeVAULTpassword service: "HTTP/{{ groups.ipaserver[0] }}" register: result failed_when: not result.changed @@ -689,7 +854,7 @@ state: absent # cleaup - - name: Ensure test vaults are absent + - name: Ensure user01 vaults are absent ipavault: ipaadmin_password: SomeADMINpassword name: @@ -699,6 +864,16 @@ username: user01 state: absent + - name: Ensure test vaults are absent + ipavault: + ipaadmin_password: SomeADMINpassword + name: + - stdvault + - symvault + - asymvault + username: admin + state: absent + - name: Ensure shared vaults are absent ipavault: ipaadmin_password: SomeADMINpassword @@ -727,3 +902,28 @@ ipaadmin_password: SomeADMINpassword name: vaultgroup state: absent + + - name: Remove password file from target host. + file: + path: "{{ ansible_env.HOME }}/password.txt" + state: absent + + - name: Remove public key file from target host. + file: + path: "{{ ansible_env.HOME }}/public.pem" + state: absent + + - name: Remove private key file from target host. + file: + path: "{{ ansible_env.HOME }}/private.pem" + state: absent + + - name: Remove output data file from target host. + file: + path: "{{ ansible_env.HOME }}/data.txt" + state: absent + + - name: Remove input data file from target host. + file: + path: "{{ ansible_env.HOME }}/in.txt" + state: absent