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_domain.py
Go to the documentation of this file.
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5
6from __future__ import absolute_import, division, print_function
7__metaclass__ = type
8
9ANSIBLE_METADATA = {'metadata_version': '1.1',
10 'status': ['preview'],
11 'supported_by': 'certified'}
12
13DOCUMENTATION = r'''
14---
15module: aci_domain
16short_description: Manage physical, virtual, bridged, routed or FC domain profiles (phys:DomP, vmm:DomP, l2ext:DomP, l3ext:DomP, fc:DomP)
17description:
18- Manage physical, virtual, bridged, routed or FC domain profiles on Cisco ACI fabrics.
19version_added: '2.5'
20options:
21 domain:
22 description:
23 - Name of the physical, virtual, bridged routed or FC domain profile.
24 type: str
25 aliases: [ domain_name, domain_profile, name ]
26 domain_type:
27 description:
28 - The type of domain profile.
29 - 'C(fc): The FC domain profile is a policy pertaining to single FC Management domain'
30 - 'C(l2dom): The external bridged domain profile is a policy for managing L2 bridged infrastructure bridged outside the fabric.'
31 - 'C(l3dom): The external routed domain profile is a policy for managing L3 routed infrastructure outside the fabric.'
32 - 'C(phys): The physical domain profile stores the physical resources and encap resources that should be used for EPGs associated with this domain.'
33 - 'C(vmm): The VMM domain profile is a policy for grouping VM controllers with similar networking policy requirements.'
34 type: str
35 choices: [ fc, l2dom, l3dom, phys, vmm ]
36 aliases: [ type ]
37 dscp:
38 description:
39 - The target Differentiated Service (DSCP) value.
40 - The APIC defaults to C(unspecified) when unset during creation.
41 type: str
42 choices: [ AF11, AF12, AF13, AF21, AF22, AF23, AF31, AF32, AF33, AF41, AF42, AF43, CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7, EF, VA, unspecified ]
43 aliases: [ target ]
44 encap_mode:
45 description:
46 - The layer 2 encapsulation protocol to use with the virtual switch.
47 type: str
48 choices: [ unknown, vlan, vxlan ]
49 multicast_address:
50 description:
51 - The multicast IP address to use for the virtual switch.
52 type: str
53 state:
54 description:
55 - Use C(present) or C(absent) for adding or removing.
56 - Use C(query) for listing an object or multiple objects.
57 type: str
58 choices: [ absent, present, query ]
59 default: present
60 vm_provider:
61 description:
62 - The VM platform for VMM Domains.
63 - Support for Kubernetes was added in ACI v3.0.
64 - Support for CloudFoundry, OpenShift and Red Hat was added in ACI v3.1.
65 type: str
66 choices: [ cloudfoundry, kubernetes, microsoft, openshift, openstack, redhat, vmware ]
67 vswitch:
68 description:
69 - The virtual switch to use for vmm domains.
70 - The APIC defaults to C(default) when unset during creation.
71 type: str
72 choices: [ avs, default, dvs, unknown ]
73extends_documentation_fragment: aci
74seealso:
75- module: aci_aep_to_domain
76- module: aci_domain_to_encap_pool
77- module: aci_domain_to_vlan_pool
78- name: APIC Management Information Model reference
79 description: More information about the internal APIC classes B(phys:DomP),
80 B(vmm:DomP), B(l2ext:DomP), B(l3ext:DomP) and B(fc:DomP)
81 link: https://developer.cisco.com/docs/apic-mim-ref/
82author:
83- Dag Wieers (@dagwieers)
84'''
85
86EXAMPLES = r'''
87- name: Add a new physical domain
88 aci_domain:
89 host: apic
90 username: admin
91 password: SomeSecretPassword
92 domain: phys_dom
93 domain_type: phys
94 state: present
95
96- name: Remove a physical domain
97 aci_domain:
98 host: apic
99 username: admin
100 password: SomeSecretPassword
101 domain: phys_dom
102 domain_type: phys
103 state: absent
104
105- name: Add a new VMM domain
106 aci_domain:
107 host: apic
108 username: admin
109 password: SomeSecretPassword
110 domain: hyperv_dom
111 domain_type: vmm
112 vm_provider: microsoft
113 state: present
114 delegate_to: localhost
115
116- name: Remove a VMM domain
117 aci_domain:
118 host: apic
119 username: admin
120 password: SomeSecretPassword
121 domain: hyperv_dom
122 domain_type: vmm
123 vm_provider: microsoft
124 state: absent
125 delegate_to: localhost
126
127- name: Query a specific physical domain
128 aci_domain:
129 host: apic
130 username: admin
131 password: SomeSecretPassword
132 domain: phys_dom
133 domain_type: phys
134 state: query
135 delegate_to: localhost
136 register: query_result
137
138- name: Query all domains
139 aci_domain:
140 host: apic
141 username: admin
142 password: SomeSecretPassword
143 domain_type: phys
144 state: query
145 delegate_to: localhost
146 register: query_result
147'''
148
149RETURN = r'''
150current:
151 description: The existing configuration from the APIC after the module has finished
152 returned: success
153 type: list
154 sample:
155 [
156 {
157 "fvTenant": {
158 "attributes": {
159 "descr": "Production environment",
160 "dn": "uni/tn-production",
161 "name": "production",
162 "nameAlias": "",
163 "ownerKey": "",
164 "ownerTag": ""
165 }
166 }
167 }
168 ]
169error:
170 description: The error information as returned from the APIC
171 returned: failure
172 type: dict
173 sample:
174 {
175 "code": "122",
176 "text": "unknown managed object class foo"
177 }
178raw:
179 description: The raw output returned by the APIC REST API (xml or json)
180 returned: parse error
181 type: str
182 sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
183sent:
184 description: The actual/minimal configuration pushed to the APIC
185 returned: info
186 type: list
187 sample:
188 {
189 "fvTenant": {
190 "attributes": {
191 "descr": "Production environment"
192 }
193 }
194 }
195previous:
196 description: The original configuration from the APIC before the module has started
197 returned: info
198 type: list
199 sample:
200 [
201 {
202 "fvTenant": {
203 "attributes": {
204 "descr": "Production",
205 "dn": "uni/tn-production",
206 "name": "production",
207 "nameAlias": "",
208 "ownerKey": "",
209 "ownerTag": ""
210 }
211 }
212 }
213 ]
214proposed:
215 description: The assembled configuration from the user-provided parameters
216 returned: info
217 type: dict
218 sample:
219 {
220 "fvTenant": {
221 "attributes": {
222 "descr": "Production environment",
223 "name": "production"
224 }
225 }
226 }
227filter_string:
228 description: The filter string used for the request
229 returned: failure or debug
230 type: str
231 sample: ?rsp-prop-include=config-only
232method:
233 description: The HTTP method used for the request to the APIC
234 returned: failure or debug
235 type: str
236 sample: POST
237response:
238 description: The HTTP response from the APIC
239 returned: failure or debug
240 type: str
241 sample: OK (30 bytes)
242status:
243 description: The HTTP status from the APIC
244 returned: failure or debug
245 type: int
246 sample: 200
247url:
248 description: The HTTP url used for the request to the APIC
249 returned: failure or debug
250 type: str
251 sample: https://10.11.12.13/api/mo/uni/tn-production.json
252'''
253
254from ansible.module_utils.basic import AnsibleModule
255from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
256
257VM_PROVIDER_MAPPING = dict(
258 cloudfoundry='CloudFoundry',
259 kubernetes='Kubernetes',
260 microsoft='Microsoft',
261 openshift='OpenShift',
262 openstack='OpenStack',
263 redhat='Redhat',
264 vmware='VMware',
265)
266
267VSWITCH_MAPPING = dict(
268 avs='n1kv',
269 default='default',
270 dvs='default',
271 unknown='unknown',
272)
273
274
275def main():
276 argument_spec = aci_argument_spec()
277 argument_spec.update(
278 domain_type=dict(type='str', required=True, choices=['fc', 'l2dom', 'l3dom', 'phys', 'vmm'], aliases=['type']),
279 domain=dict(type='str', aliases=['domain_name', 'domain_profile', 'name']), # Not required for querying all objects
280 dscp=dict(type='str',
281 choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42', 'AF43',
282 'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified'],
283 aliases=['target']),
284 encap_mode=dict(type='str', choices=['unknown', 'vlan', 'vxlan']),
285 multicast_address=dict(type='str'),
286 state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
287 vm_provider=dict(type='str', choices=['cloudfoundry', 'kubernetes', 'microsoft', 'openshift', 'openstack', 'redhat', 'vmware']),
288 vswitch=dict(type='str', choices=['avs', 'default', 'dvs', 'unknown']),
289 )
290
291 module = AnsibleModule(
292 argument_spec=argument_spec,
293 supports_check_mode=True,
294 required_if=[
295 ['domain_type', 'vmm', ['vm_provider']],
296 ['state', 'absent', ['domain', 'domain_type']],
297 ['state', 'present', ['domain', 'domain_type']],
298 ],
299 )
300
301 dscp = module.params['dscp']
302 domain = module.params['domain']
303 domain_type = module.params['domain_type']
304 encap_mode = module.params['encap_mode']
305 multicast_address = module.params['multicast_address']
306 vm_provider = module.params['vm_provider']
307 vswitch = module.params['vswitch']
308 if vswitch is not None:
309 vswitch = VSWITCH_MAPPING[vswitch]
310 state = module.params['state']
311
312 if domain_type != 'vmm':
313 if vm_provider is not None:
314 module.fail_json(msg="Domain type '{0}' cannot have parameter 'vm_provider'".format(domain_type))
315 if encap_mode is not None:
316 module.fail_json(msg="Domain type '{0}' cannot have parameter 'encap_mode'".format(domain_type))
317 if multicast_address is not None:
318 module.fail_json(msg="Domain type '{0}' cannot have parameter 'multicast_address'".format(domain_type))
319 if vswitch is not None:
320 module.fail_json(msg="Domain type '{0}' cannot have parameter 'vswitch'".format(domain_type))
321
322 if dscp is not None and domain_type not in ['l2dom', 'l3dom']:
323 module.fail_json(msg="DSCP values can only be assigned to 'l2ext and 'l3ext' domains")
324
325 # Compile the full domain for URL building
326 if domain_type == 'fc':
327 domain_class = 'fcDomP'
328 domain_mo = 'uni/fc-{0}'.format(domain)
329 domain_rn = 'fc-{0}'.format(domain)
330 elif domain_type == 'l2dom':
331 domain_class = 'l2extDomP'
332 domain_mo = 'uni/l2dom-{0}'.format(domain)
333 domain_rn = 'l2dom-{0}'.format(domain)
334 elif domain_type == 'l3dom':
335 domain_class = 'l3extDomP'
336 domain_mo = 'uni/l3dom-{0}'.format(domain)
337 domain_rn = 'l3dom-{0}'.format(domain)
338 elif domain_type == 'phys':
339 domain_class = 'physDomP'
340 domain_mo = 'uni/phys-{0}'.format(domain)
341 domain_rn = 'phys-{0}'.format(domain)
342 elif domain_type == 'vmm':
343 domain_class = 'vmmDomP'
344 domain_mo = 'uni/vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain)
345 domain_rn = 'vmmp-{0}/dom-{1}'.format(VM_PROVIDER_MAPPING[vm_provider], domain)
346
347 # Ensure that querying all objects works when only domain_type is provided
348 if domain is None:
349 domain_mo = None
350
351 aci = ACIModule(module)
352 aci.construct_url(
353 root_class=dict(
354 aci_class=domain_class,
355 aci_rn=domain_rn,
356 module_object=domain_mo,
357 target_filter={'name': domain},
358 ),
359 )
360
361 aci.get_existing()
362
363 if state == 'present':
364 aci.payload(
365 aci_class=domain_class,
366 class_config=dict(
367 encapMode=encap_mode,
368 mcastAddr=multicast_address,
369 mode=vswitch,
370 name=domain,
371 targetDscp=dscp,
372 ),
373 )
374
375 aci.get_diff(aci_class=domain_class)
376
377 aci.post_config()
378
379 elif state == 'absent':
380 aci.delete_config()
381
382 aci.exit_json()
383
384
385if __name__ == "__main__":
386 main()