Skip to content

Commit 0925560

Browse files
committed
Release 1.6.8
Merge branch 'develop' into master
2 parents 0726f60 + 2c0f021 commit 0925560

22 files changed

+577
-363
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
---
12
ko_fi: sleepingkyoto
23
custom:
34
- "https://monappy.jp/u/lae"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99

1010
fetch/
1111
.vagrant/
12+
/.settings/

.travis.yml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,25 @@
11
---
22
language: python
3-
python:
4-
- "2.7"
5-
- "3.6"
63
sudo: required
74
dist: bionic
85
cache:
96
directories: [ '$HOME/lxc' ]
107
pip: true
11-
env:
12-
- ANSIBLE_VERSION='~=2.9.0'
138
matrix:
149
fast_finish: true
1510
include:
1611
# FIXME: Ansible 2.10.x going through major restructuring.
1712
# https://groups.google.com/forum/#!msg/ansible-project/eXsoOKEd0Mk/XTgbnPWbCAAJ
18-
# - python: '3.6'
19-
# env: ANSIBLE_GIT_VERSION='devel' # 2.10.x development branch
20-
- python: '3.6'
21-
env: ANSIBLE_VERSION='~=2.8.0'
22-
- python: '3.6'
23-
env: ANSIBLE_VERSION='~=2.7.0'
13+
# - env: ANSIBLE_GIT_VERSION='devel' # 2.11.x development branch
14+
- env: ANSIBLE_VERSION='~=2.10.0'
15+
- env: ANSIBLE_VERSION='~=2.9.0'
16+
- env: ANSIBLE_VERSION='~=2.8.0'
2417
install:
2518
- if [ "$ANSIBLE_GIT_VERSION" ]; then pip install "https://github.com/ansible/ansible/archive/${ANSIBLE_GIT_VERSION}.tar.gz";
2619
else pip install "ansible${ANSIBLE_VERSION}"; fi;
2720
pip install --pre ansible-lint; pip install jmespath netaddr
2821
- ansible --version
29-
- ansible-galaxy install lae.travis-lxc,v0.9.0
22+
- ansible-galaxy install lae.travis-lxc,v0.10.1
3023
- ansible-playbook tests/install.yml -i tests/inventory
3124
- git archive --format tar.gz HEAD > lae.proxmox.tar.gz && ansible-galaxy install
3225
lae.proxmox.tar.gz,$(git rev-parse HEAD),lae.proxmox && rm lae.proxmox.tar.gz

README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ pve_ceph_crush_rules: [] # List of CRUSH rules to create
409409
# pve_ssl_private_key: "" # Should be set to the contents of the private key to use for HTTPS
410410
# pve_ssl_certificate: "" # Should be set to the contents of the certificate to use for HTTPS
411411
pve_ssl_letsencrypt: false # Specifies whether or not to obtain a SSL certificate using Let's Encrypt
412+
pve_roles: [] # Added more roles with specific privileges. See section on User Management.
412413
pve_groups: [] # List of group definitions to manage in PVE. See section on User Management.
413414
pve_users: [] # List of user definitions to manage in PVE. See section on User Management.
414415
pve_storages: [] # List of storages to manage in PVE. See section on Storage Management.
@@ -513,10 +514,19 @@ pve_users:
513514
Refer to `library/proxmox_user.py` [link][user-module] and
514515
`library/proxmox_group.py` [link][group-module] for module documentation.
515516

516-
For managing ACLs, a similar module is employed, but the main difference is that
517-
most of the parameters only accept lists (subject to change):
517+
For managing roles and ACLs, a similar module is employed, but the main
518+
difference is that most of the parameters only accept lists (subject to
519+
change):
518520

519521
```
522+
pve_roles:
523+
- name: Monitoring
524+
privileges:
525+
- "Sys.Modify"
526+
- "Sys.Audit"
527+
- "Datastore.Audit"
528+
- "VM.Monitor"
529+
- "VM.Audit"
520530
pve_acls:
521531
- path: /
522532
roles: [ "Administrator" ]
@@ -529,7 +539,8 @@ pve_acls:
529539
- test_users
530540
```
531541

532-
Refer to `library/proxmox_acl.py` [link][acl-module] for module documentation.
542+
Refer to `library/proxmox_role.py` [link][user-module] and
543+
`library/proxmox_acl.py` [link][acl-module] for module documentation.
533544

534545
## Storage Management
535546

defaults/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ pve_cluster_clustername: "{{ pve_group }}"
3434
pve_datacenter_cfg: {}
3535
pve_cluster_ha_groups: []
3636
pve_ssl_letsencrypt: false
37+
# additional roles for your cluster (f.e. for monitoring)
38+
pve_roles: []
3739
pve_groups: []
3840
pve_users: []
3941
pve_acls: []

files/00_remove_checked_command_buster.patch

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,17 @@ diff -ur /usr/share/pve-manager/js/pvemanagerlib.js /usr/share/pve-manager/js/pv
6464
@@ -33892,7 +33892,7 @@
6565
var version_btn = new Ext.Button({
6666
text: gettext('Package versions'),
67-
handler: function(){
67+
handler: function() {
6868
- Proxmox.Utils.checked_command(function() { me.showVersions(); });
6969
+ me.showVersions();
70-
}
70+
},
7171
});
7272

7373
@@ -45136,7 +45136,6 @@
7474
handler: function(data) {
7575
me.login = null;
7676
me.updateLoginData(data);
7777
- Proxmox.Utils.checked_command(function() {}); // display subscription status
78-
}
78+
},
7979
});
8080
}

library/proxmox_acl.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ def __init__(self, module):
8383
except ProxmoxShellError as e:
8484
self.module.fail_json(msg=e.message, status_code=e.status_code)
8585

86+
# PVE 5.x (unnecessarily) uses a string for this value. This ensures
87+
# that it's an integer for when we compare values later.
88+
for acl in self.existing_acl:
89+
acl['propagate'] = int(acl['propagate'])
90+
8691
self.parse_acls()
8792

8893
def parse_acls(self):
@@ -99,7 +104,7 @@ def parse_acls(self):
99104
for constituent in constituents:
100105
self.acls.append({
101106
"path": self.path,
102-
"propagate": "1", # possibly make this configurable in the module later
107+
"propagate": 1, # possibly make this configurable in the module later
103108
"roleid": role,
104109
"type": constituent[0],
105110
"ugid": constituent[1]

library/proxmox_role.py

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
4+
ANSIBLE_METADATA = {
5+
'metadata_version': '0.1',
6+
'status': ['preview'],
7+
'supported_by': 'lae'
8+
}
9+
10+
DOCUMENTATION = '''
11+
---
12+
module: proxmox_role
13+
short_description: Manages the Access Control List in Proxmox
14+
options:
15+
name:
16+
required: true
17+
description:
18+
- name of the role.
19+
privileges:
20+
required: true
21+
type: list
22+
description:
23+
- Specifies a list of PVE privileges for the given role.
24+
state:
25+
required: false
26+
default: "present"
27+
choices: [ "present", "absent" ]
28+
description:
29+
- Specifies whether this role should exist or not.
30+
author:
31+
- Thoralf Rickert-Wendt (@trickert76)
32+
'''
33+
34+
EXAMPLES = '''
35+
- name: Create a role for monitoring with given privileges
36+
proxmox_role:
37+
name: "monitoring"
38+
privileges: [ "Sys.Modify", "Sys.Audit", "Datastore.Audit", "VM.Monitor", "VM.Audit" ]
39+
'''
40+
41+
RETURN = '''
42+
'''
43+
44+
from ansible.module_utils.basic import AnsibleModule
45+
from ansible.module_utils._text import to_text
46+
from ansible.module_utils.pvesh import ProxmoxShellError
47+
import ansible.module_utils.pvesh as pvesh
48+
49+
class ProxmoxRole(object):
50+
def __init__(self, module):
51+
self.module = module
52+
self.name = module.params['name']
53+
self.privileges = module.params['privileges']
54+
self.state = module.params['state']
55+
56+
try:
57+
self.existing_roles = pvesh.get("access/roles")
58+
except ProxmoxShellError as e:
59+
self.module.fail_json(msg=e.message, status_code=e.status_code)
60+
61+
self.parse_roles()
62+
63+
def parse_roles(self):
64+
self.roles = []
65+
for existing_role in self.existing_roles:
66+
self.roles.append(existing_role.get('roleid'))
67+
68+
def lookup(self):
69+
self.roles = []
70+
for existing_role in self.existing_roles:
71+
if existing_role.get('roleid') == self.name:
72+
args = {}
73+
args['roleid'] = existing_role.get('roleid')
74+
args['privs'] = ','.join(sorted(existing_role.get('privs').split(',')))
75+
return args
76+
77+
return None
78+
79+
def exists(self):
80+
if self.name not in self.roles:
81+
return False
82+
83+
return True
84+
85+
def prepare_role_args(self, appendKey=True):
86+
args = {}
87+
if appendKey:
88+
args['roleid'] = self.name
89+
args['privs'] = ','.join(sorted(self.privileges))
90+
91+
return args
92+
93+
def remove_role(self):
94+
try:
95+
pvesh.delete("access/roles/{}".format(self.name))
96+
return (True, None)
97+
except ProxmoxShellError as e:
98+
return (False, e.message)
99+
100+
def create_role(self):
101+
new_role = self.prepare_role_args()
102+
103+
try:
104+
pvesh.create("access/roles", **new_role)
105+
return (True, None)
106+
except ProxmoxShellError as e:
107+
return (False, e.message)
108+
109+
def modify_role(self):
110+
existing_role = self.lookup()
111+
modified_role = self.prepare_role_args(appendKey=False)
112+
updated_fields = []
113+
error = None
114+
115+
for key in modified_role:
116+
if key not in existing_role:
117+
updated_fields.append(key)
118+
else:
119+
new_value = modified_role.get(key)
120+
old_value = existing_role.get(key)
121+
if isinstance(old_value, list):
122+
old_value = ','.join(sorted(old_value))
123+
if isinstance(new_value, list):
124+
new_value = ','.join(sorted(new_value))
125+
126+
if new_value != old_value:
127+
updated_fields.append(key)
128+
129+
if self.module.check_mode:
130+
self.module.exit_json(changed=bool(updated_fields), expected_changes=updated_fields)
131+
132+
if not updated_fields:
133+
# No changes necessary
134+
return (updated_fields, error)
135+
136+
try:
137+
pvesh.set("access/roles/{}".format(self.name), **modified_role)
138+
except ProxmoxShellError as e:
139+
error = e.message
140+
141+
return (updated_fields, error)
142+
143+
def main():
144+
# Refer to https://pve.proxmox.com/pve-docs/api-viewer/index.html
145+
module = AnsibleModule(
146+
argument_spec = dict(
147+
name=dict(type='str', required=True),
148+
privileges=dict(type='list', required=True),
149+
state=dict(default='present', choices=['present', 'absent'], type='str')
150+
),
151+
supports_check_mode=True
152+
)
153+
154+
role = ProxmoxRole(module)
155+
156+
changed = False
157+
error = None
158+
result = {}
159+
result['name'] = role.name
160+
result['state'] = role.state
161+
result['changed'] = False
162+
163+
if role.state == 'absent':
164+
if role.exists():
165+
if module.check_mode:
166+
module.exit_json(changed=True)
167+
168+
(changed, error) = role.remove_role()
169+
elif role.state == 'present':
170+
if not role.exists():
171+
if module.check_mode:
172+
module.exit_json(changed=True)
173+
174+
(changed, error) = role.create_role()
175+
else:
176+
(updated_fields, error) = role.modify_role()
177+
178+
if updated_fields:
179+
changed = True
180+
result['updated_fields'] = updated_fields
181+
182+
if error is not None:
183+
module.fail_json(name=role.name, msg=error)
184+
185+
result['changed'] = changed
186+
module.exit_json(**result)
187+
188+
if __name__ == '__main__':
189+
main()

meta/main.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
---
12
galaxy_info:
23
author: Musee Ullah
34
description: Installs and configures Proxmox 5.x (for clustering)
@@ -7,10 +8,10 @@ galaxy_info:
78
min_ansible_version: 2.4
89

910
platforms:
10-
- name: Debian
11-
versions:
12-
- stretch
13-
- buster
11+
- name: Debian
12+
versions:
13+
- stretch
14+
- buster
1415

1516
galaxy_tags:
1617
- proxmox

0 commit comments

Comments
 (0)