forked from TerryHowe/ansible-modules-hashivault
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhashivault_userpass.py
148 lines (131 loc) · 5.61 KB
/
hashivault_userpass.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env python
from ansible.module_utils.hashivault import hashivault_argspec
from ansible.module_utils.hashivault import hashivault_auth_client
from ansible.module_utils.hashivault import hashivault_init
from ansible.module_utils.hashivault import hashiwrapper
ANSIBLE_METADATA = {'status': ['stableinterface'], 'supported_by': 'community', 'version': '1.1'}
DOCUMENTATION = '''
---
module: hashivault_userpass
version_added: "3.12.0"
short_description: Hashicorp Vault userpass user management module
description:
- Module to manage userpass users in Hashicorp Vault.
options:
name:
description:
- user name to create.
pass:
description:
- user to create password.
pass_update:
description:
- whether to update the password if user exists
default: False
policies:
description:
- user policies.
default: default
token_bound_cidrs:
description:
- List of CIDR blocks; if set, specifies blocks of IP addresses which can authenticate successfully, and
ties the resulting token to these blocks as well.
state:
description:
- whether create/update or delete the user
mount_point:
description:
- default The "path" (app-id) the auth backend is mounted on.
default: userpass
extends_documentation_fragment: hashivault
'''
EXAMPLES = '''
---
- hosts: localhost
tasks:
- hashivault_userpass:
name: 'bob'
pass: 'S3cre7s'
policies: 'bob'
'''
def main():
argspec = hashivault_argspec()
argspec['name'] = dict(required=True, type='str')
argspec['pass'] = dict(required=False, type='str', default=None, no_log=True)
argspec['pass_update'] = dict(required=False, type='bool', default=False, no_log=True)
argspec['policies'] = dict(required=False, type='list', default=[])
argspec['token_bound_cidrs'] = dict(required=False, type='list', default=[])
argspec['state'] = dict(required=False, choices=['present', 'absent'], default='present')
argspec['mount_point'] = dict(required=False, type='str', default='userpass')
module = hashivault_init(argspec)
result = hashivault_userpass(module.params)
if result.get('failed'):
module.fail_json(**result)
else:
module.exit_json(**result)
def hashivault_userpass_update(client, user_details, user_name, user_pass, user_pass_update, user_policies,
mount_point, token_bound_cidrs):
policies_changed = False
token_bound_cidrs_changed = False
password_change_allowed = user_pass_update and user_pass
if set(user_details['data'].get('policies', [])) != set(user_policies):
policies_changed = True
if set(user_details['data'].get('token_bound_cidrs', [])) != set(token_bound_cidrs):
token_bound_cidrs_changed = True
attribute_changed = policies_changed or token_bound_cidrs_changed
if password_change_allowed and not attribute_changed:
client.auth.userpass.update_password_on_user(user_name, user_pass, mount_point=mount_point)
return {'changed': True}
if password_change_allowed and attribute_changed:
client.auth.userpass.create_or_update_user(user_name, user_pass, user_policies, mount_point=mount_point,
token_bound_cidrs=token_bound_cidrs)
return {'changed': True}
if not password_change_allowed and attribute_changed:
if token_bound_cidrs_changed:
err_msg = u"token_bound_cidrs can only be changed if user_pass is specified and user_pass_update is True"
return {
'rc': 1,
'failed': True,
'msg': err_msg
}
if policies_changed:
client.auth.userpass.create_or_update_user(user_name, policies=user_policies, mount_point=mount_point)
return {'changed': True}
return {'changed': False}
@hashiwrapper
def hashivault_userpass(params):
client = hashivault_auth_client(params)
state = params.get('state')
name = params.get('name')
password = params.get('pass')
password_update = params.get('pass_update')
policies = params.get('policies')
token_bound_cidrs = params.get('token_bound_cidrs')
mount_point = params.get('mount_point')
if state == 'present':
try:
user_details = client.auth.userpass.read_user(name, mount_point=mount_point)
except Exception:
if password is not None:
client.auth.userpass.create_or_update_user(name, password, policies,
token_bound_cidrs=token_bound_cidrs,
mount_point=mount_point)
return {'changed': True}
else:
return {'failed': True, 'msg': 'pass must be provided for new users'}
else:
return hashivault_userpass_update(client, user_details, user_name=name, user_pass=password,
user_pass_update=password_update, user_policies=policies,
mount_point=mount_point, token_bound_cidrs=token_bound_cidrs)
elif state == 'absent':
try:
client.auth.userpass.read_user(name, mount_point=mount_point)
except Exception:
return {'changed': False}
else:
client.auth.userpass.delete_user(name, mount_point=mount_point)
return {'changed': True}
else:
return {'failed': True, 'msg': 'Unkown state type'}
if __name__ == '__main__':
main()