From 2d4ce9f21970a2d126550135ba35f7c9a0cfb449 Mon Sep 17 00:00:00 2001 From: GuillaumeV-cemea <101114641+GuillaumeV-cemea@users.noreply.github.com> Date: Fri, 30 Dec 2022 22:09:00 +0100 Subject: [PATCH] feat: add tags to proxmox containers (#5714) * feat: add tags to proxmox containers * fix: correct version added * fix: code style * feat: changelog fragment * fix: correct version_added Co-authored-by: Felix Fontein * feat: fail on unsupported params, rather than silently ignoring them * fix: actually check unsupported feature presence before failing Co-authored-by: Felix Fontein --- .../5714-proxmox-lxc-tag-support.yml | 3 ++ plugins/modules/proxmox.py | 35 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5714-proxmox-lxc-tag-support.yml diff --git a/changelogs/fragments/5714-proxmox-lxc-tag-support.yml b/changelogs/fragments/5714-proxmox-lxc-tag-support.yml new file mode 100644 index 0000000000..5e3dcc8fcf --- /dev/null +++ b/changelogs/fragments/5714-proxmox-lxc-tag-support.yml @@ -0,0 +1,3 @@ +--- +minor_changes: +- proxmox - added new module parameter ``tags`` for use with PVE 7+ (https://github.com/ansible-collections/community.general/pull/5714). diff --git a/plugins/modules/proxmox.py b/plugins/modules/proxmox.py index 89706655f2..640f9b4114 100644 --- a/plugins/modules/proxmox.py +++ b/plugins/modules/proxmox.py @@ -106,6 +106,14 @@ options: description: - sets DNS search domain for a container type: str + tags: + description: + - List of tags to apply to the container. + - Tags must start with C([a-z0-9_]) followed by zero or more of the following characters C([a-z0-9_-+.]). + - Tags are only available in Proxmox 7+. + type: list + elements: str + version_added: 6.2.0 timeout: description: - timeout for operations @@ -391,6 +399,7 @@ EXAMPLES = r''' state: absent ''' +import re import time from ansible_collections.community.general.plugins.module_utils.version import LooseVersion @@ -415,11 +424,25 @@ class ProxmoxLxcAnsible(ProxmoxAnsible): return config['template'] def create_instance(self, vmid, node, disk, storage, cpus, memory, swap, timeout, clone, **kwargs): + + # Version limited features + minimum_version = { + 'tags': 7, + } proxmox_node = self.proxmox_api.nodes(node) # Remove all empty kwarg entries kwargs = dict((k, v) for k, v in kwargs.items() if v is not None) + version = self.version() + pve_major_version = 3 if version < LooseVersion('4.0') else version.version[0] + + # Fail on unsupported features + for option, version in minimum_version.items(): + if pve_major_version < version and option in kwargs: + self.module.fail_json(changed=False, msg="Feature {option} is only supported in PVE {version}+, and you're using PVE {pve_major_version}". + format(option=option, version=version, pve_major_version=pve_major_version)) + if VZ_TYPE == 'lxc': kwargs['cpulimit'] = cpus kwargs['rootfs'] = disk @@ -437,6 +460,14 @@ class ProxmoxLxcAnsible(ProxmoxAnsible): kwargs['cpus'] = cpus kwargs['disk'] = disk + # LXC tags are expected to be valid and presented as a comma/semi-colon delimited string + if 'tags' in kwargs: + re_tag = re.compile(r'^[a-z0-9_][a-z0-9_\-\+\.]*$') + for tag in kwargs['tags']: + if not re_tag.match(tag): + self.module.fail_json(msg='%s is not a valid tag' % tag) + kwargs['tags'] = ",".join(kwargs['tags']) + if clone is not None: if VZ_TYPE != 'lxc': self.module.fail_json(changed=False, msg="Clone operator is only supported for LXC enabled proxmox clusters.") @@ -569,6 +600,7 @@ def main(): proxmox_default_behavior=dict(type='str', default='no_defaults', choices=['compatibility', 'no_defaults']), clone=dict(type='int'), clone_type=dict(default='opportunistic', choices=['full', 'linked', 'opportunistic']), + tags=dict(type='list', elements='str') ) module_args.update(proxmox_args) @@ -674,7 +706,8 @@ def main(): features=",".join(module.params['features']) if module.params['features'] is not None else None, unprivileged=ansible_to_proxmox_bool(module.params['unprivileged']), description=module.params['description'], - hookscript=module.params['hookscript']) + hookscript=module.params['hookscript'], + tags=module.params['tags']) module.exit_json(changed=True, msg="Deployed VM %s from template %s" % (vmid, module.params['ostemplate'])) except Exception as e: