6from __future__
import absolute_import, division, print_function
9ANSIBLE_METADATA = {
'metadata_version':
'1.1',
10 'status': [
'preview'],
11 'supported_by':
'certified'}
16short_description: Manage Bridge Domains (BD) objects (fv:BD)
18- Manages Bridge Domains (BD) on Cisco ACI fabrics.
23 - Determines if the Bridge Domain should flood ARP traffic.
24 - The APIC defaults to C(no) when unset during creation.
28 - The name of the Bridge Domain.
30 aliases: [ bd_name, name ]
33 - The type of traffic on the Bridge Domain.
34 - The APIC defaults to C(ethernet) when unset during creation.
36 choices: [ ethernet, fc ]
39 - Description
for the Bridge Domain.
43 - Determines
if PIM
is enabled.
44 - The APIC defaults to C(no) when unset during creation.
48 - Determines
if IP forwarding should be allowed.
49 - The APIC defaults to C(yes) when unset during creation.
53 - Clears all End Points
in all Leaves when C(yes).
54 - The value
is not reset to disabled once End Points have been cleared; that requires a second task.
55 - The APIC defaults to C(no) when unset during creation.
59 - Determines
if GARP should be enabled to detect when End Points move.
60 - The APIC defaults to C(garp) when unset during creation.
62 choices: [ default, garp ]
63 endpoint_retention_action:
65 - Determines
if the Bridge Domain should inherit
or resolve the End Point Retention Policy.
66 - The APIC defaults to C(resolve) when unset during creation.
68 choices: [ inherit, resolve ]
69 endpoint_retention_policy:
71 - The name of the End Point Retention Policy the Bridge Domain should use when
72 overriding the default End Point Retention Policy.
76 - The name of the IGMP Snooping Policy the Bridge Domain should use when
77 overriding the default IGMP Snooping Policy.
81 - Determines
if the Bridge Domain should learn End Point IPs.
82 - The APIC defaults to C(yes) when unset during creation.
86 - The name of the IPv6 Neighbor Discovery Policy the Bridge Domain should use when
87 overridding the default IPV6 ND Policy.
91 - Determines what forwarding method to use
for unknown l2 destinations.
92 - The APIC defaults to C(proxy) when unset during creation.
94 choices: [ proxy, flood ]
97 - Determines the forwarding method to use
for unknown multicast destinations.
98 - The APIC defaults to C(flood) when unset during creation.
100 choices: [ flood, opt-flood ]
103 - Determines
if the BD should limit IP learning to only subnets owned by the Bridge Domain.
104 - The APIC defaults to C(yes) when unset during creation.
108 - The MAC Address to assign to the C(bd) instead of using the default.
109 - The APIC defaults to C(00:22:BD:F8:19:FF) when unset during creation.
115 - Determines the forwarding method
for L2 multicast, broadcast,
and link layer traffic.
116 - The APIC defaults to C(bd-flood) when unset during creation.
118 choices: [ bd-flood, drop, encap-flood ]
121 - Use C(present)
or C(absent)
for adding
or removing.
122 - Use C(query)
for listing an object
or multiple objects.
124 choices: [ absent, present, query ]
128 - The name of the Tenant.
130 aliases: [ tenant_name ]
133 - The name of the VRF.
135 aliases: [ vrf_name ]
136extends_documentation_fragment: aci
138- The C(tenant) used must exist before using this module
in your playbook.
139 The M(aci_tenant) module can be used
for this.
142- name: APIC Management Information Model reference
143 description: More information about the internal APIC
class B(fv:BD).
144 link: https://developer.cisco.com/docs/apic-mim-ref/
146- Jacob McGill (
@jmcgill298)
150- name: Add Bridge Domain
152 host: "{{ inventory_hostname }}"
153 username:
"{{ username }}"
154 password:
"{{ password }}"
158 mac_address: 00:22:BD:F8:19:FE
161 delegate_to: localhost
163- name: Add an FC Bridge Domain
165 host:
"{{ inventory_hostname }}"
166 username:
"{{ username }}"
167 password:
"{{ password }}"
175 delegate_to: localhost
177- name: Modify a Bridge Domain
179 host:
"{{ inventory_hostname }}"
180 username:
"{{ username }}"
181 password:
"{{ password }}"
186 l2_unknown_unicast: flood
188 delegate_to: localhost
190- name: Query All Bridge Domains
192 host:
"{{ inventory_hostname }}"
193 username:
"{{ username }}"
194 password:
"{{ password }}"
197 delegate_to: localhost
198 register: query_result
200- name: Query a Bridge Domain
202 host:
"{{ inventory_hostname }}"
203 username:
"{{ username }}"
204 password:
"{{ password }}"
209 delegate_to: localhost
210 register: query_result
212- name: Delete a Bridge Domain
214 host:
"{{ inventory_hostname }}"
215 username:
"{{ username }}"
216 password:
"{{ password }}"
221 delegate_to: localhost
226 description: The existing configuration from the APIC after the module has finished
234 "descr":
"Production environment",
235 "dn":
"uni/tn-production",
236 "name":
"production",
245 description: The error information
as returned
from the APIC
251 "text":
"unknown managed object class foo"
254 description: The raw output returned by the APIC REST API (xml
or json)
255 returned: parse error
257 sample:
'<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
259 description: The actual/minimal configuration pushed to the APIC
266 "descr":
"Production environment"
271 description: The original configuration
from the APIC before the module has started
279 "descr":
"Production",
280 "dn":
"uni/tn-production",
281 "name":
"production",
290 description: The assembled configuration
from the user-provided parameters
297 "descr":
"Production environment",
303 description: The filter string used
for the request
304 returned: failure
or debug
306 sample: ?rsp-prop-include=config-only
308 description: The HTTP method used
for the request to the APIC
309 returned: failure
or debug
313 description: The HTTP response
from the APIC
314 returned: failure
or debug
316 sample: OK (30 bytes)
318 description: The HTTP status
from the APIC
319 returned: failure
or debug
323 description: The HTTP url used
for the request to the APIC
324 returned: failure
or debug
326 sample: https://10.11.12.13/api/mo/uni/tn-production.json
329from ansible.module_utils.basic import AnsibleModule
330from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
335 argument_spec.update(
336 arp_flooding=dict(type='bool'),
337 bd=dict(type=
'str', aliases=[
'bd_name',
'name']),
338 bd_type=dict(type=
'str', choices=[
'ethernet',
'fc']),
339 description=dict(type=
'str'),
340 enable_multicast=dict(type=
'bool'),
341 enable_routing=dict(type=
'bool'),
342 endpoint_clear=dict(type=
'bool'),
343 endpoint_move_detect=dict(type=
'str', choices=[
'default',
'garp']),
344 endpoint_retention_action=dict(type=
'str', choices=[
'inherit',
'resolve']),
345 endpoint_retention_policy=dict(type=
'str'),
346 igmp_snoop_policy=dict(type=
'str'),
347 ip_learning=dict(type=
'bool'),
348 ipv6_nd_policy=dict(type=
'str'),
349 l2_unknown_unicast=dict(type=
'str', choices=[
'proxy',
'flood']),
350 l3_unknown_multicast=dict(type=
'str', choices=[
'flood',
'opt-flood']),
351 limit_ip_learn=dict(type=
'bool'),
352 mac_address=dict(type=
'str', aliases=[
'mac']),
353 multi_dest=dict(type=
'str', choices=[
'bd-flood',
'drop',
'encap-flood']),
354 state=dict(type=
'str', default=
'present', choices=[
'absent',
'present',
'query']),
355 tenant=dict(type=
'str', aliases=[
'tenant_name']),
356 vrf=dict(type=
'str', aliases=[
'vrf_name']),
357 gateway_ip=dict(type=
'str', removed_in_version=
'2.4'),
358 scope=dict(type=
'str', removed_in_version=
'2.4'),
359 subnet_mask=dict(type=
'str', removed_in_version=
'2.4'),
363 argument_spec=argument_spec,
364 supports_check_mode=
True,
366 [
'state',
'absent', [
'bd',
'tenant']],
367 [
'state',
'present', [
'bd',
'tenant']],
373 arp_flooding = aci.boolean(module.params[
'arp_flooding'])
374 bd = module.params[
'bd']
375 bd_type = module.params[
'bd_type']
376 if bd_type ==
'ethernet':
379 description = module.params[
'description']
380 enable_multicast = aci.boolean(module.params[
'enable_multicast'])
381 enable_routing = aci.boolean(module.params[
'enable_routing'])
382 endpoint_clear = aci.boolean(module.params[
'endpoint_clear'])
383 endpoint_move_detect = module.params[
'endpoint_move_detect']
384 if endpoint_move_detect ==
'default':
386 endpoint_move_detect =
''
387 endpoint_retention_action = module.params[
'endpoint_retention_action']
388 endpoint_retention_policy = module.params[
'endpoint_retention_policy']
389 igmp_snoop_policy = module.params[
'igmp_snoop_policy']
390 ip_learning = aci.boolean(module.params[
'ip_learning'])
391 ipv6_nd_policy = module.params[
'ipv6_nd_policy']
392 l2_unknown_unicast = module.params[
'l2_unknown_unicast']
393 l3_unknown_multicast = module.params[
'l3_unknown_multicast']
394 limit_ip_learn = aci.boolean(module.params[
'limit_ip_learn'])
395 mac_address = module.params[
'mac_address']
396 multi_dest = module.params[
'multi_dest']
397 state = module.params[
'state']
398 tenant = module.params[
'tenant']
399 vrf = module.params[
'vrf']
402 if module.params[
'gateway_ip']
or module.params[
'subnet_mask']
or module.params[
'scope']:
403 module._warnings = [
"The support for managing Subnets has been moved to its own module, aci_subnet. \
404 The new modules still supports 'gateway_ip' and 'subnet_mask' along with more features"]
408 aci_class=
'fvTenant',
409 aci_rn=
'tn-{0}'.
format(tenant),
410 module_object=tenant,
411 target_filter={
'name': tenant},
415 aci_rn=
'BD-{0}'.
format(bd),
417 target_filter={
'name': bd},
419 child_classes=[
'fvRsCtx',
'fvRsIgmpsn',
'fvRsBDToNdP',
'fvRsBdToEpRet'],
424 if state ==
'present':
428 arpFlood=arp_flooding,
430 epClear=endpoint_clear,
431 epMoveDetectMode=endpoint_move_detect,
432 ipLearning=ip_learning,
433 limitIpLearnToSubnets=limit_ip_learn,
435 mcastAllow=enable_multicast,
436 multiDstPktAct=multi_dest,
439 unicastRoute=enable_routing,
440 unkMacUcastAct=l2_unknown_unicast,
441 unkMcastAct=l3_unknown_multicast,
444 {
'fvRsCtx': {
'attributes': {
'tnFvCtxName': vrf}}},
445 {
'fvRsIgmpsn': {
'attributes': {
'tnIgmpSnoopPolName': igmp_snoop_policy}}},
446 {
'fvRsBDToNdP': {
'attributes': {
'tnNdIfPolName': ipv6_nd_policy}}},
447 {
'fvRsBdToEpRet': {
'attributes': {
'resolveAct': endpoint_retention_action,
'tnFvEpRetPolName': endpoint_retention_policy}}},
451 aci.get_diff(aci_class=
'fvBD')
455 elif state ==
'absent':
461if __name__ ==
"__main__":