|
|
@ -38,17 +38,62 @@ options:
|
|
|
|
max_links:
|
|
|
|
max_links:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- Maximum links (range 1-16).
|
|
|
|
- Maximum links (range 1-16).
|
|
|
|
- The APIC defaults new Port Channel Policies to a max links of 16.
|
|
|
|
- The APIC defaults new Port Channel Policies to C(16).
|
|
|
|
|
|
|
|
choices: [ Ranges from 1 to 16 ]
|
|
|
|
|
|
|
|
default: 16
|
|
|
|
min_links:
|
|
|
|
min_links:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- Minimum links (range 1-16).
|
|
|
|
- Minimum links (range 1-16).
|
|
|
|
- The APIC defaults new Port Channel Policies to a min links of 1.
|
|
|
|
- The APIC defaults new Port Channel Policies to C(1).
|
|
|
|
|
|
|
|
choices: [ Ranges from 1 to 16 ]
|
|
|
|
|
|
|
|
default: 1
|
|
|
|
mode:
|
|
|
|
mode:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- Port channel interface policy mode.
|
|
|
|
- Port channel interface policy mode.
|
|
|
|
- Determines the LACP method to use for forming port-channels.
|
|
|
|
- Determines the LACP method to use for forming port-channels.
|
|
|
|
- The APIC defaults new Port Channel Polices to a off mode.
|
|
|
|
- The APIC defaults new Port Channel Polices to C(off).
|
|
|
|
choices: [ active, mac-pin, mac-pin-nicload, off, passive ]
|
|
|
|
choices: [ active, mac-pin, mac-pin-nicload, off, passive ]
|
|
|
|
|
|
|
|
default: off
|
|
|
|
|
|
|
|
fast_select:
|
|
|
|
|
|
|
|
description:
|
|
|
|
|
|
|
|
- Determines if Fast Select is enabled for Hot Standby Ports.
|
|
|
|
|
|
|
|
- This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties
|
|
|
|
|
|
|
|
left undefined or set to false will not exist after the task is ran.
|
|
|
|
|
|
|
|
- The APIC defaults new LACP Policies to C(true).
|
|
|
|
|
|
|
|
type: bool
|
|
|
|
|
|
|
|
default: true
|
|
|
|
|
|
|
|
graceful_convergence:
|
|
|
|
|
|
|
|
description:
|
|
|
|
|
|
|
|
- Determines if Graceful Convergence is enabled.
|
|
|
|
|
|
|
|
- This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties
|
|
|
|
|
|
|
|
left undefined or set to false will not exist after the task is ran.
|
|
|
|
|
|
|
|
- The APIC defaults new LACP Policies to C(true).
|
|
|
|
|
|
|
|
type: bool
|
|
|
|
|
|
|
|
default: true
|
|
|
|
|
|
|
|
load_defer:
|
|
|
|
|
|
|
|
description:
|
|
|
|
|
|
|
|
- Determines if Load Defer is enabled.
|
|
|
|
|
|
|
|
- This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties
|
|
|
|
|
|
|
|
left undefined or set to false will not exist after the task is ran.
|
|
|
|
|
|
|
|
- The APIC defaults new LACP Policies to C(false).
|
|
|
|
|
|
|
|
type: bool
|
|
|
|
|
|
|
|
default: false
|
|
|
|
|
|
|
|
suspend_individual:
|
|
|
|
|
|
|
|
description:
|
|
|
|
|
|
|
|
- Determines if Suspend Individual is enabled.
|
|
|
|
|
|
|
|
- This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties
|
|
|
|
|
|
|
|
left undefined or set to false will not exist after the task is ran.
|
|
|
|
|
|
|
|
- The APIC defaults new LACP Policies to C(true).
|
|
|
|
|
|
|
|
type: bool
|
|
|
|
|
|
|
|
default: true
|
|
|
|
|
|
|
|
symmetric_hash:
|
|
|
|
|
|
|
|
description:
|
|
|
|
|
|
|
|
- Determines if Symmetric Hashing is enabled.
|
|
|
|
|
|
|
|
- This makes up the LACP Policy Control Policy; if one setting is defined, then all other Control Properties
|
|
|
|
|
|
|
|
left undefined or set to false will not exist after the task is ran.
|
|
|
|
|
|
|
|
- The APIC defaults new LACP Policies to C(false).
|
|
|
|
|
|
|
|
type: bool
|
|
|
|
|
|
|
|
default: false
|
|
|
|
state:
|
|
|
|
state:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- Use C(present) or C(absent) for adding or removing.
|
|
|
|
- Use C(present) or C(absent) for adding or removing.
|
|
|
@ -86,6 +131,11 @@ def main():
|
|
|
|
min_links=dict(type='int'),
|
|
|
|
min_links=dict(type='int'),
|
|
|
|
max_links=dict(type='int'),
|
|
|
|
max_links=dict(type='int'),
|
|
|
|
mode=dict(type='str', choices=['off', 'mac-pin', 'active', 'passive', 'mac-pin-nicload']),
|
|
|
|
mode=dict(type='str', choices=['off', 'mac-pin', 'active', 'passive', 'mac-pin-nicload']),
|
|
|
|
|
|
|
|
fast_select=dict(type='bool'),
|
|
|
|
|
|
|
|
graceful_convergence=dict(type='bool'),
|
|
|
|
|
|
|
|
load_defer=dict(type='bool'),
|
|
|
|
|
|
|
|
suspend_individual=dict(type='bool'),
|
|
|
|
|
|
|
|
symmetric_hash=dict(type='bool'),
|
|
|
|
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
|
|
|
|
state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
|
|
|
|
method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6
|
|
|
|
method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6
|
|
|
|
)
|
|
|
|
)
|
|
|
@ -93,37 +143,57 @@ def main():
|
|
|
|
module = AnsibleModule(
|
|
|
|
module = AnsibleModule(
|
|
|
|
argument_spec=argument_spec,
|
|
|
|
argument_spec=argument_spec,
|
|
|
|
supports_check_mode=True,
|
|
|
|
supports_check_mode=True,
|
|
|
|
|
|
|
|
required_if=[
|
|
|
|
|
|
|
|
['state', 'absent', ['port_channel']],
|
|
|
|
|
|
|
|
['state', 'present', ['port_channel']],
|
|
|
|
|
|
|
|
],
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
port_channel = module.params['port_channel']
|
|
|
|
port_channel = module.params['port_channel']
|
|
|
|
description = module.params['description']
|
|
|
|
description = module.params['description']
|
|
|
|
# TODO: Validate min_links is in the acceptable range
|
|
|
|
min_links = module.params['min_links']
|
|
|
|
min_links = module.params['min_link']
|
|
|
|
if min_links is not None and min_links not in range(1, 17):
|
|
|
|
# TODO: Validate max_links is in the acceptable range
|
|
|
|
module.fail_json(msg='The "min_links" must be a value between 1 and 16')
|
|
|
|
min_links = str(min_links)
|
|
|
|
max_links = module.params['max_links']
|
|
|
|
max_links = module.params['max_link']
|
|
|
|
if max_links is not None and max_links not in range(1, 17):
|
|
|
|
max_links = str(max_links)
|
|
|
|
module.fail_json(msg='The "max_links" must be a value between 1 and 16')
|
|
|
|
mode = module.params['mode']
|
|
|
|
mode = module.params['mode']
|
|
|
|
state = module.params['state']
|
|
|
|
state = module.params['state']
|
|
|
|
|
|
|
|
|
|
|
|
aci = ACIModule(module)
|
|
|
|
# Build ctrl value for request
|
|
|
|
|
|
|
|
ctrl = []
|
|
|
|
# TODO: This logic could be cleaner.
|
|
|
|
if module.params['fast_select'] is True:
|
|
|
|
if port_channel is not None:
|
|
|
|
ctrl.append('fast-sel-hot-stdby')
|
|
|
|
path = 'api/mo/uni/infra/lacplagp-%(port_channel)s.json' % module.params
|
|
|
|
if module.params['graceful_convergence'] is True:
|
|
|
|
elif state == 'query':
|
|
|
|
ctrl.append('graceful-conv')
|
|
|
|
# Query all objects
|
|
|
|
if module.params['load_defer'] is True:
|
|
|
|
path = 'api/node/class/lacplagPol.json'
|
|
|
|
ctrl.append('load-defer')
|
|
|
|
|
|
|
|
if module.params['suspend_individual'] is True:
|
|
|
|
|
|
|
|
ctrl.append('susp-individual')
|
|
|
|
|
|
|
|
if module.params['symmetric_hash'] is True:
|
|
|
|
|
|
|
|
ctrl.append('symmetric-hash')
|
|
|
|
|
|
|
|
if not ctrl:
|
|
|
|
|
|
|
|
ctrl = None
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
module.fail_json(msg="Parameter 'port_channel' is required for state 'absent' or 'present'")
|
|
|
|
ctrl = ",".join(ctrl)
|
|
|
|
|
|
|
|
|
|
|
|
aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
aci = ACIModule(module)
|
|
|
|
|
|
|
|
aci.construct_url(root_class='port_channel')
|
|
|
|
aci.get_existing()
|
|
|
|
aci.get_existing()
|
|
|
|
|
|
|
|
|
|
|
|
if state == 'present':
|
|
|
|
if state == 'present':
|
|
|
|
# Filter out module parameters with null values
|
|
|
|
# Filter out module parameters with null values
|
|
|
|
aci.payload(aci_class='lacpLagPol', class_config=dict(name=port_channel, descr=description, minLinks=min_links, maxLinks=max_links, mode=mode))
|
|
|
|
aci.payload(
|
|
|
|
|
|
|
|
aci_class='lacpLagPol',
|
|
|
|
|
|
|
|
class_config=dict(
|
|
|
|
|
|
|
|
name=port_channel,
|
|
|
|
|
|
|
|
ctrl=ctrl,
|
|
|
|
|
|
|
|
descr=description,
|
|
|
|
|
|
|
|
minLinks=min_links,
|
|
|
|
|
|
|
|
maxLinks=max_links,
|
|
|
|
|
|
|
|
mode=mode,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# Generate config diff which will be used as POST request body
|
|
|
|
# Generate config diff which will be used as POST request body
|
|
|
|
aci.get_diff(aci_class='lacpLagPol')
|
|
|
|
aci.get_diff(aci_class='lacpLagPol')
|
|
|
|