From f56435ede25ea4c6916e61ae31498924c46eef90 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 9 Oct 2025 10:46:16 -0400 Subject: [PATCH 01/17] updates for using vrf module solely for msd-level vrf mgmt --- roles/dtc/common/tasks/sub_main_msd.yml | 5 ++ .../dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 | 2 +- .../msd_fabric/child_fabric/3.1/.gitkeep | 0 .../child_fabric/3.1/msd_child_fabric_vrf.j2 | 51 ---------------- .../msd_fabric/child_fabric/3.2/.gitkeep | 0 .../child_fabric/3.2/msd_child_fabric_vrf.j2 | 58 ------------------- .../msd_fabric/child_fabric/4.1/.gitkeep | 0 .../child_fabric/4.1/msd_child_fabric_vrf.j2 | 58 ------------------- .../child_fabric/msd_child_fabric_vrf.j2 | 58 ------------------- .../child_fabric/msd_child_fabric_vrfs.j2 | 34 ----------- .../ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 | 37 ++++++++++++ roles/dtc/create/tasks/msd/vrfs_networks.yml | 14 ++--- 12 files changed, 47 insertions(+), 270 deletions(-) delete mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.1/.gitkeep delete mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.1/msd_child_fabric_vrf.j2 delete mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.2/.gitkeep delete mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.2/msd_child_fabric_vrf.j2 delete mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/4.1/.gitkeep delete mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/4.1/msd_child_fabric_vrf.j2 delete mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrf.j2 delete mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrfs.j2 diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index f1c09d880..37f2b121c 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -65,6 +65,11 @@ # Build MSD Fabric VRFs Attach List From Template # ------------------------------------------------------------------------ +# This is not used for MSD as VRFs and Networks are handled in create/sub_main_msd.yml +# because we need to process the Multsite data first before we can process the VRFs, +# mainly for switch attachment data as MSD fabrics do not have switches declared in +# the data model as this a function of the child fabric to manage device inventory. + # - name: Build MSD Fabric VRFs Attach List From Template # ansible.builtin.import_tasks: msd/ndfc_vrfs.yml diff --git a/roles/dtc/common/templates/ndfc_vrfs/dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 b/roles/dtc/common/templates/ndfc_vrfs/dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 index f17f321ba..4b268c20d 100644 --- a/roles/dtc/common/templates/ndfc_vrfs/dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_vrfs/dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 @@ -11,6 +11,7 @@ {# ------------------------------------------------------ #} vrf_id: {{ vrf['vrf_id'] | default(omit) }} vlan_id: {{ vrf['vlan_id'] | default(omit) }} + l3vni_wo_vlan: {{ vrf['enable_l3_vni_no_vlan'] | default(defaults.vxlan.global[simplified_fabric_type].enable_l3_vni_no_vlan) }} vrf_vlan_name: {{ vrf['vrf_vlan_name'] | default(omit) }} vrf_intf_desc: {{ vrf['vrf_intf_desc'] | default(defaults.vxlan.overlay.vrfs.vrf_intf_desc) }} vrf_description: {{ vrf['vrf_description'] | default(defaults.vxlan.overlay.vrfs.vrf_description) }} @@ -32,7 +33,6 @@ import_mvpn_rt: {{ vrf['import_mvpn_rt'] | default(omit) }} import_vpn_rt: {{ vrf['import_vpn_rt'] | default(omit) }} netflow_enable: {{ vrf['netflow_enable'] | default(defaults.vxlan.overlay.vrfs.netflow_enable) }} - l3vni_wo_vlan: {{ vrf['enable_l3_vni_no_vlan'] | default(defaults.vxlan.global[simplified_fabric_type].enable_l3_vni_no_vlan) }} {% if vrf['netflow_enable'] is defined and vrf['netflow_enable'] | bool %} nf_monitor: {{ vrf['netflow_monitor'] }} {% endif %} diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.1/.gitkeep b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.1/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.1/msd_child_fabric_vrf.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.1/msd_child_fabric_vrf.j2 deleted file mode 100644 index 40ea0b195..000000000 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.1/msd_child_fabric_vrf.j2 +++ /dev/null @@ -1,51 +0,0 @@ -{# Auto-generated NDFC VXLAN EVPN MSD Child Fabric VRF config data structure for fabric {{ fabric_name }} #} -{ - "fabric": "{{ fabric_name }}", - "vrfName": "{{ ndfc.vrfName }}", - "vrfTemplate": "Default_VRF_Universal", - "vrfExtensionTemplate": "Default_VRF_Extension_Universal", - "vrfTemplateConfig": "{{ { - "asn": ndfc.asn, - "nveId": ndfc.nveId, - "vrfName": ndfc.vrfName, - "vrfSegmentId": ndfc.vrfSegmentId, - "vrfVlanId": ndfc.vrfVlanId, - "vrfVlanName": ndfc.vrfVlanName, - "vrfDescription": ndfc.vrfDescription, - "vrfIntfDescription": ndfc.vrfIntfDescription, - "mtu": ndfc.mtu, - "tag": ndfc.tag, - "vrfRouteMap": ndfc.vrfRouteMap, - "maxBgpPaths": ndfc.maxBgpPaths, - "maxIbgpPaths": ndfc.maxIbgpPaths, - "ipv6LinkLocalFlag": ndfc.ipv6LinkLocalFlag, - "enableL3VniNoVlan": ndfc.enableL3VniNoVlan, - "advertiseHostRouteFlag": dm.adv_host_routes | default(ndfc.advertiseHostRouteFlag), - "advertiseDefaultRouteFlag": dm.adv_default_routes | default(ndfc.advertiseDefaultRouteFlag), - "configureStaticDefaultRouteFlag": dm.static_default_route | default(ndfc.configureStaticDefaultRouteFlag), - "bgpPassword": dm.bgp_password | default(ndfc.bgpPassword), - "bgpPasswordKeyType": dm.bgp_password_encryption_type | default(ndfc.bgpPasswordKeyType) | default(""), - "ENABLE_NETFLOW": dm.enable_netflow if dm.enable_netflow is defined else ndfc.ENABLE_NETFLOW, - "NETFLOW_MONITOR": dm.netflow_monitor if (dm.enable_netflow is defined and dm.enable_netflow) else ndfc.NETFLOW_MONITOR, - "trmEnabled": dm.trm_enable if dm.trm_enable is defined else ndfc.trmEnabled, - "loopbackNumber": dm.rp_loopback_id if (dm.rp_loopback_id is defined and ((not dm.no_rp | default(ndfc.isRPAbsent) | bool) or (not dm.rp_external | default(ndfc.isRPExternal) | bool))) else ndfc.loopbackNumber | default(""), - "rpAddress": dm.rp_address if (dm.rp_address is defined and (not dm.no_rp | default(ndfc.isRPAbsent) | bool)) else ndfc.rpAddress | default(""), - "isRPAbsent": dm.no_rp | default(ndfc.isRPAbsent), - "isRPExternal": dm.rp_external | default(ndfc.isRPExternal), - "L3VniMcastGroup": dm.underlay_mcast_ip | default(ndfc.L3VniMcastGroup) | default(""), - "multicastGroup": dm.overlay_multicast_group | default(ndfc.multicastGroup) if (dm.overlay_multicast_group is defined and (not dm.no_rp | default(ndfc.isRPAbsent) | bool)) else ndfc.multicastGroup, - "disableRtAuto": ndfc.disableRtAuto, - "routeTargetImport": ndfc.routeTargetImport, - "routeTargetExport": ndfc.routeTargetExport, - "routeTargetImportEvpn": ndfc.routeTargetImportEvpn, - "routeTargetExportEvpn": ndfc.routeTargetExportEvpn, - "routeTargetImportMvpn": dm.import_mvpn_rt | default(ndfc.routeTargetImportMvpn) | default(""), - "routeTargetExportMvpn": dm.export_mvpn_rt | default(ndfc.routeTargetExportMvpn) | default(""), - "mvpnInterAs": ndfc.mvpnInterAs, - "trmBGWMSiteEnabled": dm.trm_bgw_msite | default(ndfc.trmBGWMSiteEnabled) - } }}", - "vrfId": "{{ ndfc.vrfSegmentId }}", - "hierarchicalKey": "{{ fabric_name }}", - "vrfVlanId": "{{ ndfc.vrfVlanId }}", - "displayName": "{{ ndfc.vrfName }}" -} diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.2/.gitkeep b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.2/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.2/msd_child_fabric_vrf.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.2/msd_child_fabric_vrf.j2 deleted file mode 100644 index 9e1ebb443..000000000 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/3.2/msd_child_fabric_vrf.j2 +++ /dev/null @@ -1,58 +0,0 @@ -{# Auto-generated NDFC VXLAN EVPN MSD Child Fabric VRF config data structure for fabric {{ fabric_name }} #} -{ - "fabric": "{{ fabric_name }}", - "vrfName": "{{ ndfc.vrfName }}", - "vrfTemplate": "Default_VRF_Universal", - "vrfExtensionTemplate": "Default_VRF_Extension_Universal", - "vrfTemplateConfig": "{{ { - "asn": ndfc.asn, - "nveId": ndfc.nveId, - "vrfName": ndfc.vrfName, - "vrfSegmentId": ndfc.vrfSegmentId, - "vrfVlanId": ndfc.vrfVlanId, - "vrfVlanName": ndfc.vrfVlanName, - "vrfDescription": ndfc.vrfDescription, - "vrfIntfDescription": ndfc.vrfIntfDescription, - "mtu": ndfc.mtu, - "tag": ndfc.tag, - "vrfRouteMap": ndfc.vrfRouteMap, - "v6VrfRouteMap": ndfc.v6VrfRouteMap, - "maxBgpPaths": ndfc.maxBgpPaths, - "maxIbgpPaths": ndfc.maxIbgpPaths, - "ipv6LinkLocalFlag": ndfc.ipv6LinkLocalFlag, - "enableL3VniNoVlan": dm.enable_l3_vni_no_vlan if dm.enable_l3_vni_no_vlan is defined else ndfc.enableL3VniNoVlan, - "enableBgpBestPathEcmp": ndfc.enableBgpBestPathEcmp, - "advertiseHostRouteFlag": dm.adv_host_routes | default(ndfc.advertiseHostRouteFlag), - "advertiseDefaultRouteFlag": dm.adv_default_routes | default(ndfc.advertiseDefaultRouteFlag), - "configureStaticDefaultRouteFlag": dm.static_default_route | default(ndfc.configureStaticDefaultRouteFlag), - "bgpPassword": dm.bgp_password | default(ndfc.bgpPassword), - "bgpPasswordKeyType": dm.bgp_password_encryption_type | default(ndfc.bgpPasswordKeyType) | default(""), - "ENABLE_NETFLOW": dm.enable_netflow if dm.enable_netflow is defined else ndfc.ENABLE_NETFLOW, - "NETFLOW_MONITOR": dm.netflow_monitor if (dm.enable_netflow is defined and dm.enable_netflow) else ndfc.NETFLOW_MONITOR, - "trmEnabled": dm.trm_enable if dm.trm_enable is defined else ndfc.trmEnabled, - "loopbackNumber": dm.rp_loopback_id if (dm.rp_loopback_id is defined and ((not dm.no_rp | default(ndfc.isRPAbsent) | bool) or (not dm.rp_external | default(ndfc.isRPExternal) | bool))) else ndfc.loopbackNumber | default(""), - "rpAddress": dm.rp_address if (dm.rp_address is defined and (not dm.no_rp | default(ndfc.isRPAbsent) | bool)) else ndfc.rpAddress | default(""), - "isRPAbsent": dm.no_rp | default(ndfc.isRPAbsent), - "isRPExternal": dm.rp_external | default(ndfc.isRPExternal), - "L3VniMcastGroup": dm.underlay_mcast_ip | default(ndfc.L3VniMcastGroup) | default(""), - "multicastGroup": dm.overlay_multicast_group | default(ndfc.multicastGroup) if (dm.overlay_multicast_group is defined and (not dm.no_rp | default(ndfc.isRPAbsent) | bool)) else ndfc.multicastGroup, - "trmV6Enabled": ndfc.trmV6Enabled, - "rpV6Address": ndfc.rpV6Address if ndfc.rpV6Address is defined else "", - "isV6RPAbsent": ndfc.isV6RPAbsent, - "isV6RPExternal": ndfc.isV6RPExternal, - "ipv6MulticastGroup": ndfc.ipv6MulticastGroup, - "disableRtAuto": ndfc.disableRtAuto, - "routeTargetImport": ndfc.routeTargetImport, - "routeTargetExport": ndfc.routeTargetExport, - "routeTargetImportEvpn": ndfc.routeTargetImportEvpn, - "routeTargetExportEvpn": ndfc.routeTargetExportEvpn, - "routeTargetImportMvpn": dm.import_mvpn_rt | default(ndfc.routeTargetImportMvpn) | default(""), - "routeTargetExportMvpn": dm.export_mvpn_rt | default(ndfc.routeTargetExportMvpn) | default(""), - "mvpnInterAs": ndfc.mvpnInterAs, - "trmBGWMSiteEnabled": dm.trm_bgw_msite | default(ndfc.trmBGWMSiteEnabled) - } }}", - "vrfId": "{{ ndfc.vrfSegmentId }}", - "hierarchicalKey": "{{ fabric_name }}", - "vrfVlanId": "{{ ndfc.vrfVlanId }}", - "displayName": "{{ ndfc.vrfName }}" -} diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/4.1/.gitkeep b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/4.1/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/4.1/msd_child_fabric_vrf.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/4.1/msd_child_fabric_vrf.j2 deleted file mode 100644 index 9e1ebb443..000000000 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/4.1/msd_child_fabric_vrf.j2 +++ /dev/null @@ -1,58 +0,0 @@ -{# Auto-generated NDFC VXLAN EVPN MSD Child Fabric VRF config data structure for fabric {{ fabric_name }} #} -{ - "fabric": "{{ fabric_name }}", - "vrfName": "{{ ndfc.vrfName }}", - "vrfTemplate": "Default_VRF_Universal", - "vrfExtensionTemplate": "Default_VRF_Extension_Universal", - "vrfTemplateConfig": "{{ { - "asn": ndfc.asn, - "nveId": ndfc.nveId, - "vrfName": ndfc.vrfName, - "vrfSegmentId": ndfc.vrfSegmentId, - "vrfVlanId": ndfc.vrfVlanId, - "vrfVlanName": ndfc.vrfVlanName, - "vrfDescription": ndfc.vrfDescription, - "vrfIntfDescription": ndfc.vrfIntfDescription, - "mtu": ndfc.mtu, - "tag": ndfc.tag, - "vrfRouteMap": ndfc.vrfRouteMap, - "v6VrfRouteMap": ndfc.v6VrfRouteMap, - "maxBgpPaths": ndfc.maxBgpPaths, - "maxIbgpPaths": ndfc.maxIbgpPaths, - "ipv6LinkLocalFlag": ndfc.ipv6LinkLocalFlag, - "enableL3VniNoVlan": dm.enable_l3_vni_no_vlan if dm.enable_l3_vni_no_vlan is defined else ndfc.enableL3VniNoVlan, - "enableBgpBestPathEcmp": ndfc.enableBgpBestPathEcmp, - "advertiseHostRouteFlag": dm.adv_host_routes | default(ndfc.advertiseHostRouteFlag), - "advertiseDefaultRouteFlag": dm.adv_default_routes | default(ndfc.advertiseDefaultRouteFlag), - "configureStaticDefaultRouteFlag": dm.static_default_route | default(ndfc.configureStaticDefaultRouteFlag), - "bgpPassword": dm.bgp_password | default(ndfc.bgpPassword), - "bgpPasswordKeyType": dm.bgp_password_encryption_type | default(ndfc.bgpPasswordKeyType) | default(""), - "ENABLE_NETFLOW": dm.enable_netflow if dm.enable_netflow is defined else ndfc.ENABLE_NETFLOW, - "NETFLOW_MONITOR": dm.netflow_monitor if (dm.enable_netflow is defined and dm.enable_netflow) else ndfc.NETFLOW_MONITOR, - "trmEnabled": dm.trm_enable if dm.trm_enable is defined else ndfc.trmEnabled, - "loopbackNumber": dm.rp_loopback_id if (dm.rp_loopback_id is defined and ((not dm.no_rp | default(ndfc.isRPAbsent) | bool) or (not dm.rp_external | default(ndfc.isRPExternal) | bool))) else ndfc.loopbackNumber | default(""), - "rpAddress": dm.rp_address if (dm.rp_address is defined and (not dm.no_rp | default(ndfc.isRPAbsent) | bool)) else ndfc.rpAddress | default(""), - "isRPAbsent": dm.no_rp | default(ndfc.isRPAbsent), - "isRPExternal": dm.rp_external | default(ndfc.isRPExternal), - "L3VniMcastGroup": dm.underlay_mcast_ip | default(ndfc.L3VniMcastGroup) | default(""), - "multicastGroup": dm.overlay_multicast_group | default(ndfc.multicastGroup) if (dm.overlay_multicast_group is defined and (not dm.no_rp | default(ndfc.isRPAbsent) | bool)) else ndfc.multicastGroup, - "trmV6Enabled": ndfc.trmV6Enabled, - "rpV6Address": ndfc.rpV6Address if ndfc.rpV6Address is defined else "", - "isV6RPAbsent": ndfc.isV6RPAbsent, - "isV6RPExternal": ndfc.isV6RPExternal, - "ipv6MulticastGroup": ndfc.ipv6MulticastGroup, - "disableRtAuto": ndfc.disableRtAuto, - "routeTargetImport": ndfc.routeTargetImport, - "routeTargetExport": ndfc.routeTargetExport, - "routeTargetImportEvpn": ndfc.routeTargetImportEvpn, - "routeTargetExportEvpn": ndfc.routeTargetExportEvpn, - "routeTargetImportMvpn": dm.import_mvpn_rt | default(ndfc.routeTargetImportMvpn) | default(""), - "routeTargetExportMvpn": dm.export_mvpn_rt | default(ndfc.routeTargetExportMvpn) | default(""), - "mvpnInterAs": ndfc.mvpnInterAs, - "trmBGWMSiteEnabled": dm.trm_bgw_msite | default(ndfc.trmBGWMSiteEnabled) - } }}", - "vrfId": "{{ ndfc.vrfSegmentId }}", - "hierarchicalKey": "{{ fabric_name }}", - "vrfVlanId": "{{ ndfc.vrfVlanId }}", - "displayName": "{{ ndfc.vrfName }}" -} diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrf.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrf.j2 deleted file mode 100644 index 6b907f2f1..000000000 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrf.j2 +++ /dev/null @@ -1,58 +0,0 @@ -{# Auto-generated NDFC VXLAN EVPN MSD Child Fabric VRF config data structure for fabric {{ fabric_name }} #} -{ - "fabric": "{{ fabric_name }}", - "vrfName": "{{ ndfc.vrfName }}", - "vrfTemplate": "Default_VRF_Universal", - "vrfExtensionTemplate": "Default_VRF_Extension_Universal", - "vrfTemplateConfig": "{{ { - "asn": ndfc.asn, - "nveId": ndfc.nveId, - "vrfName": ndfc.vrfName, - "vrfSegmentId": ndfc.vrfSegmentId, - "vrfVlanId": ndfc.vrfVlanId, - "vrfVlanName": ndfc.vrfVlanName, - "vrfDescription": ndfc.vrfDescription, - "vrfIntfDescription": ndfc.vrfIntfDescription, - "mtu": ndfc.mtu, - "tag": ndfc.tag, - "vrfRouteMap": ndfc.vrfRouteMap, - "v6VrfRouteMap": ndfc.v6VrfRouteMap, - "maxBgpPaths": ndfc.maxBgpPaths, - "maxIbgpPaths": ndfc.maxIbgpPaths, - "ipv6LinkLocalFlag": ndfc.ipv6LinkLocalFlag, - "enableL3VniNoVlan": ndfc.enableL3VniNoVlan, - "enableBgpBestPathEcmp": ndfc.enableBgpBestPathEcmp, - "advertiseHostRouteFlag": dm.adv_host_routes | default(ndfc.advertiseHostRouteFlag), - "advertiseDefaultRouteFlag": dm.adv_default_routes | default(ndfc.advertiseDefaultRouteFlag), - "configureStaticDefaultRouteFlag": dm.static_default_route | default(ndfc.configureStaticDefaultRouteFlag), - "bgpPassword": dm.bgp_password | default(ndfc.bgpPassword), - "bgpPasswordKeyType": dm.bgp_password_encryption_type | default(ndfc.bgpPasswordKeyType) | default(""), - "ENABLE_NETFLOW": dm.enable_netflow if dm.enable_netflow is defined else ndfc.ENABLE_NETFLOW, - "NETFLOW_MONITOR": dm.netflow_monitor if (dm.enable_netflow is defined and dm.enable_netflow) else ndfc.NETFLOW_MONITOR, - "trmEnabled": dm.trm_enable if dm.trm_enable is defined else ndfc.trmEnabled, - "loopbackNumber": dm.rp_loopback_id if ((dm.no_rp is defined and not dm.no_rp | default(ndfc.isRPAbsent)) or (dm.rp_external is defined and not dm.rp_external | default(ndfc.isRPExternal))) else ndfc.loopbackNumber | default(""), - "rpAddress": dm.rp_address if (dm.no_rp is defined and not dm.no_rp) else ndfc.rpAddress | default(""), - "isRPAbsent": dm.no_rp | default(ndfc.isRPAbsent), - "isRPExternal": dm.rp_external | default(ndfc.isRPExternal), - "L3VniMcastGroup": dm.underlay_mcast_ip | default(ndfc.L3VniMcastGroup) | default(""), - "multicastGroup": dm.overlay_multicast_group | default(ndfc.multicastGroup) if (dm.no_rp is defined and not dm.no_rp | default(ndfc.isRPAbsent)) else ndfc.multicastGroup, - "trmV6Enabled": ndfc.trmV6Enabled, - "rpV6Address": ndfc.rpV6Address if ndfc.rpV6Address is defined else "", - "isV6RPAbsent": ndfc.isV6RPAbsent, - "isV6RPExternal": ndfc.isV6RPExternal, - "ipv6MulticastGroup": ndfc.ipv6MulticastGroup, - "disableRtAuto": ndfc.disableRtAuto, - "routeTargetImport": ndfc.routeTargetImport, - "routeTargetExport": ndfc.routeTargetExport, - "routeTargetImportEvpn": ndfc.routeTargetImportEvpn, - "routeTargetExportEvpn": ndfc.routeTargetExportEvpn, - "routeTargetImportMvpn": dm.import_mvpn_rt | default(ndfc.routeTargetImportMvpn) | default(""), - "routeTargetExportMvpn": dm.export_mvpn_rt | default(ndfc.routeTargetExportMvpn) | default(""), - "mvpnInterAs": ndfc.mvpnInterAs, - "trmBGWMSiteEnabled": dm.trm_bgw_msite | default(ndfc.trmBGWMSiteEnabled) - } }}", - "vrfId": "{{ ndfc.vrfSegmentId }}", - "hierarchicalKey": "{{ fabric_name }}", - "vrfVlanId": "{{ ndfc.vrfVlanId }}", - "displayName": "{{ ndfc.vrfName }}" -} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrfs.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrfs.j2 deleted file mode 100644 index 983414029..000000000 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrfs.j2 +++ /dev/null @@ -1,34 +0,0 @@ -{# Auto-generated NDFC VXLAN EVPN MSD VRFs config data structure for fabric {{ vxlan.fabric.name }} #} -{% set vrfs = [] %} -{% if MD_Extended.vxlan.multisite.overlay.vrfs is defined and MD_Extended.vxlan.multisite.overlay.vrfs %} -{% set vrfs = MD_Extended.vxlan.multisite.overlay.vrfs %} -{% endif %} -{% for vrf in vrfs %} -- vrf_name: {{ vrf['name'] }} -{# ------------------------------------------------------ #} -{# Properties Section #} -{# ------------------------------------------------------ #} - vrf_id: {{ vrf['vrf_id'] | default(omit) }} - vlan_id: {{ vrf['vlan_id'] | default(omit) }} - adv_host_routes: {{ vrf['adv_host_routes'] | default(defaults.vxlan.overlay.vrfs.adv_host_routes) }} - adv_default_routes: {{ vrf['adv_default_routes'] | default(defaults.vxlan.overlay.vrfs.adv_default_routes) }} - static_default_route: {{ vrf['static_default_route'] | default(defaults.vxlan.overlay.vrfs.static_default_route) }} - bgp_password: {{ vrf['bgp_password'] | default(omit) }} - bgp_password_encryption_type: {{ vrf['bgp_password_encryption_type'] | default(omit) }} - netflow_enable: {{ vrf['netflow_enable'] | default(defaults.vxlan.overlay.vrfs.netflow_enable) }} -{% if vrf['netflow_enable'] is defined and vrf['netflow_enable'] | bool %} - nf_monitor: {{ vrf['netflow_monitor'] }} -{% endif %} - no_rp: {{ vrf['no_rp'] | default(defaults.vxlan.overlay.vrfs.no_rp) }} - trm_enable: {{ vrf['trm_enable'] | default(defaults.vxlan.overlay.vrfs.trm_enable) }} -{% if vrf['trm_enable'] is defined and vrf['trm_enable'] | bool %} - overlay_mcast_group: {{ vrf['overlay_multicast_group'] | default(omit) }} - rp_address: {{ vrf['rp_address'] | default(omit) }} - rp_external: {{ vrf['rp_external'] | default(omit) }} - rp_loopback_id: {{ vrf['rp_loopback_id'] | default(omit) }} - trm_bgw_msite: {{ vrf['trm_bgw_msite'] | default(defaults.vxlan.overlay.vrfs.trm_bgw_msite) }} - underlay_mcast_ip: {{ vrf['underlay_mcast_ip'] | default(omit) }} -{% endif %} - import_mvpn_rt: {{ vrf['import_mvpn_rt'] | default(omit) }} - export_mvpn_rt: {{ vrf['export_mvpn_rt'] | default(omit) }} -{% endfor %} diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 index 4b0b39897..f9d02cc0e 100644 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 @@ -29,6 +29,43 @@ {% if (ndfc_version | cisco.nac_dc_vxlan.version_compare('12.2.2', '>=')) %} v6_redist_direct_rmap: {{ vrf['ipv6_redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.ipv6_redist_direct_routemap) }} {% endif %} +{% if vrf.child_fabrics is defined and vrf.child_fabrics %} +{% set child_fabrics = vrf.child_fabrics %} +{% else %} +{% set child_fabrics = [] %} +{% endif %} + child_fabric_config: +{% for child_fabric in child_fabrics %} + - fabric_name: {{ child_fabric['name'] | default(omit) }} + l3vni_wo_vlan: {{ child_fabric['enable_l3_vni_no_vlan'] | default(omit) }} + adv_host_routes: {{ child_fabric['adv_host_routes'] | default(omit) }} + adv_default_routes: {{ child_fabric['adv_default_routes'] | default(omit) }} + static_default_route: {{ child_fabric['static_default_route'] | default(omit) }} + bgp_password: {{ child_fabric['bgp_password'] | default(omit) }} + bgp_password_encryption_type: {{ child_fabric['bgp_password_encryption_type'] | default(omit) }} + import_mvpn_rt: {{ child_fabric['import_mvpn_rt'] | default(omit) }} + export_mvpn_rt: {{ child_fabric['export_mvpn_rt'] | default(omit) }} + netflow_enable: {{ child_fabric['netflow_enable'] | default(omit) }} +{% if child_fabric['netflow_enable'] is defined and child_fabric['netflow_enable'] | bool %} + nf_monitor: {{ child_fabric['netflow_monitor'] | default(omit) }} +{% endif %} + no_rp: {{ child_fabric['no_rp'] | default(omit) }} + trm_enable: {{ child_fabric['trm_enable'] | default(omit) }} +{% if child_fabric['trm_enable'] is defined and child_fabric['trm_enable'] | bool %} + overlay_mcast_group: {{ child_fabric['overlay_multicast_group'] | default(omit) }} + rp_address: {{ child_fabric['rp_address'] | default(omit) }} + rp_external: {{ child_fabric['rp_external'] | default(omit) }} + rp_loopback_id: {{ child_fabric['rp_loopback_id'] | default(omit) }} + trm_bgw_msite: {{ child_fabric['trm_bgw_msite'] | default(omit) }} +{# Staging trmv6 attributes for later usage after low-level collection adds support. #} +{# trmv6_enable: {{ child_fabric['trmv6_enable'] | default(omit) }} #} +{# trmv6_no_rp: {{ child_fabric['trmv6_no_rp'] | default(omit) }} #} +{# trmv6_overlay_mcast_group: {{ child_fabric['trmv6_overlay_multicast_group'] | default(omit) }} #} +{# trmv6_rp_address: {{ child_fabric['trmv6_rp_address'] | default(omit) }} #} +{# trmv6_rp_external: {{ child_fabric['trmv6_rp_external'] | default(omit) }} #} + underlay_mcast_ip: {{ child_fabric['underlay_mcast_ip'] | default(omit) }} +{% endif %} +{% endfor %} {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} diff --git a/roles/dtc/create/tasks/msd/vrfs_networks.yml b/roles/dtc/create/tasks/msd/vrfs_networks.yml index e71faa4e8..4be5ef1ad 100644 --- a/roles/dtc/create/tasks/msd/vrfs_networks.yml +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Cisco Systems, Inc. and its affiliates +# Copyright (c) 2025 Cisco Systems, Inc. and its affiliates # # Permission is hereby granted, free of charge, to any person obtaining a copy of # this software and associated documentation files (the "Software"), to deal in @@ -91,13 +91,13 @@ - "+ Force Run Flag - [ {{ force_run_all }} ]" - "----------------------------------------------------------------" -# With the VRFs and Networking pre-processed, we can now send the configuration for the MSD fabric to NDFC -# based on the detected changes. This is done in the following tasks. +# With the VRFs and Networking pre-processed, we can now send the configuration for the MSD fabric to ND/NDFC +# based on the detected changes. This is done in the next task. # -------------------------------------------------------------------- # Manage VRF Configuration on NDFC # -------------------------------------------------------------------- -# The cisco.dcnm.dcnm_vrf module works for MSD fabrics to create and update VRFs. + - name: Manage MSD Fabric VRFs in Nexus Dashboard cisco.dcnm.dcnm_vrf: fabric: "{{ MD_Extended.vxlan.fabric.name }}" @@ -109,12 +109,6 @@ - MD_Extended.vxlan.multisite.overlay.vrfs - vars_common_msd.changes_detected_vrfs -- name: Manage Child Fabric VRFs in Nexus Dashboard - cisco.nac_dc_vxlan.dtc.manage_child_fabric_vrfs: - nd_version: "{{ nd_version }}" - msite_data: "{{ MD_Multisite }}" - register: child_fabric_vrf_results - # -------------------------------------------------------------------- # Manage Loopback VRF attachments on NDFC # -------------------------------------------------------------------- From 8ca69f22890d38eed5a77024a9a797282e7374e8 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 9 Oct 2025 12:50:02 -0400 Subject: [PATCH 02/17] updates for using network module for msd-level network mgmt --- .../msd_fabric/child_fabric/3.1/.gitkeep | 0 .../3.1/msd_child_fabric_network.j2 | 47 --------------- .../msd_fabric/child_fabric/3.2/.gitkeep | 0 .../3.2/msd_child_fabric_network.j2 | 49 ---------------- .../msd_fabric/child_fabric/4.1/.gitkeep | 0 .../4.1/msd_child_fabric_network.j2 | 48 --------------- .../child_fabric/msd_child_fabric_network.j2 | 50 ---------------- .../msd_fabric/msd_fabric_networks.j2 | 38 ++++++++++++ .../msd_fabric/msd_fabric_networks.j2.orig | 58 +++++++++++++++++++ roles/dtc/create/tasks/msd/vrfs_networks.yml | 10 ++-- 10 files changed, 101 insertions(+), 199 deletions(-) delete mode 100644 roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/.gitkeep delete mode 100644 roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 delete mode 100644 roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/.gitkeep delete mode 100644 roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 delete mode 100644 roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/.gitkeep delete mode 100644 roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 delete mode 100644 roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 create mode 100644 roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2.orig diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/.gitkeep b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/.gitkeep deleted file mode 100644 index e69de29bb..000000000 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 deleted file mode 100644 index 269d89ad7..000000000 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.1/msd_child_fabric_network.j2 +++ /dev/null @@ -1,47 +0,0 @@ -{# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} -{ - "fabric": "{{ fabric_name }}", - "networkName": "{{ network_name }}", - "displayName": "{{ network_name }}", - "networkId": "{{ ndfc.segmentId }}", - "networkTemplate": "Default_Network_Universal", - "networkExtensionTemplate": "Default_Network_Extension_Universal", - "networkTemplateConfig": "{{ { - "vrfName": ndfc.vrfName, - "vlanId": ndfc.vlanId, - "vlanName": ndfc.vlanName, - "segmentId": ndfc.segmentId, - "intfDescription": ndfc.intfDescription, - "gatewayIpAddress": ndfc.gatewayIpAddress, - "gatewayIpV6Address": ndfc.gatewayIpV6Address, - "mtu": ndfc.mtu, - "isLayer2Only": ndfc.isLayer2Only, - "suppressArp": ndfc.suppressArp, - "mcastGroup": dm.multicast_group_address | default(ndfc.mcastGroup), - "tag": ndfc.tag, - "secondaryGW1": ndfc.secondaryGW1, - "secondaryGW2": ndfc.secondaryGW2, - "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 "", - "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, - "enableIR": ndfc.enableIR, - "trmEnabled": dm.trm_enable if dm.trm_enable is defined else ndfc.trmEnabled, - "igmpVersion": ndfc.igmpVersion, - "rtBothAuto": ndfc.rtBothAuto, - "enableL3OnBorder": dm.l3gw_on_border if dm.l3gw_on_border is defined else ndfc.enableL3OnBorder, - "nveId": ndfc.nveId, - "type": "Normal", - } }}", - "vrf": "{{ ndfc.vrfName }}", - "type": "Normal", - "hierarchicalKey": "{{ fabric_name }}" -} diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/.gitkeep b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/.gitkeep deleted file mode 100644 index e69de29bb..000000000 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 deleted file mode 100644 index f48e4a0b7..000000000 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/3.2/msd_child_fabric_network.j2 +++ /dev/null @@ -1,49 +0,0 @@ -{# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} -{ - "fabric": "{{ fabric_name }}", - "networkName": "{{ network_name }}", - "displayName": "{{ network_name }}", - "networkId": "{{ ndfc.segmentId }}", - "networkTemplate": "Default_Network_Universal", - "networkExtensionTemplate": "Default_Network_Extension_Universal", - "networkTemplateConfig": "{{ { - "vrfName": ndfc.vrfName, - "vlanId": ndfc.vlanId, - "vlanName": ndfc.vlanName, - "segmentId": ndfc.segmentId, - "intfDescription": ndfc.intfDescription, - "gatewayIpAddress": ndfc.gatewayIpAddress, - "gatewayIpV6Address": ndfc.gatewayIpV6Address, - "mtu": ndfc.mtu, - "isLayer2Only": ndfc.isLayer2Only, - "suppressArp": ndfc.suppressArp, - "mcastGroup": dm.multicast_group_address | default(ndfc.mcastGroup), - "tag": ndfc.tag, - "secondaryGW1": ndfc.secondaryGW1, - "secondaryGW2": ndfc.secondaryGW2, - "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 "", - "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, - "enableIR": ndfc.enableIR, - "trmEnabled": dm.trm_enable if dm.trm_enable is defined else ndfc.trmEnabled, - "igmpVersion": ndfc.igmpVersion, - "trmV6Enabled": ndfc.trmV6Enabled, - "rtBothAuto": ndfc.rtBothAuto, - "enableL3OnBorder": dm.l3gw_on_border if dm.l3gw_on_border is defined else ndfc.enableL3OnBorder, - "enableL3OnBorderVpcBgw": ndfc.enableL3OnBorderVpcBgw, - "nveId": ndfc.nveId, - "type": "Normal", - } }}", - "vrf": "{{ ndfc.vrfName }}", - "type": "Normal", - "hierarchicalKey": "{{ fabric_name }}" -} diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/.gitkeep b/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/.gitkeep deleted file mode 100644 index e69de29bb..000000000 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 deleted file mode 100644 index d8687a95f..000000000 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/4.1/msd_child_fabric_network.j2 +++ /dev/null @@ -1,48 +0,0 @@ -{# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} -{ - "fabric": "{{ fabric_name }}", - "networkName": "{{ network_name }}", - "displayName": "{{ network_name }}", - "networkId": "{{ ndfc.segmentId }}", - "networkTemplate": "Default_Network_Universal", - "networkExtensionTemplate": "Default_Network_Extension_Universal", - "networkTemplateConfig": "{{ { - "vrfName": ndfc.vrfName, - "vlanId": ndfc.vlanId, - "vlanName": ndfc.vlanName, - "segmentId": ndfc.segmentId, - "intfDescription": ndfc.intfDescription, - "gatewayIpAddress": ndfc.gatewayIpAddress, - "gatewayIpV6Address": ndfc.gatewayIpV6Address, - "mtu": ndfc.mtu, - "isLayer2Only": ndfc.isLayer2Only, - "suppressArp": ndfc.suppressArp, - "mcastGroup": dm.multicast_group_address | default(ndfc.mcastGroup), - "tag": ndfc.tag, - "secondaryGW1": ndfc.secondaryGW1, - "secondaryGW2": ndfc.secondaryGW2, - "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 "", - "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, - "enableIR": ndfc.enableIR, - "trmEnabled": dm.trm_enable if dm.trm_enable is defined else ndfc.trmEnabled, - "igmpVersion": ndfc.igmpVersion, - "trmV6Enabled": ndfc.trmV6Enabled, - "rtBothAuto": ndfc.rtBothAuto, - "enableL3OnBorder": dm.l3gw_on_border if dm.l3gw_on_border is defined else ndfc.enableL3OnBorder, - "nveId": ndfc.nveId, - "type": "Normal", - } }}", - "vrf": "{{ ndfc.vrfName }}", - "type": "Normal", - "hierarchicalKey": "{{ fabric_name }}" -} 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 deleted file mode 100644 index f29208713..000000000 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/child_fabric/msd_child_fabric_network.j2 +++ /dev/null @@ -1,50 +0,0 @@ -{# Auto-generated NDFC VXLAN EVPN MSD Child Fabric Network config data structure for fabric {{ fabric_name }} #} -{ - "fabric": "{{ fabric_name }}", - "networkName": "{{ network_name }}", - "displayName": "{{ network_name }}", - "networkId": "{{ ndfc.segmentId }}", - "networkTemplate": "Default_Network_Universal", - "networkExtensionTemplate": "Default_Network_Extension_Universal", - "networkTemplateConfig": " {{ { - "vrfName": ndfc.vrfName, - "networkName": network_name, - "vlanId": ndfc.vlanId, - "vlanName": ndfc.vlanName, - "segmentId": ndfc.segmentId, - "intfDescription": ndfc.intfDescription, - "gatewayIpAddress": ndfc.gatewayIpAddress, - "gatewayIpV6Address": ndfc.gatewayIpV6Address, - "mtu": ndfc.mtu, - "isLayer2Only": ndfc.isLayer2Only, - "suppressArp": ndfc.suppressArp, - "mcastGroup": dm.multicast_group_address | default(ndfc.mcastGroup), - "tag": ndfc.tag, - "secondaryGW1": ndfc.secondaryGW1, - "secondaryGW2": ndfc.secondaryGW2, - "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 "", - "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, - "enableIR": ndfc.enableIR, - "trmEnabled": dm.trm_enable if dm.trm_enable is defined else ndfc.trmEnabled, - "igmpVersion": ndfc.igmpVersion, - "trmV6Enabled": ndfc.trmV6Enabled, - "rtBothAuto": ndfc.rtBothAuto, - "enableL3OnBorder": dm.l3gw_on_border if dm.l3gw_on_border is defined else ndfc.enableL3OnBorder, - "enableL3OnBorderVpcBgw": ndfc.enableL3OnBorderVpcBgw, - "nveId": ndfc.nveId, - "type": "Normal", - } }}", - "vrf": "{{ ndfc.vrfName }}", - "type": "Normal", - "hierarchicalKey": "{{ fabric_name }}" -} diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2 b/roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2 index 755f313e0..46ea36ce4 100644 --- a/roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2 +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2 @@ -38,6 +38,44 @@ mtu_l3intf: {{ net['mtu_l3intf'] | default(defaults.vxlan.overlay.networks.mtu_l3intf) }} route_target_both: {{ net['route_target_both'] | default(defaults.vxlan.overlay.networks.route_target_both) }} routing_tag: {{ net['route_tag'] | default(defaults.vxlan.overlay.networks.route_tag) }} +{% if net.child_fabrics is defined and net.child_fabrics %} +{% set child_fabrics = net.child_fabrics %} + child_fabric_config: +{% else %} +{% set child_fabrics = [] %} +{% endif %} +{% for child_fabric in child_fabrics %} + - fabric_name: {{ child_fabric['name'] | default(omit) }} +{% if (MD_Multisite.child_fabrics_data[child_fabric['name']]['attributes']['REPLICATION_MODE'] | lower) == 'multicast' %} + multicast_group_address: {{ child_fabric['multicast_group_address'] | default(omit) }} +{% endif %} + dhcp_loopback_id: {{ child_fabric['dhcp_loopback_id'] | default(omit) }} +{% if child_fabric.dhcp_servers is defined %} +{% if child_fabric.dhcp_servers | length == 1 %} + dhcp_srvr1_ip: {{ child_fabric['dhcp_servers'][0]['ip_address'] }} + dhcp_srvr1_vrf: {{ child_fabric['dhcp_servers'][0]['vrf'] }} +{% elif child_fabric.dhcp_servers | length == 2 %} + dhcp_srvr1_ip: {{ child_fabric['dhcp_servers'][0]['ip_address'] }} + dhcp_srvr1_vrf: {{ child_fabric['dhcp_servers'][0]['vrf'] }} + dhcp_srvr2_ip: {{ child_fabric['dhcp_servers'][1]['ip_address'] }} + dhcp_srvr2_vrf: {{ child_fabric['dhcp_servers'][1]['vrf'] }} +{% elif child_fabric.dhcp_servers | length == 3 %} + dhcp_srvr1_ip: {{ child_fabric['dhcp_servers'][0]['ip_address'] }} + dhcp_srvr1_vrf: {{ child_fabric['dhcp_servers'][0]['vrf'] }} + dhcp_srvr2_ip: {{ child_fabric['dhcp_servers'][1]['ip_address'] }} + dhcp_srvr2_vrf: {{ child_fabric['dhcp_servers'][1]['vrf'] }} + dhcp_srvr3_ip: {{ child_fabric['dhcp_servers'][2]['ip_address'] }} + dhcp_srvr3_vrf: {{ child_fabric['dhcp_servers'][2]['vrf'] }} +{% endif %} +{% endif %} + trm_enable: {{ child_fabric['trm_enable'] | default(omit) }} +{# trmv6_enable: {{ child_fabric['trmv6_enable'] | default(omit) }} #} + l3gw_on_border: {{ child_fabric['l3gw_on_border'] | default(omit) }} + netflow_enable: {{ child_fabric['netflow_enable'] | default(omit) }} +{% if child_fabric['netflow_enable'] is defined and child_fabric['netflow_enable'] | bool %} + vlan_nf_monitor: {{ child_fabric['vlan_netflow_monitor'] | default(omit) }} +{% endif %} +{% endfor %} {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} diff --git a/roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2.orig b/roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2.orig new file mode 100644 index 000000000..755f313e0 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2.orig @@ -0,0 +1,58 @@ +{# Auto-generated NDFC MSD network_attach_groups_dict config data structure for fabric {{ vxlan.fabric.name }} #} +{% if MD_Extended.vxlan.multisite.overlay.networks is defined and MD_Extended.vxlan.multisite.overlay.networks %} +{% set networks = MD_Extended.vxlan.multisite.overlay.networks %} +{% else %} +{% set networks = [] %} +{% endif %} +{% for net in networks %} +- net_name: {{ net['name'] }} +{# ------------------------------------------------------ #} +{# Properties Section #} +{# ------------------------------------------------------ #} + is_l2only: {{ net['is_l2_only'] | default(defaults.vxlan.overlay.networks.is_l2_only) }} + vrf_name: {{ net['vrf_name'] | default(omit) }} + net_id: {{ net['net_id'] | default(omit) }} + vlan_id: {{ net['vlan_id'] | default(omit) }} + vlan_name: {{ net['vlan_name'] | default(omit) }} + gw_ip_subnet: {{ net['gw_ip_address'] | default(omit) }} +{% if net.secondary_ip_addresses is defined %} +{% if net.secondary_ip_addresses | length == 1 %} + secondary_ip_gw1: {{ net['secondary_ip_addresses'][0]['ip_address'] }} +{% elif net.secondary_ip_addresses | length == 2 %} + secondary_ip_gw1: {{ net['secondary_ip_addresses'][0]['ip_address'] }} + secondary_ip_gw2: {{ net['secondary_ip_addresses'][1]['ip_address'] }} +{% elif net.secondary_ip_addresses | length == 3 %} + secondary_ip_gw1: {{ net['secondary_ip_addresses'][0]['ip_address'] }} + secondary_ip_gw2: {{ net['secondary_ip_addresses'][1]['ip_address'] }} + secondary_ip_gw3: {{ net['secondary_ip_addresses'][2]['ip_address'] }} +{% elif net.secondary_ip_addresses | length == 4 %} + secondary_ip_gw1: {{ net['secondary_ip_addresses'][0]['ip_address'] }} + secondary_ip_gw2: {{ net['secondary_ip_addresses'][1]['ip_address'] }} + secondary_ip_gw3: {{ net['secondary_ip_addresses'][2]['ip_address'] }} + secondary_ip_gw4: {{ net['secondary_ip_addresses'][3]['ip_address'] }} +{% endif %} +{% endif %} + arp_suppress: {{ net['arp_suppress'] | default(defaults.vxlan.overlay.networks.arp_supress) }} + gw_ipv6_subnet: {{ net['gw_ipv6_address'] | default(omit) }} + int_desc: {{ net['int_desc'] | default(defaults.vxlan.overlay.networks.net_description) }} + mtu_l3intf: {{ net['mtu_l3intf'] | default(defaults.vxlan.overlay.networks.mtu_l3intf) }} + route_target_both: {{ net['route_target_both'] | default(defaults.vxlan.overlay.networks.route_target_both) }} + routing_tag: {{ net['route_tag'] | default(defaults.vxlan.overlay.networks.route_tag) }} +{# ------------------------------------------------------ #} +{# Attach Group Section #} +{# ------------------------------------------------------ #} +{# Don't need to attach vrfs if there are no msd_switches #} +{% if net['network_attach_group'] is defined %} + attach: +{% if MD_Multisite.overlay_attach_groups.network_attach_groups_dict is defined and MD_Multisite.overlay_attach_groups.network_attach_groups_dict %} +{% set network_attach_groups_dict = MD_Multisite.overlay_attach_groups.network_attach_groups_dict %} +{% endif %} +{% for attach in network_attach_groups_dict[net['network_attach_group']] %} + - ip_address: {{ attach['mgmt_ip_address'] }} +{% if attach['ports'] is defined %} + ports: {{ attach['ports'] }} +{% endif %} +{% endfor %} + deploy: false +{% endif %} +{% endfor %} diff --git a/roles/dtc/create/tasks/msd/vrfs_networks.yml b/roles/dtc/create/tasks/msd/vrfs_networks.yml index e71faa4e8..6694a8060 100644 --- a/roles/dtc/create/tasks/msd/vrfs_networks.yml +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -144,11 +144,11 @@ - MD_Extended.vxlan.multisite.overlay.networks - vars_common_msd.changes_detected_networks -- name: Manage Child Fabric Networks in Nexus Dashboard - cisco.nac_dc_vxlan.dtc.manage_child_fabric_networks: - nd_version: "{{ nd_version }}" - msite_data: "{{ MD_Multisite }}" - register: child_fabric_network_results +# - name: Manage Child Fabric Networks in Nexus Dashboard +# cisco.nac_dc_vxlan.dtc.manage_child_fabric_networks: +# nd_version: "{{ nd_version }}" +# msite_data: "{{ MD_Multisite }}" +# register: child_fabric_network_results - name: Update Child Fabrics VRFs and Networks Changed State ansible.builtin.set_fact: From 02c57014e1085ac75119d0840067aff1d590eaff Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 9 Oct 2025 12:52:23 -0400 Subject: [PATCH 03/17] clean up comment and store orig j2 for now --- roles/dtc/common/tasks/sub_main_msd.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 37f2b121c..f1d836c69 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -61,15 +61,15 @@ - name: Build MSD Child Fabric BGW Anycast VIP List From Template ansible.builtin.import_tasks: msd/ndfc_bgw_anycast_vip.yml +# This is not used for MSD as VRFs and Networks are handled in create/sub_main_msd.yml +# because we need to process the Multsite data first before we can process the VRFs +# and Networks data, mainly for switch attachment data as MSD fabrics do not have switches +# declared in the data model as this a function of the child fabric to manage device inventory. + # ------------------------------------------------------------------------ # Build MSD Fabric VRFs Attach List From Template # ------------------------------------------------------------------------ -# This is not used for MSD as VRFs and Networks are handled in create/sub_main_msd.yml -# because we need to process the Multsite data first before we can process the VRFs, -# mainly for switch attachment data as MSD fabrics do not have switches declared in -# the data model as this a function of the child fabric to manage device inventory. - # - name: Build MSD Fabric VRFs Attach List From Template # ansible.builtin.import_tasks: msd/ndfc_vrfs.yml From c419215ffc105c98a3aa1af32ed4da27181fb3f9 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 9 Oct 2025 12:52:56 -0400 Subject: [PATCH 04/17] clean up comment and store orig j2 for now --- .../msd_fabric/msd_fabric_vrfs.j2.orig | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2.orig diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2.orig b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2.orig new file mode 100644 index 000000000..4b0b39897 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2.orig @@ -0,0 +1,45 @@ +{# Auto-generated NDFC MSD VRFs config data structure for fabric {{ vxlan.fabric.name }} #} +{% if MD_Extended.vxlan.multisite.overlay.vrfs is defined and MD_Extended.vxlan.multisite.overlay.vrfs %} +{% set vrfs = MD_Extended.vxlan.multisite.overlay.vrfs %} +{# This else block may not be needed after the prepare plugin work #} +{% else %} +{% set vrfs = [] %} +{% endif %} +{% for vrf in vrfs %} +- vrf_name: {{ vrf['name'] }} +{# ------------------------------------------------------ #} +{# Properties Section #} +{# ------------------------------------------------------ #} + vrf_id: {{ vrf['vrf_id'] | default(omit) }} + vlan_id: {{ vrf['vlan_id'] | default(omit) }} + vrf_vlan_name: {{ vrf['vrf_vlan_name'] | default(omit) }} + vrf_intf_desc: {{ vrf['vrf_intf_desc'] | default(defaults.vxlan.overlay.vrfs.vrf_intf_desc) }} + vrf_description: {{ vrf['vrf_description'] | default(defaults.vxlan.overlay.vrfs.vrf_description) }} + vrf_int_mtu: {{ vrf['vrf_int_mtu'] | default(defaults.vxlan.overlay.vrfs.vrf_int_mtu) }} + loopback_route_tag: {{ vrf['loopback_route_tag'] | default(defaults.vxlan.overlay.vrfs.loopback_route_tag) }} + max_bgp_paths: {{ vrf['max_bgp_paths'] | default(defaults.vxlan.overlay.vrfs.max_bgp_paths) }} + max_ibgp_paths: {{ vrf['max_ibgp_paths'] | default(defaults.vxlan.overlay.vrfs.max_ibgp_paths) }} + ipv6_linklocal_enable: {{ vrf['ipv6_linklocal_enable'] | default(defaults.vxlan.overlay.vrfs.ipv6_linklocal_enable) }} + disable_rt_auto: {{ vrf['disable_rt_auto'] | default(defaults.vxlan.overlay.vrfs.disable_rt_auto) }} + export_evpn_rt: {{ vrf['export_evpn_rt'] | default(omit) }} + export_vpn_rt: {{ vrf['export_vpn_rt'] | default(omit) }} + import_evpn_rt: {{ vrf['import_evpn_rt'] | default(omit) }} + import_vpn_rt: {{ vrf['import_vpn_rt'] | default(omit) }} + redist_direct_rmap: {{ vrf['redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.redist_direct_routemap) }} +{% if (ndfc_version | cisco.nac_dc_vxlan.version_compare('12.2.2', '>=')) %} + v6_redist_direct_rmap: {{ vrf['ipv6_redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.ipv6_redist_direct_routemap) }} +{% endif %} +{# ------------------------------------------------------ #} +{# Attach Group Section #} +{# ------------------------------------------------------ #} +{% if vrf['vrf_attach_group'] is defined %} + attach: +{% if MD_Multisite.overlay_attach_groups.vrf_attach_groups_dict is defined and MD_Multisite.overlay_attach_groups.vrf_attach_groups_dict %} +{% set vrf_attach_groups_dict = MD_Multisite.overlay_attach_groups.vrf_attach_groups_dict %} +{% endif %} +{% for attach in vrf_attach_groups_dict[vrf['vrf_attach_group']] %} + - ip_address: {{ attach['mgmt_ip_address'] }} +{% endfor %} +{% endif %} + deploy: false +{% endfor %} From eae7c6d190573fe11468eabd83e29039859a8d2b Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Fri, 17 Oct 2025 13:22:46 -0400 Subject: [PATCH 05/17] remove comment --- roles/dtc/common/tasks/sub_main_msd.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 663b71f19..f769273a1 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -61,11 +61,6 @@ - name: Build MSD Child Fabric BGW Anycast VIP List From Template ansible.builtin.import_tasks: msd/ndfc_bgw_anycast_vip.yml -# This is not used for MSD as VRFs and Networks are handled in create/sub_main_msd.yml -# because we need to process the Multsite data first before we can process the VRFs -# and Networks data, mainly for switch attachment data as MSD fabrics do not have switches -# declared in the data model as this a function of the child fabric to manage device inventory. - # ------------------------------------------------------------------------ # Save Local Variables To NameSpace Dict For Use Elsewhere # ------------------------------------------------------------------------ From 959dba114231a5e3964ff3b75cb2429fb7c9f1d2 Mon Sep 17 00:00:00 2001 From: Akshayanat C S <83760554+AKDRG@users.noreply.github.com> Date: Tue, 4 Nov 2025 03:15:50 +0530 Subject: [PATCH 06/17] VRF (MSD) Base Module and Action Plugin Support (#659) * Adding/Modifying NDFC MSD VRFs template properties * Update VRF change detection logic to use manage_vrf_result --- .../ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 | 26 +++++++++++-------- roles/dtc/create/tasks/msd/vrfs_networks.yml | 6 ++--- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 index f9d02cc0e..7fa266b5c 100644 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 @@ -8,7 +8,7 @@ {% for vrf in vrfs %} - vrf_name: {{ vrf['name'] }} {# ------------------------------------------------------ #} -{# Properties Section #} +{# Parent MSD Properties Section #} {# ------------------------------------------------------ #} vrf_id: {{ vrf['vrf_id'] | default(omit) }} vlan_id: {{ vrf['vlan_id'] | default(omit) }} @@ -29,20 +29,20 @@ {% if (ndfc_version | cisco.nac_dc_vxlan.version_compare('12.2.2', '>=')) %} v6_redist_direct_rmap: {{ vrf['ipv6_redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.ipv6_redist_direct_routemap) }} {% endif %} +{# ------------------------------------------------------ #} +{# Child MSD Fabric Configuration Section #} +{# ------------------------------------------------------ #} {% if vrf.child_fabrics is defined and vrf.child_fabrics %} {% set child_fabrics = vrf.child_fabrics %} -{% else %} -{% set child_fabrics = [] %} -{% endif %} child_fabric_config: {% for child_fabric in child_fabrics %} - - fabric_name: {{ child_fabric['name'] | default(omit) }} - l3vni_wo_vlan: {{ child_fabric['enable_l3_vni_no_vlan'] | default(omit) }} - adv_host_routes: {{ child_fabric['adv_host_routes'] | default(omit) }} - adv_default_routes: {{ child_fabric['adv_default_routes'] | default(omit) }} - static_default_route: {{ child_fabric['static_default_route'] | default(omit) }} + - fabric: {{ child_fabric['name'] | default(omit) }} + l3vni_wo_vlan: {{ child_fabric['l3vni_wo_vlan'] | default(omit) }} + adv_host_routes: {{ child_fabric['adv_host_routes'] | default(omit) }} + adv_default_routes: {{ child_fabric['adv_default_routes'] | default(omit) }} + static_default_route: {{ child_fabric['static_default_route'] | default(omit) }} bgp_password: {{ child_fabric['bgp_password'] | default(omit) }} - bgp_password_encryption_type: {{ child_fabric['bgp_password_encryption_type'] | default(omit) }} + bgp_passwd_encrypt: {{ child_fabric['bgp_password_encryption_type'] | default(omit) }} import_mvpn_rt: {{ child_fabric['import_mvpn_rt'] | default(omit) }} export_mvpn_rt: {{ child_fabric['export_mvpn_rt'] | default(omit) }} netflow_enable: {{ child_fabric['netflow_enable'] | default(omit) }} @@ -66,6 +66,7 @@ underlay_mcast_ip: {{ child_fabric['underlay_mcast_ip'] | default(omit) }} {% endif %} {% endfor %} +{% endif %} {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} @@ -73,10 +74,13 @@ attach: {% if MD_Multisite.overlay_attach_groups.vrf_attach_groups_dict is defined and MD_Multisite.overlay_attach_groups.vrf_attach_groups_dict %} {% set vrf_attach_groups_dict = MD_Multisite.overlay_attach_groups.vrf_attach_groups_dict %} -{% endif %} {% for attach in vrf_attach_groups_dict[vrf['vrf_attach_group']] %} - ip_address: {{ attach['mgmt_ip_address'] }} +{% if attach['vrf_lite'] is defined and attach['vrf_lite'] %} + vrf_lite: {{ attach['vrf_lite'] }} +{% endif %} {% endfor %} {% endif %} deploy: false +{% endif %} {% endfor %} diff --git a/roles/dtc/create/tasks/msd/vrfs_networks.yml b/roles/dtc/create/tasks/msd/vrfs_networks.yml index 38ad160a9..92af6976c 100644 --- a/roles/dtc/create/tasks/msd/vrfs_networks.yml +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -176,10 +176,10 @@ ansible.builtin.set_fact: child_fabrics_vrfs_networks_changed: "{{ vrf_changed | ansible.builtin.union(network_changed) }}" vars: - vrf_changed: "{{ child_fabric_vrf_results.child_fabrics_changed | default([]) }}" + vrf_changed: "{{ manage_vrf_result.changed | default([]) }}" network_changed: "{{ child_fabric_network_results.child_fabrics_changed | default([]) }}" when: > - (child_fabric_vrf_results.child_fabrics_changed is defined and - child_fabric_vrf_results.child_fabrics_changed | length > 0) or + (manage_vrf_result.changed is defined and + manage_vrf_result.changed | length > 0) or (child_fabric_network_results.child_fabrics_changed is defined and child_fabric_network_results.child_fabrics_changed | length > 0) From b2b447885140a0062b3558240849da352c533960 Mon Sep 17 00:00:00 2001 From: mwiebe Date: Mon, 3 Nov 2025 16:50:12 -0500 Subject: [PATCH 07/17] Fixup local and incomming changes --- .../ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 index 7fa266b5c..8a72e32e9 100644 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 @@ -8,7 +8,7 @@ {% for vrf in vrfs %} - vrf_name: {{ vrf['name'] }} {# ------------------------------------------------------ #} -{# Parent MSD Properties Section #} +{# Properties Section #} {# ------------------------------------------------------ #} vrf_id: {{ vrf['vrf_id'] | default(omit) }} vlan_id: {{ vrf['vlan_id'] | default(omit) }} @@ -29,18 +29,18 @@ {% if (ndfc_version | cisco.nac_dc_vxlan.version_compare('12.2.2', '>=')) %} v6_redist_direct_rmap: {{ vrf['ipv6_redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.ipv6_redist_direct_routemap) }} {% endif %} -{# ------------------------------------------------------ #} -{# Child MSD Fabric Configuration Section #} -{# ------------------------------------------------------ #} {% if vrf.child_fabrics is defined and vrf.child_fabrics %} {% set child_fabrics = vrf.child_fabrics %} +{% else %} +{% set child_fabrics = [] %} +{% endif %} child_fabric_config: {% for child_fabric in child_fabrics %} - fabric: {{ child_fabric['name'] | default(omit) }} - l3vni_wo_vlan: {{ child_fabric['l3vni_wo_vlan'] | default(omit) }} - adv_host_routes: {{ child_fabric['adv_host_routes'] | default(omit) }} - adv_default_routes: {{ child_fabric['adv_default_routes'] | default(omit) }} - static_default_route: {{ child_fabric['static_default_route'] | default(omit) }} + l3vni_wo_vlan: {{ child_fabric['enable_l3_vni_no_vlan'] | default(omit) }} + adv_host_routes: {{ child_fabric['adv_host_routes'] | default(omit) }} + adv_default_routes: {{ child_fabric['adv_default_routes'] | default(omit) }} + static_default_route: {{ child_fabric['static_default_route'] | default(omit) }} bgp_password: {{ child_fabric['bgp_password'] | default(omit) }} bgp_passwd_encrypt: {{ child_fabric['bgp_password_encryption_type'] | default(omit) }} import_mvpn_rt: {{ child_fabric['import_mvpn_rt'] | default(omit) }} @@ -66,7 +66,6 @@ underlay_mcast_ip: {{ child_fabric['underlay_mcast_ip'] | default(omit) }} {% endif %} {% endfor %} -{% endif %} {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} @@ -74,13 +73,11 @@ attach: {% if MD_Multisite.overlay_attach_groups.vrf_attach_groups_dict is defined and MD_Multisite.overlay_attach_groups.vrf_attach_groups_dict %} {% set vrf_attach_groups_dict = MD_Multisite.overlay_attach_groups.vrf_attach_groups_dict %} +{% endif %} {% for attach in vrf_attach_groups_dict[vrf['vrf_attach_group']] %} - ip_address: {{ attach['mgmt_ip_address'] }} -{% if attach['vrf_lite'] is defined and attach['vrf_lite'] %} - vrf_lite: {{ attach['vrf_lite'] }} -{% endif %} {% endfor %} {% endif %} deploy: false -{% endif %} {% endfor %} + From 2218277dcd066fddd31b90a2640708aee9077b99 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 4 Nov 2025 08:52:28 -0500 Subject: [PATCH 08/17] remove extra space --- .../templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 index 8a72e32e9..ef60918fc 100644 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 @@ -38,9 +38,9 @@ {% for child_fabric in child_fabrics %} - fabric: {{ child_fabric['name'] | default(omit) }} l3vni_wo_vlan: {{ child_fabric['enable_l3_vni_no_vlan'] | default(omit) }} - adv_host_routes: {{ child_fabric['adv_host_routes'] | default(omit) }} - adv_default_routes: {{ child_fabric['adv_default_routes'] | default(omit) }} - static_default_route: {{ child_fabric['static_default_route'] | default(omit) }} + adv_host_routes: {{ child_fabric['adv_host_routes'] | default(omit) }} + adv_default_routes: {{ child_fabric['adv_default_routes'] | default(omit) }} + static_default_route: {{ child_fabric['static_default_route'] | default(omit) }} bgp_password: {{ child_fabric['bgp_password'] | default(omit) }} bgp_passwd_encrypt: {{ child_fabric['bgp_password_encryption_type'] | default(omit) }} import_mvpn_rt: {{ child_fabric['import_mvpn_rt'] | default(omit) }} @@ -80,4 +80,3 @@ {% endif %} deploy: false {% endfor %} - From 5a3e3bf35aa411a7d07901ef9f5005e78fe422f2 Mon Sep 17 00:00:00 2001 From: mwiebe Date: Tue, 4 Nov 2025 17:50:40 -0500 Subject: [PATCH 09/17] deploy manager updates --- plugins/action/dtc/fabric_deploy_manager.py | 76 ++++++++++++++++++-- roles/dtc/create/tasks/msd/vrfs_networks.yml | 4 +- roles/dtc/deploy/tasks/sub_main_msd.yml | 1 + 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/plugins/action/dtc/fabric_deploy_manager.py b/plugins/action/dtc/fabric_deploy_manager.py index ee7c45f79..9c02a2cf3 100644 --- a/plugins/action/dtc/fabric_deploy_manager.py +++ b/plugins/action/dtc/fabric_deploy_manager.py @@ -165,10 +165,79 @@ def run(self, tmp=None, task_vars=None): results['failed'] = False params = {} + # Module Execution Context Parameters + params['task_vars'] = task_vars + params['tmp'] = tmp + params['action_module'] = self + params['fabric_name'] = self._task.args["fabric_name"] params['fabric_type'] = self._task.args["fabric_type"] params['operation'] = self._task.args.get("operation") + # Manage Deployment For Multisite or Standalone Fabric + results = self.manage_fabrics(results, params) + if results.get('failed'): + return results + + params['child_fabric_vrf_data'] = self._task.args.get("child_fabric_vrf_data", {}) + import epdb ; epdb.set_trace() + + return results + # for key in ['fabric_type', 'fabric_name', 'operation']: + # if params[key] is None: + # results['failed'] = True + # results['msg'] = f"Missing required parameter '{key}'" + # return results + + # if params['operation'] not in ['all', 'config_save', 'config_deploy', 'check_sync']: + # results['failed'] = True + # results['msg'] = "Parameter 'operation' must be one of: [all, config_save, config_deploy, check_sync]" + # return results + + # fabric_manager = FabricDeployManager(params) + + # # Workflows + # if params['operation'] in ['all']: + # fabric_manager.fabric_config_save() + # fabric_manager.fabric_deploy() + # fabric_manager.fabric_check_sync() + + # if not fabric_manager.fabric_in_sync and params['fabric_type'] != 'MSD': + # # If the fabric is out of sync after deployment try one more time before giving up + # fabric_manager.fabric_history_get() + # display.warning(fabric_manager.fabric_history) + # display.warning("Fabric is out of sync after initial deployment. Attempting one more deployment.") + # fabric_manager.fabric_config_save() + # fabric_manager.fabric_deploy() + # fabric_manager.fabric_check_sync() + + # if not fabric_manager.fabric_in_sync and params['fabric_type'] != 'MSD': + # fabric_manager.fabric_history_get() + # results['msg'] = f"Fabric {fabric_manager.fabric_name} is out of sync after deployment." + # results['fabric_history'] = fabric_manager.fabric_history + # results['failed'] = True + + # if params['operation'] in ['config_save']: + # fabric_manager.fabric_config_save() + # if not fabric_manager.fabric_save_succeeded: + # results['failed'] = True + + # if params['operation'] in ['config_deploy']: + # fabric_manager.fabric_deploy() + # if not fabric_manager.fabric_deploy_succeeded: + # results['failed'] = True + + # if params['operation'] in ['check_sync']: + # fabric_manager.fabric_check_sync() + # if not fabric_manager.fabric_in_sync: + # fabric_manager.fabric_history_get() + # results['msg'] = f"Fabric {fabric_manager.fabric_name} is out of sync." + # results['fabric_history'] = fabric_manager.fabric_history + # results['failed'] = True + + + def manage_fabrics(self, results, params): + for key in ['fabric_type', 'fabric_name', 'operation']: if params[key] is None: results['failed'] = True @@ -180,11 +249,6 @@ def run(self, tmp=None, task_vars=None): results['msg'] = "Parameter 'operation' must be one of: [all, config_save, config_deploy, check_sync]" return results - # Module Execution Context Parameters - params['task_vars'] = task_vars - params['tmp'] = tmp - params['action_module'] = self - fabric_manager = FabricDeployManager(params) # Workflows @@ -226,4 +290,4 @@ def run(self, tmp=None, task_vars=None): results['fabric_history'] = fabric_manager.fabric_history results['failed'] = True - return results + return results \ No newline at end of file diff --git a/roles/dtc/create/tasks/msd/vrfs_networks.yml b/roles/dtc/create/tasks/msd/vrfs_networks.yml index 92af6976c..a38ce0449 100644 --- a/roles/dtc/create/tasks/msd/vrfs_networks.yml +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -176,10 +176,8 @@ ansible.builtin.set_fact: child_fabrics_vrfs_networks_changed: "{{ vrf_changed | ansible.builtin.union(network_changed) }}" vars: - vrf_changed: "{{ manage_vrf_result.changed | default([]) }}" + vrf_changed: [] network_changed: "{{ child_fabric_network_results.child_fabrics_changed | default([]) }}" when: > - (manage_vrf_result.changed is defined and - manage_vrf_result.changed | length > 0) or (child_fabric_network_results.child_fabrics_changed is defined and child_fabric_network_results.child_fabrics_changed | length > 0) diff --git a/roles/dtc/deploy/tasks/sub_main_msd.yml b/roles/dtc/deploy/tasks/sub_main_msd.yml index 67aa37e42..de75f7737 100644 --- a/roles/dtc/deploy/tasks/sub_main_msd.yml +++ b/roles/dtc/deploy/tasks/sub_main_msd.yml @@ -33,6 +33,7 @@ fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" fabric_type: "{{ MD_Extended.vxlan.fabric.type }}" operation: all + child_fabric_vrf_data: "{{ manage_vrf_result }}" vars: ansible_command_timeout: 3000 ansible_connect_timeout: 3000 From 0fb858c5071c78d99c93ac725dfeeae8f8b0be13 Mon Sep 17 00:00:00 2001 From: mwiebe Date: Tue, 4 Nov 2025 17:52:45 -0500 Subject: [PATCH 10/17] remove epdb --- plugins/action/dtc/fabric_deploy_manager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/action/dtc/fabric_deploy_manager.py b/plugins/action/dtc/fabric_deploy_manager.py index 9c02a2cf3..fcef6bc0a 100644 --- a/plugins/action/dtc/fabric_deploy_manager.py +++ b/plugins/action/dtc/fabric_deploy_manager.py @@ -180,7 +180,6 @@ def run(self, tmp=None, task_vars=None): return results params['child_fabric_vrf_data'] = self._task.args.get("child_fabric_vrf_data", {}) - import epdb ; epdb.set_trace() return results # for key in ['fabric_type', 'fabric_name', 'operation']: From ef9acb381a68818d9b80e236945d9b2171cc684e Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Wed, 5 Nov 2025 09:14:10 -0500 Subject: [PATCH 11/17] msite overlay defaults --- roles/validate/files/defaults.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/roles/validate/files/defaults.yml b/roles/validate/files/defaults.yml index 3856e9cd3..7ebaf838c 100644 --- a/roles/validate/files/defaults.yml +++ b/roles/validate/files/defaults.yml @@ -464,6 +464,36 @@ factory_defaults: delay_restore: 300 enable_ebgp_password: false enable_trm: false + overlay: + vrfs: + vrf_description: "Configured by Ansible NetAsCode" + vrf_intf_desc: "Configured by Ansible NetAsCode" + vrf_int_mtu: 9216 + loopback_route_tag: 12345 + max_bgp_paths: 1 + max_ibgp_paths: 2 + ipv6_linklocal_enable: true + adv_host_routes: false + adv_default_routes: true + static_default_route: true + disable_rt_auto: false + netflow_enable: false + no_rp: false + rp_external: false + redist_direct_routemap: FABRIC-RMAP-REDIST-SUBNET + trm_enable: false + trm_bgw_msite: false + networks: + net_description: "Configured by Ansible NetAsCode" + is_l2_only: false + arp_supress: false + l3gw_on_border: false + mtu_l3intf: 9216 + multicast_group_address: 239.1.1.1 + netflow_enable: false + route_target_both: false + route_tag: 12345 + trm_enable: false isn: auth_proto: MD5 sub_int_range: 2-511 From b9fef7504a7111bbe61330e2a24646d98df4cb95 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Fri, 7 Nov 2025 07:49:07 -0500 Subject: [PATCH 12/17] Fix missing newline at end of fabric_deploy_manager.py Add a newline at the end of the file. --- plugins/action/dtc/fabric_deploy_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/action/dtc/fabric_deploy_manager.py b/plugins/action/dtc/fabric_deploy_manager.py index fcef6bc0a..657485567 100644 --- a/plugins/action/dtc/fabric_deploy_manager.py +++ b/plugins/action/dtc/fabric_deploy_manager.py @@ -289,4 +289,4 @@ def manage_fabrics(self, results, params): results['fabric_history'] = fabric_manager.fabric_history results['failed'] = True - return results \ No newline at end of file + return results From cd8d92eae33e3c6f9701ac1ee81634c9bd0049b1 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Fri, 7 Nov 2025 07:50:07 -0500 Subject: [PATCH 13/17] Remove commented-out code and extra whitespace --- plugins/action/dtc/fabric_deploy_manager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/action/dtc/fabric_deploy_manager.py b/plugins/action/dtc/fabric_deploy_manager.py index 657485567..496dbc89d 100644 --- a/plugins/action/dtc/fabric_deploy_manager.py +++ b/plugins/action/dtc/fabric_deploy_manager.py @@ -234,9 +234,7 @@ def run(self, tmp=None, task_vars=None): # results['fabric_history'] = fabric_manager.fabric_history # results['failed'] = True - def manage_fabrics(self, results, params): - for key in ['fabric_type', 'fabric_name', 'operation']: if params[key] is None: results['failed'] = True From d524ec7979a585a4bd0cc9cbe65522f7b509dbae Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Mon, 24 Nov 2025 13:53:25 -0500 Subject: [PATCH 14/17] remove dup key --- roles/validate/files/defaults.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/roles/validate/files/defaults.yml b/roles/validate/files/defaults.yml index 9d14d25e7..7ebaf838c 100644 --- a/roles/validate/files/defaults.yml +++ b/roles/validate/files/defaults.yml @@ -448,36 +448,6 @@ factory_defaults: bgw_ip_tag: 54321 ipv4_vtep_loopback_range: 10.10.0.0/24 ipv6_vtep_loopback_range: fd00::a10:0/120 - overlay: - vrfs: - vrf_description: "Configured by Ansible NetAsCode" - vrf_intf_desc: "Configured by Ansible NetAsCode" - vrf_int_mtu: 9216 - loopback_route_tag: 12345 - max_bgp_paths: 1 - max_ibgp_paths: 2 - ipv6_linklocal_enable: true - adv_host_routes: false - adv_default_routes: true - static_default_route: true - disable_rt_auto: false - netflow_enable: false - no_rp: false - rp_external: false - redist_direct_routemap: FABRIC-RMAP-REDIST-SUBNET - trm_enable: false - trm_bgw_msite: false - networks: - net_description: "Configured by Ansible NetAsCode" - is_l2_only: false - arp_supress: false - l3gw_on_border: false - mtu_l3intf: 9216 - multicast_group_address: 239.1.1.1 - netflow_enable: false - route_target_both: false - route_tag: 12345 - trm_enable: false overlay_dci: deployment_method: Direct_To_BGWS route_server: From c7100a8611e04c16d616844319899c8cb5188e4e Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 25 Nov 2025 11:40:57 -0500 Subject: [PATCH 15/17] updates for standup --- plugins/action/dtc/prepare_msite_data.py | 2 + .../ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 | 24 +++++------ roles/dtc/create/tasks/mcfg/fabric.yml | 8 ++-- roles/dtc/create/tasks/msd/vrfs_networks.yml | 3 ++ roles/dtc/create/tasks/sub_main_msd.yml | 43 ++++++++++--------- roles/validate/files/defaults.yml | 1 + 6 files changed, 44 insertions(+), 37 deletions(-) diff --git a/plugins/action/dtc/prepare_msite_data.py b/plugins/action/dtc/prepare_msite_data.py index 4f66479f4..6fc1a265f 100644 --- a/plugins/action/dtc/prepare_msite_data.py +++ b/plugins/action/dtc/prepare_msite_data.py @@ -138,4 +138,6 @@ def run(self, tmp=None, task_vars=None): results['overlay_attach_groups'] = data_model['vxlan']['multisite']['overlay'] + import epdb ; epdb.set_trace() + return results diff --git a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 index f88b6c379..4c7858311 100644 --- a/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 @@ -13,27 +13,24 @@ vrf_id: {{ vrf['vrf_id'] | default(omit) }} vlan_id: {{ vrf['vlan_id'] | default(omit) }} vrf_vlan_name: {{ vrf['vrf_vlan_name'] | default(omit) }} - vrf_intf_desc: {{ vrf['vrf_intf_desc'] | default(defaults.vxlan.overlay.vrfs.vrf_intf_desc) }} - vrf_description: {{ vrf['vrf_description'] | default(defaults.vxlan.overlay.vrfs.vrf_description) }} - vrf_int_mtu: {{ vrf['vrf_int_mtu'] | default(defaults.vxlan.overlay.vrfs.vrf_int_mtu) }} - loopback_route_tag: {{ vrf['loopback_route_tag'] | default(defaults.vxlan.overlay.vrfs.loopback_route_tag) }} - max_bgp_paths: {{ vrf['max_bgp_paths'] | default(defaults.vxlan.overlay.vrfs.max_bgp_paths) }} - max_ibgp_paths: {{ vrf['max_ibgp_paths'] | default(defaults.vxlan.overlay.vrfs.max_ibgp_paths) }} - ipv6_linklocal_enable: {{ vrf['ipv6_linklocal_enable'] | default(defaults.vxlan.overlay.vrfs.ipv6_linklocal_enable) }} - disable_rt_auto: {{ vrf['disable_rt_auto'] | default(defaults.vxlan.overlay.vrfs.disable_rt_auto) }} + vrf_intf_desc: {{ vrf['vrf_intf_desc'] | default(defaults.vxlan.multisite.overlay.vrfs.vrf_intf_desc) }} + vrf_description: {{ vrf['vrf_description'] | default(defaults.vxlan.multisite.overlay.vrfs.vrf_description) }} + vrf_int_mtu: {{ vrf['vrf_int_mtu'] | default(defaults.vxlan.multisite.overlay.vrfs.vrf_int_mtu) }} + loopback_route_tag: {{ vrf['loopback_route_tag'] | default(defaults.vxlan.multisite.overlay.vrfs.loopback_route_tag) }} + max_bgp_paths: {{ vrf['max_bgp_paths'] | default(defaults.vxlan.multisite.overlay.vrfs.max_bgp_paths) }} + max_ibgp_paths: {{ vrf['max_ibgp_paths'] | default(defaults.vxlan.multisite.overlay.vrfs.max_ibgp_paths) }} + ipv6_linklocal_enable: {{ vrf['ipv6_linklocal_enable'] | default(defaults.vxlan.multisite.overlay.vrfs.ipv6_linklocal_enable) }} + disable_rt_auto: {{ vrf['disable_rt_auto'] | default(defaults.vxlan.multisite.overlay.vrfs.disable_rt_auto) }} export_evpn_rt: {{ vrf['export_evpn_rt'] | default(omit) }} export_vpn_rt: {{ vrf['export_vpn_rt'] | default(omit) }} import_evpn_rt: {{ vrf['import_evpn_rt'] | default(omit) }} import_vpn_rt: {{ vrf['import_vpn_rt'] | default(omit) }} - redist_direct_rmap: {{ vrf['redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.redist_direct_routemap) }} + redist_direct_rmap: {{ vrf['redist_direct_routemap'] | default(defaults.vxlan.multisite.overlay.vrfs.redist_direct_routemap) }} {% if (ndfc_version | cisco.nac_dc_vxlan.version_compare('12.2.2', '>=')) %} - v6_redist_direct_rmap: {{ vrf['ipv6_redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.ipv6_redist_direct_routemap) }} + v6_redist_direct_rmap: {{ vrf['ipv6_redist_direct_routemap'] | default(defaults.vxlan.multisite.overlay.vrfs.ipv6_redist_direct_routemap) }} {% endif %} {% if vrf.child_fabrics is defined and vrf.child_fabrics %} {% set child_fabrics = vrf.child_fabrics %} -{% else %} -{% set child_fabrics = [] %} -{% endif %} child_fabric_config: {% for child_fabric in child_fabrics %} - fabric: {{ child_fabric['name'] | default(omit) }} @@ -66,6 +63,7 @@ underlay_mcast_ip: {{ child_fabric['underlay_mcast_ip'] | default(omit) }} {% endif %} {% endfor %} +{% endif %} {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} diff --git a/roles/dtc/create/tasks/mcfg/fabric.yml b/roles/dtc/create/tasks/mcfg/fabric.yml index 8d00e3f5f..fdc060838 100644 --- a/roles/dtc/create/tasks/mcfg/fabric.yml +++ b/roles/dtc/create/tasks/mcfg/fabric.yml @@ -33,7 +33,7 @@ - "+ Manage Fabric {{ data_model_extended.vxlan.fabric.name }}" - "---------------------------------------------------------------" -- name: Manage MCFG Fabric in Nexus Dashboard - cisco.dcnm.dcnm_fabric_group: - state: merged - config: "{{ vars_common_mcfg.fabric_config }}" +# - name: Manage MCFG Fabric in Nexus Dashboard +# cisco.dcnm.dcnm_fabric_group: +# state: merged +# config: "{{ vars_common_mcfg.fabric_config }}" diff --git a/roles/dtc/create/tasks/msd/vrfs_networks.yml b/roles/dtc/create/tasks/msd/vrfs_networks.yml index b5604a7da..486eb86d9 100644 --- a/roles/dtc/create/tasks/msd/vrfs_networks.yml +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -137,6 +137,9 @@ - data_model_extended.vxlan.multisite.overlay.vrfs - change_flags_multisite.changes_detected_vrfs +- ansible.builtin.pause: + minutes: 600 + # -------------------------------------------------------------------- # Manage Loopback VRF attachments on NDFC # -------------------------------------------------------------------- diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index aba02fd1a..d32d78460 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -47,29 +47,32 @@ when: - data_model_extended.vxlan.multisite.child_fabrics is defined and data_model_extended.vxlan.multisite.child_fabrics | length > 0 -- name: Prepare Multisite Data - cisco.nac_dc_vxlan.dtc.prepare_msite_data: - data_model: "{{ data_model_extended }}" - parent_fabric: "{{ data_model_extended.vxlan.fabric.name }}" - register: data_model_multisite - tags: "{{ nac_tags.create_vrfs_networks }}" - -- name: Create Border Gateway Site Anycast VIP Loopback in Nexus Dashboard - cisco.dcnm.dcnm_resource_manager: - state: merged - fabric: "{{ data_model_extended.vxlan.fabric.name }}" - config: "{{ vars_common_msd.bgw_anycast_vip }}" +- name: Manage MSD Fabric Border Gateway Anycast VIP Loopback When Unallocated in Nexus Dashboard when: - - (data_model_multisite.child_fabrics_data - | dict2items - | selectattr('value.attributes', 'defined') - | selectattr('value.attributes.STATIC_UNDERLAY_IP_ALLOC', 'defined') - | selectattr('value.attributes.STATIC_UNDERLAY_IP_ALLOC', 'in', ["true", true]) - | map(attribute='key') - | list - | length > 0) - vars_common_msd.bgw_anycast_vip | length > 0 - change_flags.changes_detected_bgw_anycast_vip + block: + - name: Prepare Multisite Data + cisco.nac_dc_vxlan.dtc.prepare_msite_data: + data_model: "{{ data_model_extended }}" + parent_fabric: "{{ data_model_extended.vxlan.fabric.name }}" + register: data_model_multisite + tags: "{{ nac_tags.create_vrfs_networks }}" + + - name: Create Border Gateway Site Anycast VIP Loopback in Nexus Dashboard + cisco.dcnm.dcnm_resource_manager: + state: merged + fabric: "{{ data_model_extended.vxlan.fabric.name }}" + config: "{{ vars_common_msd.bgw_anycast_vip }}" + when: + - (data_model_multisite.child_fabrics_data + | dict2items + | selectattr('value.attributes', 'defined') + | selectattr('value.attributes.STATIC_UNDERLAY_IP_ALLOC', 'defined') + | selectattr('value.attributes.STATIC_UNDERLAY_IP_ALLOC', 'in', ["true", true]) + | map(attribute='key') + | list + | length > 0) - name: Manage MSD Fabric VRFs and Networks in Nexus Dashboard ansible.builtin.import_tasks: msd/vrfs_networks.yml diff --git a/roles/validate/files/defaults.yml b/roles/validate/files/defaults.yml index 7ebaf838c..b84b1ce05 100644 --- a/roles/validate/files/defaults.yml +++ b/roles/validate/files/defaults.yml @@ -481,6 +481,7 @@ factory_defaults: no_rp: false rp_external: false redist_direct_routemap: FABRIC-RMAP-REDIST-SUBNET + ipv6_redist_direct_routemap: FABRIC-RMAP-REDIST-SUBNET trm_enable: false trm_bgw_msite: false networks: From 0862a279c4d1ff2aa1499a4bd9c5fc4fbdc46606 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Mon, 1 Dec 2025 16:58:47 -0500 Subject: [PATCH 16/17] update deploy mgr for child fabrics --- plugins/action/dtc/fabric_deploy_manager.py | 122 +++++++++---------- plugins/action/dtc/prepare_msite_data.py | 2 - roles/dtc/create/tasks/mcfg/fabric.yml | 8 +- roles/dtc/create/tasks/msd/vrfs_networks.yml | 13 -- roles/dtc/create/tasks/sub_main_msd.yml | 46 ++++--- roles/dtc/deploy/tasks/sub_main_msd.yml | 36 +++--- 6 files changed, 104 insertions(+), 123 deletions(-) diff --git a/plugins/action/dtc/fabric_deploy_manager.py b/plugins/action/dtc/fabric_deploy_manager.py index b18e220b2..7ddc2e9eb 100644 --- a/plugins/action/dtc/fabric_deploy_manager.py +++ b/plugins/action/dtc/fabric_deploy_manager.py @@ -73,17 +73,18 @@ def fabric_check_sync(self): self.fabric_in_sync = True response = self._send_request("GET", self.api_paths["get_switches_by_fabric"]) - for attempt in range(5): - self._fabric_check_sync_helper(response) - if self.fabric_in_sync: - break - if (attempt + 1) == 5 and not self.fabric_in_sync: - break - else: - display.warning(f"Fabric {self.fabric_name} is out of sync. Attempt {attempt + 1}/5. Sleeping 2 seconds before retry.") - sleep(2) - self.fabric_in_sync = True - response = self._send_request("GET", self.api_paths["get_switches_by_fabric"]) + if self.fabric_type not in ['MSD', 'MCFG']: + for attempt in range(5): + self._fabric_check_sync_helper(response) + if self.fabric_in_sync: + break + if (attempt + 1) == 5 and not self.fabric_in_sync: + break + else: + display.warning(f"Fabric {self.fabric_name} is out of sync. Attempt {attempt + 1}/5. Sleeping 2 seconds before retry.") + sleep(2) + self.fabric_in_sync = True + response = self._send_request("GET", self.api_paths["get_switches_by_fabric"]) display.banner(f">>>> Fabric: ({self.fabric_name}) Type: ({self.fabric_type}) in sync: {self.fabric_in_sync}") display.banner(">>>>") @@ -172,67 +173,62 @@ def run(self, tmp=None, task_vars=None): params['fabric_name'] = self._task.args["fabric_name"] params['fabric_type'] = self._task.args["fabric_type"] + + # Operations supported include 'all', 'config_save', 'config_deploy', 'check_sync' params['operation'] = self._task.args.get("operation") + # If force_run_all is set to True, all operations will be executed regardless of change detection + force_run_all = self._task.args.get("force_run_all") + # Manage Deployment For Multisite or Standalone Fabric results = self.manage_fabrics(results, params) if results.get('failed'): return results - params['child_fabric_vrf_data'] = self._task.args.get("child_fabric_vrf_data", {}) + + changed_fabrics = [] + if self._task.args["vrf_response_data"]: + vrf_changed_fabrics = [] + vrf_response_data = self._task.args.get("vrf_response_data") + if vrf_response_data.get('child_fabrics'): + child_fabric_vrf_data = vrf_response_data['child_fabrics'] + + if force_run_all: + vrf_changed_fabrics = [item['fabric'] for item in child_fabric_vrf_data] + else: + vrf_changed_fabrics = [item['fabric'] for item in child_fabric_vrf_data if item.get('changed')] + + if self._task.args["network_response_data"]: + network_changed_fabrics = [] + network_response_data = self._task.args.get("network_response_data") + if network_response_data.get('child_fabrics'): + child_fabric_network_data = network_response_data['child_fabrics'] + + if force_run_all: + network_changed_fabrics = [ + item['fabric'] + for item in child_fabric_network_data + if item['fabric'] not in vrf_changed_fabrics + ] + else: + network_changed_fabrics = [ + item['fabric'] + for item in child_fabric_network_data + if item.get('changed') and item['fabric'] not in vrf_changed_fabrics + ] + + + changed_fabrics = list(set(vrf_changed_fabrics) | set(network_changed_fabrics)) + + if changed_fabrics: + params['fabric_type'] = "Multi-Site_Child_Fabric" + for changed_fabric in changed_fabrics: + params['fabric_name'] = changed_fabric + results = self.manage_fabrics(results, params) + if results.get('failed'): + return results return results - # for key in ['fabric_type', 'fabric_name', 'operation']: - # if params[key] is None: - # results['failed'] = True - # results['msg'] = f"Missing required parameter '{key}'" - # return results - - # if params['operation'] not in ['all', 'config_save', 'config_deploy', 'check_sync']: - # results['failed'] = True - # results['msg'] = "Parameter 'operation' must be one of: [all, config_save, config_deploy, check_sync]" - # return results - - # fabric_manager = FabricDeployManager(params) - - # # Workflows - # if params['operation'] in ['all']: - # fabric_manager.fabric_config_save() - # fabric_manager.fabric_deploy() - # fabric_manager.fabric_check_sync() - - # if not fabric_manager.fabric_in_sync and params['fabric_type'] != 'MSD': - # # If the fabric is out of sync after deployment try one more time before giving up - # fabric_manager.fabric_history_get() - # display.warning(fabric_manager.fabric_history) - # display.warning("Fabric is out of sync after initial deployment. Attempting one more deployment.") - # fabric_manager.fabric_config_save() - # fabric_manager.fabric_deploy() - # fabric_manager.fabric_check_sync() - - # if not fabric_manager.fabric_in_sync and params['fabric_type'] != 'MSD': - # fabric_manager.fabric_history_get() - # results['msg'] = f"Fabric {fabric_manager.fabric_name} is out of sync after deployment." - # results['fabric_history'] = fabric_manager.fabric_history - # results['failed'] = True - - # if params['operation'] in ['config_save']: - # fabric_manager.fabric_config_save() - # if not fabric_manager.fabric_save_succeeded: - # results['failed'] = True - - # if params['operation'] in ['config_deploy']: - # fabric_manager.fabric_deploy() - # if not fabric_manager.fabric_deploy_succeeded: - # results['failed'] = True - - # if params['operation'] in ['check_sync']: - # fabric_manager.fabric_check_sync() - # if not fabric_manager.fabric_in_sync: - # fabric_manager.fabric_history_get() - # results['msg'] = f"Fabric {fabric_manager.fabric_name} is out of sync." - # results['fabric_history'] = fabric_manager.fabric_history - # results['failed'] = True def manage_fabrics(self, results, params): for key in ['fabric_type', 'fabric_name', 'operation']: diff --git a/plugins/action/dtc/prepare_msite_data.py b/plugins/action/dtc/prepare_msite_data.py index 6fc1a265f..4f66479f4 100644 --- a/plugins/action/dtc/prepare_msite_data.py +++ b/plugins/action/dtc/prepare_msite_data.py @@ -138,6 +138,4 @@ def run(self, tmp=None, task_vars=None): results['overlay_attach_groups'] = data_model['vxlan']['multisite']['overlay'] - import epdb ; epdb.set_trace() - return results diff --git a/roles/dtc/create/tasks/mcfg/fabric.yml b/roles/dtc/create/tasks/mcfg/fabric.yml index fdc060838..8d00e3f5f 100644 --- a/roles/dtc/create/tasks/mcfg/fabric.yml +++ b/roles/dtc/create/tasks/mcfg/fabric.yml @@ -33,7 +33,7 @@ - "+ Manage Fabric {{ data_model_extended.vxlan.fabric.name }}" - "---------------------------------------------------------------" -# - name: Manage MCFG Fabric in Nexus Dashboard -# cisco.dcnm.dcnm_fabric_group: -# state: merged -# config: "{{ vars_common_mcfg.fabric_config }}" +- name: Manage MCFG Fabric in Nexus Dashboard + cisco.dcnm.dcnm_fabric_group: + state: merged + config: "{{ vars_common_mcfg.fabric_config }}" diff --git a/roles/dtc/create/tasks/msd/vrfs_networks.yml b/roles/dtc/create/tasks/msd/vrfs_networks.yml index 486eb86d9..0a16ed008 100644 --- a/roles/dtc/create/tasks/msd/vrfs_networks.yml +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -137,9 +137,6 @@ - data_model_extended.vxlan.multisite.overlay.vrfs - change_flags_multisite.changes_detected_vrfs -- ansible.builtin.pause: - minutes: 600 - # -------------------------------------------------------------------- # Manage Loopback VRF attachments on NDFC # -------------------------------------------------------------------- @@ -168,13 +165,3 @@ - data_model_extended.vxlan.multisite.overlay.networks is defined - data_model_extended.vxlan.multisite.overlay.networks - change_flags_multisite.changes_detected_networks - -- name: Update Child Fabrics VRFs and Networks Changed State - ansible.builtin.set_fact: - child_fabrics_vrfs_networks_changed: "{{ vrf_changed | ansible.builtin.union(network_changed) }}" - vars: - vrf_changed: [] - network_changed: "{{ child_fabric_network_results.child_fabrics_changed | default([]) }}" - when: > - (child_fabric_network_results.child_fabrics_changed is defined and - child_fabric_network_results.child_fabrics_changed | length > 0) diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index d32d78460..fce1b5a87 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -45,34 +45,32 @@ - name: Manage MSD Fabric Child Fabrics in Nexus Dashboard ansible.builtin.import_tasks: msd/child_fabrics.yml when: - - data_model_extended.vxlan.multisite.child_fabrics is defined and data_model_extended.vxlan.multisite.child_fabrics | length > 0 + - data_model_extended.vxlan.multisite.child_fabrics is defined + - data_model_extended.vxlan.multisite.child_fabrics | length > 0 -- name: Manage MSD Fabric Border Gateway Anycast VIP Loopback When Unallocated in Nexus Dashboard +- name: Prepare Multisite Data + cisco.nac_dc_vxlan.dtc.prepare_msite_data: + data_model: "{{ data_model_extended }}" + parent_fabric: "{{ data_model_extended.vxlan.fabric.name }}" + register: data_model_multisite + tags: "{{ nac_tags.create_vrfs_networks }}" + +- name: Create Border Gateway Site Anycast VIP Loopback in Nexus Dashboard + cisco.dcnm.dcnm_resource_manager: + state: merged + fabric: "{{ data_model_extended.vxlan.fabric.name }}" + config: "{{ vars_common_msd.bgw_anycast_vip }}" when: + - (data_model_multisite.child_fabrics_data + | dict2items + | selectattr('value.attributes', 'defined') + | selectattr('value.attributes.STATIC_UNDERLAY_IP_ALLOC', 'defined') + | selectattr('value.attributes.STATIC_UNDERLAY_IP_ALLOC', 'in', ["true", true]) + | map(attribute='key') + | list + | length > 0) - vars_common_msd.bgw_anycast_vip | length > 0 - change_flags.changes_detected_bgw_anycast_vip - block: - - name: Prepare Multisite Data - cisco.nac_dc_vxlan.dtc.prepare_msite_data: - data_model: "{{ data_model_extended }}" - parent_fabric: "{{ data_model_extended.vxlan.fabric.name }}" - register: data_model_multisite - tags: "{{ nac_tags.create_vrfs_networks }}" - - - name: Create Border Gateway Site Anycast VIP Loopback in Nexus Dashboard - cisco.dcnm.dcnm_resource_manager: - state: merged - fabric: "{{ data_model_extended.vxlan.fabric.name }}" - config: "{{ vars_common_msd.bgw_anycast_vip }}" - when: - - (data_model_multisite.child_fabrics_data - | dict2items - | selectattr('value.attributes', 'defined') - | selectattr('value.attributes.STATIC_UNDERLAY_IP_ALLOC', 'defined') - | selectattr('value.attributes.STATIC_UNDERLAY_IP_ALLOC', 'in', ["true", true]) - | map(attribute='key') - | list - | length > 0) - name: Manage MSD Fabric VRFs and Networks in Nexus Dashboard ansible.builtin.import_tasks: msd/vrfs_networks.yml diff --git a/roles/dtc/deploy/tasks/sub_main_msd.yml b/roles/dtc/deploy/tasks/sub_main_msd.yml index 1476ba99b..a83565afc 100644 --- a/roles/dtc/deploy/tasks/sub_main_msd.yml +++ b/roles/dtc/deploy/tasks/sub_main_msd.yml @@ -32,8 +32,10 @@ cisco.nac_dc_vxlan.dtc.fabric_deploy_manager: fabric_name: "{{ data_model_extended.vxlan.fabric.name }}" fabric_type: "{{ data_model_extended.vxlan.fabric.type }}" + vrf_response_data: "{{ manage_vrf_result }}" + network_response_data: "{{ manage_network_result }}" + force_run_all: "{{ force_run_all }}" operation: all - child_fabric_vrf_data: "{{ manage_vrf_result }}" vars: ansible_command_timeout: 3000 ansible_connect_timeout: 3000 @@ -41,20 +43,20 @@ - data_model_extended.vxlan.multisite.child_fabrics is defined - data_model_extended.vxlan.multisite.child_fabrics | length > 0 -# TODO: Update cisco.nac_dc_vxlan.dtc.fabric_deploy_manager to handle a list of child fabrics -- name: Config-Save For MSD Child Fabrics in Nexus Dashboard - cisco.nac_dc_vxlan.dtc.fabrics_config_save: - fabrics: "{{ child_fabrics_vrfs_networks_changed }}" - when: > - data_model_extended.vxlan.fabric.type == 'MSD' and - (child_fabrics_vrfs_networks_changed is defined and child_fabrics_vrfs_networks_changed | length > 0) +# # TODO: Update cisco.nac_dc_vxlan.dtc.fabric_deploy_manager to handle a list of child fabrics +# - name: Config-Save For MSD Child Fabrics in Nexus Dashboard +# cisco.nac_dc_vxlan.dtc.fabrics_config_save: +# fabrics: "{{ child_fabrics_vrfs_networks_changed }}" +# when: > +# data_model_extended.vxlan.fabric.type == 'MSD' and +# (child_fabrics_vrfs_networks_changed is defined and child_fabrics_vrfs_networks_changed | length > 0) -- name: Deploy For MSD Child Fabrics in Nexus Dashboard - cisco.nac_dc_vxlan.dtc.fabrics_deploy: - fabrics: "{{ child_fabrics_vrfs_networks_changed }}" - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - when: > - data_model_extended.vxlan.fabric.type == 'MSD' and - (child_fabrics_vrfs_networks_changed is defined and child_fabrics_vrfs_networks_changed | length > 0) +# - name: Deploy For MSD Child Fabrics in Nexus Dashboard +# cisco.nac_dc_vxlan.dtc.fabrics_deploy: +# fabrics: "{{ child_fabrics_vrfs_networks_changed }}" +# vars: +# ansible_command_timeout: 3000 +# ansible_connect_timeout: 3000 +# when: > +# data_model_extended.vxlan.fabric.type == 'MSD' and +# (child_fabrics_vrfs_networks_changed is defined and child_fabrics_vrfs_networks_changed | length > 0) From a775b934a6d2e3ae124d5a066137023a41db8531 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Mon, 1 Dec 2025 17:11:52 -0500 Subject: [PATCH 17/17] fix lint issues --- plugins/action/dtc/fabric_deploy_manager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/action/dtc/fabric_deploy_manager.py b/plugins/action/dtc/fabric_deploy_manager.py index 7ddc2e9eb..eec8c170c 100644 --- a/plugins/action/dtc/fabric_deploy_manager.py +++ b/plugins/action/dtc/fabric_deploy_manager.py @@ -185,7 +185,6 @@ def run(self, tmp=None, task_vars=None): if results.get('failed'): return results - changed_fabrics = [] if self._task.args["vrf_response_data"]: vrf_changed_fabrics = [] @@ -217,7 +216,6 @@ def run(self, tmp=None, task_vars=None): if item.get('changed') and item['fabric'] not in vrf_changed_fabrics ] - changed_fabrics = list(set(vrf_changed_fabrics) | set(network_changed_fabrics)) if changed_fabrics: