Skip to content

Commit 2da5a72

Browse files
authored
Fix for tor pairing (#618)
* dcnm_network: Refactor torports handling to accumulate configurations. Fix for #585 * Prevent deletion of TOR uplink port-channels and vPC interfaces in dcnm_interface.py * Skip deletion of TOR uplink member interfaces and vPC interfaces in dcnm_interface.py Fix for #617 * Enhance TOR uplink vPC interface handling to prevent deletion during overrides * Refine TOR member policy check to only include access port member template * Refactor underlayPolicies access to use get() method for safer handling * Refactor alias checks in DcnmIntf to use get() method for safer handling
1 parent f475cdb commit 2da5a72

1 file changed

Lines changed: 100 additions & 1 deletion

File tree

plugins/modules/dcnm_interface.py

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5025,6 +5025,24 @@ def dcnm_intf_get_diff_overridden(self, cfg):
50255025
)
50265026
continue
50275027

5028+
# Skip TOR uplink member interfaces
5029+
if have.get("underlayPolicies") is not None:
5030+
is_tor_member = False
5031+
for policy in have.get("underlayPolicies"):
5032+
if policy.get("templateName") in ["int_vpc_uplink_access_po_member"]:
5033+
is_tor_member = True
5034+
break
5035+
5036+
if is_tor_member:
5037+
self.changed_dict[0]["skipped"].append(
5038+
{
5039+
"Name": name,
5040+
"Alias": have["alias"],
5041+
"Reason": "TOR uplink member interface",
5042+
}
5043+
)
5044+
continue
5045+
50285046
if str(have["deletable"]).lower() == "false":
50295047
# Add this 'have to a deferred list. We will process this list once we have processed all the 'haves'
50305048
defer_list.append(have)
@@ -5157,6 +5175,48 @@ def dcnm_intf_get_diff_overridden(self, cfg):
51575175
}
51585176
)
51595177
continue
5178+
# Port-channel which are created as part of TOR uplink should not be deleted
5179+
# This includes both TOR-side and leaf-side port-channels:
5180+
# - TOR side: "tor-connected-to-vPC-leaf:" or "tor-connected-to-leaf:"
5181+
# - Leaf side: "leaf-connected-to-vPC-tor:" or "leaf-connected-to-tor:"
5182+
if have.get("alias") is not None and (
5183+
"tor-connected-to" in have.get("alias")
5184+
or "leaf-connected-to-vPC-tor" in have.get("alias")
5185+
or "leaf-connected-to-tor" in have.get("alias")
5186+
):
5187+
self.changed_dict[0]["skipped"].append(
5188+
{
5189+
"Name": name,
5190+
"Alias": have["alias"],
5191+
"Underlay Policies": have[
5192+
"underlayPolicies"
5193+
],
5194+
}
5195+
)
5196+
continue
5197+
# Also check if port-channel uses TOR uplink templates
5198+
skip_pc = False
5199+
if have.get("underlayPolicies") is not None:
5200+
tor_uplink_templates = [
5201+
"int_vpc_uplink_access_po",
5202+
"int_port_channel_uplink_access",
5203+
]
5204+
for policy in have.get("underlayPolicies"):
5205+
if policy.get("templateName") in tor_uplink_templates:
5206+
self.changed_dict[0]["skipped"].append(
5207+
{
5208+
"Name": name,
5209+
"Alias": have["alias"],
5210+
"Underlay Policies": have[
5211+
"underlayPolicies"
5212+
],
5213+
"Skip Reason": "TOR uplink port-channel (template match)",
5214+
}
5215+
)
5216+
skip_pc = True
5217+
break
5218+
if skip_pc:
5219+
continue
51605220
else:
51615221
self.changed_dict[0]["debugs"].append(
51625222
{
@@ -5168,10 +5228,49 @@ def dcnm_intf_get_diff_overridden(self, cfg):
51685228
}
51695229
)
51705230

5231+
# TOR uplink vPC interfaces should NEVER be deleted through interface override.
5232+
# TOR uplink vPCs are auto-generated by NDFC when TOR switches are paired
5233+
# with leaf switches. These vPC interfaces (vPC1, vPC2, etc.) represent
5234+
# the uplink bundle between TOR and leaf switches.
5235+
#
5236+
# TOR uplink vPCs can be identified by:
5237+
# - ifType: INTERFACE_VPC
5238+
# - underlayPolicies templateName starting with "int_vpc_uplink_"
5239+
# - alias patterns: "tor-connected-to", "leaf-connected-to-vPC-tor"
5240+
if have.get("ifType") == "INTERFACE_VPC":
5241+
is_tor_uplink = False
5242+
5243+
# Check alias patterns for TOR uplinks
5244+
if have.get("alias") is not None and (
5245+
"tor-connected-to" in have.get("alias")
5246+
or "leaf-connected-to-vPC-tor" in have.get("alias")
5247+
or "leaf-connected-to-tor" in have.get("alias")
5248+
):
5249+
is_tor_uplink = True
5250+
5251+
# Check underlayPolicies templateName for TOR uplink patterns
5252+
if not is_tor_uplink and have.get("underlayPolicies"):
5253+
for policy in have["underlayPolicies"]:
5254+
template_name = policy.get("templateName", "")
5255+
if template_name and template_name.startswith("int_vpc_uplink_"):
5256+
is_tor_uplink = True
5257+
break
5258+
5259+
if is_tor_uplink:
5260+
self.changed_dict[0]["skipped"].append(
5261+
{
5262+
"Name": name,
5263+
"Alias": have["alias"],
5264+
"Underlay Policies": have["underlayPolicies"],
5265+
"Reason": "TOR uplink vPC interface",
5266+
}
5267+
)
5268+
continue
5269+
51715270
# Interfaces sometimes take time to get deleted from DCNM. Such interfaces will have
51725271
# underlayPolicies set to "None". Such interfaces need not be deleted again
51735272

5174-
if have["underlayPolicies"] is None:
5273+
if have.get("underlayPolicies") is None:
51755274
self.changed_dict[0]["skipped"].append(
51765275
{
51775276
"Name": name,

0 commit comments

Comments
 (0)