ansible  2.9.27
About: Ansible is an IT Configuration Management, Deployment \
About: Ansible (2.x) is an IT Configuration Management, Deployment & Orchestration tool.
ansible download page.
  Fossies Dox: ansible-2.9.27.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

aci_aaa_user.py
Go to the documentation of this file.
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4# Copyright: (c) 2018, Dag Wieers (dagwieers) <dag@wieers.com>
5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6
7from __future__ import absolute_import, division, print_function
8__metaclass__ = type
9
10ANSIBLE_METADATA = {'metadata_version': '1.1',
11 'status': ['preview'],
12 'supported_by': 'certified'}
13
14DOCUMENTATION = r'''
15---
16module: aci_aaa_user
17short_description: Manage AAA users (aaa:User)
18description:
19- Manage AAA users on Cisco ACI fabrics.
20requirements:
21- python-dateutil
22version_added: '2.5'
23options:
24 aaa_password:
25 description:
26 - The password of the locally-authenticated user.
27 type: str
28 aaa_password_lifetime:
29 description:
30 - The lifetime of the locally-authenticated user password.
31 type: int
32 aaa_password_update_required:
33 description:
34 - Whether this account needs password update.
35 type: bool
36 aaa_user:
37 description:
38 - The name of the locally-authenticated user user to add.
39 type: str
40 aliases: [ name, user ]
41 clear_password_history:
42 description:
43 - Whether to clear the password history of a locally-authenticated user.
44 type: bool
45 description:
46 description:
47 - Description for the AAA user.
48 type: str
49 aliases: [ descr ]
50 email:
51 description:
52 - The email address of the locally-authenticated user.
53 type: str
54 enabled:
55 description:
56 - The status of the locally-authenticated user account.
57 type: bool
58 expiration:
59 description:
60 - The expiration date of the locally-authenticated user account.
61 type: str
62 expires:
63 description:
64 - Whether to enable an expiration date for the locally-authenticated user account.
65 type: bool
66 first_name:
67 description:
68 - The first name of the locally-authenticated user.
69 type: str
70 last_name:
71 description:
72 - The last name of the locally-authenticated user.
73 type: str
74 phone:
75 description:
76 - The phone number of the locally-authenticated user.
77 type: str
78 state:
79 description:
80 - Use C(present) or C(absent) for adding or removing.
81 - Use C(query) for listing an object or multiple objects.
82 type: str
83 choices: [ absent, present, query ]
84 default: present
85extends_documentation_fragment: aci
86notes:
87- This module is not idempotent when C(aaa_password) is being used
88 (even if that password was already set identically). This
89 appears to be an inconsistency wrt. the idempotent nature
90 of the APIC REST API. The vendor has been informed.
91 More information in :ref:`the ACI documentation <aci_guide_known_issues>`.
92seealso:
93- module: aci_aaa_user_certificate
94- name: APIC Management Information Model reference
95 description: More information about the internal APIC class B(aaa:User).
96 link: https://developer.cisco.com/docs/apic-mim-ref/
97author:
98- Dag Wieers (@dagwieers)
99'''
100
101EXAMPLES = r'''
102- name: Add a user
103 aci_aaa_user:
104 host: apic
105 username: admin
106 password: SomeSecretPassword
107 aaa_user: dag
108 aaa_password: AnotherSecretPassword
109 expiration: never
110 expires: no
111 email: dag@wieers.com
112 phone: 1-234-555-678
113 first_name: Dag
114 last_name: Wieers
115 state: present
116 delegate_to: localhost
117
118- name: Remove a user
119 aci_aaa_user:
120 host: apic
121 username: admin
122 password: SomeSecretPassword
123 aaa_user: dag
124 state: absent
125 delegate_to: localhost
126
127- name: Query a user
128 aci_aaa_user:
129 host: apic
130 username: admin
131 password: SomeSecretPassword
132 aaa_user: dag
133 state: query
134 delegate_to: localhost
135 register: query_result
136
137- name: Query all users
138 aci_aaa_user:
139 host: apic
140 username: admin
141 password: SomeSecretPassword
142 state: query
143 delegate_to: localhost
144 register: query_result
145'''
146
147RETURN = r'''
148current:
149 description: The existing configuration from the APIC after the module has finished
150 returned: success
151 type: list
152 sample:
153 [
154 {
155 "fvTenant": {
156 "attributes": {
157 "descr": "Production environment",
158 "dn": "uni/tn-production",
159 "name": "production",
160 "nameAlias": "",
161 "ownerKey": "",
162 "ownerTag": ""
163 }
164 }
165 }
166 ]
167error:
168 description: The error information as returned from the APIC
169 returned: failure
170 type: dict
171 sample:
172 {
173 "code": "122",
174 "text": "unknown managed object class foo"
175 }
176raw:
177 description: The raw output returned by the APIC REST API (xml or json)
178 returned: parse error
179 type: str
180 sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
181sent:
182 description: The actual/minimal configuration pushed to the APIC
183 returned: info
184 type: list
185 sample:
186 {
187 "fvTenant": {
188 "attributes": {
189 "descr": "Production environment"
190 }
191 }
192 }
193previous:
194 description: The original configuration from the APIC before the module has started
195 returned: info
196 type: list
197 sample:
198 [
199 {
200 "fvTenant": {
201 "attributes": {
202 "descr": "Production",
203 "dn": "uni/tn-production",
204 "name": "production",
205 "nameAlias": "",
206 "ownerKey": "",
207 "ownerTag": ""
208 }
209 }
210 }
211 ]
212proposed:
213 description: The assembled configuration from the user-provided parameters
214 returned: info
215 type: dict
216 sample:
217 {
218 "fvTenant": {
219 "attributes": {
220 "descr": "Production environment",
221 "name": "production"
222 }
223 }
224 }
225filter_string:
226 description: The filter string used for the request
227 returned: failure or debug
228 type: str
229 sample: '?rsp-prop-include=config-only'
230method:
231 description: The HTTP method used for the request to the APIC
232 returned: failure or debug
233 type: str
234 sample: POST
235response:
236 description: The HTTP response from the APIC
237 returned: failure or debug
238 type: str
239 sample: OK (30 bytes)
240status:
241 description: The HTTP status from the APIC
242 returned: failure or debug
243 type: int
244 sample: 200
245url:
246 description: The HTTP url used for the request to the APIC
247 returned: failure or debug
248 type: str
249 sample: https://10.11.12.13/api/mo/uni/tn-production.json
250'''
251
252try:
253 from dateutil.tz import tzutc
254 import dateutil.parser
255 HAS_DATEUTIL = True
256except ImportError:
257 HAS_DATEUTIL = False
258
259from ansible.module_utils.basic import AnsibleModule
260from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
261
262
263def main():
264 argument_spec = aci_argument_spec()
265 argument_spec.update(
266 aaa_password=dict(type='str', no_log=True),
267 aaa_password_lifetime=dict(type='int'),
268 aaa_password_update_required=dict(type='bool'),
269 aaa_user=dict(type='str', aliases=['name']), # Not required for querying all objects
270 clear_password_history=dict(type='bool'),
271 description=dict(type='str', aliases=['descr']),
272 email=dict(type='str'),
273 enabled=dict(type='bool'),
274 expiration=dict(type='str'),
275 expires=dict(type='bool'),
276 first_name=dict(type='str'),
277 last_name=dict(type='str'),
278 phone=dict(type='str'),
279 state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
280 )
281
282 module = AnsibleModule(
283 argument_spec=argument_spec,
284 supports_check_mode=True,
285 required_if=[
286 ['state', 'absent', ['aaa_user']],
287 ['state', 'present', ['aaa_user']],
288 ['expires', True, ['expiration']],
289 ],
290 )
291
292 aci = ACIModule(module)
293
294 if not HAS_DATEUTIL:
295 module.fail_json(msg='dateutil required for this module')
296
297 aaa_password = module.params['aaa_password']
298 aaa_password_lifetime = module.params['aaa_password_lifetime']
299 aaa_password_update_required = aci.boolean(module.params['aaa_password_update_required'])
300 aaa_user = module.params['aaa_user']
301 clear_password_history = aci.boolean(module.params['clear_password_history'], 'yes', 'no')
302 description = module.params['description']
303 email = module.params['email']
304 enabled = aci.boolean(module.params['enabled'], 'active', 'inactive')
305 expires = aci.boolean(module.params['expires'])
306 first_name = module.params['first_name']
307 last_name = module.params['last_name']
308 phone = module.params['phone']
309 state = module.params['state']
310
311 expiration = module.params['expiration']
312 if expiration is not None and expiration != 'never':
313 try:
314 expiration = aci.iso8601_format(dateutil.parser.parse(expiration).replace(tzinfo=tzutc()))
315 except Exception as e:
316 module.fail_json(msg="Failed to parse date format '%s', %s" % (module.params['expiration'], e))
317
318 aci.construct_url(
319 root_class=dict(
320 aci_class='aaaUser',
321 aci_rn='userext/user-{0}'.format(aaa_user),
322 module_object=aaa_user,
323 target_filter={'name': aaa_user},
324 ),
325 )
326 aci.get_existing()
327
328 if state == 'present':
329 aci.payload(
330 aci_class='aaaUser',
331 class_config=dict(
332 accountStatus=enabled,
333 clearPwdHistory=clear_password_history,
334 descr=description,
335 email=email,
336 expiration=expiration,
337 expires=expires,
338 firstName=first_name,
339 lastName=last_name,
340 name=aaa_user,
341 phone=phone,
342 pwd=aaa_password,
343 pwdLifeTime=aaa_password_lifetime,
344 pwdUpdateRequired=aaa_password_update_required,
345 ),
346 )
347
348 aci.get_diff(aci_class='aaaUser')
349
350 aci.post_config()
351
352 elif state == 'absent':
353 aci.delete_config()
354
355 aci.exit_json()
356
357
358if __name__ == "__main__":
359 main()