Compare commits

...

15 Commits

Author SHA1 Message Date
Thomas Woerner
aff2703bdf Merge pull request #196 from rjeffman/fix_logger_info_calls
Removes invalid and unnecessary calls to logger.info.
2020-02-03 16:20:07 +01:00
Rafael Guterres Jeffman
fda761b4bf Removes invalid and unnecessary calls to logger.info. 2020-01-24 23:49:55 -03:00
Rafael Guterres Jeffman
daa9359bb7 Removes invalid and unnecessary calls to logger.info. 2020-01-24 21:41:04 -03:00
Rafael Guterres Jeffman
499e738509 Merge pull request #186 from jesmg/master
Add missing validation in ipasudocmd
2020-01-16 19:10:24 -03:00
Jesús Marín
34f23e68b7 Add missing validation in ipasudocmd
This fixes the issue https://github.com/freeipa/ansible-freeipa/issues/185, where the python script was launching an exception
There was a lack of verification that the input string (for the description) was a text string
2020-01-16 16:06:03 +01:00
Varun Mylaraiah
6b3cae53a5 Update README-sudorule.md 2019-12-30 15:21:29 +05:30
Rafael Guterres Jeffman
f501bfd886 Merge pull request #174 from t-woerner/ipahost_member_only_fail
ipahost: Enhanced failure msg for member params used without member action.
2019-12-24 12:19:52 -03:00
Rafael Guterres Jeffman
3fc5da58c4 Merge pull request #172 from t-woerner/ipahost_fix_auth_ind
ipahost: Fix choices of auth_ind parameter, allow to reset parameter
2019-12-23 20:46:05 -03:00
Rafael Guterres Jeffman
b226ed2c7b Merge pull request #173 from t-woerner/ipauser_allow_userauthtype_reset
ipauser: Allow reset of userauthtype, do not depend on first,last for…
2019-12-23 11:38:32 -03:00
Varun Mylaraiah
28fef00803 Update README-hbacsvcgroup.md 2019-12-23 08:38:39 +05:30
Thomas Woerner
a999f30110 Merge pull request #154 from rjeffman/vault
New vault management module.
2019-12-19 16:20:15 +01:00
Thomas Woerner
24515e40ad ipahost: Enhanced failure msg for member params used without member action
The failure message if member parameters like certificate, managedby_host,
principal, allow_create_keytab_* and allow_retrieve_keytab_* are used
without member action for state absent has been enhanced to propose the
member action.
2019-12-18 12:28:03 +01:00
Thomas Woerner
36c1c83708 ipauser: Allow reset of userauthtype, do not depend on first,last for mod
It was not possible to reset the userauthtype. The empty string has been
added to userauthtype for this.

Also ipauser will only depend on given first and last name if the user
does not exist yet. For the update operation these parameters are not
needed anymore.
2019-12-17 15:30:45 +01:00
Thomas Woerner
b6100f0c19 ipahost: Fix choices of auth_ind parameter, allow to reset parameter
The choices for the auth_ind parameter have been wrong. The choices are now
['radius', 'otp', 'pkinit', 'hardened', '']. The empty string has been added
to be able to rest auth_ind for the host entry.
2019-12-17 14:59:26 +01:00
Rafael Guterres Jeffman
af4e8432ad New vault management module.
There is a new vault management module placed in the plugins folder:

  plugins/modules/ipavault.py

The vault module allows to ensure presence and absence of vaults, manage
members and owner of the vault, and archive data in the vault.

Here is the documentation for the module:

    README-vault.md

New example playbooks have been added:

    playbooks/vault/data-archive-in-asymmetric-vault.yml
    playbooks/vault/data-archive-in-symmetric-vault.yml
    playbooks/vault/ensure-asymetric-vault-is-absent.yml
    playbooks/vault/ensure-asymetric-vault-is-present.yml
    playbooks/vault/ensure-service-vault-is-absent.yml
    playbooks/vault/ensure-service-vault-is-present.yml
    playbooks/vault/ensure-shared-vault-is-absent.yml
    playbooks/vault/ensure-shared-vault-is-present.yml
    playbooks/vault/ensure-standard-vault-is-absent.yml
    playbooks/vault/ensure-standard-vault-is-present.yml
    playbooks/vault/ensure-symetric-vault-is-absent.yml
    playbooks/vault/ensure-symetric-vault-is-present.yml
    playbooks/vault/ensure-vault-is-present-with-members.yml
    playbooks/vault/ensure-vault-member-group-is-absent.yml
    playbooks/vault/ensure-vault-member-group-is-present.yml
    playbooks/vault/ensure-vault-member-user-is-absent.yml
    playbooks/vault/ensure-vault-member-user-is-present.yml
    playbooks/vault/ensure-vault-owner-is-absent.yml
    playbooks/vault/ensure-vault-owner-is-present.yml

New tests added for the module:

    tests/vault/test_vault.yml
2019-12-16 14:39:42 -03:00
31 changed files with 1727 additions and 29 deletions

View File

@@ -4,7 +4,7 @@ HBACsvcgroup module
Description
-----------
The hbacsvcgroup (HBAC Service Group) module allows to ensure presence and absence of HBAP Service Groups and members of the groups.
The hbacsvcgroup (HBAC Service Group) module allows to ensure presence and absence of HBAC Service Groups and members of the groups.
Features

View File

@@ -280,7 +280,7 @@ Variable | Description | Required
`mac_address` \| `macaddress` | List of hardware MAC addresses. | no
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys | no
`userclass` \| `class` | Host category (semantics placed on this attribute are for local interpretation) | no
`auth_ind` \| `krbprincipalauthind` | Defines a whitelist for Authentication Indicators. Use 'otp' to allow OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA authentications. Other values may be used for custom configurations. choices: ["radius", "otp", "pkinit", "hardened"] | no
`auth_ind` \| `krbprincipalauthind` | Defines a whitelist for Authentication Indicators. Use 'otp' to allow OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA authentications. Use empty string to reset auth_ind to the initial value. Other values may be used for custom configurations. choices: ["radius", "otp", "pkinit", "hardened", ""] | no
`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service (bool) | no
`ok_as_delegate` \| `ipakrbokasdelegate` | Client credentials may be delegated to the service (bool) | no
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client (bool) | no

View File

@@ -106,6 +106,7 @@ Example playbook to make sure Sudo Rule is absent:
- ipasudorule:
ipaadmin_password: MyPassword123
name: testrule1
state: absent
```

View File

@@ -408,7 +408,7 @@ Variable | Description | Required
`manager` | List of manager user names. | no
`carlicense` | List of car licenses. | no
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys. | no
`userauthtype` | List of supported user authentication types. Choices: `password`, `radius` and `otp` | no
`userauthtype` | List of supported user authentication types. Choices: `password`, `radius`, `otp` and ``. Use empty string to reset userauthtype to the initial value. | no
`userclass` | User category. (semantics placed on this attribute are for local interpretation). | no
`radius` | RADIUS proxy configuration | no
`radiususer` | RADIUS proxy username | no

203
README-vault.md Normal file
View File

@@ -0,0 +1,203 @@
Vault module
===================
Description
-----------
The vault module allows to ensure presence and absence of vault and members of vaults.
The vault module is as compatible as possible to the Ansible upstream `ipa_vault` module, and additionally offers to make sure that vault members, groups and owners are present or absent in a vault, and allow the archival of data in vaults.
Features
--------
* Vault management
Supported FreeIPA Versions
--------------------------
FreeIPA versions 4.4.0 and up are supported by the ipavault module.
Requirements
------------
**Controller**
* Ansible version: 2.8+
**Node**
* Supported FreeIPA version (see above)
* KRA service must be enabled
Usage
=====
Example inventory file
```ini
[ipaserver]
ipaserver.test.local
```
Example playbook to make sure vault is present:
```yaml
---
- name: Playbook to handle vaults
hosts: ipaserver
become: true
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
vault_password: MyVaultPassword123
description: A standard private vault.
```
Example playbook to make sure that a vault and its members are present:
```yaml
---
- name: Playbook to handle vaults
hosts: ipaserver
become: true
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
users: user01
```
`action` controls if the vault, data, member or owner will be handled. To add or remove members or vault data, set `action` to `member`.
Example playbook to make sure that a vault member is present in vault:
```yaml
---
- name: Playbook to handle vaults
hosts: ipaserver
become: true
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
users: user01
action: member
```
Example playbook to make sure that a vault owner is absent in vault:
```yaml
---
- name: Playbook to handle vaults
hosts: ipaserver
become: true
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
owner: user01
action: member
state: absent
```
Example playbook to make sure vault data is present in a symmetric vault:
```yaml
---
- name: Playbook to handle vaults
hosts: ipaserver
become: true
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
vault_password: MyVaultPassword123
vault_data: >
Data archived.
More data archived.
action: member
```
Example playbook to make sure vault data is absent in a symmetric vault:
```yaml
---
- name: Playbook to handle vaults
hosts: ipaserver
become: true
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
vault_password: MyVaultPassword123
action: member
state: absent
```
Example playbook to make sure vault is absent:
```yaml
---
- name: Playbook to handle vaults
hosts: ipaserver
become: true
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
state: absent
```
Variables
=========
ipavault
-------
Variable | Description | Required
-------- | ----------- | --------
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
`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
`vault_type` \| `ipavaulttype` | Vault types are based on security level. It can be one of `standard`, `symmetric` or `asymmetric`, default: `symmetric` | no
`service` | Any service can own one or more service vaults. | no
`user` | Any user can own one or more user vaults. | no
`shared` | Vault is shared. Default to false. (bool) | no
`users` | Users that are members of the vault. | no
`groups` | Groups that are member of the vault. | no
`vault_data` \| `ipavaultdata` | Data to be stored in the vault. | 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
Notes
=====
ipavault uses a client context to execute, and it might affect execution time.
Authors
=======
Rafael Jeffman

View File

@@ -23,6 +23,7 @@ Features
* Modules for sudorule management
* Modules for topology management
* Modules for user management
* Modules for vault management
Supported FreeIPA Versions
--------------------------
@@ -418,3 +419,4 @@ Modules in plugin/modules
* [ipatopologysegment](README-topology.md)
* [ipatopologysuffix](README-topology.md)
* [ipauser](README-user.md)
* [ipavault](README-vault.md)

View File

@@ -0,0 +1,13 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: user01
vault_data: The world of π is half rounded.
action: member

View File

@@ -0,0 +1,14 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
vault_password: MyVaultPassword123
vault_data: The world of π is half rounded.
action: member

View File

@@ -0,0 +1,12 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: admin
state: absent

View File

@@ -0,0 +1,13 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: admin
vault_public_key: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM295VTFEMnFOZERYeGtSaFFETXBiUEVSWWlHbE1jbzdhN0hIVDk1bGNQbmhObVFkb3VGdHlVbFBUVS96V1kKZldYWTBOeU1UbUtoeFRseUV3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=
vault_type: asymmetric

View File

@@ -0,0 +1,12 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: svcvault
service: "HTTP/{{ groups.ipaserver[0] }}"
state: absent

View File

@@ -0,0 +1,13 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: svcvault
service: "HTTP/{{ groups.ipaserver[0] }}"
ipavaultpassword: MyVaultPassword123
state: present

View File

@@ -0,0 +1,12 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: sharedvault
shared: True
state: absent

View File

@@ -0,0 +1,13 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: sharedvault
shared: True
ipavaultpassword: MyVaultPassword123
state: present

View File

@@ -0,0 +1,12 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: admin
state: absent

View File

@@ -0,0 +1,13 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: stdvault
vault_type: standard
username: admin
description: A standard private vault.

View File

@@ -0,0 +1,12 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
state: absent

View File

@@ -0,0 +1,13 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
vault_password: MyVaultPassword123
vault_type: symmetric

View File

@@ -0,0 +1,17 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: stdvault
vault_type: standard
username: admin
users:
- user01
- user02
groups:
- ipausers

View File

@@ -0,0 +1,14 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: keychain
username: admin
state: absent
action: member
groups: ipausers

View File

@@ -0,0 +1,14 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: keychain
username: admin
state: present
action: member
groups: ipausers

View File

@@ -0,0 +1,16 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: keychain
username: admin
state: absent
action: member
users:
- user01
- user02

View File

@@ -0,0 +1,14 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: keychain
username: admin
state: present
action: member
users: user1

View File

@@ -0,0 +1,15 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
owners: user01
ownergroups: ipausers
action: member
state: absent

View File

@@ -0,0 +1,15 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
owners: user01
ownergroups: ipausers
action: member
state: present

View File

@@ -147,9 +147,10 @@ options:
Defines a whitelist for Authentication Indicators. Use 'otp' to allow
OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA
authentications. Other values may be used for custom configurations.
Use empty string to reset auth_ind to the initial value.
type: list
aliases: ["krbprincipalauthind"]
choices: ["radius", "otp", "pkinit", "hardened"]
choices: ["radius", "otp", "pkinit", "hardened", ""]
required: false
requires_pre_auth:
description: Pre-authentication is required for the service
@@ -277,9 +278,10 @@ options:
Defines a whitelist for Authentication Indicators. Use 'otp' to allow
OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA
authentications. Other values may be used for custom configurations.
Use empty string to reset auth_ind to the initial value.
type: list
aliases: ["krbprincipalauthind"]
choices: ["radius", "otp", "pkinit", "hardened"]
choices: ["radius", "otp", "pkinit", "hardened", ""]
required: false
requires_pre_auth:
description: Pre-authentication is required for the service
@@ -511,19 +513,25 @@ def check_parameters(
"userclass", "auth_ind", "requires_pre_auth",
"ok_as_delegate", "ok_to_auth_as_delegate", "force",
"reverse", "ip_address", "update_password"]
if action == "host":
invalid.extend([
"certificate", "managedby_host", "principal",
"allow_create_keytab_user", "allow_create_keytab_group",
"allow_create_keytab_host", "allow_create_keytab_hostgroup",
"allow_retrieve_keytab_user", "allow_retrieve_keytab_group",
"allow_retrieve_keytab_host",
"allow_retrieve_keytab_hostgroup"])
for x in invalid:
if vars()[x] is not None:
module.fail_json(
msg="Argument '%s' can not be used with state '%s'" %
(x, state))
if action == "host":
invalid = [
"certificate", "managedby_host", "principal",
"allow_create_keytab_user", "allow_create_keytab_group",
"allow_create_keytab_host", "allow_create_keytab_hostgroup",
"allow_retrieve_keytab_user", "allow_retrieve_keytab_group",
"allow_retrieve_keytab_host",
"allow_retrieve_keytab_hostgroup"
]
for x in invalid:
if vars()[x] is not None:
module.fail_json(
msg="Argument '%s' can only be used with action "
"'member' for state '%s'" % (x, state))
def main():
@@ -590,7 +598,7 @@ def main():
default=None),
auth_ind=dict(type='list', aliases=["krbprincipalauthind"],
default=None,
choices=['password', 'radius', 'otp']),
choices=['radius', 'otp', 'pkinit', 'hardened', '']),
requires_pre_auth=dict(type="bool", aliases=["ipakrbrequirespreauth"],
default=None),
ok_as_delegate=dict(type="bool", aliases=["ipakrbokasdelegate"],
@@ -835,6 +843,13 @@ def main():
if x in args:
del args[x]
# Ignore auth_ind if it is empty (for resetting)
# and not set in for the host
if "krbprincipalauthind" not in res_find and \
"krbprincipalauthind" in args and \
args["krbprincipalauthind"] == ['']:
del args["krbprincipalauthind"]
# For all settings is args, check if there are
# different settings in the find result.
# If yes: modify

View File

@@ -97,7 +97,7 @@ def find_sudocmd(module, name):
def gen_args(description):
_args = {}
if description is not None:
_args["description"] = description
_args["description"] = to_text(description)
return _args

View File

@@ -153,9 +153,12 @@ options:
required: false
aliases: ["ipasshpubkey"]
userauthtype:
description: List of supported user authentication types
choices=['password', 'radius', 'otp']
description:
List of supported user authentication types
Use empty string to reset userauthtype to the initial value.
choices=['password', 'radius', 'otp', '']
required: false
aliases: ["ipauserauthtype"]
userclass:
description:
- User category
@@ -310,9 +313,12 @@ options:
required: false
aliases: ["ipasshpubkey"]
userauthtype:
description: List of supported user authentication types
choices=['password', 'radius', 'otp']
description:
List of supported user authentication types
Use empty string to reset userauthtype to the initial value.
choices=['password', 'radius', 'otp', '']
required: false
aliases: ["ipauserauthtype"]
userclass:
description:
- User category
@@ -710,7 +716,7 @@ def main():
default=None),
userauthtype=dict(type='list', aliases=["ipauserauthtype"],
default=None,
choices=['password', 'radius', 'otp']),
choices=['password', 'radius', 'otp', '']),
userclass=dict(type="list", aliases=["class"],
default=None),
radius=dict(type="str", aliases=["ipatokenradiusconfiglink"],
@@ -854,13 +860,6 @@ def main():
if names is not None and len(names) != 1:
ansible_module.fail_json(
msg="Only one user can be added at a time using name.")
if action != "member":
# Only check first and last here if names is set
if names is not None:
if first is None:
ansible_module.fail_json(msg="First name is needed")
if last is None:
ansible_module.fail_json(msg="Last name is needed")
check_parameters(
ansible_module, state, action,
@@ -1035,6 +1034,13 @@ def main():
if "noprivate" in args:
del args["noprivate"]
# Ignore userauthtype if it is empty (for resetting)
# and not set in for the user
if "ipauserauthtype" not in res_find and \
"ipauserauthtype" in args and \
args["ipauserauthtype"] == ['']:
del args["ipauserauthtype"]
# For all settings is args, check if there are
# different settings in the find result.
# If yes: modify
@@ -1043,6 +1049,14 @@ def main():
commands.append([name, "user_mod", args])
else:
# Make sure we have a first and last name
if first is None:
ansible_module.fail_json(
msg="First name is needed")
if last is None:
ansible_module.fail_json(
msg="Last name is needed")
commands.append([name, "user_add", args])
# Handle members: principal, manager, certificate and

646
plugins/modules/ipavault.py Normal file
View File

@@ -0,0 +1,646 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Authors:
# Rafael Guterres Jeffman <rjeffman@redhat.com>
#
# Copyright (C) 2019 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {
"metadata_version": "1.0",
"supported_by": "community",
"status": ["preview"],
}
DOCUMENTATION = """
---
module: ipavault
short description: Manage vaults and secret vaults.
description: Manage vaults and secret vaults. KRA service must be enabled.
options:
ipaadmin_principal:
description: The admin principal
default: admin
ipaadmin_password:
description: The admin password
required: false
name:
description: The vault name
required: true
aliases: ["cn"]
description:
description: The vault description
required: false
vault_public_key:
description: Base64 encoded public key.
required: false
type: list
aliases: ["ipavaultpublickey"]
vault_salt:
description: Vault salt.
required: false
type: list
aliases: ["ipavaultsalt"]
vault_password:
description: password to be used on symmetric vault.
required: false
type: string
aliases: ["ipavaultpassword"]
vault_type:
description: Vault types are based on security level.
required: true
default: symmetric
choices: ["standard", "symmetric", "asymmetric"]
aliases: ["ipavaulttype"]
service:
description: Any service can own one or more service vaults.
required: false
type: list
username:
description: Any user can own one or more user vaults.
required: false
type: string
aliases: ["user"]
shared:
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
type: list
users:
description: Users that are member of the container.
required: false
type: list
groups:
description: Groups that are member of the container.
required: false
type: list
action:
description: Work on vault or member level.
default: vault
choices: ["vault", "member"]
state:
description: State to ensure
default: present
choices: ["present", "absent"]
author:
- Rafael Jeffman
"""
EXAMPLES = """
# Ensure vault symvault is present
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
vault_password: MyVaultPassword123
vault_salt: MTIzNDU2Nzg5MAo=
vault_type: symmetric
# Ensure group ipausers is a vault member.
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
groups: ipausers
action: member
# Ensure group ipausers is not a vault member.
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
groups: ipausers
action: member
state: absent
# Ensure vault users are present.
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
users:
- user01
- user02
action: member
# Ensure vault users are absent.
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
users:
- user01
- user02
action: member
status: absent
# Ensure user owns vault.
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
action: member
owners: user01
# Ensure user does not own vault.
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
owners: user01
action: member
status: absent
# Ensure data is archived to a symmetric vault
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: admin
vault_password: MyVaultPassword123
vault_data: >
Data archived.
More data archived.
action: member
# Ensure vault symvault is absent
- ipavault:
ipaadmin_password: MyPassword123
name: symvault
user: admin
state: absent
# Ensure asymmetric vault is present.
- ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: user01
description: An asymmetric vault
vault_type: asymmetric
vault_public_key:
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR
HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi
9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM
295VTFEMnFOZERYeGtSaFFETXBiUEVSWWlHbE1jbzdhN0hIVDk1bGNQbmhObVFkb3VGdHlV
bFBUVS96V1kKZldYWTBOeU1UbUtoeFRseUV3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVk
tLS0tLQo=
# Ensure data is archived in an asymmetric vault
- ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: admin
vault_data: >
Data archived.
More data archived.
action: member
# Ensure asymmetric vault is absent.
- ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: user01
vault_type: asymmetric
state: absent
"""
RETURN = """
"""
import os
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, \
gen_add_del_lists, compare_args_ipa, module_params_get
from ipalib.errors import EmptyModlist
def find_vault(module, name, username, service, shared):
_args = {
"all": True,
"cn": name,
}
if username is not None:
_args['username'] = username
elif service is not None:
_args['service'] = service
else:
_args['shared'] = shared
_result = api_command(module, "vault_find", name, _args)
if len(_result["result"]) > 1:
module.fail_json(
msg="There is more than one vault '%s'" % (name))
if len(_result["result"]) == 1:
return _result["result"][0]
return None
def gen_args(description, username, service, shared, vault_type, salt,
public_key, vault_data):
_args = {}
if description is not None:
_args['description'] = description
if username is not None:
_args['username'] = username
if service is not None:
_args['service'] = service
if shared is not None:
_args['shared'] = shared
if vault_type is not None:
_args['ipavaulttype'] = vault_type
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')
return _args
def gen_member_args(args, users, groups):
_args = args.copy()
for arg in ['ipavaulttype', 'description', 'ipavaultpublickey',
'ipavaultsalt']:
if arg in _args:
del _args[arg]
_args['user'] = users
_args['group'] = groups
return _args
def data_storage_args(args, data, password):
_args = {}
if 'username' in args:
_args['username'] = args['username']
if 'service' in args:
_args['service'] = args['service']
if 'shared' in args:
_args['shared'] = args['shared']
if password is not None:
_args['password'] = password
_args['data'] = data
return _args
def check_parameters(module, state, action, description, username, service,
shared, users, groups, owners, ownergroups, vault_type,
salt, password, public_key, vault_data):
invalid = []
if state == "present":
if action == "member":
invalid = ['description', 'public_key', 'salt']
for param in invalid:
if vars()[param] is not None:
module.fail_json(
msg="Argument '%s' can not be used with action '%s'" %
(param, action))
elif state == "absent":
invalid = ['description', 'salt']
if action == "vault":
invalid.extend(['users', 'groups', 'owners', 'ownergroups',
'password', 'public_key'])
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))
def check_encryption_params(module, state, vault_type, password, public_key,
vault_data, res_find):
if state == "present":
if vault_type == "symmetric":
if password is None \
and (vault_data is not None or res_find is None):
module.fail_json(
msg="Vault password required for symmetric vault.")
if vault_type == "asymmetric":
if public_key is None and res_find is None:
module.fail_json(
msg="Public Key required for asymmetric vault.")
def main():
ansible_module = AnsibleModule(
argument_spec=dict(
# generalgroups
ipaadmin_principal=dict(type="str", default="admin"),
ipaadmin_password=dict(type="str", required=False, no_log=True),
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']),
vault_salt=dict(type="str", required=False, default=None,
aliases=['ipavaultsalt']),
username=dict(type="str", required=False, default=None,
aliases=['user']),
service=dict(type="str", required=False, default=None),
shared=dict(type="bool", required=False, default=None),
users=dict(required=False, type='list', default=None),
groups=dict(required=False, type='list', default=None),
owners=dict(required=False, type='list', default=None),
ownergroups=dict(required=False, type='list', default=None),
vault_data=dict(type="str", required=False, default=None,
aliases=['ipavaultdata']),
vault_password=dict(type="str", required=False, default=None,
no_log=True, aliases=['ipavaultpassword']),
# state
action=dict(type="str", default="vault",
choices=["vault", "data", "member"]),
state=dict(type="str", default="present",
choices=["present", "absent"]),
),
supports_check_mode=True,
mutually_exclusive=[['username', 'service', 'shared']],
required_one_of=[['username', 'service', 'shared']]
)
ansible_module._ansible_debug = True
# general
ipaadmin_principal = module_params_get(ansible_module,
"ipaadmin_principal")
ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
names = module_params_get(ansible_module, "name")
# present
description = module_params_get(ansible_module, "description")
username = module_params_get(ansible_module, "username")
service = module_params_get(ansible_module, "service")
shared = module_params_get(ansible_module, "shared")
users = module_params_get(ansible_module, "users")
groups = module_params_get(ansible_module, "groups")
owners = module_params_get(ansible_module, "owners")
ownergroups = module_params_get(ansible_module, "ownergroups")
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")
public_key = module_params_get(ansible_module, "vault_public_key")
vault_data = module_params_get(ansible_module, "vault_data")
action = module_params_get(ansible_module, "action")
# state
state = module_params_get(ansible_module, "state")
# Check parameters
if state == "present":
if len(names) != 1:
ansible_module.fail_json(
msg="Only one vault can be added at a time.")
elif state == "absent":
if len(names) < 1:
ansible_module.fail_json(msg="No name given.")
else:
ansible_module.fail_json(msg="Invalid state '%s'" % state)
check_parameters(ansible_module, state, action, description, username,
service, shared, users, groups, owners, ownergroups,
vault_type, salt, password, public_key, vault_data)
# Init
changed = False
exit_args = {}
ccache_dir = None
ccache_name = None
try:
if not valid_creds(ansible_module, ipaadmin_principal):
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
ipaadmin_password)
api_connect(context='ansible-freeipa')
commands = []
for name in names:
# Make sure vault exists
res_find = find_vault(
ansible_module, name, username, service, shared)
# Generate args
args = gen_args(description, username, service, shared, vault_type,
salt, public_key, vault_data)
# Set default vault_type if needed.
if vault_type is None and vault_data is not None:
if res_find is not None:
res_vault_type = res_find.get('ipavaulttype')[0]
args['ipavaulttype'] = vault_type = res_vault_type
else:
args['ipavaulttype'] = vault_type = "symmetric"
# verify data encription args
check_encryption_params(ansible_module, state, vault_type,
password, public_key, vault_data, res_find)
# Create command
if state == "present":
# Found the vault
if action == "vault":
if res_find is not None:
# For all settings is args, check if there are
# different settings in the find result.
# If yes: modify
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])
# Set res_find to empty dict for next step # noqa
res_find = {}
# Generate adittion and removal lists
user_add, user_del = \
gen_add_del_lists(users,
res_find.get('member_user', []))
group_add, group_del = \
gen_add_del_lists(groups,
res_find.get('member_group', []))
owner_add, owner_del = \
gen_add_del_lists(owners,
res_find.get('owner_user', []))
ownergroups_add, ownergroups_del = \
gen_add_del_lists(ownergroups,
res_find.get('owner_group', []))
# Add users and groups
if len(user_add) > 0 or len(group_add) > 0:
user_add_args = gen_member_args(args, user_add,
group_add)
commands.append([name, 'vault_add_member',
user_add_args])
# Remove users and groups
if len(user_del) > 0 or len(group_del) > 0:
user_del_args = gen_member_args(args, user_del,
group_del)
commands.append([name, 'vault_remove_member',
user_del_args])
# Add owner users and groups
if len(user_add) > 0 or len(group_add) > 0:
owner_add_args = gen_member_args(args, owner_add,
ownergroups_add)
commands.append([name, 'vault_add_owner',
owner_add_args])
# Remove owner users and groups
if len(user_del) > 0 or len(group_del) > 0:
owner_del_args = gen_member_args(args, owner_del,
ownergroups_del)
commands.append([name, 'vault_remove_owner',
owner_del_args])
elif action in "member":
# Add users and groups
if users is not None or groups is not None:
user_args = gen_member_args(args, users, groups)
commands.append([name, 'vault_add_member', user_args])
if owners is not None or ownergroups is not None:
owner_args = gen_member_args(args, owners, ownergroups)
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])
elif state == "absent":
if 'ipavaulttype' in args:
del args['ipavaulttype']
if action == "vault":
if res_find is not None:
commands.append([name, "vault_del", args])
elif action == "member":
# remove users and groups
if users is not None or groups is not None:
user_args = gen_member_args(args, users, groups)
commands.append([name, 'vault_remove_member',
user_args])
if owners is not None or ownergroups is not None:
owner_args = gen_member_args(args, owners, ownergroups)
commands.append([name, 'vault_remove_owner',
owner_args])
else:
ansible_module.fail_json(
msg="Invalid action '%s' for state '%s'" %
(action, state))
else:
ansible_module.fail_json(msg="Unkown state '%s'" % state)
# Execute commands
errors = []
for name, command, args in commands:
try:
result = api_command(ansible_module, command, name, args)
if command == 'vault_archive':
changed = 'Archived data into' in result['summary']
else:
if "completed" in result:
if result["completed"] > 0:
changed = True
else:
changed = True
except EmptyModlist:
result = {}
except Exception as exception:
ansible_module.fail_json(
msg="%s: %s: %s" % (command, name, str(exception)))
# Get all errors
# All "already a member" and "not a member" failures in the
# result are ignored. All others are reported.
if "failed" in result and len(result["failed"]) > 0:
for item in result["failed"]:
failed_item = result["failed"][item]
for member_type in failed_item:
for member, failure in failed_item[member_type]:
if "already a member" in failure \
or "not a member" in failure:
continue
errors.append("%s: %s %s: %s" % (
command, member_type, member, failure))
if len(errors) > 0:
ansible_module.fail_json(msg=", ".join(errors))
except Exception as exception:
ansible_module.fail_json(msg=str(exception))
finally:
temp_kdestroy(ccache_dir, ccache_name)
# Done
ansible_module.exit_json(changed=changed, **exit_args)
if __name__ == "__main__":
main()

View File

@@ -872,14 +872,12 @@ def main():
is_ipaddr = False
if is_ipaddr:
logger.info()
logger.warning(
"It seems that you are using an IP address "
"instead of FQDN as an argument to --server. The "
"installation may fail.")
break
# logger.info()
# if not options.unattended and not user_input(
# "Continue to configure the system with these values?", False):
# raise ScriptError(rval=CLIENT_INSTALL_ERROR)

562
tests/vault/test_vault.yml Normal file
View File

@@ -0,0 +1,562 @@
---
- name: Tests
hosts: ipaserver
become: true
gather_facts: false
tasks:
- name: Ensure user vaults are absent
ipavault:
ipaadmin_password: MyPassword123
name:
- stdvault
- symvault
- asymvault
username: user01
state: absent
- name: Ensure test users do not exist.
ipauser:
ipaadmin_password: MyPassword123
name:
- user01
- user02
- user03
state: absent
- name: Ensure test groups do not exist.
ipagroup:
ipaadmin_password: MyPassword123
name: vaultgroup
state: absent
- name: Ensure vaultgroup exists.
ipagroup:
ipaadmin_password: MyPassword123
name: vaultgroup
- name: Ensure user01 exists.
ipauser:
ipaadmin_password: MyPassword123
name: user01
first: First
last: Start
- name: Ensure user02 exists.
ipauser:
ipaadmin_password: MyPassword123
name: user02
first: Second
last: Middle
- name: Ensure user03 exists.
ipauser:
ipaadmin_password: MyPassword123
name: user03
first: Third
last: Last
- name: Ensure shared vaults are absent
ipavault:
ipaadmin_password: MyPassword123
name: sharedvault
shared: True
state: absent
- name: Ensure service vaults are absent
ipavault:
ipaadmin_password: MyPassword123
name: svcvault
service: "HTTP/{{ groups.ipaserver[0] }}"
state: absent
- name: Ensure symmetric vault is present
ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: user01
vault_password: MyVaultPassword123
vault_type: symmetric
register: result
failed_when: not result.changed
- name: Ensure symmetric vault is present, again
ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: user01
vault_password: MyVaultPassword123
vault_type: symmetric
register: result
failed_when: result.changed
- name: Archive data to symmetric vault
ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: user01
vault_password: MyVaultPassword123
vault_data: Hello World.
action: member
register: result
failed_when: not result.changed
- name: Archive data with non-ASCII characters to symmetric vault
ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: user01
vault_password: MyVaultPassword123
vault_data: The world of π is half rounded.
action: member
register: result
failed_when: not result.changed
- name: Ensure symmetric vault is absent
ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: user01
state: absent
register: result
failed_when: not result.changed
- name: Ensure symmetric vault is absent, again
ipavault:
ipaadmin_password: MyPassword123
name: symvault
username: user01
state: absent
register: result
failed_when: result.changed
- name: Ensure asymmetric vault is present.
ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: user01
description: A symmetric private vault.
vault_public_key:
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR
HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi
9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM
295VTFEMnFOZERYeGtSaFFETXBiUEVSWWlHbE1jbzdhN0hIVDk1bGNQbmhObVFkb3VGdHlV
bFBUVS96V1kKZldYWTBOeU1UbUtoeFRseUV3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVk
tLS0tLQo=
vault_type: asymmetric
register: result
failed_when: not result.changed
- name: Ensure asymmetric vault is present, again.
ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: user01
vault_public_key:
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR
HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi
9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM
295VTFEMnFOZERYeGtSaFFETXBiUEVSWWlHbE1jbzdhN0hIVDk1bGNQbmhObVFkb3VGdHlV
bFBUVS96V1kKZldYWTBOeU1UbUtoeFRseUV3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVk
tLS0tLQo=
vault_type: asymmetric
register: result
failed_when: result.changed
- name: Archive data in asymmetric vault.
ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: user01
vault_data: Hello World.
action: member
register: result
failed_when: not result.changed
- name: Ensure asymmetric vault is absent.
ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: user01
state: absent
register: result
failed_when: not result.changed
- name: Ensure asymmetric vault is absent, again.
ipavault:
ipaadmin_password: MyPassword123
name: asymvault
username: user01
state: absent
register: result
failed_when: result.changed
- name: Ensure standard vault is present.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
vault_type: standard
username: user01
description: A standard private vault.
register: result
failed_when: not result.changed
- name: Ensure standard vault is present, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
vault_type: standard
description: A standard private vault.
register: result
failed_when: result.changed
- name: Archive data in standard vault.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
vault_data: Hello World.
action: member
register: result
failed_when: not result.changed
- name: Ensure standard vault member user is present.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
users:
- user02
register: result
failed_when: not result.changed
- name: Ensure standard vault member user is present, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
users:
- user02
register: result
failed_when: result.changed
- name: Ensure more vault member users are present.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
users:
- user01
- user02
register: result
failed_when: not result.changed
- name: Ensure vault member user is still present.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
users:
- user02
register: result
failed_when: result.changed
- name: Ensure vault users are absent.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
users:
- user01
- user02
state: absent
register: result
failed_when: not result.changed
- name: Ensure vault users are absent, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
users:
- user01
- user02
state: absent
register: result
failed_when: result.changed
- name: Ensure vault user is absent, once more.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
users:
- user01
state: absent
register: result
failed_when: result.changed
- name: Ensure vault member group is present.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
groups: vaultgroup
register: result
failed_when: not result.changed
- name: Ensure vault member group is present, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
groups: vaultgroup
register: result
failed_when: result.changed
- name: Ensure vault member group is absent.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
groups: vaultgroup
state: absent
register: result
failed_when: not result.changed
- name: Ensure vault member group is absent, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
action: member
groups: vaultgroup
state: absent
register: result
failed_when: result.changed
- name: Ensure vault is absent.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
state: absent
register: result
failed_when: not result.changed
- name: Ensure vault is absent, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
state: absent
register: result
failed_when: result.changed
- name: Ensure shared vault is present.
ipavault:
ipaadmin_password: MyPassword123
name: sharedvault
shared: True
ipavaultpassword: MyVaultPassword123
register: result
failed_when: not result.changed
- name: Ensure shared vault is absent.
ipavault:
ipaadmin_password: MyPassword123
name: sharedvault
shared: True
state: absent
register: result
failed_when: not result.changed
- name: Ensure service vault is present.
ipavault:
ipaadmin_password: MyPassword123
name: svcvault
ipavaultpassword: MyVaultPassword123
service: "HTTP/{{ groups.ipaserver[0] }}"
register: result
failed_when: not result.changed
- name: Ensure service vault is absent.
ipavault:
ipaadmin_password: MyPassword123
name: svcvault
service: "HTTP/{{ groups.ipaserver[0] }}"
state: absent
register: result
failed_when: not result.changed
- name: Ensure vault is present, with members.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
vault_type: standard
users:
- user02
- user03
groups:
- vaultgroup
register: result
failed_when: not result.changed
- name: Ensure vault is present, with members, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
vault_type: standard
users:
- user02
- user03
groups:
- vaultgroup
register: result
failed_when: result.changed
- name: Ensure user02 is not a member of vault stdvault.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
users: user02
state: absent
action: member
register: result
failed_when: not result.changed
- name: Ensure user02 is not a member of vault stdvault, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
users: user02
state: absent
action: member
register: result
failed_when: result.changed
- name: Ensure user02 is a member of vault stdvault.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
users: user02
action: member
register: result
failed_when: not result.changed
- name: Ensure user02 is a member of vault stdvault, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
users: user03
action: member
register: result
failed_when: result.changed
- name: Ensure user03 owns vault stdvault.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
owners: user03
action: member
register: result
failed_when: not result.changed
- name: Ensure user03 owns vault stdvault, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
owners: user03
action: member
register: result
failed_when: result.changed
- name: Ensure user03 is not owner of stdvault.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
owners: user03
state: absent
action: member
register: result
failed_when: not result.changed
- name: Ensure user03 is not owner of stdvault, again.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
owners: user03
state: absent
action: member
register: result
failed_when: result.changed
- name: Ensure vault is absent.
ipavault:
ipaadmin_password: MyPassword123
name: stdvault
username: user01
state: absent
# cleaup
- name: Ensure test vaults are absent
ipavault:
ipaadmin_password: MyPassword123
name:
- stdvault
- symvault
- asymvault
username: user01
state: absent
- name: Ensure shared vaults are absent
ipavault:
ipaadmin_password: MyPassword123
name: sharedvault
shared: True
state: absent
- name: Ensure service vaults are absent
ipavault:
ipaadmin_password: MyPassword123
name: svcvault
service: "HTTP/{{ groups.ipaserver[0] }}"
state: absent
- name: Ensure test users do not exist.
ipauser:
ipaadmin_password: MyPassword123
name:
- user01
- user02
- user03
state: absent
- name: Ensure test groups do not exist.
ipagroup:
ipaadmin_password: MyPassword123
name: vaultgroup
state: absent