1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-02-04 07:51:50 +00:00
community.general/plugins/modules/ipa_vault.py
Alexei Znamensky 634be713bb
replace batch of redundant to_native() occurrences (#11098)
* replace batch of redundant to_native() occurrences

* add changelog frag
2025-11-11 19:10:00 +13:00

258 lines
7.4 KiB
Python

#!/usr/bin/python
# Copyright (c) 2018, Juan Manuel Parrilla <jparrill@redhat.com>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
DOCUMENTATION = r"""
module: ipa_vault
author: Juan Manuel Parrilla (@jparrill)
short_description: Manage FreeIPA vaults
description:
- Add, modify and delete vaults and secret vaults.
- KRA service should be enabled to use this module.
attributes:
check_mode:
support: full
diff_mode:
support: none
options:
cn:
description:
- Vault name.
- Can not be changed as it is the unique identifier.
required: true
aliases: ["name"]
type: str
description:
description:
- Description.
type: str
ipavaulttype:
description:
- Vault types are based on security level.
default: "symmetric"
choices: ["asymmetric", "standard", "symmetric"]
aliases: ["vault_type"]
type: str
ipavaultpublickey:
description:
- Public key.
aliases: ["vault_public_key"]
type: str
ipavaultsalt:
description:
- Vault Salt.
aliases: ["vault_salt"]
type: str
username:
description:
- Any user can own one or more user vaults.
- Mutually exclusive with O(service).
aliases: ["user"]
type: list
elements: str
service:
description:
- Any service can own one or more service vaults.
- Mutually exclusive with O(user).
type: str
state:
description:
- State to ensure.
default: "present"
choices: ["absent", "present"]
type: str
replace:
description:
- Force replace the existent vault on IPA server.
type: bool
default: false
choices: ["True", "False"]
validate_certs:
description:
- Validate IPA server certificates.
type: bool
default: true
extends_documentation_fragment:
- community.general.ipa.documentation
- community.general.ipa.connection_notes
- community.general.attributes
"""
EXAMPLES = r"""
- name: Ensure vault is present
community.general.ipa_vault:
name: vault01
vault_type: standard
user: user01
ipa_host: ipa.example.com
ipa_user: admin
ipa_pass: topsecret
- name: Ensure vault is present for Admin user
community.general.ipa_vault:
name: vault01
vault_type: standard
ipa_host: ipa.example.com
ipa_user: admin
ipa_pass: topsecret
- name: Ensure vault is absent
community.general.ipa_vault:
name: vault01
vault_type: standard
user: user01
state: absent
ipa_host: ipa.example.com
ipa_user: admin
ipa_pass: topsecret
- name: Modify vault if already exists
community.general.ipa_vault:
name: vault01
vault_type: standard
description: "Vault for test"
ipa_host: ipa.example.com
ipa_user: admin
ipa_pass: topsecret
replace: true
- name: Get vault info if already exists
community.general.ipa_vault:
name: vault01
ipa_host: ipa.example.com
ipa_user: admin
ipa_pass: topsecret
"""
RETURN = r"""
vault:
description: Vault as returned by IPA API.
returned: always
type: dict
"""
import traceback
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.ipa import IPAClient, ipa_argument_spec
class VaultIPAClient(IPAClient):
def __init__(self, module, host, port, protocol):
super().__init__(module, host, port, protocol)
def vault_find(self, name):
return self._post_json(method="vault_find", name=None, item={"all": True, "cn": name})
def vault_add_internal(self, name, item):
return self._post_json(method="vault_add_internal", name=name, item=item)
def vault_mod_internal(self, name, item):
return self._post_json(method="vault_mod_internal", name=name, item=item)
def vault_del(self, name):
return self._post_json(method="vault_del", name=name)
def get_vault_dict(description=None, vault_type=None, vault_salt=None, vault_public_key=None, service=None):
vault = {}
if description is not None:
vault["description"] = description
if vault_type is not None:
vault["ipavaulttype"] = vault_type
if vault_salt is not None:
vault["ipavaultsalt"] = vault_salt
if vault_public_key is not None:
vault["ipavaultpublickey"] = vault_public_key
if service is not None:
vault["service"] = service
return vault
def get_vault_diff(client, ipa_vault, module_vault, module):
return client.get_diff(ipa_data=ipa_vault, module_data=module_vault)
def ensure(module, client):
state = module.params["state"]
name = module.params["cn"]
# user = module.params["username"] TODO is this really not needed?
replace = module.params["replace"]
module_vault = get_vault_dict(
description=module.params["description"],
vault_type=module.params["ipavaulttype"],
vault_salt=module.params["ipavaultsalt"],
vault_public_key=module.params["ipavaultpublickey"],
service=module.params["service"],
)
ipa_vault = client.vault_find(name=name)
changed = False
if state == "present":
if not ipa_vault:
# New vault
changed = True
if not module.check_mode:
ipa_vault = client.vault_add_internal(name, item=module_vault)
else:
# Already exists
if replace:
diff = get_vault_diff(client, ipa_vault, module_vault, module)
if len(diff) > 0:
changed = True
if not module.check_mode:
data = {}
for key in diff:
data[key] = module_vault.get(key)
client.vault_mod_internal(name=name, item=data)
else:
if ipa_vault:
changed = True
if not module.check_mode:
client.vault_del(name)
return changed, client.vault_find(name=name)
def main():
argument_spec = ipa_argument_spec()
argument_spec.update(
cn=dict(type="str", required=True, aliases=["name"]),
description=dict(type="str"),
ipavaulttype=dict(
type="str", default="symmetric", choices=["standard", "symmetric", "asymmetric"], aliases=["vault_type"]
),
ipavaultsalt=dict(type="str", aliases=["vault_salt"]),
ipavaultpublickey=dict(type="str", aliases=["vault_public_key"]),
service=dict(type="str"),
replace=dict(type="bool", default=False, choices=[True, False]),
state=dict(type="str", default="present", choices=["present", "absent"]),
username=dict(type="list", elements="str", aliases=["user"]),
)
module = AnsibleModule(
argument_spec=argument_spec, supports_check_mode=True, mutually_exclusive=[["username", "service"]]
)
client = VaultIPAClient(
module=module,
host=module.params["ipa_host"],
port=module.params["ipa_port"],
protocol=module.params["ipa_prot"],
)
try:
client.login(username=module.params["ipa_user"], password=module.params["ipa_pass"])
changed, vault = ensure(module, client)
module.exit_json(changed=changed, vault=vault)
except Exception as e:
module.fail_json(msg=f"{e}", exception=traceback.format_exc())
if __name__ == "__main__":
main()