Skip to content

Commit 2a156c8

Browse files
new module: proxmox_group: management of user groups (#126)
* Initial version of module * Fix sanity issues * Added version_added * update runtime * Update author
1 parent af7063d commit 2a156c8

File tree

2 files changed

+170
-1
lines changed

2 files changed

+170
-1
lines changed

meta/runtime.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ action_groups:
1414
- proxmox_backup_schedule
1515
- proxmox_cluster
1616
- proxmox_cluster_ha_resources
17-
- proxmox_cluster_ha_groups
17+
- proxmox_cluster_ha_groups
1818
- proxmox_cluster_join_info
1919
- proxmox_disk
2020
- proxmox_domain_info
21+
- proxmox_group
2122
- proxmox_group_info
2223
- proxmox_kvm
2324
- proxmox_nic

plugins/modules/proxmox_group.py

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
#
4+
# Copyright (c) 2025, Jeffrey van Pelt (@Thulium-Drake) <[email protected]>
5+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
6+
# SPDX-FileCopyrightText: (c) 2025, Jeffrey van Pelt (Thulium-Drake) <[email protected]>
7+
# SPDX-License-Identifier: GPL-3.0-or-later
8+
from __future__ import (absolute_import, division, print_function)
9+
__metaclass__ = type
10+
11+
DOCUMENTATION = r"""
12+
module: proxmox_group
13+
short_description: Group management for Proxmox VE cluster
14+
description:
15+
- Create or delete a user group for Proxmox VE clusters.
16+
author: "Jeffrey van Pelt (@Thulium-Drake) <[email protected]>"
17+
version_added: "1.2.0"
18+
attributes:
19+
check_mode:
20+
support: full
21+
diff_mode:
22+
support: none
23+
options:
24+
groupid:
25+
description:
26+
- The group name.
27+
type: str
28+
aliases: ["name"]
29+
required: true
30+
state:
31+
description:
32+
- Indicate desired state of the group.
33+
choices: ['present', 'absent']
34+
default: present
35+
type: str
36+
comment:
37+
description:
38+
- Specify the description for the group.
39+
- Parameter is ignored when group already exists or O(state=absent).
40+
type: str
41+
42+
extends_documentation_fragment:
43+
- community.proxmox.proxmox.actiongroup_proxmox
44+
- community.proxmox.proxmox.documentation
45+
- community.proxmox.attributes
46+
"""
47+
48+
EXAMPLES = r"""
49+
- name: Create new Proxmox VE user group
50+
community.proxmox.proxmox_group:
51+
api_host: node1
52+
api_user: root@pam
53+
api_password: password
54+
name: administrators
55+
comment: IT Admins
56+
57+
- name: Delete a Proxmox VE user group
58+
community.proxmox.proxmox_group:
59+
api_host: node1
60+
api_user: root@pam
61+
api_password: password
62+
name: administrators
63+
state: absent
64+
"""
65+
66+
RETURN = r"""
67+
groupid:
68+
description: The group name.
69+
returned: success
70+
type: str
71+
sample: test
72+
msg:
73+
description: A short message on what the module did.
74+
returned: always
75+
type: str
76+
sample: "Group administrators successfully created"
77+
"""
78+
79+
from ansible.module_utils.basic import AnsibleModule
80+
from ansible_collections.community.proxmox.plugins.module_utils.proxmox import (proxmox_auth_argument_spec, ProxmoxAnsible)
81+
82+
83+
class ProxmoxGroupAnsible(ProxmoxAnsible):
84+
85+
def is_group_existing(self, groupid):
86+
"""Check whether group already exist
87+
88+
:param groupid: str - name of the group
89+
:return: bool - is group exists?
90+
"""
91+
try:
92+
groups = self.proxmox_api.access.groups.get()
93+
for group in groups:
94+
if group['groupid'] == groupid:
95+
return True
96+
return False
97+
except Exception as e:
98+
self.module.fail_json(msg="Unable to retrieve groups: {0}".format(e))
99+
100+
def create_group(self, groupid, comment=None):
101+
"""Create Proxmox VE group
102+
103+
:param groupid: str - name of the group
104+
:param comment: str, optional - Description of a group
105+
:return: None
106+
"""
107+
if self.is_group_existing(groupid):
108+
self.module.exit_json(changed=False, groupid=groupid, msg="Group {0} already exists".format(groupid))
109+
110+
if self.module.check_mode:
111+
return
112+
113+
try:
114+
self.proxmox_api.access.groups.post(groupid=groupid, comment=comment)
115+
except Exception as e:
116+
self.module.fail_json(msg="Failed to create group with ID {0}: {1}".format(groupid, e))
117+
118+
def delete_group(self, groupid):
119+
"""Delete Proxmox VE group
120+
121+
:param groupid: str - name of the group
122+
:return: None
123+
"""
124+
if not self.is_group_existing(groupid):
125+
self.module.exit_json(changed=False, groupid=groupid, msg="Group {0} doesn't exist".format(groupid))
126+
127+
if self.module.check_mode:
128+
return
129+
130+
try:
131+
self.proxmox_api.access.groups(groupid).delete()
132+
except Exception as e:
133+
self.module.fail_json(msg="Failed to delete group with ID {0}: {1}".format(groupid, e))
134+
135+
136+
def main():
137+
module_args = proxmox_auth_argument_spec()
138+
groups_args = dict(
139+
groupid=dict(type="str", aliases=["name"], required=True),
140+
comment=dict(type="str"),
141+
state=dict(default="present", choices=["present", "absent"]),
142+
)
143+
144+
module_args.update(groups_args)
145+
146+
module = AnsibleModule(
147+
argument_spec=module_args,
148+
required_together=[("api_token_id", "api_token_secret")],
149+
required_one_of=[("api_password", "api_token_id")],
150+
supports_check_mode=True
151+
)
152+
153+
groupid = module.params["groupid"]
154+
comment = module.params["comment"]
155+
state = module.params["state"]
156+
157+
proxmox = ProxmoxGroupAnsible(module)
158+
159+
if state == "present":
160+
proxmox.create_group(groupid, comment)
161+
module.exit_json(changed=True, groupid=groupid, msg="Group {0} successfully created".format(groupid))
162+
else:
163+
proxmox.delete_group(groupid)
164+
module.exit_json(changed=True, groupid=groupid, msg="Group {0} successfully deleted".format(groupid))
165+
166+
167+
if __name__ == "__main__":
168+
main()

0 commit comments

Comments
 (0)