Skip to content
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

[minor_change] Add loopback interface profile as a child class for ac… #476

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion plugins/modules/aci_l3out_logical_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@
type: str
choices: [ 'yes', 'no' ]
default: 'yes'
loopback_address:
description:
- The loopback IP address.
- A configured loopback address can be removed by passing an empty string (see Examples).
type: str
aliases: [ loopback ]
state:
description:
- Use C(present) or C(absent) for adding or removing.
Expand Down Expand Up @@ -82,9 +88,23 @@
pod_id: 1
node_id: 111
router_id: 111.111.111.111
loopback_address: 111.111.111.112
state: present
delegate_to: localhost

- name: Remove a loopback address from a node in node profile
cisco.aci.aci_l3out_logical_node:
host: apic
username: admin
password: SomeSecretPassword
tenant: my_tenant
l3out: my_l3out
node_profile: my_node_profile
pod_id: 1
node_id: 111
loopback_address: ""
delegate_to: localhost

- name: Delete a node from a node profile
cisco.aci.aci_l3out_logical_node:
host: apic
Expand Down Expand Up @@ -243,6 +263,7 @@ def main():
node_id=dict(type="int"),
router_id=dict(type="str"),
router_id_as_loopback=dict(type="str", default="yes", choices=["yes", "no"]),
loopback_address=dict(type="str", aliases=["loopback"]),
gmicol marked this conversation as resolved.
Show resolved Hide resolved
state=dict(type="str", default="present", choices=["absent", "present", "query"]),
)

Expand All @@ -262,6 +283,7 @@ def main():
node_id = module.params.get("node_id")
router_id = module.params.get("router_id")
router_id_as_loopback = module.params.get("router_id_as_loopback")
loopback_address = module.params.get("loopback_address")
state = module.params.get("state")

tdn = None
Expand All @@ -270,6 +292,10 @@ def main():

aci = ACIModule(module)

child_classes = ["l3extLoopBackIfP"]

child_configs = []
gmicol marked this conversation as resolved.
Show resolved Hide resolved

aci.construct_url(
root_class=dict(
aci_class="fvTenant",
Expand All @@ -295,12 +321,25 @@ def main():
module_object=tdn,
target_filter={"name": tdn},
),
child_classes=child_classes,
)

aci.get_existing()

if state == "present":
aci.payload(aci_class="l3extRsNodeL3OutAtt", class_config=dict(rtrId=router_id, rtrIdLoopBack=router_id_as_loopback, tDn=tdn))
if loopback_address is not None:
if loopback_address == "" and isinstance(aci.existing, list) and len(aci.existing) > 0:
for child in aci.existing[0].get("l3extRsNodeL3OutAtt", {}).get("children", []):
previous_loopback_address = child.get("l3extLoopBackIfP", {}).get("attributes", {}).get("addr")
child_configs.append(dict(l3extLoopBackIfP=dict(attributes=dict(addr=previous_loopback_address, status="deleted"))))
elif loopback_address:
child_configs.append(dict(l3extLoopBackIfP=dict(attributes=dict(addr=loopback_address))))

aci.payload(
aci_class="l3extRsNodeL3OutAtt",
class_config=dict(rtrId=router_id, rtrIdLoopBack=router_id_as_loopback, tDn=tdn),
child_configs=child_configs,
)

aci.get_diff(aci_class="l3extRsNodeL3OutAtt")

Expand Down
45 changes: 38 additions & 7 deletions tests/integration/targets/aci_l3out_logical_node/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Author: Marcel Zehnder (@maercu)
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)

- name: Test that we have an ACI APIC host, ACI username and ACI password
fail:
msg: 'Please define the following variables: aci_hostname, aci_username and aci_password.'
when: aci_hostname is not defined or aci_username is not defined or aci_password is not defined

# SET VARS
- name: Set vars
set_fact:
Expand Down Expand Up @@ -79,9 +84,9 @@
- cm_add_node is changed
- nm_add_node is changed
- cm_add_node.previous == nm_add_node.previous == []
- cm_add_node.sent.l3extRsNodeL3OutAtt.attributes.rtrId == nm_add_node.sent.l3extRsNodeL3OutAtt.attributes.rtrId == '111.111.111.111'
- cm_add_node.sent.l3extRsNodeL3OutAtt.attributes.rtrIdLoopBack == nm_add_node.sent.l3extRsNodeL3OutAtt.attributes.rtrIdLoopBack == 'no'
- cm_add_node.sent.l3extRsNodeL3OutAtt.attributes.tDn == nm_add_node.sent.l3extRsNodeL3OutAtt.attributes.tDn == 'topology/pod-1/node-111'
- cm_add_node.sent.l3extRsNodeL3OutAtt.attributes.rtrId == nm_add_node.current.0.l3extRsNodeL3OutAtt.attributes.rtrId == '111.111.111.111'
- cm_add_node.sent.l3extRsNodeL3OutAtt.attributes.rtrIdLoopBack == nm_add_node.current.0.l3extRsNodeL3OutAtt.attributes.rtrIdLoopBack == 'no'
- cm_add_node.sent.l3extRsNodeL3OutAtt.attributes.tDn == nm_add_node.current.0.l3extRsNodeL3OutAtt.attributes.tDn == 'topology/pod-1/node-111'
- nm_add_node.current.0.l3extRsNodeL3OutAtt.attributes.annotation == 'orchestrator:ansible'

- name: Add node again, check if idempotency works
Expand All @@ -101,19 +106,37 @@
router_id: 11.11.11.11
register: update_node

- name: Add loopback address
cisco.aci.aci_l3out_logical_node: &node_add_loopback
<<: *node_update
loopback_address: 11.11.11.12
register: add_loopback_ip

- name: Remove loopback address
cisco.aci.aci_l3out_logical_node: &node_remove_loopback
<<: *node_add_loopback
loopback_address: ""
register: remove_loopback_ip

- name: Verify update_node
assert:
that:
- update_node is changed
- update_node.previous != []
- update_node.sent.l3extRsNodeL3OutAtt.attributes.rtrId == '11.11.11.11'
- update_node.current.0.l3extRsNodeL3OutAtt.attributes.rtrId == '11.11.11.11'
- add_loopback_ip is changed
- add_loopback_ip.previous != []
- add_loopback_ip.current.0.l3extRsNodeL3OutAtt.children.0.l3extLoopBackIfP.attributes.addr == '11.11.11.12'
- remove_loopback_ip is changed
- remove_loopback_ip.previous != []

# ADD ANOTHER NODE
- name: Add another node
cisco.aci.aci_l3out_logical_node:
cisco.aci.aci_l3out_logical_node: &second_node_present
<<: *node_present
node_id: 112
router_id: 12.12.12.12
loopback_address: 12.12.12.13

# QUERY ALL NODES
- name: Query all nodes
Expand All @@ -131,7 +154,7 @@
# QUERY A SPECIFIC NODE
- name: Query a specific node
cisco.aci.aci_l3out_logical_node:
<<: *node_update
<<: *second_node_present
state: query
register: query_spec_node

Expand All @@ -140,11 +163,13 @@
that:
- query_spec_node is not changed
- query_spec_node.current|length == 1
- query_spec_node.current.0.l3extRsNodeL3OutAtt.attributes.rtrId == '12.12.12.12'
- query_spec_node.current.0.l3extRsNodeL3OutAtt.children.0.l3extLoopBackIfP.attributes.addr == '12.12.12.13'

# REMOVE NODE
- name: Remove node
cisco.aci.aci_l3out_logical_node:
<<: *node_update
<<: *node_remove_loopback
state: absent
register: remove_node

Expand All @@ -153,3 +178,9 @@
that:
- remove_node is changed
- remove_node.current == []

- name: Remove test tenant - clean-up the environment
cisco.aci.aci_tenant:
<<: *aci_info
tenant: ansible_test
state: absent
Loading