From ea7187f920909220dfa21b260fb0203f16ee20c6 Mon Sep 17 00:00:00 2001 From: miguecor Date: Fri, 26 Sep 2025 11:50:27 -0600 Subject: [PATCH 1/4] Expand dhcp_servers to 16 --- .../dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 index a29e02956..1c19507ff 100644 --- a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 +++ b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 @@ -42,7 +42,7 @@ dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} dhcp_srvr2_ip: {{ net['dhcp_servers'][1]['ip_address'] }} dhcp_srvr2_vrf: {{ net['dhcp_servers'][1]['vrf'] }} -{% elif net.dhcp_servers | length == 3 %} +{% elif net.dhcp_servers | length >= 3 %} dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} dhcp_srvr2_ip: {{ net['dhcp_servers'][1]['ip_address'] }} @@ -50,6 +50,15 @@ dhcp_srvr3_ip: {{ net['dhcp_servers'][2]['ip_address'] }} dhcp_srvr3_vrf: {{ net['dhcp_servers'][2]['vrf'] }} {% endif %} +{% if net.dhcp_servers | length > 0 %} + dhcp_servers: +{% for dhcp_server in net.dhcp_servers[:16] %} + - srvr_ip: {{ dhcp_server['ip_address'] }} +{% if dhcp_server['vrf'] is defined %} + srvr_vrf: {{ dhcp_server['vrf'] }} +{% endif %} +{% endfor %} +{% endif %} {% endif %} gw_ipv6_subnet: {{ net['gw_ipv6_address'] | default(omit) }} int_desc: {{ net['int_desc'] | default(defaults.vxlan.overlay.networks.net_description) }} From c1961f22300d3c04fd0ba1641754d00f9d082468 Mon Sep 17 00:00:00 2001 From: miguecor Date: Wed, 1 Oct 2025 11:42:57 -0600 Subject: [PATCH 2/4] Fix issue 492 - Add dhcp_servers list --- plugins/action/dtc/manage_child_fabric_networks.py | 1 + .../child_fabric/3.1/msd_child_fabric_network.j2 | 14 ++++++++++++++ .../child_fabric/3.2/msd_child_fabric_network.j2 | 14 ++++++++++++++ .../child_fabric/4.1/msd_child_fabric_network.j2 | 14 ++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/plugins/action/dtc/manage_child_fabric_networks.py b/plugins/action/dtc/manage_child_fabric_networks.py index 17d8a8fcb..2b9e5bcfe 100644 --- a/plugins/action/dtc/manage_child_fabric_networks.py +++ b/plugins/action/dtc/manage_child_fabric_networks.py @@ -43,6 +43,7 @@ # Currently supported Network template config keys and their mapping to data model keys NETWORK_TEMPLATE_CONFIG_MAP = { 'loopbackId': {'dm_key': 'dhcp_loopback_id', 'default': ''}, + 'dhcpServers': {'dm_key': 'dhcp_servers', 'default': ''}, 'ENABLE_NETFLOW': {'dm_key': 'netflow_enable', 'default': False}, 'VLAN_NETFLOW_MONITOR': {'dm_key': 'vlan_netflow_monitor', 'default': ''}, 'trmEnabled': {'dm_key': 'trm_enable', 'default': False}, diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 index 269d89ad7..de13b1701 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 @@ -1,4 +1,17 @@ {# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} +{# Build dhcpServers as a JSON dict (or empty string) #} +{%- set _dhcp_pairs = [] -%} +{%- if dm is defined and dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} + {%- for srvr in dm['dhcp_servers'] -%} + {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} + {%- set _ = _dhcp_pairs.append({ + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] + }) -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} +{%- set _dhcp_obj = {'dhcpServers': _dhcp_pairs} -%} +{%- set dhcpServers = _dhcp_obj if (_dhcp_pairs|length > 0) else '' -%} { "fabric": "{{ fabric_name }}", "networkName": "{{ network_name }}", @@ -30,6 +43,7 @@ "vrfDhcp2": dm['dhcp_servers'][1]['vrf'] if dm['dhcp_servers'][1]['ip_address'] is defined else "", "dhcpServerAddr3": dm['dhcp_servers'][2]['ip_address'] if dm['dhcp_servers'][2]['ip_address'] is defined else ndfc.dhcpServerAddr3, "vrfDhcp3": dm['dhcp_servers'][2]['vrf'] if dm['dhcp_servers'][2]['vrf'] is defined else "", + "dhcpServers": dhcpServers, "ENABLE_NETFLOW": dm.netflow_enable if dm.netflow_enable is defined else ndfc.ENABLE_NETFLOW, "SVI_NETFLOW_MONITOR": ndfc.SVI_NETFLOW_MONITOR, "VLAN_NETFLOW_MONITOR": dm.vlan_netflow_monitor if (dm.netflow_enable is defined and dm.netflow_enable) else ndfc.VLAN_NETFLOW_MONITOR, diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 index f48e4a0b7..a15d237db 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 @@ -1,4 +1,17 @@ {# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} +{# Build dhcpServers as a JSON dict (or empty string) #} +{%- set _dhcp_pairs = [] -%} +{%- if dm is defined and dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} + {%- for srvr in dm['dhcp_servers'] -%} + {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} + {%- set _ = _dhcp_pairs.append({ + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] + }) -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} +{%- set _dhcp_obj = {'dhcpServers': _dhcp_pairs} -%} +{%- set dhcpServers = _dhcp_obj if (_dhcp_pairs|length > 0) else '' -%} { "fabric": "{{ fabric_name }}", "networkName": "{{ network_name }}", @@ -30,6 +43,7 @@ "vrfDhcp2": dm['dhcp_servers'][1]['vrf'] if dm['dhcp_servers'][1]['ip_address'] is defined else "", "dhcpServerAddr3": dm['dhcp_servers'][2]['ip_address'] if dm['dhcp_servers'][2]['ip_address'] is defined else ndfc.dhcpServerAddr3, "vrfDhcp3": dm['dhcp_servers'][2]['vrf'] if dm['dhcp_servers'][2]['vrf'] is defined else "", + "dhcpServers": dhcpServers, "ENABLE_NETFLOW": dm.netflow_enable if dm.netflow_enable is defined else ndfc.ENABLE_NETFLOW, "SVI_NETFLOW_MONITOR": ndfc.SVI_NETFLOW_MONITOR, "VLAN_NETFLOW_MONITOR": dm.vlan_netflow_monitor if (dm.netflow_enable is defined and dm.netflow_enable) else ndfc.VLAN_NETFLOW_MONITOR, diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 index d8687a95f..c267cbcdf 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 @@ -1,4 +1,17 @@ {# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} +{# Build dhcpServers as a JSON dict (or empty string) #} +{%- set _dhcp_pairs = [] -%} +{%- if dm is defined and dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} + {%- for srvr in dm['dhcp_servers'] -%} + {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} + {%- set _ = _dhcp_pairs.append({ + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] + }) -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} +{%- set _dhcp_obj = {'dhcpServers': _dhcp_pairs} -%} +{%- set dhcpServers = _dhcp_obj if (_dhcp_pairs|length > 0) else '' -%} { "fabric": "{{ fabric_name }}", "networkName": "{{ network_name }}", @@ -30,6 +43,7 @@ "vrfDhcp2": dm['dhcp_servers'][1]['vrf'] if dm['dhcp_servers'][1]['ip_address'] is defined else "", "dhcpServerAddr3": dm['dhcp_servers'][2]['ip_address'] if dm['dhcp_servers'][2]['ip_address'] is defined else ndfc.dhcpServerAddr3, "vrfDhcp3": dm['dhcp_servers'][2]['vrf'] if dm['dhcp_servers'][2]['vrf'] is defined else "", + "dhcpServers": dhcpServers, "ENABLE_NETFLOW": dm.netflow_enable if dm.netflow_enable is defined else ndfc.ENABLE_NETFLOW, "SVI_NETFLOW_MONITOR": ndfc.SVI_NETFLOW_MONITOR, "VLAN_NETFLOW_MONITOR": dm.vlan_netflow_monitor if (dm.netflow_enable is defined and dm.netflow_enable) else ndfc.VLAN_NETFLOW_MONITOR, From 496e73b0d7f37f7493319da3ece383d51903a197 Mon Sep 17 00:00:00 2001 From: Miguel Corona Date: Tue, 11 Nov 2025 12:16:14 -0600 Subject: [PATCH 3/4] Remove dependency on dhcp_srvrX_ip and dhcp_srvrX_vrf --- .../dc_vxlan_fabric_networks.j2 | 20 +------------------ .../3.1/msd_child_fabric_network.j2 | 8 +------- .../3.2/msd_child_fabric_network.j2 | 8 +------- .../4.1/msd_child_fabric_network.j2 | 8 +------- .../child_fabric/msd_child_fabric_network.j2 | 19 ++++++++++++------ 5 files changed, 17 insertions(+), 46 deletions(-) diff --git a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 index 0deb2562e..c10bc85d9 100644 --- a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 +++ b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 @@ -34,29 +34,11 @@ arp_suppress: {{ net['arp_suppress'] | default(defaults.vxlan.overlay.networks.arp_supress) }} dhcp_loopback_id: {{ net['dhcp_loopback_id'] | default(omit) }} {% if net.dhcp_servers is defined %} -{% if net.dhcp_servers | length == 1 %} - dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} - dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} -{% elif net.dhcp_servers | length == 2 %} - dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} - dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} - dhcp_srvr2_ip: {{ net['dhcp_servers'][1]['ip_address'] }} - dhcp_srvr2_vrf: {{ net['dhcp_servers'][1]['vrf'] }} -{% elif net.dhcp_servers | length >= 3 %} - dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} - dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} - dhcp_srvr2_ip: {{ net['dhcp_servers'][1]['ip_address'] }} - dhcp_srvr2_vrf: {{ net['dhcp_servers'][1]['vrf'] }} - dhcp_srvr3_ip: {{ net['dhcp_servers'][2]['ip_address'] }} - dhcp_srvr3_vrf: {{ net['dhcp_servers'][2]['vrf'] }} -{% endif %} -{% if net.dhcp_servers | length > 0 %} +{% if net.dhcp_servers | length > 0 and net.dhcp_servers | length <= 16 %} dhcp_servers: {% for dhcp_server in net.dhcp_servers[:16] %} - srvr_ip: {{ dhcp_server['ip_address'] }} -{% if dhcp_server['vrf'] is defined %} srvr_vrf: {{ dhcp_server['vrf'] }} -{% endif %} {% endfor %} {% endif %} {% endif %} diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 index de13b1701..7267af8ee 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 @@ -5,7 +5,7 @@ {%- for srvr in dm['dhcp_servers'] -%} {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} {%- set _ = _dhcp_pairs.append({ - "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] }) -%} {%- endif -%} {%- endfor -%} @@ -37,12 +37,6 @@ "secondaryGW3": ndfc.secondaryGW3, "secondaryGW4": ndfc.secondaryGW4, "loopbackId": dm.dhcp_loopback_id | default(ndfc.loopbackId), - "dhcpServerAddr1": dm['dhcp_servers'][0]['ip_address'] if dm['dhcp_servers'][0]['ip_address'] is defined else "", - "vrfDhcp": dm['dhcp_servers'][0]['vrf'] if dm['dhcp_servers'][0]['ip_address'] is defined else ndfc.vrfDhcp, - "dhcpServerAddr2": dm['dhcp_servers'][1]['ip_address'] if dm['dhcp_servers'][1]['ip_address'] is defined else ndfc.dhcpServerAddr2, - "vrfDhcp2": dm['dhcp_servers'][1]['vrf'] if dm['dhcp_servers'][1]['ip_address'] is defined else "", - "dhcpServerAddr3": dm['dhcp_servers'][2]['ip_address'] if dm['dhcp_servers'][2]['ip_address'] is defined else ndfc.dhcpServerAddr3, - "vrfDhcp3": dm['dhcp_servers'][2]['vrf'] if dm['dhcp_servers'][2]['vrf'] is defined else "", "dhcpServers": dhcpServers, "ENABLE_NETFLOW": dm.netflow_enable if dm.netflow_enable is defined else ndfc.ENABLE_NETFLOW, "SVI_NETFLOW_MONITOR": ndfc.SVI_NETFLOW_MONITOR, diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 index a15d237db..db9c8bcae 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 @@ -5,7 +5,7 @@ {%- for srvr in dm['dhcp_servers'] -%} {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} {%- set _ = _dhcp_pairs.append({ - "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] }) -%} {%- endif -%} {%- endfor -%} @@ -37,12 +37,6 @@ "secondaryGW3": ndfc.secondaryGW3, "secondaryGW4": ndfc.secondaryGW4, "loopbackId": dm.dhcp_loopback_id | default(ndfc.loopbackId), - "dhcpServerAddr1": dm['dhcp_servers'][0]['ip_address'] if dm['dhcp_servers'][0]['ip_address'] is defined else "", - "vrfDhcp": dm['dhcp_servers'][0]['vrf'] if dm['dhcp_servers'][0]['ip_address'] is defined else ndfc.vrfDhcp, - "dhcpServerAddr2": dm['dhcp_servers'][1]['ip_address'] if dm['dhcp_servers'][1]['ip_address'] is defined else ndfc.dhcpServerAddr2, - "vrfDhcp2": dm['dhcp_servers'][1]['vrf'] if dm['dhcp_servers'][1]['ip_address'] is defined else "", - "dhcpServerAddr3": dm['dhcp_servers'][2]['ip_address'] if dm['dhcp_servers'][2]['ip_address'] is defined else ndfc.dhcpServerAddr3, - "vrfDhcp3": dm['dhcp_servers'][2]['vrf'] if dm['dhcp_servers'][2]['vrf'] is defined else "", "dhcpServers": dhcpServers, "ENABLE_NETFLOW": dm.netflow_enable if dm.netflow_enable is defined else ndfc.ENABLE_NETFLOW, "SVI_NETFLOW_MONITOR": ndfc.SVI_NETFLOW_MONITOR, diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 index c267cbcdf..1e0daa3b0 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 @@ -5,7 +5,7 @@ {%- for srvr in dm['dhcp_servers'] -%} {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} {%- set _ = _dhcp_pairs.append({ - "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] }) -%} {%- endif -%} {%- endfor -%} @@ -37,12 +37,6 @@ "secondaryGW3": ndfc.secondaryGW3, "secondaryGW4": ndfc.secondaryGW4, "loopbackId": dm.dhcp_loopback_id | default(ndfc.loopbackId), - "dhcpServerAddr1": dm['dhcp_servers'][0]['ip_address'] if dm['dhcp_servers'][0]['ip_address'] is defined else "", - "vrfDhcp": dm['dhcp_servers'][0]['vrf'] if dm['dhcp_servers'][0]['ip_address'] is defined else ndfc.vrfDhcp, - "dhcpServerAddr2": dm['dhcp_servers'][1]['ip_address'] if dm['dhcp_servers'][1]['ip_address'] is defined else ndfc.dhcpServerAddr2, - "vrfDhcp2": dm['dhcp_servers'][1]['vrf'] if dm['dhcp_servers'][1]['ip_address'] is defined else "", - "dhcpServerAddr3": dm['dhcp_servers'][2]['ip_address'] if dm['dhcp_servers'][2]['ip_address'] is defined else ndfc.dhcpServerAddr3, - "vrfDhcp3": dm['dhcp_servers'][2]['vrf'] if dm['dhcp_servers'][2]['vrf'] is defined else "", "dhcpServers": dhcpServers, "ENABLE_NETFLOW": dm.netflow_enable if dm.netflow_enable is defined else ndfc.ENABLE_NETFLOW, "SVI_NETFLOW_MONITOR": ndfc.SVI_NETFLOW_MONITOR, diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 index f29208713..68135eb89 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 @@ -1,4 +1,16 @@ {# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} +{%- set _dhcp_pairs = [] -%} +{%- if dm is defined and dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} + {%- for srvr in dm['dhcp_servers'] -%} + {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} + {%- set _ = _dhcp_pairs.append({ + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] | default("") + }) -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} +{%- set _dhcp_obj = {'dhcpServers': _dhcp_pairs} -%} +{%- set dhcpServers = _dhcp_obj if (_dhcp_pairs|length > 0) else '' -%} { "fabric": "{{ fabric_name }}", "networkName": "{{ network_name }}", @@ -25,12 +37,7 @@ "secondaryGW3": ndfc.secondaryGW3, "secondaryGW4": ndfc.secondaryGW4, "loopbackId": dm.dhcp_loopback_id | default(ndfc.loopbackId), - "dhcpServerAddr1": dm['dhcp_servers'][0]['ip_address'] if dm['dhcp_servers'][0]['ip_address'] is defined else "", - "vrfDhcp": dm['dhcp_servers'][0]['vrf'] if dm['dhcp_servers'][0]['ip_address'] is defined else ndfc.vrfDhcp, - "dhcpServerAddr2": dm['dhcp_servers'][1]['ip_address'] if dm['dhcp_servers'][1]['ip_address'] is defined else ndfc.dhcpServerAddr2, - "vrfDhcp2": dm['dhcp_servers'][1]['vrf'] if dm['dhcp_servers'][1]['ip_address'] is defined else "", - "dhcpServerAddr3": dm['dhcp_servers'][2]['ip_address'] if dm['dhcp_servers'][2]['ip_address'] is defined else ndfc.dhcpServerAddr3, - "vrfDhcp3": dm['dhcp_servers'][2]['vrf'] if dm['dhcp_servers'][2]['vrf'] is defined else "", + "dhcpServers": dhcpServers, "ENABLE_NETFLOW": dm.netflow_enable if dm.netflow_enable is defined else ndfc.ENABLE_NETFLOW, "SVI_NETFLOW_MONITOR": ndfc.SVI_NETFLOW_MONITOR, "VLAN_NETFLOW_MONITOR": dm.vlan_netflow_monitor if (dm.netflow_enable is defined and dm.netflow_enable) else ndfc.VLAN_NETFLOW_MONITOR, From db5528fd2343f8a0a349250a2f967b020e82adf1 Mon Sep 17 00:00:00 2001 From: Miguel Corona Date: Thu, 13 Nov 2025 20:40:02 -0600 Subject: [PATCH 4/4] Normalized jinja template logic for dhcp_servers definition --- .../dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 | 6 ++---- .../child_fabric/3.1/msd_child_fabric_network.j2 | 15 ++++++--------- .../child_fabric/3.2/msd_child_fabric_network.j2 | 15 ++++++--------- .../child_fabric/msd_child_fabric_network.j2 | 14 ++++++-------- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 index c10bc85d9..a4d031f55 100644 --- a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 +++ b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 @@ -33,14 +33,12 @@ {% endif %} arp_suppress: {{ net['arp_suppress'] | default(defaults.vxlan.overlay.networks.arp_supress) }} dhcp_loopback_id: {{ net['dhcp_loopback_id'] | default(omit) }} -{% if net.dhcp_servers is defined %} -{% if net.dhcp_servers | length > 0 and net.dhcp_servers | length <= 16 %} +{% if net.dhcp_servers is defined and net.dhcp_servers %} dhcp_servers: -{% for dhcp_server in net.dhcp_servers[:16] %} +{% for dhcp_server in net.dhcp_servers %} - srvr_ip: {{ dhcp_server['ip_address'] }} srvr_vrf: {{ dhcp_server['vrf'] }} {% endfor %} -{% endif %} {% endif %} gw_ipv6_subnet: {{ net['gw_ipv6_address'] | default(omit) }} int_desc: {{ net['int_desc'] | default(defaults.vxlan.overlay.networks.net_description) }} diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 index 7267af8ee..07a86a5c8 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 @@ -1,14 +1,11 @@ {# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} -{# Build dhcpServers as a JSON dict (or empty string) #} {%- set _dhcp_pairs = [] -%} -{%- if dm is defined and dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} - {%- for srvr in dm['dhcp_servers'] -%} - {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} - {%- set _ = _dhcp_pairs.append({ - "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] - }) -%} - {%- endif -%} - {%- endfor -%} +{%- if dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} +{%- for srvr in dm['dhcp_servers'] -%} +{%- set _ = _dhcp_pairs.append({ + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] | default("") +}) -%} +{%- endfor -%} {%- endif -%} {%- set _dhcp_obj = {'dhcpServers': _dhcp_pairs} -%} {%- set dhcpServers = _dhcp_obj if (_dhcp_pairs|length > 0) else '' -%} diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 index db9c8bcae..750f0764f 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 @@ -1,14 +1,11 @@ {# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} -{# Build dhcpServers as a JSON dict (or empty string) #} {%- set _dhcp_pairs = [] -%} -{%- if dm is defined and dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} - {%- for srvr in dm['dhcp_servers'] -%} - {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} - {%- set _ = _dhcp_pairs.append({ - "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] - }) -%} - {%- endif -%} - {%- endfor -%} +{%- if dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} +{%- for srvr in dm['dhcp_servers'] -%} +{%- set _ = _dhcp_pairs.append({ + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] | default("") +}) -%} +{%- endfor -%} {%- endif -%} {%- set _dhcp_obj = {'dhcpServers': _dhcp_pairs} -%} {%- set dhcpServers = _dhcp_obj if (_dhcp_pairs|length > 0) else '' -%} diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 index 68135eb89..603384aea 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 @@ -1,13 +1,11 @@ {# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} {%- set _dhcp_pairs = [] -%} -{%- if dm is defined and dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} - {%- for srvr in dm['dhcp_servers'] -%} - {%- if srvr['ip_address'] is defined and srvr['ip_address'] -%} - {%- set _ = _dhcp_pairs.append({ - "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] | default("") - }) -%} - {%- endif -%} - {%- endfor -%} +{%- if dm['dhcp_servers'] is defined and dm['dhcp_servers'] -%} +{%- for srvr in dm['dhcp_servers'] -%} +{%- set _ = _dhcp_pairs.append({ + "srvrAddr": srvr['ip_address'], "srvrVrf": srvr['vrf'] | default("") +}) -%} +{%- endfor -%} {%- endif -%} {%- set _dhcp_obj = {'dhcpServers': _dhcp_pairs} -%} {%- set dhcpServers = _dhcp_obj if (_dhcp_pairs|length > 0) else '' -%}