#!/usr/bin/python # coding: utf-8 # (c) 2022, Johanna Dorothea Reichmann __metaclass__ = type import traceback from ansible.module_utils.basic import AnsibleModule from ansible_collections.finallycoffee.proxmox.plugins.module_utils.common import * from ansible_collections.finallycoffee.proxmox.plugins.module_utils.proxmox_datacenter_acl import * LIB_IMP_ERR = None try: from ansible_collections.finallycoffee.proxmox.plugins.module_utils.proxmox_datacenter_acl import set_acl from ansible_collections.finallycoffee.proxmox.plugins.module_utils.proxmox_datacenter_acl import ProxmoxACL HAS_LIB = True except: HAS_LIB = False LIB_IMP_ERR = traceback.format_exc() DOCUMENTATION = r''' --- module: acl author: - Johanna Dorothea Reichmann (transcaffeine@finally.coffee) requirements: - python >= 3.9 short_description: Configures an access control list in a proxmox node description: - "Configue access control lists in a proxmox instance" options: proxmox_instance: description: Location of the proxmox API with scheme, domain name/ip and port, e.g. https://localhost:8006 type: str required: true proxmox_api_token_id: description: The token ID containing username, realm and token name (format: user@realm!name) type: str required: true proxmox_api_secret: description: The secret type: str required: true proxmox_api_verify_cert: description: If the certificate presented for `proxmox_instance_url` should be verified type: bool required: false default: true path: description: Path to which access should be granted. Must be a valid proxmox access control path type: str required: true role: description: The role which the user/group/token should be added to when they match the ACL type: str required: true group: description: The group to match on the ACL. Must be a valid proxmox group id type: str required: false user: description: The user to match on the ACL. Must be a valid proxmox user id type: str required: false token: description: The token to match on the ACL. Must be a valid proxmox token id type: str required: false propagate: description: Wether to allow inheriting permissions or not. type: bool default: true required: false state: description: >- If the access control list should be present, absent or exact. When state is exact, the value of `propagate` is also considered, and if an existing access control rule is found which only differs in the value of `propagate`, the old rule is removed by the module, essentially replacing it. type: str choices: [present, exact, absent] default: present required: false ''' EXAMPLES = r''' - name: Configure an admin group from LDAP as proxmox global admins finallycoffee.proxmox.acl: proxmox_instance: https://my.proxmox-node.local:8006 promox_api_token_id: root@pam!token proxmox_api_secret: supersecuretokencontent path: / roles: Administrator groups: proxmox-admins-openldap propagate: true state: present - name: Configure an LDAP user to use their own VM finallycoffee.proxmox.acl: proxmox_instance: https://my.proxmox-node.local:8006 promox_api_token_id: root@pam!token proxmox_api_secret: supersecuretokencontent path: /vms/1000 roles: PVEVMUser groups: myusername-openldap state: present ''' RETURN = r''' acl: description: The updated/created access control list returned: always type: complex ''' def main(): _ = dict module = AnsibleModule( argument_spec=_( proxmox_instance=_(required=True, type='str'), proxmox_api_token_id=_(required=True, type='str'), proxmox_api_secret=_(type='str', required=True, no_log=True), proxmox_api_verify_cert=_(type='bool', required=False, default=True), path=_(required=True, type='str'), role=_(required=True, type='str'), group=_(required=False, type='str'), user=_(required=False, type='str'), token=_(required=False, type='str'), propagate=_(required=False, default=True, type='bool'), state=_(type='str', required=False, default='present', choices=['present', 'exact', 'absent']) ), supports_check_mode=True ) result = _( changed=False, diff={}, message='' ) realms = [] try: acl_spec = ProxmoxACL( module.params['path'], module.params['role'], module.params['propagate'], module.params.get('user', None), module.params.get('group', None), module.params.get('token', None), ) acl_change = set_acl(ProxmoxAuthInfo( module.params['proxmox_instance'], module.params['proxmox_api_token_id'], module.params['proxmox_api_secret'], module.params['proxmox_api_verify_cert'], ), acl_spec, module.check_mode, module.params['state']) except IOError as owie: result['msg'] = owie module.exit_json(**result) diff_excluded_keys = [] result['acl'] = acl_change[1] result['diff'] = { 'before_header': f"{acl_change[0].get('role', module.params['role'])}@{acl_change[0].get('path', module.params['path'])}" if acl_change[0] else acl_change[0], 'after_header': f"{acl_change[1].get('role', module.params['role'])}@{acl_change[1].get('path', module.params['path'])}" if acl_change[1] else acl_change[1], 'before': {k: v for k, v in acl_change[0].items() if k not in diff_excluded_keys} if acl_change[0] else acl_change[0], 'after': {k: v for k, v in acl_change[1].items() if k not in diff_excluded_keys} if acl_change[1] else acl_change[1], } # TODO: Needs special handling for state=exact result['changed'] = acl_change[0] != acl_change[1] module.exit_json(**result) if __name__ == '__main__': main()