Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{# Auto-generated NDFC DC VXLAN EVPN Freeform config data structure for fabric {{ vxlan.fabric.name }} #}
{% if ndfc_version | cisco.nac_dc_vxlan.version_compare('12.2.2', '>=') and
nd_version | regex_replace('^(\\d+\\.\\d+\\.\\d+).*', '\\1') | cisco.nac_dc_vxlan.version_compare('3.2.1', '>') %}
{% if preinterface_config_supported | default(false) %}
preInterfaceConfigSpine: |
{{ vxlan.global.ibgp.spine_pre_interface_freeform | default("") | indent(4) }}
preInterfaceConfigLeaf: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
{{ vxlan.global.ebgp.leaf_post_interface_freeform | default("") | indent(4) }}
EXTRA_CONF_INTRA_LINKS: |2
{{ vxlan.global.ebgp.intra_fabric_link_freeform | default("") | indent(4) }}
{% if ndfc_version | cisco.nac_dc_vxlan.version_compare('12.2.2', '>=') and
nd_version | regex_replace('^(\\d+\\.\\d+\\.\\d+).*', '\\1') | cisco.nac_dc_vxlan.version_compare('3.2.1', '>') %}
{% if preinterface_config_supported | default(false) %}
preInterfaceConfigSpine: |
{{ vxlan.global.ebgp.spine_pre_interface_freeform | default("") | indent(4) }}
preInterfaceConfigLeaf: |
Expand Down
15 changes: 15 additions & 0 deletions roles/dtc/connectivity_check/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@
ndfc_version: "{{ ndfc_version.response.DATA.version }}"
tags: "{{ nac_tags.connectivity_check }}" # Tags defined in roles/common_global/vars/main.yml

# Single source of truth for the NDFC 'preInterfaceConfig{Spine,Leaf,Tor}' feature
# (config emitted before interface config, used to carry *_pre_interface_freeform).
# Consumed by the fabric freeform templates and the create-role guard so the
# version gate lives in exactly one place.
- name: Set preInterfaceConfig Support Flag From NDFC/ND Version
ansible.builtin.set_fact:
preinterface_config_supported: >-
{{ ((ndfc_version | default('') | cisco.nac_dc_vxlan.version_compare('12.2.2', '>='))
and (nd_version | default('') | regex_replace('^(\d+\.\d+\.\d+).*', '\1')
| cisco.nac_dc_vxlan.version_compare('3.2.1', '>'))) | bool }}
when:
- nd_version | default('') | length > 0
- ndfc_version | default('') | length > 0
tags: "{{ nac_tags.connectivity_check }}" # Tags defined in roles/common_global/vars/main.yml

# # ── Phase 2: Centralized Controller State Discovery (Recommendation #3) ──────
# # Queries fabric switches, multisite associations, and fabric existence once.
# # Sets facts consumed by common, create, and remove roles downstream.
Expand Down
40 changes: 40 additions & 0 deletions roles/dtc/create/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,46 @@

---

# ─────────────────────────────────────────────────────────────────────────────
# Guard: fail loud if *_pre_interface_freeform is set but the target NDFC/ND
# version has no 'preInterfaceConfig' field.
#
# On unsupported versions the fabric freeform templates silently drop the
# pre-interface config (e.g. a QoS policy-map) while any dependent
# intra_fabric_link_freeform (e.g. the QoS service-policy that references it) is
# still pushed, leaving the fabric permanently Out-of-Sync ("cannot apply
# non-existing policy to interface"). Guard here, at create time — where the
# fabric config originates — so remove/cleanup is never blocked. On older
# NDFC/ND create the prerequisite config via 'vxlan.policy' (switch_freeform).
# ─────────────────────────────────────────────────────────────────────────────
- name: Fail If Pre-Interface Freeform Is Set But Unsupported By The NDFC/ND Version
vars:
_fabric_global: "{{ data_model_extended.vxlan.global | default({}) }}"
_pre_if_ff_values:
- "{{ (_fabric_global.ibgp | default({})).spine_pre_interface_freeform | default('') }}"
- "{{ (_fabric_global.ibgp | default({})).leaf_pre_interface_freeform | default('') }}"
- "{{ (_fabric_global.ibgp | default({})).tor_pre_interface_freeform | default('') }}"
- "{{ (_fabric_global.ebgp | default({})).spine_pre_interface_freeform | default('') }}"
- "{{ (_fabric_global.ebgp | default({})).leaf_pre_interface_freeform | default('') }}"
- "{{ (_fabric_global.ebgp | default({})).tor_pre_interface_freeform | default('') }}"
ansible.builtin.fail:
msg: >-
Fabric '{{ data_model_extended.vxlan.fabric.name }}': pre-interface freeform
(spine_pre_interface_freeform / leaf_pre_interface_freeform / tor_pre_interface_freeform)
requires NDFC >= 12.2.2 and Nexus Dashboard > 3.2.1, but detected NDFC
'{{ ndfc_version | default("unknown") }}' / ND '{{ nd_version | default("unknown") }}'.
On this version NDFC has no 'preInterfaceConfig' field, so this config is silently
dropped while any dependent intra_fabric_link_freeform (e.g. a QoS service-policy) is
still pushed, leaving the fabric permanently Out-of-Sync. Create the prerequisite
config (e.g. the QoS policy-map) via 'vxlan.policy' (switch_freeform) instead, or
upgrade NDFC/ND.
when:
- preinterface_config_supported is defined
- not (preinterface_config_supported | bool)
- (_pre_if_ff_values | map('trim') | reject('equalto', '') | list | length) > 0
delegate_to: localhost
tags: "{{ nac_tags.create }}"

- name: Execute Create Resources
cisco.nac_dc_vxlan.dtc.manage_resources:
fabric_type: "{{ data_model_extended.vxlan.fabric.type }}"
Expand Down
Loading