-
Notifications
You must be signed in to change notification settings - Fork 104
Addition of a new module for enhanced_lag_policy (DCNE-422) #768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 5 commits
4c70cc3
1551ff6
29c003d
10d5480
6cd9f92
61a2709
187af50
146ad7f
e9a8cce
b2a58b8
992c92f
493411e
f918f35
bc2bc36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,340 @@ | ||||||||
#!/usr/bin/python | ||||||||
# -*- coding: utf-8 -*- | ||||||||
|
||||||||
# Copyright: (c) 2025, Dev Sinha (@DevSinha13) <devsinh@cisco.com> | ||||||||
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) | ||||||||
from __future__ import absolute_import, division, print_function | ||||||||
|
||||||||
__metaclass__ = type | ||||||||
|
||||||||
ANSIBLE_METADATA = {"metadata_version": "1.1", "status": ["preview"], "supported_by": "community"} | ||||||||
|
||||||||
DOCUMENTATION = r""" | ||||||||
--- | ||||||||
module: aci_vmm_enhanced_lag_policy | ||||||||
short_description: Manage Enhanced LACP Policy for Virtual Machine Manager (VMM) in Cisco ACI | ||||||||
description: | ||||||||
- Manage Enhanced LACP Policy (lacpEnhancedLagPol) for VMM domains on Cisco ACI fabrics. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't think we put class names in the descriptions |
||||||||
- The Enhanced LACP Policy allows you to configure advanced Link Aggregation Control Protocol (LACP) settings for virtual switches in VMM domains. | ||||||||
- This policy is a child of the C(vmmVSwitchPolicyCont) class. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is children something we decided to add to the descriptions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I understand the thumbs up here? Has this been decided? |
||||||||
|
||||||||
options: | ||||||||
name: | ||||||||
description: | ||||||||
- The name of the Enhanced LACP Policy. | ||||||||
type: str | ||||||||
domain: | ||||||||
description: | ||||||||
- The name of the virtual domain profile where the Enhanced LACP Policy is applied. | ||||||||
type: str | ||||||||
aliases: [ domain_name, domain_profile ] | ||||||||
vm_provider: | ||||||||
description: | ||||||||
- The virtualization platform provider for the VMM domain. | ||||||||
type: str | ||||||||
choices: [ cloudfoundry, kubernetes, microsoft, openshift, openstack, redhat, vmware ] | ||||||||
lacp_mode: | ||||||||
description: | ||||||||
- The LACP mode for the policy. | ||||||||
- Determines whether the policy initiates or responds to LACP negotiations. | ||||||||
akinross marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
type: str | ||||||||
choices: [ active, passive ] | ||||||||
load_balancing_mode: | ||||||||
description: | ||||||||
- The load balancing algorithm for distributing traffic across links in the port channel. | ||||||||
- See the APIC Management Information Model reference for more details. | ||||||||
akinross marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
type: str | ||||||||
choices: | ||||||||
- dst-ip | ||||||||
- dst-ip-l4port | ||||||||
- dst-ip-vlan | ||||||||
- dst-ip-l4port-vlan | ||||||||
- dst-mac | ||||||||
- dst-l4port | ||||||||
- src-ip | ||||||||
- src-ip-l4port | ||||||||
- src-ip-vlan | ||||||||
- src-ip-l4port-vlan | ||||||||
- src-mac | ||||||||
- src-l4port | ||||||||
- src-dst-ip | ||||||||
- src-dst-ip-l4port | ||||||||
- src-dst-ip-vlan | ||||||||
- src-dst-ip-l4port-vlan | ||||||||
- src-dst-mac | ||||||||
- src-dst-l4port | ||||||||
- src-port-id | ||||||||
- vlan | ||||||||
number_uplinks: | ||||||||
akinross marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
description: | ||||||||
- The minimum number of uplinks required for the port channel. | ||||||||
- Must be a value between 2 and 8. | ||||||||
type: int | ||||||||
state: | ||||||||
description: | ||||||||
- The desired state of the Enhanced LACP Policy. | ||||||||
- Use C(present) to create or update the policy. | ||||||||
- Use C(absent) to delete the policy. | ||||||||
- Use C(query) to retrieve information about the policy. | ||||||||
type: str | ||||||||
choices: [ absent, present, query ] | ||||||||
default: present | ||||||||
extends_documentation_fragment: | ||||||||
- cisco.aci.aci | ||||||||
- cisco.aci.annotation | ||||||||
- cisco.aci.owner | ||||||||
|
||||||||
akinross marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
seealso: | ||||||||
- module: cisco.aci.aci_domain | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry about that, I have made the fix |
||||||||
- name: APIC Management Information Model reference | ||||||||
description: More information about the internal APIC classes B(lacp:EnhancedLagPol). | ||||||||
link: https://developer.cisco.com/docs/apic-mim-ref/ | ||||||||
author: | ||||||||
- Dev Sinha (@DevSinha13) | ||||||||
""" | ||||||||
|
||||||||
EXAMPLES = r""" | ||||||||
- name: Create an Enhanced LACP Policy | ||||||||
cisco.aci.aci_vmm_enhanced_lag_policy: | ||||||||
host: apic.example.com | ||||||||
username: admin | ||||||||
password: SomeSecretPassword | ||||||||
name: my_enhanced_lag_policy | ||||||||
domain: my_vmm_domain | ||||||||
vm_provider: vmware | ||||||||
lacp_mode: active | ||||||||
load_balancing_mode: src-dst-ip | ||||||||
number_uplinks: 4 | ||||||||
state: present | ||||||||
|
||||||||
- name: Simulate creation of an Enhanced LACP Policy (Check Mode) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dont think we include this type of example in other modules There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I understand the thumbs up here? Has this been decided to include? |
||||||||
cisco.aci.aci_vmm_enhanced_lag_policy: | ||||||||
host: apic.example.com | ||||||||
username: admin | ||||||||
password: SomeSecretPassword | ||||||||
name: my_enhanced_lag_policy | ||||||||
domain: my_vmm_domain | ||||||||
vm_provider: vmware | ||||||||
lacp_mode: active | ||||||||
load_balancing_mode: src-dst-ip | ||||||||
number_uplinks: 4 | ||||||||
state: present | ||||||||
check_mode: true | ||||||||
|
||||||||
- name: Update an existing Enhanced LACP Policy | ||||||||
cisco.aci.aci_vmm_enhanced_lag_policy: | ||||||||
host: apic.example.com | ||||||||
username: admin | ||||||||
password: SomeSecretPassword | ||||||||
name: my_enhanced_lag_policy | ||||||||
domain: my_vmm_domain | ||||||||
vm_provider: vmware | ||||||||
lacp_mode: passive | ||||||||
load_balancing_mode: src-dst-ip-l4port | ||||||||
number_uplinks: 6 | ||||||||
state: present | ||||||||
|
||||||||
- name: Query a specific Enhanced LACP Policy | ||||||||
cisco.aci.aci_vmm_enhanced_lag_policy: | ||||||||
host: apic.example.com | ||||||||
username: admin | ||||||||
password: SomeSecretPassword | ||||||||
name: my_enhanced_lag_policy | ||||||||
domain: my_vmm_domain | ||||||||
vm_provider: vmware | ||||||||
state: query | ||||||||
register: query_result | ||||||||
|
||||||||
- name: Query all Enhanced LACP Policies in a VMM domain | ||||||||
cisco.aci.aci_vmm_enhanced_lag_policy: | ||||||||
host: apic.example.com | ||||||||
username: admin | ||||||||
password: SomeSecretPassword | ||||||||
domain: my_vmm_domain | ||||||||
vm_provider: vmware | ||||||||
state: query | ||||||||
register: query_all_result | ||||||||
|
||||||||
- name: Ensure idempotency when creating an Enhanced LACP Policy | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dont think we include this type of example in other modules |
||||||||
cisco.aci.aci_vmm_enhanced_lag_policy: | ||||||||
host: apic.example.com | ||||||||
username: admin | ||||||||
password: SomeSecretPassword | ||||||||
name: my_enhanced_lag_policy | ||||||||
domain: my_vmm_domain | ||||||||
vm_provider: vmware | ||||||||
lacp_mode: active | ||||||||
load_balancing_mode: src-dst-ip | ||||||||
number_uplinks: 4 | ||||||||
state: present | ||||||||
|
||||||||
- name: Delete an Enhanced LACP Policy | ||||||||
cisco.aci.aci_vmm_enhanced_lag_policy: | ||||||||
host: apic.example.com | ||||||||
username: admin | ||||||||
password: SomeSecretPassword | ||||||||
name: my_enhanced_lag_policy | ||||||||
domain: my_vmm_domain | ||||||||
vm_provider: vmware | ||||||||
state: absent | ||||||||
|
||||||||
- name: Simulate deletion of an Enhanced LACP Policy (Check Mode) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dont think we include this type of example in other modules There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Noted, I have deleted that example. Thank you for the clarification. |
||||||||
cisco.aci.aci_vmm_enhanced_lag_policy: | ||||||||
host: apic.example.com | ||||||||
username: admin | ||||||||
password: SomeSecretPassword | ||||||||
name: my_enhanced_lag_policy | ||||||||
domain: my_vmm_domain | ||||||||
vm_provider: vmware | ||||||||
state: absent | ||||||||
check_mode: true | ||||||||
""" | ||||||||
RETURN = r""" | ||||||||
current: | ||||||||
description: The existing configuration of the Enhanced LACP Policy from the APIC after the module has finished. | ||||||||
returned: success | ||||||||
type: list | ||||||||
sample: | ||||||||
[ | ||||||||
{ | ||||||||
"lacpEnhancedLagPol": { | ||||||||
"attributes": { | ||||||||
"name": "test_enhanced_lag_policy", | ||||||||
"mode": "active", | ||||||||
"lbmode": "src-dst-ip", | ||||||||
"numLinks": "4", | ||||||||
"dn": "uni/vmmp-VMware/dom-test_vmm_dom/vswitchpolcont/enlacplagp-test_enhanced_lag_policy" | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
] | ||||||||
error: | ||||||||
description: The error information as returned from the APIC. | ||||||||
returned: failure | ||||||||
type: dict | ||||||||
sample: | ||||||||
{ | ||||||||
"code": "801", | ||||||||
"text": "property name of enlacplagp-test_enhanced_lag_policy failed validation" | ||||||||
} | ||||||||
proposed: | ||||||||
description: The configuration sent to the APIC. | ||||||||
returned: info | ||||||||
type: dict | ||||||||
sample: | ||||||||
{ | ||||||||
"lacpEnhancedLagPol": { | ||||||||
"attributes": { | ||||||||
"name": "test_enhanced_lag_policy", | ||||||||
"mode": "active", | ||||||||
"lbmode": "src-dst-ip", | ||||||||
"numLinks": "4" | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
""" | ||||||||
|
||||||||
from ansible.module_utils.basic import AnsibleModule | ||||||||
from ansible_collections.cisco.aci.plugins.module_utils.aci import ( | ||||||||
ACIModule, | ||||||||
aci_argument_spec, | ||||||||
enhanced_lag_spec, | ||||||||
) | ||||||||
from ansible_collections.cisco.aci.plugins.module_utils.aci import ( | ||||||||
aci_annotation_spec, | ||||||||
aci_owner_spec, | ||||||||
) | ||||||||
|
||||||||
VM_PROVIDER_MAPPING = dict( | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can import and use the VM_PROVIDER_MAPPING defined in module_utils/constants.py |
||||||||
cloudfoundry="CloudFoundry", | ||||||||
kubernetes="Kubernetes", | ||||||||
microsoft="Microsoft", | ||||||||
openshift="OpenShift", | ||||||||
openstack="OpenStack", | ||||||||
redhat="Redhat", | ||||||||
vmware="VMware", | ||||||||
) | ||||||||
|
||||||||
|
||||||||
def main(): | ||||||||
argument_spec = aci_argument_spec() | ||||||||
argument_spec.update(aci_annotation_spec()) | ||||||||
argument_spec.update(aci_owner_spec()) | ||||||||
argument_spec.update(enhanced_lag_spec(name_is_required=False)) | ||||||||
argument_spec.update( | ||||||||
domain=dict(type="str", aliases=["domain_name", "domain_profile"]), | ||||||||
state=dict(type="str", default="present", choices=["absent", "present", "query"]), | ||||||||
vm_provider=dict(type="str", choices=list(VM_PROVIDER_MAPPING.keys())), | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't think the
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed, removed the .keys() function and maintained functionality across all tests. Thanks for the feedback. |
||||||||
) | ||||||||
|
||||||||
module = AnsibleModule( | ||||||||
argument_spec=argument_spec, | ||||||||
supports_check_mode=True, | ||||||||
required_if=[ | ||||||||
["state", "absent", ["name", "domain", "vm_provider"]], | ||||||||
["state", "present", ["name", "domain", "vm_provider"]], | ||||||||
], | ||||||||
) | ||||||||
|
||||||||
name = module.params.get("name") | ||||||||
lacp_mode = module.params.get("lacp_mode") | ||||||||
load_balancing_mode = module.params.get("load_balancing_mode") | ||||||||
number_uplinks = module.params.get("number_uplinks") | ||||||||
domain = module.params.get("domain") | ||||||||
state = module.params.get("state") | ||||||||
vm_provider = module.params.get("vm_provider") | ||||||||
|
||||||||
aci = ACIModule(module) | ||||||||
|
||||||||
aci.construct_url( | ||||||||
root_class=dict( | ||||||||
aci_class="vmmProvP", | ||||||||
aci_rn="vmmp-{0}".format(VM_PROVIDER_MAPPING.get(vm_provider)), | ||||||||
module_object=vm_provider, | ||||||||
target_filter={"name": vm_provider}, | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think vmmProvP idtenifier is
Suggested change
|
||||||||
), | ||||||||
subclass_1=dict( | ||||||||
aci_class="vmmDomP", | ||||||||
aci_rn="dom-{0}".format(domain), | ||||||||
module_object=domain, | ||||||||
target_filter={"name": domain}, | ||||||||
), | ||||||||
subclass_2=dict( | ||||||||
aci_class="vmmVSwitchPolicyCont", | ||||||||
aci_rn="vswitchpolcont", | ||||||||
module_object="vswitchpolcont", | ||||||||
target_filter={"name": "vswitchpolcont"}, | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need to define an target_filter? this class has no identifiers, so would not be able to filter on it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't quite know how I should identify if this is required or not, would love to discuss it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would start by testing the behaviour with and without for both module_object and target_filter. The target_filter is referencing a property now that exist but is not configurable according to the model, so is it always There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. had a quick look and from what I read in code if module_object is defined that should be enough, target_filter is not used at all in the logic as far as I can tell so can be excluded, since it only uses the filter of the object defined in subclass_3. See _construct_url_4) function in aci.py |
||||||||
), | ||||||||
subclass_3=dict( | ||||||||
aci_class="lacpEnhancedLagPol", | ||||||||
aci_rn="enlacplagp-{0}".format(name), | ||||||||
module_object=name, | ||||||||
target_filter={"name": name}, | ||||||||
), | ||||||||
) | ||||||||
|
||||||||
aci.get_existing() | ||||||||
|
||||||||
if state == "present": | ||||||||
aci.payload( | ||||||||
aci_class="lacpEnhancedLagPol", | ||||||||
class_config=dict( | ||||||||
name=name, | ||||||||
mode=lacp_mode, | ||||||||
lbmode=load_balancing_mode, | ||||||||
numLinks=number_uplinks, | ||||||||
), | ||||||||
) | ||||||||
|
||||||||
aci.get_diff(aci_class="lacpEnhancedLagPol") | ||||||||
|
||||||||
aci.post_config() | ||||||||
|
||||||||
elif state == "absent": | ||||||||
aci.delete_config() | ||||||||
|
||||||||
aci.exit_json() | ||||||||
|
||||||||
|
||||||||
if __name__ == "__main__": | ||||||||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# No ACI simulator yet, so not enabled | ||
# unsupported |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other modules I think we include the classname to the short description (lacp:EnhancedLagPol) at the end. If not mistaken this was done for search-ability of classes in documentation