blob: 285269f8b673d4753ac97924f0e887c7e6039584 [file] [log] [blame]
David K. Bainbridge6e23ac82016-12-07 12:55:41 -08001#!/usr/bin/python
2
3DOCUMENTATION = '''
4---
5module: maas_user
6short_description: Manage MAAS Clusters Interfaces
7options:
8 maas:
9 description:
10 - URL of MAAS server
11 default: http://localhost/MAAS/api/1.0/
12 key:
13 description:
14 - MAAS API key
15 required: yes
16 name:
17 description:
18 - name of the user
19 required: yes
20 email:
21 description:
22 - email address of the user
23 required: no
24 password:
25 description:
26 - password for the user
27 required: no
28 is_superuser:
29 description:
30 - does the user have priviledges
31 default: no
32 state:
33 description:
34 - possible states for this user
35 choices: ['present', 'absent', 'query']
36 default: present
37
38requirements: [ipaddress, requests_oauthlib, maasclient]
39author: David Bainbridge
40'''
41
42EXAMPLES = '''
43examples:
44 maas_user:
45 maas: http://my.maas.server.com/MAAS/api/1.0/
46 key: 'xBvr9dx5k7S52myufC:fqBXV7hJgXegNZDw9c:K8hsmL47XjAppfQy2pDVW7G49p6PELgp'
47 name: MyUser
48 email: user@company.com
49 password: donttell
50 is_superuser: no
51 state: present
52
53 maas_user:
54 maas: http://my.maas.server.com/MAAS/api/1.0/
55 key: 'xBvr9dx5k7S52myufC:fqBXV7hJgXegNZDw9c:K8hsmL47XjAppfQy2pDVW7G49p6PELgp'
56 name: MyDeadUser
57 state: absent
58'''
59
60import sys
61import json
62import ipaddress
63import requests
64from maasclient.auth import MaasAuth
65from maasclient import MaasClient
66
67# For some reason the maasclient doesn't provide a put method. So
68# we will add it here
69def put(client, url, params=None):
70 return requests.put(url=client.auth.api_url + url,
71 auth=client._oauth(), data=params)
72
73# Attempt to interpret the given value as a JSON object, if that fails
74# just return it as a string
75def string_or_object(val):
76 try:
77 return json.loads(val)
78 except:
79 return val
80
81# Return a copy of the given dictionary with any `null` valued entries
82# removed
83def remove_null(d_in):
84 d = d_in.copy()
85 to_remove = []
86 for k in d.keys():
87 if d[k] == None:
88 to_remove.append(k)
89 for k in to_remove:
90 del d[k]
91 return d
92
93# Deterine if two dictionaries are different
94def different(have, want):
95 have_keys = have.keys()
96 for key in want.keys():
97 if (key in have_keys and want[key] != have[key]) or key not in have_keys:
98 return True
99 return False
100
101# Get an user from MAAS using its name, if not found return None
102def get_user(maas, name):
103 res = maas.get('/users/%s/' % name)
104 if res.ok:
105 return json.loads(res.text)
106 return None
107
108# Create an user based on the value given
109def create_user(maas, user):
110 merged = user.copy()
111 # merged['op'] = 'new'
112 res = maas.post('/users/', merged)
113 if res.ok:
114 return { 'error': False, 'status': get_user(maas, merged['username']) }
115 return { 'error': True, 'status': string_or_object(res.text) }
116
117# Delete an user based on the name
118def delete_user(maas, name):
119 res = maas.delete('/users/%s/' % name)
120 if res.ok:
121 return { 'error': False }
122 return { 'error': True, 'status': string_or_object(res.text) }
123
124def main():
125 module = AnsibleModule(
126 argument_spec = dict(
127 maas=dict(default='http://localhost/MAAS/api/1.0/'),
128 key=dict(required=True),
129 name=dict(required=True),
130 email=dict(required=False),
131 password=dict(required=False),
132 is_superuser=dict(default=False, type='bool'),
133 state=dict(default='present', choices=['present', 'absent', 'query'])
134 ),
135 supports_check_mode = False
136 )
137
138 maas = module.params['maas']
139 key = module.params['key']
140 state = module.params['state']
141
142 # Construct a sparsely populate desired state
143 desired = remove_null({
144 'username': module.params['name'],
145 'email': module.params['email'],
146 'password': module.params['password'],
147 'is_superuser': 0 if not module.params['is_superuser'] else 1
148 })
149
150 # Authenticate into MAAS
151 auth = MaasAuth(maas, key)
152 maas = MaasClient(auth)
153
154 # Attempt to get the user from MAAS
155 user = get_user(maas, desired['username'])
156
157 # Actions if the user does not currently exist
158 if not user:
159 if state == 'query':
160 # If this is a query, returne it is not found
161 module.exit_json(changed=False, found=False)
162 elif state == 'present':
163 # If this should be present, then attempt to create it
164 res = create_user(maas, desired)
165 if res['error']:
166 module.fail_json(msg=res['status'])
167 else:
168 module.exit_json(changed=True, user=res['status'])
169 else:
170 # If this should be absent, then we are done and in the desired state
171 module.exit_json(changed=False)
172
173 # Done with users does not exists actions
174 return
175
176 # Actions if the user does exist
177 if state == 'query':
178 # If this is a query, return the user
179 module.exit_json(changed=False, found=True, user=user)
180 elif state == 'present':
181 # If we want this to exists check to see if this is different and
182 # needs updated
183 if different(user, desired):
184 module.fail_json(msg='Specified user, "%s", exists and MAAS does not allow the user to be modified programatically'
185 % user['username'])
186 else:
187 # No differences, to nothing to change
188 module.exit_json(changed=False, user=user)
189 else:
190 # If we don't want this user, then delete it
191 res = delete_user(maas, user['username'])
192 if res['error']:
193 module.fail_json(msg=res['status'])
194 else:
195 module.exit_json(changed=True, user=user)
196
197# this is magic, see lib/ansible/module_common.py
198#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
199if __name__ == '__main__':
200 main()