From a86f75644d7c974057792ffc55626489545ae456 Mon Sep 17 00:00:00 2001 From: "Aneesh Ramgopal (anramgop)" Date: Mon, 25 Nov 2024 15:10:38 -0800 Subject: [PATCH 01/66] MSD sub-main changes --- roles/validate/tasks/sub_main_common.yml | 148 +++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 roles/validate/tasks/sub_main_common.yml diff --git a/roles/validate/tasks/sub_main_common.yml b/roles/validate/tasks/sub_main_common.yml new file mode 100644 index 00000000..876a3fab --- /dev/null +++ b/roles/validate/tasks/sub_main_common.yml @@ -0,0 +1,148 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Role Entry Point - [cisco.nac_dc_vxlan.validate] + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Calling Role - [cisco.nac_dc_vxlan.validate] +" + - "----------------------------------------------------------------" + +- ansible.builtin.debug: msg="Role Path - {{ role_path }}" + +- ansible.builtin.debug: msg="Inventory Directory - {{ inventory_dir }}" + +- name: Validate NDFC Service Model Data + ansible.builtin.debug: msg="Calling Role Validate - nac_dc_vxlan.validate" + +- ansible.builtin.debug: msg="Workflow is Direct to Device (DTD)" + when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.nxos.nxos" + +- ansible.builtin.debug: msg="Workflow is Direct to Controller (DTC)" + when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.dcnm.dcnm" + +- name: Check for Schema Path Being Defined + ansible.builtin.set_fact: + schema_path: '' + when: schema_path is not defined + delegate_to: localhost + +- name: Check for Enhanced Roles Path Being Defined + ansible.builtin.set_fact: + enhanced_rules_path: '' + when: enhanced_rules_path is not defined + delegate_to: localhost + +- name: Perform Required Syntax and Semantic Model Validation + cisco.nac_dc_vxlan.common.nac_dc_validate: + schema: "{{ schema_path }}" + mdata: "{{ data_path }}" + rules: "{{ rules_path }}" + register: model_data + vars: + data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" + rules_path: "{{ role_path }}/files/rules/required_rules/msd" + delegate_to: localhost + +- name: Perform Enhanced Syntax and Semantic Model Validation + cisco.nac_dc_vxlan.common.nac_dc_validate: + schema: "{{ schema_path }}" + mdata: "{{ data_path }}" + rules: "{{ enhanced_rules_path }}" + vars: + data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" + when: enhanced_rules_path is defined and enhanced_rules_path + delegate_to: localhost + +# - name: Stat Factory Defaults +# ansible.builtin.stat: path="{{ role_path }}/files/defaults.yml" +# register: factory_defaults_file +# delegate_to: localhost + +# - name: Include Factory Defaults if Available +# ansible.builtin.include_vars: +# file: "{{ role_path }}/files/defaults.yml" +# when: factory_defaults_file.stat.exists +# delegate_to: localhost + +# - name: Merge factory and custom defaults +# cisco.nac_dc_vxlan.common.merge_defaults: +# factory_defaults: "{{ factory_defaults }}" +# model_data: "{{ model_data['data'] }}" +# register: defaults +# delegate_to: localhost + +# - name: Register Variable With Only Defaults from Previous Task +# ansible.builtin.set_fact: +# defaults: "{{ defaults['defaults'] }}" +# delegate_to: localhost + +- name: Prepare Service Model + cisco.nac_dc_vxlan.common.prepare_service_model: + inventory_hostname: "{{ inventory_hostname }}" + hostvars: "{{ hostvars }}" + model_data: "{{ model_data['data'] }}" + register: smd + delegate_to: localhost + +- name: Store Golden Service Model Data + ansible.builtin.set_fact: + MD: "{{ smd['model_golden'] }}" + delegate_to: localhost + +- name: Store Extended Service Model Data + ansible.builtin.set_fact: + MD_Extended: "{{ smd['model_extended'] }}" + delegate_to: localhost + +- name: Check Roles + cisco.nac_dc_vxlan.common.check_roles: + role_list: "{{ role_names }}" + register: check_roles + delegate_to: localhost + +- name: Read Run Map From Previous Run + cisco.nac_dc_vxlan.common.read_run_map: + model_data: "{{ MD_Extended }}" + register: run_map_read_result + delegate_to: localhost + +- name: Debug Run Map Read Result + ansible.builtin.debug: + msg: "{{ run_map_read_result }}" + delegate_to: localhost + +- name: Initialize Run Map + cisco.nac_dc_vxlan.common.run_map: + model_data: "{{ MD_Extended }}" + stage: starting_execution + register: run_map + delegate_to: localhost + +- name: Manage Previous Service Model Data Files + ansible.builtin.include_tasks: manage_model_files_previous.yml + when: check_roles['save_previous'] + +- name: Manage Current Service Model Data Files + ansible.builtin.include_tasks: manage_model_files_current.yml + when: check_roles['save_previous'] \ No newline at end of file From 77532eec2281693bfbe123c57b9019fbb108375d Mon Sep 17 00:00:00 2001 From: "Aneesh Ramgopal (anramgop)" Date: Mon, 25 Nov 2024 15:11:05 -0800 Subject: [PATCH 02/66] MSD sub-main changes --- roles/validate/tasks/sub_main.yml | 104 +++++++++++++++--------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/roles/validate/tasks/sub_main.yml b/roles/validate/tasks/sub_main.yml index d19ebe20..62191b4d 100644 --- a/roles/validate/tasks/sub_main.yml +++ b/roles/validate/tasks/sub_main.yml @@ -21,58 +21,58 @@ --- -- name: Role Entry Point - [cisco.nac_dc_vxlan.validate] - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Calling Role - [cisco.nac_dc_vxlan.validate] +" - - "----------------------------------------------------------------" - -- ansible.builtin.debug: msg="Role Path - {{ role_path }}" - -- ansible.builtin.debug: msg="Inventory Directory - {{ inventory_dir }}" - -- name: Validate NDFC Service Model Data - ansible.builtin.debug: msg="Calling Role Validate - nac_dc_vxlan.validate" - -- ansible.builtin.debug: msg="Workflow is Direct to Device (DTD)" - when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.nxos.nxos" - -- ansible.builtin.debug: msg="Workflow is Direct to Controller (DTC)" - when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.dcnm.dcnm" - -- name: Check for Schema Path Being Defined - ansible.builtin.set_fact: - schema_path: '' - when: schema_path is not defined - delegate_to: localhost - -- name: Check for Enhanced Roles Path Being Defined - ansible.builtin.set_fact: - enhanced_rules_path: '' - when: enhanced_rules_path is not defined - delegate_to: localhost - -- name: Perform Required Syntax and Semantic Model Validation - cisco.nac_dc_vxlan.common.nac_dc_validate: - schema: "{{ schema_path }}" - mdata: "{{ data_path }}" - rules: "{{ rules_path }}" - register: model_data - vars: - data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - rules_path: "{{ role_path }}/files/rules/required_rules/" - delegate_to: localhost - -- name: Perform Enhanced Syntax and Semantic Model Validation - cisco.nac_dc_vxlan.common.nac_dc_validate: - schema: "{{ schema_path }}" - mdata: "{{ data_path }}" - rules: "{{ enhanced_rules_path }}" - vars: - data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - when: enhanced_rules_path is defined and enhanced_rules_path - delegate_to: localhost +# - name: Role Entry Point - [cisco.nac_dc_vxlan.validate] +# ansible.builtin.debug: +# msg: +# - "----------------------------------------------------------------" +# - "+ Calling Role - [cisco.nac_dc_vxlan.validate] +" +# - "----------------------------------------------------------------" + +# - ansible.builtin.debug: msg="Role Path - {{ role_path }}" + +# - ansible.builtin.debug: msg="Inventory Directory - {{ inventory_dir }}" + +# - name: Validate NDFC Service Model Data +# ansible.builtin.debug: msg="Calling Role Validate - nac_dc_vxlan.validate" + +# - ansible.builtin.debug: msg="Workflow is Direct to Device (DTD)" +# when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.nxos.nxos" + +# - ansible.builtin.debug: msg="Workflow is Direct to Controller (DTC)" +# when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.dcnm.dcnm" + +# - name: Check for Schema Path Being Defined +# ansible.builtin.set_fact: +# schema_path: '' +# when: schema_path is not defined +# delegate_to: localhost + +# - name: Check for Enhanced Roles Path Being Defined +# ansible.builtin.set_fact: +# enhanced_rules_path: '' +# when: enhanced_rules_path is not defined +# delegate_to: localhost + +# - name: Perform Required Syntax and Semantic Model Validation +# cisco.nac_dc_vxlan.common.nac_dc_validate: +# schema: "{{ schema_path }}" +# mdata: "{{ data_path }}" +# rules: "{{ rules_path }}" +# register: model_data +# vars: +# data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" +# rules_path: "{{ role_path }}/files/rules/required_rules/" +# delegate_to: localhost + +# - name: Perform Enhanced Syntax and Semantic Model Validation +# cisco.nac_dc_vxlan.common.nac_dc_validate: +# schema: "{{ schema_path }}" +# mdata: "{{ data_path }}" +# rules: "{{ enhanced_rules_path }}" +# vars: +# data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" +# when: enhanced_rules_path is defined and enhanced_rules_path +# delegate_to: localhost - name: Stat Factory Defaults ansible.builtin.stat: path="{{ role_path }}/files/defaults.yml" From d37cdc46e60052fc41671bc34a06b0f95311b6a3 Mon Sep 17 00:00:00 2001 From: "Aneesh Ramgopal (anramgop)" Date: Tue, 26 Nov 2024 15:31:30 -0800 Subject: [PATCH 03/66] Added sub-main-common and service model validation --- plugins/action/common/nac_dc_import.py | 70 +++++++++++++++ .../action/common/prepare_service_model.py | 3 + plugins/action/common/read_run_map.py | 2 +- plugins/action/common/run_map.py | 2 +- roles/validate/tasks/main.yml | 10 +++ roles/validate/tasks/sub_main.yml | 85 +++---------------- roles/validate/tasks/sub_main_common.yml | 65 +++++++------- roles/validate/tasks/sub_main_msd.yml | 85 +++++++++++++++++++ 8 files changed, 212 insertions(+), 110 deletions(-) create mode 100644 plugins/action/common/nac_dc_import.py create mode 100644 roles/validate/tasks/sub_main_msd.yml diff --git a/plugins/action/common/nac_dc_import.py b/plugins/action/common/nac_dc_import.py new file mode 100644 index 00000000..94eae990 --- /dev/null +++ b/plugins/action/common/nac_dc_import.py @@ -0,0 +1,70 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible.utils.display import Display +from ansible.plugins.action import ActionBase +from ansible.errors import AnsibleError + +try: + from iac_validate.yaml import load_yaml_files + from iac_validate.cli.options import DEFAULT_SCHEMA +except ImportError as imp_exc: + IAC_VALIDATE_IMPORT_ERROR = imp_exc +else: + IAC_VALIDATE_IMPORT_ERROR = None + +import os + +display = Display() + + +class ActionModule(ActionBase): + + def run(self, tmp=None, task_vars=None): + results = super(ActionModule, self).run(tmp, task_vars) + results['failed'] = False + results['msg'] = None + results['data'] = {} + + if IAC_VALIDATE_IMPORT_ERROR: + raise AnsibleError('iac-validate not found and must be installed. Please pip install iac-validate.') from IAC_VALIDATE_IMPORT_ERROR + + mdata = self._task.args.get('mdata') + + # Verify That Data Sources Exists + if mdata and not os.path.exists(mdata): + results['failed'] = True + results['msg'] = "The data directory ({0}) for this fabric does not appear to exist!".format(mdata) + return results + if len(os.listdir(mdata)) == 0: + results['failed'] = True + results['msg'] = "The data directory ({0}) for this fabric is empty!".format(mdata) + return results + + # Return Schema Validated Model Data + results['data'] = load_yaml_files([mdata]) + + return results diff --git a/plugins/action/common/prepare_service_model.py b/plugins/action/common/prepare_service_model.py index 68d806fc..d546ca5c 100644 --- a/plugins/action/common/prepare_service_model.py +++ b/plugins/action/common/prepare_service_model.py @@ -54,9 +54,12 @@ def run(self, tmp=None, task_vars=None): sm_data = self._task.args['model_data'] # results['model_extended'] contains the data that can be extended by the plugins results['model_extended'] = copy.deepcopy(sm_data) + fabric_type = sm_data.get('vxlan').get('fabric_type', None) full_plugin_path = "ansible_collections.cisco.nac_dc_vxlan.plugins.action.common.prepare_plugins" glob_plugin_path = os.path.dirname(__file__) + "/prepare_plugins" + if fabric_type == 'MSD': + glob_plugin_path = os.path.dirname(__file__) + "/prepare_plugins/msd" plugin_prefix = "prep*.py" prepare_libs = set(x.stem for x in pathlib.Path.glob(pathlib.Path(glob_plugin_path), plugin_prefix)) diff --git a/plugins/action/common/read_run_map.py b/plugins/action/common/read_run_map.py index 9c6eac28..b7c24448 100644 --- a/plugins/action/common/read_run_map.py +++ b/plugins/action/common/read_run_map.py @@ -40,7 +40,7 @@ def run(self, tmp=None, task_vars=None): results['diff_run'] = True model_data = task_vars['model_data']['data'] - fabric_name = model_data["vxlan"]["global"]["name"] + fabric_name = model_data["vxlan"]["name"] if 'dtc' in task_vars['role_path']: common_role_path = os.path.dirname(task_vars['role_path']) diff --git a/plugins/action/common/run_map.py b/plugins/action/common/run_map.py index 2784a0b9..0d4a7f7e 100644 --- a/plugins/action/common/run_map.py +++ b/plugins/action/common/run_map.py @@ -43,7 +43,7 @@ def run(self, tmp=None, task_vars=None): model_data = task_vars['model_data']['data'] stage = self._task.args['stage'] - fabric_name = model_data["vxlan"]["global"]["name"] + fabric_name = model_data["vxlan"]["name"] if 'dtc' in task_vars['role_path']: common_role_path = os.path.dirname(task_vars['role_path']) diff --git a/roles/validate/tasks/main.yml b/roles/validate/tasks/main.yml index 9d6e722c..bf91a43f 100644 --- a/roles/validate/tasks/main.yml +++ b/roles/validate/tasks/main.yml @@ -23,8 +23,18 @@ - debug: msg="{{ nac_tags.all }}" - name: Import Role Tasks + ansible.builtin.import_tasks: sub_main_common.yml + tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml + +- name: Import Role Tasks for MSD Fabric + ansible.builtin.import_tasks: sub_main_msd.yml + tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml + when: MD_Extended.vxlan.fabric_type == 'MSD' + +- name: Import Role Tasks for VxLAN Fabric ansible.builtin.import_tasks: sub_main.yml tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml + when: MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' # Problems with lower versions of python and ansible # Python 3.9.16 and Ansible 7.3.0 (Ansible-Core 2.14.4) # Could ignore errors and try again with tags specified as below as a work around ... diff --git a/roles/validate/tasks/sub_main.yml b/roles/validate/tasks/sub_main.yml index 62191b4d..ade2b558 100644 --- a/roles/validate/tasks/sub_main.yml +++ b/roles/validate/tasks/sub_main.yml @@ -21,87 +21,22 @@ --- -# - name: Role Entry Point - [cisco.nac_dc_vxlan.validate] -# ansible.builtin.debug: -# msg: -# - "----------------------------------------------------------------" -# - "+ Calling Role - [cisco.nac_dc_vxlan.validate] +" -# - "----------------------------------------------------------------" - -# - ansible.builtin.debug: msg="Role Path - {{ role_path }}" - -# - ansible.builtin.debug: msg="Inventory Directory - {{ inventory_dir }}" - -# - name: Validate NDFC Service Model Data -# ansible.builtin.debug: msg="Calling Role Validate - nac_dc_vxlan.validate" - -# - ansible.builtin.debug: msg="Workflow is Direct to Device (DTD)" -# when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.nxos.nxos" - -# - ansible.builtin.debug: msg="Workflow is Direct to Controller (DTC)" -# when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.dcnm.dcnm" - -# - name: Check for Schema Path Being Defined -# ansible.builtin.set_fact: -# schema_path: '' -# when: schema_path is not defined -# delegate_to: localhost - -# - name: Check for Enhanced Roles Path Being Defined -# ansible.builtin.set_fact: -# enhanced_rules_path: '' -# when: enhanced_rules_path is not defined -# delegate_to: localhost - -# - name: Perform Required Syntax and Semantic Model Validation -# cisco.nac_dc_vxlan.common.nac_dc_validate: -# schema: "{{ schema_path }}" -# mdata: "{{ data_path }}" -# rules: "{{ rules_path }}" -# register: model_data -# vars: -# data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" -# rules_path: "{{ role_path }}/files/rules/required_rules/" -# delegate_to: localhost - -# - name: Perform Enhanced Syntax and Semantic Model Validation -# cisco.nac_dc_vxlan.common.nac_dc_validate: -# schema: "{{ schema_path }}" -# mdata: "{{ data_path }}" -# rules: "{{ enhanced_rules_path }}" -# vars: -# data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" -# when: enhanced_rules_path is defined and enhanced_rules_path -# delegate_to: localhost - -- name: Stat Factory Defaults - ansible.builtin.stat: path="{{ role_path }}/files/defaults.yml" - register: factory_defaults_file - delegate_to: localhost - -- name: Include Factory Defaults if Available - ansible.builtin.include_vars: - file: "{{ role_path }}/files/defaults.yml" - when: factory_defaults_file.stat.exists - delegate_to: localhost - -- name: Merge factory and custom defaults - cisco.nac_dc_vxlan.common.merge_defaults: - factory_defaults: "{{ factory_defaults }}" - model_data: "{{ model_data['data'] }}" - register: defaults - delegate_to: localhost - -- name: Register Variable With Only Defaults from Previous Task - ansible.builtin.set_fact: - defaults: "{{ defaults['defaults'] }}" +- name: Perform Required Syntax and Semantic Model Validation + cisco.nac_dc_vxlan.common.nac_dc_validate: + schema: "{{ schema_path }}" + mdata: "{{ data_path }}" + rules: "{{ rules_path }}" + register: model_data_vxlan + vars: + data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" + rules_path: "{{ role_path }}/files/rules/required_rules/" delegate_to: localhost - name: Prepare Service Model cisco.nac_dc_vxlan.common.prepare_service_model: inventory_hostname: "{{ inventory_hostname }}" hostvars: "{{ hostvars }}" - model_data: "{{ model_data['data'] }}" + model_data: "{{ model_data_vxlan['data'] }}" default_values: "{{ defaults }}" templates_path: "{{ role_path }}/../dtc/common/templates/" register: smd diff --git a/roles/validate/tasks/sub_main_common.yml b/roles/validate/tasks/sub_main_common.yml index 876a3fab..8907154f 100644 --- a/roles/validate/tasks/sub_main_common.yml +++ b/roles/validate/tasks/sub_main_common.yml @@ -53,55 +53,54 @@ when: enhanced_rules_path is not defined delegate_to: localhost -- name: Perform Required Syntax and Semantic Model Validation - cisco.nac_dc_vxlan.common.nac_dc_validate: - schema: "{{ schema_path }}" +- name: Import Semantic Model + cisco.nac_dc_vxlan.common.nac_dc_import: mdata: "{{ data_path }}" - rules: "{{ rules_path }}" register: model_data vars: data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - rules_path: "{{ role_path }}/files/rules/required_rules/msd" delegate_to: localhost -- name: Perform Enhanced Syntax and Semantic Model Validation - cisco.nac_dc_vxlan.common.nac_dc_validate: - schema: "{{ schema_path }}" - mdata: "{{ data_path }}" - rules: "{{ enhanced_rules_path }}" - vars: - data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - when: enhanced_rules_path is defined and enhanced_rules_path - delegate_to: localhost - -# - name: Stat Factory Defaults -# ansible.builtin.stat: path="{{ role_path }}/files/defaults.yml" -# register: factory_defaults_file +# - name: Perform Enhanced Syntax and Semantic Model Validation +# cisco.nac_dc_vxlan.common.nac_dc_validate: +# schema: "{{ schema_path }}" +# mdata: "{{ data_path }}" +# rules: "{{ enhanced_rules_path }}" +# vars: +# data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" +# when: enhanced_rules_path is defined and enhanced_rules_path # delegate_to: localhost -# - name: Include Factory Defaults if Available -# ansible.builtin.include_vars: -# file: "{{ role_path }}/files/defaults.yml" -# when: factory_defaults_file.stat.exists -# delegate_to: localhost +- name: Stat Factory Defaults + ansible.builtin.stat: path="{{ role_path }}/files/defaults.yml" + register: factory_defaults_file + delegate_to: localhost -# - name: Merge factory and custom defaults -# cisco.nac_dc_vxlan.common.merge_defaults: -# factory_defaults: "{{ factory_defaults }}" -# model_data: "{{ model_data['data'] }}" -# register: defaults -# delegate_to: localhost +- name: Include Factory Defaults if Available + ansible.builtin.include_vars: + file: "{{ role_path }}/files/defaults.yml" + when: factory_defaults_file.stat.exists + delegate_to: localhost -# - name: Register Variable With Only Defaults from Previous Task -# ansible.builtin.set_fact: -# defaults: "{{ defaults['defaults'] }}" -# delegate_to: localhost +- name: Merge factory and custom defaults + cisco.nac_dc_vxlan.common.merge_defaults: + factory_defaults: "{{ factory_defaults }}" + model_data: "{{ model_data['data'] }}" + register: defaults + delegate_to: localhost + +- name: Register Variable With Only Defaults from Previous Task + ansible.builtin.set_fact: + defaults: "{{ defaults['defaults'] }}" + delegate_to: localhost - name: Prepare Service Model cisco.nac_dc_vxlan.common.prepare_service_model: inventory_hostname: "{{ inventory_hostname }}" hostvars: "{{ hostvars }}" model_data: "{{ model_data['data'] }}" + default_values: "{{ defaults }}" + templates_path: "{{ role_path }}/../dtc/common/templates/" register: smd delegate_to: localhost diff --git a/roles/validate/tasks/sub_main_msd.yml b/roles/validate/tasks/sub_main_msd.yml new file mode 100644 index 00000000..22ad6cc1 --- /dev/null +++ b/roles/validate/tasks/sub_main_msd.yml @@ -0,0 +1,85 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Perform Required Syntax and Semantic Model Validation + cisco.nac_dc_vxlan.common.nac_dc_validate: + schema: "{{ schema_path }}" + mdata: "{{ data_path }}" + rules: "{{ rules_path }}" + register: model_data_msd + vars: + data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" + rules_path: "{{ role_path }}/files/rules/required_rules/msd/" + delegate_to: localhost + +- name: Prepare Service Model + cisco.nac_dc_vxlan.common.prepare_service_model: + inventory_hostname: "{{ inventory_hostname }}" + hostvars: "{{ hostvars }}" + model_data: "{{ model_data_msd['data'] }}" + default_values: "{{ defaults }}" + templates_path: "{{ role_path }}/../dtc/common/templates/" + register: smd + delegate_to: localhost + +- name: Store Golden Service Model Data + ansible.builtin.set_fact: + MD: "{{ smd['model_golden'] }}" + delegate_to: localhost + +- name: Store Extended Service Model Data + ansible.builtin.set_fact: + MD_Extended: "{{ smd['model_extended'] }}" + delegate_to: localhost + +- name: Check Roles + cisco.nac_dc_vxlan.common.check_roles: + role_list: "{{ role_names }}" + register: check_roles + delegate_to: localhost + +- name: Read Run Map From Previous Run + cisco.nac_dc_vxlan.common.read_run_map: + model_data: "{{ MD_Extended }}" + register: run_map_read_result + delegate_to: localhost + +- name: Debug Run Map Read Result + ansible.builtin.debug: + msg: "{{ run_map_read_result }}" + delegate_to: localhost + +- name: Initialize Run Map + cisco.nac_dc_vxlan.common.run_map: + model_data: "{{ MD_Extended }}" + stage: starting_execution + register: run_map + delegate_to: localhost + +- name: Manage Previous Service Model Data Files + ansible.builtin.include_tasks: manage_model_files_previous.yml + when: check_roles['save_previous'] + +- name: Manage Current Service Model Data Files + ansible.builtin.include_tasks: manage_model_files_current.yml + when: check_roles['save_previous'] \ No newline at end of file From 49dcb6d15ae67f4136c067f25bd9b276d5d64536 Mon Sep 17 00:00:00 2001 From: "Aneesh Ramgopal (anramgop)" Date: Wed, 27 Nov 2024 10:18:59 -0800 Subject: [PATCH 04/66] Split validate and load functions --- .../action/common/{nac_dc_import.py => nac_dc_load.py} | 0 plugins/action/common/nac_dc_validate.py | 4 ---- roles/validate/tasks/sub_main.yml | 3 +-- roles/validate/tasks/sub_main_common.yml | 4 ++-- roles/validate/tasks/sub_main_msd.yml | 9 ++++++--- 5 files changed, 9 insertions(+), 11 deletions(-) rename plugins/action/common/{nac_dc_import.py => nac_dc_load.py} (100%) diff --git a/plugins/action/common/nac_dc_import.py b/plugins/action/common/nac_dc_load.py similarity index 100% rename from plugins/action/common/nac_dc_import.py rename to plugins/action/common/nac_dc_load.py diff --git a/plugins/action/common/nac_dc_validate.py b/plugins/action/common/nac_dc_validate.py index 3af8b48d..c7a91085 100644 --- a/plugins/action/common/nac_dc_validate.py +++ b/plugins/action/common/nac_dc_validate.py @@ -48,7 +48,6 @@ def run(self, tmp=None, task_vars=None): results = super(ActionModule, self).run(tmp, task_vars) results['failed'] = False results['msg'] = None - results['data'] = {} if IAC_VALIDATE_IMPORT_ERROR: raise AnsibleError('iac-validate not found and must be installed. Please pip install iac-validate.') from IAC_VALIDATE_IMPORT_ERROR @@ -93,7 +92,4 @@ def run(self, tmp=None, task_vars=None): results['failed'] = True results['msg'] = msg - # Return Schema Validated Model Data - results['data'] = load_yaml_files([mdata]) - return results diff --git a/roles/validate/tasks/sub_main.yml b/roles/validate/tasks/sub_main.yml index ade2b558..3381aa95 100644 --- a/roles/validate/tasks/sub_main.yml +++ b/roles/validate/tasks/sub_main.yml @@ -26,7 +26,6 @@ schema: "{{ schema_path }}" mdata: "{{ data_path }}" rules: "{{ rules_path }}" - register: model_data_vxlan vars: data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" rules_path: "{{ role_path }}/files/rules/required_rules/" @@ -36,7 +35,7 @@ cisco.nac_dc_vxlan.common.prepare_service_model: inventory_hostname: "{{ inventory_hostname }}" hostvars: "{{ hostvars }}" - model_data: "{{ model_data_vxlan['data'] }}" + model_data: "{{ model_data['data'] }}" default_values: "{{ defaults }}" templates_path: "{{ role_path }}/../dtc/common/templates/" register: smd diff --git a/roles/validate/tasks/sub_main_common.yml b/roles/validate/tasks/sub_main_common.yml index 8907154f..310a79e6 100644 --- a/roles/validate/tasks/sub_main_common.yml +++ b/roles/validate/tasks/sub_main_common.yml @@ -53,8 +53,8 @@ when: enhanced_rules_path is not defined delegate_to: localhost -- name: Import Semantic Model - cisco.nac_dc_vxlan.common.nac_dc_import: +- name: Load Data Model + cisco.nac_dc_vxlan.common.nac_dc_load: mdata: "{{ data_path }}" register: model_data vars: diff --git a/roles/validate/tasks/sub_main_msd.yml b/roles/validate/tasks/sub_main_msd.yml index 22ad6cc1..f4a566d3 100644 --- a/roles/validate/tasks/sub_main_msd.yml +++ b/roles/validate/tasks/sub_main_msd.yml @@ -26,7 +26,6 @@ schema: "{{ schema_path }}" mdata: "{{ data_path }}" rules: "{{ rules_path }}" - register: model_data_msd vars: data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" rules_path: "{{ role_path }}/files/rules/required_rules/msd/" @@ -36,7 +35,7 @@ cisco.nac_dc_vxlan.common.prepare_service_model: inventory_hostname: "{{ inventory_hostname }}" hostvars: "{{ hostvars }}" - model_data: "{{ model_data_msd['data'] }}" + model_data: "{{ model_data['data'] }}" default_values: "{{ defaults }}" templates_path: "{{ role_path }}/../dtc/common/templates/" register: smd @@ -82,4 +81,8 @@ - name: Manage Current Service Model Data Files ansible.builtin.include_tasks: manage_model_files_current.yml - when: check_roles['save_previous'] \ No newline at end of file + when: check_roles['save_previous'] + +- debug: msg="{{ MD }}" + +- debug: msg="{{ MD_Extended }}" \ No newline at end of file From 7ef9df8601d9d517c7b38f54610055d92ba2cd91 Mon Sep 17 00:00:00 2001 From: "Aneesh Ramgopal (anramgop)" Date: Wed, 27 Nov 2024 10:38:54 -0800 Subject: [PATCH 05/66] Refactoring sub main common --- roles/validate/tasks/main.yml | 6 +- roles/validate/tasks/sub_main_common.yml | 74 +++++++------------ roles/validate/tasks/sub_main_msd.yml | 40 +++++----- .../{sub_main.yml => sub_main_vxlan.yml} | 34 ++++----- 4 files changed, 66 insertions(+), 88 deletions(-) rename roles/validate/tasks/{sub_main.yml => sub_main_vxlan.yml} (78%) diff --git a/roles/validate/tasks/main.yml b/roles/validate/tasks/main.yml index bf91a43f..a454e6c3 100644 --- a/roles/validate/tasks/main.yml +++ b/roles/validate/tasks/main.yml @@ -32,7 +32,7 @@ when: MD_Extended.vxlan.fabric_type == 'MSD' - name: Import Role Tasks for VxLAN Fabric - ansible.builtin.import_tasks: sub_main.yml + ansible.builtin.import_tasks: sub_main_vxlan.yml tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml when: MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' # Problems with lower versions of python and ansible @@ -62,3 +62,7 @@ stage: role_validate_completed register: run_map delegate_to: localhost + +- debug: msg="{{ MD }}" + +- debug: msg="{{ MD_Extended }}" \ No newline at end of file diff --git a/roles/validate/tasks/sub_main_common.yml b/roles/validate/tasks/sub_main_common.yml index 310a79e6..fdcb3680 100644 --- a/roles/validate/tasks/sub_main_common.yml +++ b/roles/validate/tasks/sub_main_common.yml @@ -41,18 +41,6 @@ - ansible.builtin.debug: msg="Workflow is Direct to Controller (DTC)" when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.dcnm.dcnm" -- name: Check for Schema Path Being Defined - ansible.builtin.set_fact: - schema_path: '' - when: schema_path is not defined - delegate_to: localhost - -- name: Check for Enhanced Roles Path Being Defined - ansible.builtin.set_fact: - enhanced_rules_path: '' - when: enhanced_rules_path is not defined - delegate_to: localhost - - name: Load Data Model cisco.nac_dc_vxlan.common.nac_dc_load: mdata: "{{ data_path }}" @@ -61,16 +49,6 @@ data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" delegate_to: localhost -# - name: Perform Enhanced Syntax and Semantic Model Validation -# cisco.nac_dc_vxlan.common.nac_dc_validate: -# schema: "{{ schema_path }}" -# mdata: "{{ data_path }}" -# rules: "{{ enhanced_rules_path }}" -# vars: -# data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" -# when: enhanced_rules_path is defined and enhanced_rules_path -# delegate_to: localhost - - name: Stat Factory Defaults ansible.builtin.stat: path="{{ role_path }}/files/defaults.yml" register: factory_defaults_file @@ -114,34 +92,34 @@ MD_Extended: "{{ smd['model_extended'] }}" delegate_to: localhost -- name: Check Roles - cisco.nac_dc_vxlan.common.check_roles: - role_list: "{{ role_names }}" - register: check_roles - delegate_to: localhost +# - name: Check Roles +# cisco.nac_dc_vxlan.common.check_roles: +# role_list: "{{ role_names }}" +# register: check_roles +# delegate_to: localhost -- name: Read Run Map From Previous Run - cisco.nac_dc_vxlan.common.read_run_map: - model_data: "{{ MD_Extended }}" - register: run_map_read_result - delegate_to: localhost +# - name: Read Run Map From Previous Run +# cisco.nac_dc_vxlan.common.read_run_map: +# model_data: "{{ MD_Extended }}" +# register: run_map_read_result +# delegate_to: localhost -- name: Debug Run Map Read Result - ansible.builtin.debug: - msg: "{{ run_map_read_result }}" - delegate_to: localhost +# - name: Debug Run Map Read Result +# ansible.builtin.debug: +# msg: "{{ run_map_read_result }}" +# delegate_to: localhost -- name: Initialize Run Map - cisco.nac_dc_vxlan.common.run_map: - model_data: "{{ MD_Extended }}" - stage: starting_execution - register: run_map - delegate_to: localhost +# - name: Initialize Run Map +# cisco.nac_dc_vxlan.common.run_map: +# model_data: "{{ MD_Extended }}" +# stage: starting_execution +# register: run_map +# delegate_to: localhost -- name: Manage Previous Service Model Data Files - ansible.builtin.include_tasks: manage_model_files_previous.yml - when: check_roles['save_previous'] +# - name: Manage Previous Service Model Data Files +# ansible.builtin.include_tasks: manage_model_files_previous.yml +# when: check_roles['save_previous'] -- name: Manage Current Service Model Data Files - ansible.builtin.include_tasks: manage_model_files_current.yml - when: check_roles['save_previous'] \ No newline at end of file +# - name: Manage Current Service Model Data Files +# ansible.builtin.include_tasks: manage_model_files_current.yml +# when: check_roles['save_previous'] \ No newline at end of file diff --git a/roles/validate/tasks/sub_main_msd.yml b/roles/validate/tasks/sub_main_msd.yml index f4a566d3..0134d9f3 100644 --- a/roles/validate/tasks/sub_main_msd.yml +++ b/roles/validate/tasks/sub_main_msd.yml @@ -31,25 +31,25 @@ rules_path: "{{ role_path }}/files/rules/required_rules/msd/" delegate_to: localhost -- name: Prepare Service Model - cisco.nac_dc_vxlan.common.prepare_service_model: - inventory_hostname: "{{ inventory_hostname }}" - hostvars: "{{ hostvars }}" - model_data: "{{ model_data['data'] }}" - default_values: "{{ defaults }}" - templates_path: "{{ role_path }}/../dtc/common/templates/" - register: smd - delegate_to: localhost +# - name: Prepare Service Model +# cisco.nac_dc_vxlan.common.prepare_service_model: +# inventory_hostname: "{{ inventory_hostname }}" +# hostvars: "{{ hostvars }}" +# model_data: "{{ model_data['data'] }}" +# default_values: "{{ defaults }}" +# templates_path: "{{ role_path }}/../dtc/common/templates/" +# register: smd +# delegate_to: localhost -- name: Store Golden Service Model Data - ansible.builtin.set_fact: - MD: "{{ smd['model_golden'] }}" - delegate_to: localhost +# - name: Store Golden Service Model Data +# ansible.builtin.set_fact: +# MD: "{{ smd['model_golden'] }}" +# delegate_to: localhost -- name: Store Extended Service Model Data - ansible.builtin.set_fact: - MD_Extended: "{{ smd['model_extended'] }}" - delegate_to: localhost +# - name: Store Extended Service Model Data +# ansible.builtin.set_fact: +# MD_Extended: "{{ smd['model_extended'] }}" +# delegate_to: localhost - name: Check Roles cisco.nac_dc_vxlan.common.check_roles: @@ -81,8 +81,4 @@ - name: Manage Current Service Model Data Files ansible.builtin.include_tasks: manage_model_files_current.yml - when: check_roles['save_previous'] - -- debug: msg="{{ MD }}" - -- debug: msg="{{ MD_Extended }}" \ No newline at end of file + when: check_roles['save_previous'] \ No newline at end of file diff --git a/roles/validate/tasks/sub_main.yml b/roles/validate/tasks/sub_main_vxlan.yml similarity index 78% rename from roles/validate/tasks/sub_main.yml rename to roles/validate/tasks/sub_main_vxlan.yml index 3381aa95..9484ae52 100644 --- a/roles/validate/tasks/sub_main.yml +++ b/roles/validate/tasks/sub_main_vxlan.yml @@ -31,25 +31,25 @@ rules_path: "{{ role_path }}/files/rules/required_rules/" delegate_to: localhost -- name: Prepare Service Model - cisco.nac_dc_vxlan.common.prepare_service_model: - inventory_hostname: "{{ inventory_hostname }}" - hostvars: "{{ hostvars }}" - model_data: "{{ model_data['data'] }}" - default_values: "{{ defaults }}" - templates_path: "{{ role_path }}/../dtc/common/templates/" - register: smd - delegate_to: localhost +# - name: Prepare Service Model +# cisco.nac_dc_vxlan.common.prepare_service_model: +# inventory_hostname: "{{ inventory_hostname }}" +# hostvars: "{{ hostvars }}" +# model_data: "{{ model_data['data'] }}" +# default_values: "{{ defaults }}" +# templates_path: "{{ role_path }}/../dtc/common/templates/" +# register: smd +# delegate_to: localhost -- name: Store Golden Service Model Data - ansible.builtin.set_fact: - MD: "{{ smd['model_golden'] }}" - delegate_to: localhost +# - name: Store Golden Service Model Data +# ansible.builtin.set_fact: +# MD: "{{ smd['model_golden'] }}" +# delegate_to: localhost -- name: Store Extended Service Model Data - ansible.builtin.set_fact: - MD_Extended: "{{ smd['model_extended'] }}" - delegate_to: localhost +# - name: Store Extended Service Model Data +# ansible.builtin.set_fact: +# MD_Extended: "{{ smd['model_extended'] }}" +# delegate_to: localhost - name: Check Roles cisco.nac_dc_vxlan.common.check_roles: From 0bd0e4f417df8cde5d12e7136e42f857c0353432 Mon Sep 17 00:00:00 2001 From: "Aneesh Ramgopal (anramgop)" Date: Wed, 27 Nov 2024 11:36:04 -0800 Subject: [PATCH 06/66] MSD create role --- roles/dtc/common/tasks/main.yml | 8 +++- roles/dtc/common/tasks/sub_main_msd.yml | 30 +++++++++++++++ .../{sub_main.yml => sub_main_vxlan.yml} | 0 roles/dtc/create/tasks/main.yml | 12 ++++-- roles/dtc/create/tasks/msd/fabric.yml | 36 ++++++++++++++++++ roles/dtc/create/tasks/sub_main_msd.yml | 37 +++++++++++++++++++ .../{sub_main.yml => sub_main_vxlan.yml} | 12 +++--- .../dtc/create/tasks/{ => vxlan}/devices.yml | 0 .../tasks/{ => vxlan}/devices_discovery.yml | 0 .../{ => vxlan}/devices_preprovision.yml | 0 roles/dtc/create/tasks/{ => vxlan}/fabric.yml | 0 .../create/tasks/{ => vxlan}/interfaces.yml | 0 .../dtc/create/tasks/{ => vxlan}/policies.yml | 0 roles/dtc/create/tasks/{ => vxlan}/reset.yml | 0 .../create/tasks/{ => vxlan}/vpc_peering.yml | 0 .../tasks/{ => vxlan}/vrfs_networks.yml | 0 .../tasks/manage_model_files_current.yml | 6 +-- .../tasks/manage_model_files_previous.yml | 10 ++--- 18 files changed, 133 insertions(+), 18 deletions(-) create mode 100644 roles/dtc/common/tasks/sub_main_msd.yml rename roles/dtc/common/tasks/{sub_main.yml => sub_main_vxlan.yml} (100%) create mode 100644 roles/dtc/create/tasks/msd/fabric.yml create mode 100644 roles/dtc/create/tasks/sub_main_msd.yml rename roles/dtc/create/tasks/{sub_main.yml => sub_main_vxlan.yml} (90%) rename roles/dtc/create/tasks/{ => vxlan}/devices.yml (100%) rename roles/dtc/create/tasks/{ => vxlan}/devices_discovery.yml (100%) rename roles/dtc/create/tasks/{ => vxlan}/devices_preprovision.yml (100%) rename roles/dtc/create/tasks/{ => vxlan}/fabric.yml (100%) rename roles/dtc/create/tasks/{ => vxlan}/interfaces.yml (100%) rename roles/dtc/create/tasks/{ => vxlan}/policies.yml (100%) rename roles/dtc/create/tasks/{ => vxlan}/reset.yml (100%) rename roles/dtc/create/tasks/{ => vxlan}/vpc_peering.yml (100%) rename roles/dtc/create/tasks/{ => vxlan}/vrfs_networks.yml (100%) diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index 7b71bf04..62ccc602 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -22,5 +22,11 @@ --- - name: Import Role Tasks - ansible.builtin.import_tasks: sub_main.yml + ansible.builtin.import_tasks: sub_main_msd.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml + when: MD_Extended.vxlan.fabric_type == 'MSD' + +- name: Import Role Tasks + ansible.builtin.import_tasks: sub_main_vxlan.yml + tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml + when: MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml new file mode 100644 index 00000000..9a0be877 --- /dev/null +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -0,0 +1,30 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.create] + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Calling MSD Role - [cisco.nac_dc_vxlan.dtc.create] +" + - "----------------------------------------------------------------" + tags: "{{ nac_tags.create }}" # Tags defined in roles/common_global/vars/main.yml diff --git a/roles/dtc/common/tasks/sub_main.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml similarity index 100% rename from roles/dtc/common/tasks/sub_main.yml rename to roles/dtc/common/tasks/sub_main_vxlan.yml diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index f2f9ff15..f90755d4 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -21,9 +21,15 @@ --- -- name: Import Role Tasks - ansible.builtin.import_tasks: sub_main.yml - when: changes_detected_fabric or changes_detected_inventory or changes_detected_vpc_peering or changes_detected_interfaces or changes_detected_link_vpc_peering or changes_detected_vrfs or changes_detected_networks or changes_detected_policy +- name: Import VxLAN Role Tasks + ansible.builtin.import_tasks: sub_main_msd.yml + when: MD_Extended.vxlan.fabric_type == 'MSD' + +# - name: Import MSD Role Tasks +# ansible.builtin.import_tasks: sub_main_vxlan.yml +# when: +# - MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' +# - changes_detected_fabric or changes_detected_inventory or changes_detected_vpc_peering or changes_detected_interfaces or changes_detected_link_vpc_peering or changes_detected_vrfs or changes_detected_networks or changes_detected_policy - name: Mark Stage Role Create Completed cisco.nac_dc_vxlan.common.run_map: diff --git a/roles/dtc/create/tasks/msd/fabric.yml b/roles/dtc/create/tasks/msd/fabric.yml new file mode 100644 index 00000000..2d7677ff --- /dev/null +++ b/roles/dtc/create/tasks/msd/fabric.yml @@ -0,0 +1,36 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Manage Fabric Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Fabric {{ MD.vxlan.name }}" + - "----------------------------------------------------------------" + +- name: Manage fabric {{ MD.vxlan.name }} in NDFC + cisco.dcnm.dcnm_fabric: + state: merged + config: + - FABRIC_NAME: MSD_Fabric + FABRIC_TYPE: VXLAN_EVPN_MSD diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml new file mode 100644 index 00000000..12ea1f70 --- /dev/null +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -0,0 +1,37 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.create] + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Calling MSD Role - [cisco.nac_dc_vxlan.dtc.create] +" + - "----------------------------------------------------------------" + tags: "{{ nac_tags.create }}" # Tags defined in roles/common_global/vars/main.yml + +- name: Create NDFC MSD Fabric + ansible.builtin.import_tasks: msd/fabric.yml + # when: + # - MD_Extended.vxlan.global is defined + # - changes_detected_fabric + tags: "{{ nac_tags.create_fabric }}" diff --git a/roles/dtc/create/tasks/sub_main.yml b/roles/dtc/create/tasks/sub_main_vxlan.yml similarity index 90% rename from roles/dtc/create/tasks/sub_main.yml rename to roles/dtc/create/tasks/sub_main_vxlan.yml index cb1ec174..855af8f2 100644 --- a/roles/dtc/create/tasks/sub_main.yml +++ b/roles/dtc/create/tasks/sub_main_vxlan.yml @@ -33,42 +33,42 @@ tags: "{{ nac_tags.create }}" - name: Create NDFC Fabric - ansible.builtin.import_tasks: fabric.yml + ansible.builtin.import_tasks: vxlan/fabric.yml when: - MD_Extended.vxlan.global is defined - changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" - name: Manage NDFC Fabric Switches - ansible.builtin.import_tasks: devices.yml + ansible.builtin.import_tasks: vxlan/devices.yml when: - MD_Extended.vxlan.topology.switches | length > 0 - changes_detected_inventory tags: "{{ nac_tags.create_switches }}" - name: Manage VPC Peering - ansible.builtin.import_tasks: vpc_peering.yml + ansible.builtin.import_tasks: vxlan/vpc_peering.yml when: - MD_Extended.vxlan.topology.vpc_peers | length > 0 - changes_detected_vpc_peering tags: "{{ nac_tags.create_vpc_peers }}" - name: Manage NDFC Fabric Interfaces - ansible.builtin.import_tasks: interfaces.yml + ansible.builtin.import_tasks: vxlan/interfaces.yml when: - (MD_Extended.vxlan.topology.interfaces.modes.all.count >0) and (MD_Extended.vxlan.topology.switches | length > 0) - changes_detected_interfaces tags: "{{ nac_tags.create_interfaces }}" - name: Manage NDFC Fabric VRFs and Networks - ansible.builtin.import_tasks: vrfs_networks.yml + ansible.builtin.import_tasks: vxlan/vrfs_networks.yml when: - (MD.vxlan.overlay_services is defined) and (MD_Extended.vxlan.topology.switches | length > 0) - changes_detected_vrfs or changes_detected_networks tags: "{{ nac_tags.create_vrfs_networks }}" - name: Manage NDFC Fabric Policies - ansible.builtin.import_tasks: policies.yml + ansible.builtin.import_tasks: vxlan/policies.yml when: - (MD_Extended.vxlan.policy is defined) and (MD_Extended.vxlan.policy.policies | length > 0) - changes_detected_policy diff --git a/roles/dtc/create/tasks/devices.yml b/roles/dtc/create/tasks/vxlan/devices.yml similarity index 100% rename from roles/dtc/create/tasks/devices.yml rename to roles/dtc/create/tasks/vxlan/devices.yml diff --git a/roles/dtc/create/tasks/devices_discovery.yml b/roles/dtc/create/tasks/vxlan/devices_discovery.yml similarity index 100% rename from roles/dtc/create/tasks/devices_discovery.yml rename to roles/dtc/create/tasks/vxlan/devices_discovery.yml diff --git a/roles/dtc/create/tasks/devices_preprovision.yml b/roles/dtc/create/tasks/vxlan/devices_preprovision.yml similarity index 100% rename from roles/dtc/create/tasks/devices_preprovision.yml rename to roles/dtc/create/tasks/vxlan/devices_preprovision.yml diff --git a/roles/dtc/create/tasks/fabric.yml b/roles/dtc/create/tasks/vxlan/fabric.yml similarity index 100% rename from roles/dtc/create/tasks/fabric.yml rename to roles/dtc/create/tasks/vxlan/fabric.yml diff --git a/roles/dtc/create/tasks/interfaces.yml b/roles/dtc/create/tasks/vxlan/interfaces.yml similarity index 100% rename from roles/dtc/create/tasks/interfaces.yml rename to roles/dtc/create/tasks/vxlan/interfaces.yml diff --git a/roles/dtc/create/tasks/policies.yml b/roles/dtc/create/tasks/vxlan/policies.yml similarity index 100% rename from roles/dtc/create/tasks/policies.yml rename to roles/dtc/create/tasks/vxlan/policies.yml diff --git a/roles/dtc/create/tasks/reset.yml b/roles/dtc/create/tasks/vxlan/reset.yml similarity index 100% rename from roles/dtc/create/tasks/reset.yml rename to roles/dtc/create/tasks/vxlan/reset.yml diff --git a/roles/dtc/create/tasks/vpc_peering.yml b/roles/dtc/create/tasks/vxlan/vpc_peering.yml similarity index 100% rename from roles/dtc/create/tasks/vpc_peering.yml rename to roles/dtc/create/tasks/vxlan/vpc_peering.yml diff --git a/roles/dtc/create/tasks/vrfs_networks.yml b/roles/dtc/create/tasks/vxlan/vrfs_networks.yml similarity index 100% rename from roles/dtc/create/tasks/vrfs_networks.yml rename to roles/dtc/create/tasks/vxlan/vrfs_networks.yml diff --git a/roles/validate/tasks/manage_model_files_current.yml b/roles/validate/tasks/manage_model_files_current.yml index 2711fc3c..43030ab0 100644 --- a/roles/validate/tasks/manage_model_files_current.yml +++ b/roles/validate/tasks/manage_model_files_current.yml @@ -25,7 +25,7 @@ - name: Copy Service Model Data to Host ansible.builtin.copy: content: "{{ MD | to_nice_json }}" - dest: "{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_golden.json" + dest: "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" force: yes delegate_to: localhost @@ -33,14 +33,14 @@ - name: Copy Extended Service Model Data to Host ansible.builtin.copy: content: "{{ MD_Extended | to_nice_json }}" - dest: "{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_extended.json" + dest: "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_extended.json" force: yes delegate_to: localhost # Read current golden service model data into a variable called 'smd_golden_current' - name: Read Current Service Model Data from Host ansible.builtin.include_vars: - file: "{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_golden.json" + file: "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" register: smd_golden_current delegate_to: localhost diff --git a/roles/validate/tasks/manage_model_files_previous.yml b/roles/validate/tasks/manage_model_files_previous.yml index 25fa16da..59050292 100644 --- a/roles/validate/tasks/manage_model_files_previous.yml +++ b/roles/validate/tasks/manage_model_files_previous.yml @@ -29,31 +29,31 @@ # Check if golden and extended service model data files exist from previous runs - name: Stat the Golden Service Model Data - ansible.builtin.stat: path="{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_golden.json" + ansible.builtin.stat: path="{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" register: golden_stat delegate_to: localhost - name: Stat the Extended Service Model Data - ansible.builtin.stat: path="{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_extended.json" + ansible.builtin.stat: path="{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_extended.json" register: extended_stat delegate_to: localhost # Read and store previous golden service model data into a variable called 'smd_golden_previous' - name: Read Previous Golden Service Model Data from Host ansible.builtin.include_vars: - file: "{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_golden.json" + file: "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" register: smd_golden_previous when: golden_stat.stat.exists and check_roles['save_previous'] delegate_to: localhost # Rename golden file from previous run to append '_previous' to the filename - name: Move Golden Service Model Data Previous - ansible.builtin.command: mv "{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_golden.json" "{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_golden_previous.json" + ansible.builtin.command: mv "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden_previous.json" when: golden_stat.stat.exists and check_roles['save_previous'] delegate_to: localhost # Rename extended file from previous run to append '_previous' to the filename - name: Move Extended Service Model Data Previous - ansible.builtin.command: mv "{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_extended.json" "{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_extended_previous.json" + ansible.builtin.command: mv "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_extended.json" "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_extended_previous.json" when: extended_stat.stat.exists and check_roles['save_previous'] delegate_to: localhost From 075475e13762160799a5faa35075ed3c968b69d3 Mon Sep 17 00:00:00 2001 From: mwiebe Date: Mon, 2 Dec 2024 20:11:19 -0500 Subject: [PATCH 07/66] Additional refactoring for MSD and VXLAN workflows --- plugins/action/common/nac_dc_validate.py | 1 - roles/dtc/common/tasks/main.yml | 4 +- roles/dtc/common/tasks/msd/ndfc_children.yml | 3 + roles/dtc/common/tasks/msd/ndfc_fabric.yml | 3 + roles/dtc/common/tasks/sub_main_msd.yml | 32 ++++++++--- roles/dtc/common/tasks/sub_main_vxlan.yml | 34 +++++------ .../common/tasks/{ => vxlan}/ndfc_fabric.yml | 0 .../{ => vxlan}/ndfc_interface_access.yml | 0 .../{ => vxlan}/ndfc_interface_access_po.yml | 0 .../tasks/{ => vxlan}/ndfc_interface_all.yml | 0 .../{ => vxlan}/ndfc_interface_loopback.yml | 0 .../{ => vxlan}/ndfc_interface_po_routed.yml | 0 .../{ => vxlan}/ndfc_interface_routed.yml | 0 .../{ => vxlan}/ndfc_interface_trunk.yml | 0 .../{ => vxlan}/ndfc_interface_trunk_po.yml | 0 .../tasks/{ => vxlan}/ndfc_interface_vpc.yml | 0 .../tasks/{ => vxlan}/ndfc_inventory.yml | 0 .../{ => vxlan}/ndfc_link_vpc_peering.yml | 0 .../tasks/{ => vxlan}/ndfc_networks.yml | 0 .../common/tasks/{ => vxlan}/ndfc_policy.yml | 0 .../{ => vxlan}/ndfc_sub_interface_routed.yml | 0 .../tasks/{ => vxlan}/ndfc_vpc_peering.yml | 0 .../common/tasks/{ => vxlan}/ndfc_vrfs.yml | 0 roles/dtc/create/tasks/msd/fabric.yml | 2 +- .../files/rules/required_rules/msd/.gitkeep | 0 .../files/rules/required_rules/vxlan/.gitkeep | 0 .../{ => vxlan}/201_global_spanning_tree.py | 0 .../202_global_underlay_mcast_trm.py | 0 .../{ => vxlan}/203_global_underlay_isis.py | 0 .../{ => vxlan}/301_topology_switch_serial.py | 0 .../302_topology_switch_management.py | 0 .../{ => vxlan}/303_topology_switch_role.py | 0 ...pology_switch_interfaces_members_unique.py | 0 .../305_topology_switch_interfaces_vpc.py | 0 .../401_overlay_services_cross_reference.py | 0 .../{ => vxlan}/402_overlay_services_vrfs.py | 0 .../403_overlay_services_networks.py | 0 .../{ => vxlan}/501_policy_cross_reference.py | 0 .../502_policy_vrf_lite_cross_reference.py | 0 roles/validate/tasks/main.yml | 12 ++-- roles/validate/tasks/sub_main_common_post.yml | 54 ++++++++++++++++++ ...ain_common.yml => sub_main_common_pre.yml} | 35 ------------ roles/validate/tasks/sub_main_msd.yml | 54 +----------------- roles/validate/tasks/sub_main_vxlan.yml | 56 +------------------ 44 files changed, 116 insertions(+), 174 deletions(-) create mode 100644 roles/dtc/common/tasks/msd/ndfc_children.yml create mode 100644 roles/dtc/common/tasks/msd/ndfc_fabric.yml rename roles/dtc/common/tasks/{ => vxlan}/ndfc_fabric.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_interface_access.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_interface_access_po.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_interface_all.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_interface_loopback.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_interface_po_routed.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_interface_routed.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_interface_trunk.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_interface_trunk_po.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_interface_vpc.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_inventory.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_link_vpc_peering.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_networks.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_policy.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_sub_interface_routed.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_vpc_peering.yml (100%) rename roles/dtc/common/tasks/{ => vxlan}/ndfc_vrfs.yml (100%) create mode 100644 roles/validate/files/rules/required_rules/msd/.gitkeep create mode 100644 roles/validate/files/rules/required_rules/vxlan/.gitkeep rename roles/validate/files/rules/required_rules/{ => vxlan}/201_global_spanning_tree.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/202_global_underlay_mcast_trm.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/203_global_underlay_isis.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/301_topology_switch_serial.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/302_topology_switch_management.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/303_topology_switch_role.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/304_topology_switch_interfaces_members_unique.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/305_topology_switch_interfaces_vpc.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/401_overlay_services_cross_reference.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/402_overlay_services_vrfs.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/403_overlay_services_networks.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/501_policy_cross_reference.py (100%) rename roles/validate/files/rules/required_rules/{ => vxlan}/502_policy_vrf_lite_cross_reference.py (100%) create mode 100644 roles/validate/tasks/sub_main_common_post.yml rename roles/validate/tasks/{sub_main_common.yml => sub_main_common_pre.yml} (75%) diff --git a/plugins/action/common/nac_dc_validate.py b/plugins/action/common/nac_dc_validate.py index c7a91085..6e32f610 100644 --- a/plugins/action/common/nac_dc_validate.py +++ b/plugins/action/common/nac_dc_validate.py @@ -30,7 +30,6 @@ try: import iac_validate.validator - from iac_validate.yaml import load_yaml_files from iac_validate.cli.options import DEFAULT_SCHEMA except ImportError as imp_exc: IAC_VALIDATE_IMPORT_ERROR = imp_exc diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index 62ccc602..d219dee4 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -21,12 +21,12 @@ --- -- name: Import Role Tasks +- name: Import Role Tasks for MSD Fabric ansible.builtin.import_tasks: sub_main_msd.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml when: MD_Extended.vxlan.fabric_type == 'MSD' -- name: Import Role Tasks +- name: Import Role Tasks for VXLAN Fabric ansible.builtin.import_tasks: sub_main_vxlan.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml when: MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' diff --git a/roles/dtc/common/tasks/msd/ndfc_children.yml b/roles/dtc/common/tasks/msd/ndfc_children.yml new file mode 100644 index 00000000..6def6b2e --- /dev/null +++ b/roles/dtc/common/tasks/msd/ndfc_children.yml @@ -0,0 +1,3 @@ +--- + +- debug: msg="Building NDFC MSD Child Fabric Data" \ No newline at end of file diff --git a/roles/dtc/common/tasks/msd/ndfc_fabric.yml b/roles/dtc/common/tasks/msd/ndfc_fabric.yml new file mode 100644 index 00000000..fa74285b --- /dev/null +++ b/roles/dtc/common/tasks/msd/ndfc_fabric.yml @@ -0,0 +1,3 @@ +--- + +- debug: msg="Building NDFC MSD Fabric Data" \ No newline at end of file diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 9a0be877..12a6bd25 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -21,10 +21,28 @@ --- -- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.create] - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Calling MSD Role - [cisco.nac_dc_vxlan.dtc.create] +" - - "----------------------------------------------------------------" - tags: "{{ nac_tags.create }}" # Tags defined in roles/common_global/vars/main.yml +- ansible.builtin.fail: msg="Service Model Not Defined. Role cisco.nac_dc_vxlan.validate Must Be Called First" + when: MD is undefined + delegate_to: localhost + +# -------------------------------------------------------------------- +# Remove all files from the previous run if run_map requires it +# -------------------------------------------------------------------- +- name: Cleanup Files from Previous Run if run_map requires it + ansible.builtin.include_tasks: cleanup_files.yml + when: + - not run_map_read_result.diff_run or ((force_run_all is defined) and (force_run_all is true|bool)) + +# -------------------------------------------------------------------- +# Build Create Fabric parameter List From Template +# -------------------------------------------------------------------- + +- name: Build Fabric Create Parameters + ansible.builtin.include_tasks: msd/ndfc_fabric.yml + +# -------------------------------------------------------------------- +# Build NDFC Child Fabric Inventory List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Child Fabric Inventory List From Template + ansible.builtin.include_tasks: msd/ndfc_children.yml diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index 41331d3d..9029aa98 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -38,119 +38,119 @@ # -------------------------------------------------------------------- - name: Build Fabric Create Parameters - ansible.builtin.include_tasks: ndfc_fabric.yml + ansible.builtin.include_tasks: vxlan/ndfc_fabric.yml # -------------------------------------------------------------------- # Build NDFC Fabric Switch Inventory List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Switch Inventory List From Template - ansible.builtin.include_tasks: ndfc_inventory.yml + ansible.builtin.include_tasks: vxlan/ndfc_inventory.yml # -------------------------------------------------------------------- # Build Fabric intra links for vpc peering From Template # -------------------------------------------------------------------- - name: Build Intra Fabric Links From Template - ansible.builtin.include_tasks: ndfc_link_vpc_peering.yml + ansible.builtin.include_tasks: vxlan/ndfc_link_vpc_peering.yml # -------------------------------------------------------------------- # Build vPC Peering parameter List From Template # -------------------------------------------------------------------- - name: Build vPC Peering Parameters - ansible.builtin.include_tasks: ndfc_vpc_peering.yml + ansible.builtin.include_tasks: vxlan/ndfc_vpc_peering.yml # -------------------------------------------------------------------- # Build NDFC Fabric VRFs Attach List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric VRFs Attach List From Template - ansible.builtin.include_tasks: ndfc_vrfs.yml + ansible.builtin.include_tasks: vxlan/ndfc_vrfs.yml # -------------------------------------------------------------------- # Build NDFC Fabric Networks Attach List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Networks Attach List From Template - ansible.builtin.include_tasks: ndfc_networks.yml + ansible.builtin.include_tasks: vxlan/ndfc_networks.yml # -------------------------------------------------------------------- # Build NDFC Fabric Loopback Interfaces List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Loopback Interfaces List From Template - ansible.builtin.include_tasks: ndfc_interface_loopback.yml + ansible.builtin.include_tasks: vxlan/ndfc_interface_loopback.yml # -------------------------------------------------------------------- # Build NDFC Fabric Access Port-Channel Interfaces List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Access Port-Channel Interfaces List From Template - ansible.builtin.include_tasks: ndfc_interface_access_po.yml + ansible.builtin.include_tasks: vxlan/ndfc_interface_access_po.yml # -------------------------------------------------------------------- # Build NDFC Fabric Trunk Port-Channel Interfaces List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Trunk Port-Channel Interfaces List From Template - ansible.builtin.include_tasks: ndfc_interface_trunk_po.yml + ansible.builtin.include_tasks: vxlan/ndfc_interface_trunk_po.yml # -------------------------------------------------------------------- # Build NDFC Fabric Interface Routed List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Interface Routed List From Template - ansible.builtin.include_tasks: ndfc_interface_routed.yml + ansible.builtin.include_tasks: vxlan/ndfc_interface_routed.yml # -------------------------------------------------------------------- # Build NDFC Fabric Sub-Interface Routed List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Sub-Interface Routed List From Template - ansible.builtin.include_tasks: ndfc_sub_interface_routed.yml + ansible.builtin.include_tasks: vxlan/ndfc_sub_interface_routed.yml # -------------------------------------------------------------------- # Build NDFC Fabric Routed Port-Channel Interface List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Routed Port-Channel Interface List From Template - ansible.builtin.include_tasks: ndfc_interface_po_routed.yml + ansible.builtin.include_tasks: vxlan/ndfc_interface_po_routed.yml # -------------------------------------------------------------------- # Build Trunk Interfaces List From Template # -------------------------------------------------------------------- - name: Build Trunk Interfaces List From Template - ansible.builtin.include_tasks: ndfc_interface_trunk.yml + ansible.builtin.include_tasks: vxlan/ndfc_interface_trunk.yml # -------------------------------------------------------------------- # Build Access Interfaces List From Template # -------------------------------------------------------------------- - name: Build Access Interfaces List From Template - ansible.builtin.include_tasks: ndfc_interface_access.yml + ansible.builtin.include_tasks: vxlan/ndfc_interface_access.yml # -------------------------------------------------------------------- # Build Fabric interface VPC List From Template # -------------------------------------------------------------------- - name: Build Fabric interface VPC List From Template - ansible.builtin.include_tasks: ndfc_interface_vpc.yml + ansible.builtin.include_tasks: vxlan/ndfc_interface_vpc.yml # -------------------------------------------------------------------- # Build Fabric interface all List From Template # -------------------------------------------------------------------- - name: Build Fabric interface All List From Template - ansible.builtin.include_tasks: ndfc_interface_all.yml + ansible.builtin.include_tasks: vxlan/ndfc_interface_all.yml # -------------------------------------------------------------------- # Build Fabric Policy List From Template # -------------------------------------------------------------------- - name: Build Fabric Policy List From Template - ansible.builtin.include_tasks: ndfc_policy.yml + ansible.builtin.include_tasks: vxlan/ndfc_policy.yml - name: Run Diff Flags ansible.builtin.debug: diff --git a/roles/dtc/common/tasks/ndfc_fabric.yml b/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_fabric.yml rename to roles/dtc/common/tasks/vxlan/ndfc_fabric.yml diff --git a/roles/dtc/common/tasks/ndfc_interface_access.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_interface_access.yml rename to roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml diff --git a/roles/dtc/common/tasks/ndfc_interface_access_po.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_interface_access_po.yml rename to roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml diff --git a/roles/dtc/common/tasks/ndfc_interface_all.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_interface_all.yml rename to roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml diff --git a/roles/dtc/common/tasks/ndfc_interface_loopback.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_interface_loopback.yml rename to roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml diff --git a/roles/dtc/common/tasks/ndfc_interface_po_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_interface_po_routed.yml rename to roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml diff --git a/roles/dtc/common/tasks/ndfc_interface_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_interface_routed.yml rename to roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml diff --git a/roles/dtc/common/tasks/ndfc_interface_trunk.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_interface_trunk.yml rename to roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml diff --git a/roles/dtc/common/tasks/ndfc_interface_trunk_po.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_interface_trunk_po.yml rename to roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml diff --git a/roles/dtc/common/tasks/ndfc_interface_vpc.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_interface_vpc.yml rename to roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml diff --git a/roles/dtc/common/tasks/ndfc_inventory.yml b/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_inventory.yml rename to roles/dtc/common/tasks/vxlan/ndfc_inventory.yml diff --git a/roles/dtc/common/tasks/ndfc_link_vpc_peering.yml b/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_link_vpc_peering.yml rename to roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml diff --git a/roles/dtc/common/tasks/ndfc_networks.yml b/roles/dtc/common/tasks/vxlan/ndfc_networks.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_networks.yml rename to roles/dtc/common/tasks/vxlan/ndfc_networks.yml diff --git a/roles/dtc/common/tasks/ndfc_policy.yml b/roles/dtc/common/tasks/vxlan/ndfc_policy.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_policy.yml rename to roles/dtc/common/tasks/vxlan/ndfc_policy.yml diff --git a/roles/dtc/common/tasks/ndfc_sub_interface_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_sub_interface_routed.yml rename to roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml diff --git a/roles/dtc/common/tasks/ndfc_vpc_peering.yml b/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_vpc_peering.yml rename to roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml diff --git a/roles/dtc/common/tasks/ndfc_vrfs.yml b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml similarity index 100% rename from roles/dtc/common/tasks/ndfc_vrfs.yml rename to roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml diff --git a/roles/dtc/create/tasks/msd/fabric.yml b/roles/dtc/create/tasks/msd/fabric.yml index 2d7677ff..27797fac 100644 --- a/roles/dtc/create/tasks/msd/fabric.yml +++ b/roles/dtc/create/tasks/msd/fabric.yml @@ -32,5 +32,5 @@ cisco.dcnm.dcnm_fabric: state: merged config: - - FABRIC_NAME: MSD_Fabric + - FABRIC_NAME: "{{ MD.vxlan.name }}" FABRIC_TYPE: VXLAN_EVPN_MSD diff --git a/roles/validate/files/rules/required_rules/msd/.gitkeep b/roles/validate/files/rules/required_rules/msd/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/validate/files/rules/required_rules/vxlan/.gitkeep b/roles/validate/files/rules/required_rules/vxlan/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/validate/files/rules/required_rules/201_global_spanning_tree.py b/roles/validate/files/rules/required_rules/vxlan/201_global_spanning_tree.py similarity index 100% rename from roles/validate/files/rules/required_rules/201_global_spanning_tree.py rename to roles/validate/files/rules/required_rules/vxlan/201_global_spanning_tree.py diff --git a/roles/validate/files/rules/required_rules/202_global_underlay_mcast_trm.py b/roles/validate/files/rules/required_rules/vxlan/202_global_underlay_mcast_trm.py similarity index 100% rename from roles/validate/files/rules/required_rules/202_global_underlay_mcast_trm.py rename to roles/validate/files/rules/required_rules/vxlan/202_global_underlay_mcast_trm.py diff --git a/roles/validate/files/rules/required_rules/203_global_underlay_isis.py b/roles/validate/files/rules/required_rules/vxlan/203_global_underlay_isis.py similarity index 100% rename from roles/validate/files/rules/required_rules/203_global_underlay_isis.py rename to roles/validate/files/rules/required_rules/vxlan/203_global_underlay_isis.py diff --git a/roles/validate/files/rules/required_rules/301_topology_switch_serial.py b/roles/validate/files/rules/required_rules/vxlan/301_topology_switch_serial.py similarity index 100% rename from roles/validate/files/rules/required_rules/301_topology_switch_serial.py rename to roles/validate/files/rules/required_rules/vxlan/301_topology_switch_serial.py diff --git a/roles/validate/files/rules/required_rules/302_topology_switch_management.py b/roles/validate/files/rules/required_rules/vxlan/302_topology_switch_management.py similarity index 100% rename from roles/validate/files/rules/required_rules/302_topology_switch_management.py rename to roles/validate/files/rules/required_rules/vxlan/302_topology_switch_management.py diff --git a/roles/validate/files/rules/required_rules/303_topology_switch_role.py b/roles/validate/files/rules/required_rules/vxlan/303_topology_switch_role.py similarity index 100% rename from roles/validate/files/rules/required_rules/303_topology_switch_role.py rename to roles/validate/files/rules/required_rules/vxlan/303_topology_switch_role.py diff --git a/roles/validate/files/rules/required_rules/304_topology_switch_interfaces_members_unique.py b/roles/validate/files/rules/required_rules/vxlan/304_topology_switch_interfaces_members_unique.py similarity index 100% rename from roles/validate/files/rules/required_rules/304_topology_switch_interfaces_members_unique.py rename to roles/validate/files/rules/required_rules/vxlan/304_topology_switch_interfaces_members_unique.py diff --git a/roles/validate/files/rules/required_rules/305_topology_switch_interfaces_vpc.py b/roles/validate/files/rules/required_rules/vxlan/305_topology_switch_interfaces_vpc.py similarity index 100% rename from roles/validate/files/rules/required_rules/305_topology_switch_interfaces_vpc.py rename to roles/validate/files/rules/required_rules/vxlan/305_topology_switch_interfaces_vpc.py diff --git a/roles/validate/files/rules/required_rules/401_overlay_services_cross_reference.py b/roles/validate/files/rules/required_rules/vxlan/401_overlay_services_cross_reference.py similarity index 100% rename from roles/validate/files/rules/required_rules/401_overlay_services_cross_reference.py rename to roles/validate/files/rules/required_rules/vxlan/401_overlay_services_cross_reference.py diff --git a/roles/validate/files/rules/required_rules/402_overlay_services_vrfs.py b/roles/validate/files/rules/required_rules/vxlan/402_overlay_services_vrfs.py similarity index 100% rename from roles/validate/files/rules/required_rules/402_overlay_services_vrfs.py rename to roles/validate/files/rules/required_rules/vxlan/402_overlay_services_vrfs.py diff --git a/roles/validate/files/rules/required_rules/403_overlay_services_networks.py b/roles/validate/files/rules/required_rules/vxlan/403_overlay_services_networks.py similarity index 100% rename from roles/validate/files/rules/required_rules/403_overlay_services_networks.py rename to roles/validate/files/rules/required_rules/vxlan/403_overlay_services_networks.py diff --git a/roles/validate/files/rules/required_rules/501_policy_cross_reference.py b/roles/validate/files/rules/required_rules/vxlan/501_policy_cross_reference.py similarity index 100% rename from roles/validate/files/rules/required_rules/501_policy_cross_reference.py rename to roles/validate/files/rules/required_rules/vxlan/501_policy_cross_reference.py diff --git a/roles/validate/files/rules/required_rules/502_policy_vrf_lite_cross_reference.py b/roles/validate/files/rules/required_rules/vxlan/502_policy_vrf_lite_cross_reference.py similarity index 100% rename from roles/validate/files/rules/required_rules/502_policy_vrf_lite_cross_reference.py rename to roles/validate/files/rules/required_rules/vxlan/502_policy_vrf_lite_cross_reference.py diff --git a/roles/validate/tasks/main.yml b/roles/validate/tasks/main.yml index a454e6c3..db816574 100644 --- a/roles/validate/tasks/main.yml +++ b/roles/validate/tasks/main.yml @@ -22,16 +22,16 @@ --- - debug: msg="{{ nac_tags.all }}" -- name: Import Role Tasks - ansible.builtin.import_tasks: sub_main_common.yml +- name: Import Common Pre Role Tasks + ansible.builtin.import_tasks: sub_main_common_pre.yml tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml -- name: Import Role Tasks for MSD Fabric +- name: Import MSD Fabric Role Tasks ansible.builtin.import_tasks: sub_main_msd.yml tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml when: MD_Extended.vxlan.fabric_type == 'MSD' -- name: Import Role Tasks for VxLAN Fabric +- name: Import VxLAN Fabric Role Tasks ansible.builtin.import_tasks: sub_main_vxlan.yml tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml when: MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' @@ -57,6 +57,10 @@ # - role_deploy # - role_remove +- name: Import Common Post Role Tasks + ansible.builtin.import_tasks: sub_main_common_post.yml + tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml + - name: Mark Stage Role Validate Completed cisco.nac_dc_vxlan.common.run_map: stage: role_validate_completed diff --git a/roles/validate/tasks/sub_main_common_post.yml b/roles/validate/tasks/sub_main_common_post.yml new file mode 100644 index 00000000..351ff963 --- /dev/null +++ b/roles/validate/tasks/sub_main_common_post.yml @@ -0,0 +1,54 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Check Roles + cisco.nac_dc_vxlan.common.check_roles: + role_list: "{{ role_names }}" + register: check_roles + delegate_to: localhost + +- name: Read Run Map From Previous Run + cisco.nac_dc_vxlan.common.read_run_map: + model_data: "{{ MD_Extended }}" + register: run_map_read_result + delegate_to: localhost + +- name: Debug Run Map Read Result + ansible.builtin.debug: + msg: "{{ run_map_read_result }}" + delegate_to: localhost + +- name: Initialize Run Map + cisco.nac_dc_vxlan.common.run_map: + model_data: "{{ MD_Extended }}" + stage: starting_execution + register: run_map + delegate_to: localhost + +- name: Manage Previous Service Model Data Files + ansible.builtin.include_tasks: manage_model_files_previous.yml + when: check_roles['save_previous'] + +- name: Manage Current Service Model Data Files + ansible.builtin.include_tasks: manage_model_files_current.yml + when: check_roles['save_previous'] diff --git a/roles/validate/tasks/sub_main_common.yml b/roles/validate/tasks/sub_main_common_pre.yml similarity index 75% rename from roles/validate/tasks/sub_main_common.yml rename to roles/validate/tasks/sub_main_common_pre.yml index fdcb3680..a75c5e52 100644 --- a/roles/validate/tasks/sub_main_common.yml +++ b/roles/validate/tasks/sub_main_common_pre.yml @@ -35,9 +35,6 @@ - name: Validate NDFC Service Model Data ansible.builtin.debug: msg="Calling Role Validate - nac_dc_vxlan.validate" -- ansible.builtin.debug: msg="Workflow is Direct to Device (DTD)" - when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.nxos.nxos" - - ansible.builtin.debug: msg="Workflow is Direct to Controller (DTC)" when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.dcnm.dcnm" @@ -91,35 +88,3 @@ ansible.builtin.set_fact: MD_Extended: "{{ smd['model_extended'] }}" delegate_to: localhost - -# - name: Check Roles -# cisco.nac_dc_vxlan.common.check_roles: -# role_list: "{{ role_names }}" -# register: check_roles -# delegate_to: localhost - -# - name: Read Run Map From Previous Run -# cisco.nac_dc_vxlan.common.read_run_map: -# model_data: "{{ MD_Extended }}" -# register: run_map_read_result -# delegate_to: localhost - -# - name: Debug Run Map Read Result -# ansible.builtin.debug: -# msg: "{{ run_map_read_result }}" -# delegate_to: localhost - -# - name: Initialize Run Map -# cisco.nac_dc_vxlan.common.run_map: -# model_data: "{{ MD_Extended }}" -# stage: starting_execution -# register: run_map -# delegate_to: localhost - -# - name: Manage Previous Service Model Data Files -# ansible.builtin.include_tasks: manage_model_files_previous.yml -# when: check_roles['save_previous'] - -# - name: Manage Current Service Model Data Files -# ansible.builtin.include_tasks: manage_model_files_current.yml -# when: check_roles['save_previous'] \ No newline at end of file diff --git a/roles/validate/tasks/sub_main_msd.yml b/roles/validate/tasks/sub_main_msd.yml index 0134d9f3..400d755c 100644 --- a/roles/validate/tasks/sub_main_msd.yml +++ b/roles/validate/tasks/sub_main_msd.yml @@ -21,7 +21,7 @@ --- -- name: Perform Required Syntax and Semantic Model Validation +- name: Perform Required Syntax and Semantic Model Validation for MSD Fabric cisco.nac_dc_vxlan.common.nac_dc_validate: schema: "{{ schema_path }}" mdata: "{{ data_path }}" @@ -30,55 +30,3 @@ data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" rules_path: "{{ role_path }}/files/rules/required_rules/msd/" delegate_to: localhost - -# - name: Prepare Service Model -# cisco.nac_dc_vxlan.common.prepare_service_model: -# inventory_hostname: "{{ inventory_hostname }}" -# hostvars: "{{ hostvars }}" -# model_data: "{{ model_data['data'] }}" -# default_values: "{{ defaults }}" -# templates_path: "{{ role_path }}/../dtc/common/templates/" -# register: smd -# delegate_to: localhost - -# - name: Store Golden Service Model Data -# ansible.builtin.set_fact: -# MD: "{{ smd['model_golden'] }}" -# delegate_to: localhost - -# - name: Store Extended Service Model Data -# ansible.builtin.set_fact: -# MD_Extended: "{{ smd['model_extended'] }}" -# delegate_to: localhost - -- name: Check Roles - cisco.nac_dc_vxlan.common.check_roles: - role_list: "{{ role_names }}" - register: check_roles - delegate_to: localhost - -- name: Read Run Map From Previous Run - cisco.nac_dc_vxlan.common.read_run_map: - model_data: "{{ MD_Extended }}" - register: run_map_read_result - delegate_to: localhost - -- name: Debug Run Map Read Result - ansible.builtin.debug: - msg: "{{ run_map_read_result }}" - delegate_to: localhost - -- name: Initialize Run Map - cisco.nac_dc_vxlan.common.run_map: - model_data: "{{ MD_Extended }}" - stage: starting_execution - register: run_map - delegate_to: localhost - -- name: Manage Previous Service Model Data Files - ansible.builtin.include_tasks: manage_model_files_previous.yml - when: check_roles['save_previous'] - -- name: Manage Current Service Model Data Files - ansible.builtin.include_tasks: manage_model_files_current.yml - when: check_roles['save_previous'] \ No newline at end of file diff --git a/roles/validate/tasks/sub_main_vxlan.yml b/roles/validate/tasks/sub_main_vxlan.yml index 9484ae52..c14bef23 100644 --- a/roles/validate/tasks/sub_main_vxlan.yml +++ b/roles/validate/tasks/sub_main_vxlan.yml @@ -21,64 +21,12 @@ --- -- name: Perform Required Syntax and Semantic Model Validation +- name: Perform Required Syntax and Semantic Model Validation for VXLAN Fabric cisco.nac_dc_vxlan.common.nac_dc_validate: schema: "{{ schema_path }}" mdata: "{{ data_path }}" rules: "{{ rules_path }}" vars: data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - rules_path: "{{ role_path }}/files/rules/required_rules/" + rules_path: "{{ role_path }}/files/rules/required_rules/vxlan/" delegate_to: localhost - -# - name: Prepare Service Model -# cisco.nac_dc_vxlan.common.prepare_service_model: -# inventory_hostname: "{{ inventory_hostname }}" -# hostvars: "{{ hostvars }}" -# model_data: "{{ model_data['data'] }}" -# default_values: "{{ defaults }}" -# templates_path: "{{ role_path }}/../dtc/common/templates/" -# register: smd -# delegate_to: localhost - -# - name: Store Golden Service Model Data -# ansible.builtin.set_fact: -# MD: "{{ smd['model_golden'] }}" -# delegate_to: localhost - -# - name: Store Extended Service Model Data -# ansible.builtin.set_fact: -# MD_Extended: "{{ smd['model_extended'] }}" -# delegate_to: localhost - -- name: Check Roles - cisco.nac_dc_vxlan.common.check_roles: - role_list: "{{ role_names }}" - register: check_roles - delegate_to: localhost - -- name: Read Run Map From Previous Run - cisco.nac_dc_vxlan.common.read_run_map: - model_data: "{{ MD_Extended }}" - register: run_map_read_result - delegate_to: localhost - -- name: Debug Run Map Read Result - ansible.builtin.debug: - msg: "{{ run_map_read_result }}" - delegate_to: localhost - -- name: Initialize Run Map - cisco.nac_dc_vxlan.common.run_map: - model_data: "{{ MD_Extended }}" - stage: starting_execution - register: run_map - delegate_to: localhost - -- name: Manage Previous Service Model Data Files - ansible.builtin.include_tasks: manage_model_files_previous.yml - when: check_roles['save_previous'] - -- name: Manage Current Service Model Data Files - ansible.builtin.include_tasks: manage_model_files_current.yml - when: check_roles['save_previous'] \ No newline at end of file From 9a73ea9ad1ea9650b431623387c0dc2defaa861d Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Mon, 2 Dec 2024 21:35:32 -0500 Subject: [PATCH 08/66] updates for msd fabric templating --- plugins/action/common/nac_dc_load.py | 5 +++- plugins/action/common/nac_dc_validate.py | 1 - roles/dtc/common/tasks/ndfc_fabric.yml | 8 ++++-- roles/dtc/common/tasks/sub_main_msd.yml | 25 +++++++++++++------ roles/dtc/common/templates/ndfc_fabric.j2 | 9 +++++-- .../templates/ndfc_fabric/msd_fabric/.gitkeep | 0 .../ndfc_fabric/msd_fabric/dci/.gitkeep | 0 .../msd_fabric/dci/msd_fabric_dci.j2 | 12 +++++++++ .../ndfc_fabric/msd_fabric/general/.gitkeep | 0 .../msd_fabric/general/msd_fabric_general.j2 | 6 +++++ .../ndfc_fabric/msd_fabric/msd_fabric_base.j2 | 7 ++++++ .../ndfc_fabric/msd_fabric/resources/.gitkeep | 0 .../resources/msd_fabric_resources.j2 | 4 +++ .../ndfc_fabric/msd_fabric/security/.gitkeep | 0 .../security/msd_fabric_security.j2 | 2 ++ 15 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 diff --git a/plugins/action/common/nac_dc_load.py b/plugins/action/common/nac_dc_load.py index 94eae990..2b5154ba 100644 --- a/plugins/action/common/nac_dc_load.py +++ b/plugins/action/common/nac_dc_load.py @@ -58,13 +58,16 @@ def run(self, tmp=None, task_vars=None): if mdata and not os.path.exists(mdata): results['failed'] = True results['msg'] = "The data directory ({0}) for this fabric does not appear to exist!".format(mdata) + return results + if len(os.listdir(mdata)) == 0: results['failed'] = True results['msg'] = "The data directory ({0}) for this fabric is empty!".format(mdata) + return results - # Return Schema Validated Model Data + # Return Merged Model Data results['data'] = load_yaml_files([mdata]) return results diff --git a/plugins/action/common/nac_dc_validate.py b/plugins/action/common/nac_dc_validate.py index c7a91085..6e32f610 100644 --- a/plugins/action/common/nac_dc_validate.py +++ b/plugins/action/common/nac_dc_validate.py @@ -30,7 +30,6 @@ try: import iac_validate.validator - from iac_validate.yaml import load_yaml_files from iac_validate.cli.options import DEFAULT_SCHEMA except ImportError as imp_exc: IAC_VALIDATE_IMPORT_ERROR = imp_exc diff --git a/roles/dtc/common/tasks/ndfc_fabric.yml b/roles/dtc/common/tasks/ndfc_fabric.yml index 26a8351a..629a458b 100644 --- a/roles/dtc/common/tasks/ndfc_fabric.yml +++ b/roles/dtc/common/tasks/ndfc_fabric.yml @@ -28,7 +28,11 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_fabric.yml" + file_name: >- + {% if MD.vxlan.name is defined and MD.vxlan.name %} + {{ MD.vxlan.name }}_ndfc_fabric.yml + {% elif MD.vxlan.global.name is defined and MD.vxlan.global.name %} + {{ MD.vxlan.global.name }}_ndfc_fabric.yml delegate_to: localhost - name: Stat Previous File If It Exists @@ -59,7 +63,7 @@ - ansible.builtin.set_fact: fabric_config: "{{ lookup('file', file_name) | from_yaml }}" - when: MD.vxlan.global + when: MD.vxlan.global or MD.vxlan.multisite delegate_to: localhost - name: Diff Previous and Current Data Files diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 9a0be877..4be7dab8 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -21,10 +21,21 @@ --- -- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.create] - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Calling MSD Role - [cisco.nac_dc_vxlan.dtc.create] +" - - "----------------------------------------------------------------" - tags: "{{ nac_tags.create }}" # Tags defined in roles/common_global/vars/main.yml +- ansible.builtin.fail: msg="Service Model Not Defined. Role cisco.nac_dc_vxlan.validate Must Be Called First" + when: MD is undefined + delegate_to: localhost + +# -------------------------------------------------------------------- +# Remove all files from the previous run if run_map requires it +# -------------------------------------------------------------------- +- name: Cleanup Files from Previous Run if run_map requires it + ansible.builtin.include_tasks: cleanup_files.yml + when: + - not run_map_read_result.diff_run or ((force_run_all is defined) and (force_run_all is true|bool)) + +# -------------------------------------------------------------------- +# Build Create Fabric Parameter List From Template +# -------------------------------------------------------------------- + +- name: Build MSD Fabric Create Parameters + ansible.builtin.include_tasks: ndfc_fabric.yml diff --git a/roles/dtc/common/templates/ndfc_fabric.j2 b/roles/dtc/common/templates/ndfc_fabric.j2 index f8aa6e2f..51e478ed 100644 --- a/roles/dtc/common/templates/ndfc_fabric.j2 +++ b/roles/dtc/common/templates/ndfc_fabric.j2 @@ -5,12 +5,17 @@ {% set vxlan = MD_Extended.vxlan %} {% set global = vxlan.global %} {% set fabric_type = vxlan.global.fabric_type | default('VXLAN_EVPN') %} -{% if fabric_type == 'VXLAN_EVPN' %} +{% if fabric_type == 'VXLAN_EVPN' or vxlan.fabric_type == 'VXLAN_EVPN' %} {# Include NDFC DC VXLAN EVPN Base Template #} {% include '/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2' %} +{% elif vxlan.fabric_type == 'MSD'%} + +{# Include NDFC MSD Base Template #} +{% include '/ndfc_fabric/msd/msd_fabric_base.j2' %} + {% else %} -{# Supported fabric types are: DC VXLAN EVPN #} +{# Supported fabric types are: DC VXLAN EVPN, MSD #} {% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 new file mode 100644 index 00000000..a06fccaa --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 @@ -0,0 +1,12 @@ +{# Auto-generated NDFC MSD DCI config data structure for fabric {{ vxlan.name }} #} + BORDER_GWY_CONNECTIONS: {{ vxlan.multisite.overlay_ifc | default(defaults.vxlan.multisite.overlay_ifc) }} + MS_UNDERLAY_AUTOCONFIG: {{ vxlan.multisite.underlay_autoconfig | default(defaults.vxlan.multisite.underlay_autoconfig) }} + ENABLE_BGP_SEND_COMM: {{ vxlan.multisite.enable_bgp_send_community | default(defaults.vxlan.multisite.enable_bgp_send_community) }} + ENABLE_BGP_LOG_NEIGHBOR_CHANGE: {{ vxlan.multisite.enable_bgp_log_neighbor_change | default(defaults.vxlan.multisite.enable_bgp_log_neighbor_change) }} + ENABLE_BGP_BFD: {{ vxlan.multisite.enable_bgp_bfd | default(defaults.vxlan.multisite.enable_bgp_bfd) }} + DELAY_RESTORE: {{ vxlan.multisite.delay_restore | default(defaults.vxlan.multisite.delay_restore) }} + MS_IFC_BGP_PASSWORD_ENABLE: {{ vxlan.multisite.enable_bgp_password | default(defaults.vxlan.multisite.enable_bgp_password) }} +{% if vxlan.multisite.enable_bgp_password is defined and vxlan.multisite.enable_bgp_password %} + MS_IFC_BGP_PASSWORD: {{ vxlan.multisite.bgp_password }} + MS_IFC_BGP_AUTH_KEY_TYPE: {{ vxlan.multisite.bgp_auth_key_type | default(defaults.vxlan.multisite.bgp_auth_key_type) }} +{% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 new file mode 100644 index 00000000..1c4e92ca --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 @@ -0,0 +1,6 @@ +{# Auto-generated NDFC MSD General config data structure for fabric {{ vxlan.name }} #} + ENABLE_PVLAN: false + ANYCAST_GW_MAC: {{ vxlan.multisite.anycast_gateway_mac | default(defaults.vxlan.multisite.anycast_gateway_mac) }} + MS_LOOPBACK_ID: {{ vxlan.multisite.loopback_id | default(defaults.vxlan.multisite.loopback_id) }} + BGW_ROUTING_TAG: {{ vxlan.multisite.bgw_ip_tag | default(defaults.vxlan.multisite.bgw_ip_tag) }} +{# #} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 new file mode 100644 index 00000000..8f4d07d0 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 @@ -0,0 +1,7 @@ +{# Auto-generated NDFC DC VXLAN EVPN Base config data structure for fabric {{ vxlan.name }} #} +- FABRIC_NAME: {{ vxlan.name }} + FABRIC_TYPE: VXLAN_EVPN_MSD + DEPLOY: True + +{# Include NDFC DC VXLAN EVPN General Template #} +{% include '/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2' %} diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 new file mode 100644 index 00000000..31bd7dd8 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 @@ -0,0 +1,4 @@ +{# Auto-generated NDFC MSD Resources config data structure for fabric {{ vxlan.name }} #} + LOOPBACK100_IP_RANGE: {{ vxlan.multisite.vtep_loopback_ip_range | default(defaults.vxlan.multisite.vtep_loopback_ip_range) }} + DCI_SUBNET_RANGE: {{ vxlan.multisite.dci_subnet_range | default(defaults.vxlan.multisite.dci_subnet_range) }} + DCI_SUBNET_MASK: {{ vxlan.multisite.dci_subnet_mask | default(defaults.vxlan.multisite.dci_subnet_mask) }} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 new file mode 100644 index 00000000..a7f56a61 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 @@ -0,0 +1,2 @@ +{# Auto-generated NDFC MSD Security config data structure for fabric {{ vxlan.name }} #} + ENABLE_SGT: false \ No newline at end of file From 0a1b04264c29273d4926a25747abcd11f4e434c5 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Mon, 2 Dec 2024 21:37:59 -0500 Subject: [PATCH 09/66] remove dup file --- roles/dtc/common/tasks/msd/ndfc_fabric.yml | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 roles/dtc/common/tasks/msd/ndfc_fabric.yml diff --git a/roles/dtc/common/tasks/msd/ndfc_fabric.yml b/roles/dtc/common/tasks/msd/ndfc_fabric.yml deleted file mode 100644 index fa74285b..00000000 --- a/roles/dtc/common/tasks/msd/ndfc_fabric.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -- debug: msg="Building NDFC MSD Fabric Data" \ No newline at end of file From e413ba3471826a0c4808fa47d550410694b9ca5d Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Mon, 2 Dec 2024 21:39:52 -0500 Subject: [PATCH 10/66] update create task for msd --- roles/dtc/create/tasks/msd/fabric.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/roles/dtc/create/tasks/msd/fabric.yml b/roles/dtc/create/tasks/msd/fabric.yml index 27797fac..153b16aa 100644 --- a/roles/dtc/create/tasks/msd/fabric.yml +++ b/roles/dtc/create/tasks/msd/fabric.yml @@ -31,6 +31,4 @@ - name: Manage fabric {{ MD.vxlan.name }} in NDFC cisco.dcnm.dcnm_fabric: state: merged - config: - - FABRIC_NAME: "{{ MD.vxlan.name }}" - FABRIC_TYPE: VXLAN_EVPN_MSD + config: "{{ fabric_config }}" From a220eddfe00a3805ec35a1eb4dfb9abe8776bfde Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Mon, 2 Dec 2024 21:41:11 -0500 Subject: [PATCH 11/66] update create task for msd --- roles/dtc/create/tasks/sub_main_msd.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index 12ea1f70..53bb19fe 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -31,7 +31,7 @@ - name: Create NDFC MSD Fabric ansible.builtin.import_tasks: msd/fabric.yml - # when: - # - MD_Extended.vxlan.global is defined - # - changes_detected_fabric + when: + - MD_Extended.vxlan.multisite is defined + - changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" From 87c8395fcfc9c008b16dee8d61c54ce8850b9595 Mon Sep 17 00:00:00 2001 From: mwiebe Date: Mon, 2 Dec 2024 21:44:22 -0500 Subject: [PATCH 12/66] Add child fabrics logic --- plugins/action/dtc/move_child_fabrics.py | 83 ++++++++++++++++++++ roles/dtc/create/tasks/msd/child_fabrics.yml | 42 ++++++++++ roles/dtc/create/tasks/msd/fabric.yml | 2 +- roles/dtc/create/tasks/sub_main_msd.yml | 14 +++- 4 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 plugins/action/dtc/move_child_fabrics.py create mode 100644 roles/dtc/create/tasks/msd/child_fabrics.yml diff --git a/plugins/action/dtc/move_child_fabrics.py b/plugins/action/dtc/move_child_fabrics.py new file mode 100644 index 00000000..7163d029 --- /dev/null +++ b/plugins/action/dtc/move_child_fabrics.py @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible.utils.display import Display +from ansible.plugins.action import ActionBase + +display = Display() + + +class ActionModule(ActionBase): + + def run(self, tmp=None, task_vars=None): + results = super(ActionModule, self).run(tmp, task_vars) + results['failed'] = False + + fabric_associations = self._task.args['fabric_associations'].get('response').get('DATA') + parent_fabric_name = self._task.args['parent_fabric_name'] + child_fabrics = self._task.args['child_fabrics'] + + # Build a list of child fabrics that are associated with the parent fabric + associated_child_fabrics = [] + for fabric in fabric_associations: + if fabric.get('fabricParent') == parent_fabric_name: + associated_child_fabrics.append(fabric.get('fabricName')) + + for fabric in child_fabrics: + if fabric.get('name') not in associated_child_fabrics: + json_data = '{"destFabric":"%s","sourceFabric":"%s"}' % (parent_fabric_name, fabric.get('name')) + add_fabric_result = self._execute_module( + module_name="cisco.dcnm.dcnm_rest", + module_args={ + "method": "POST", + "path": f"/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd", + "json_data": json_data + }, + task_vars=task_vars, + tmp=tmp + ) + + return results + + +# cisco.dcnm.dcnm_rest: +# method: POST +# path: /appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd +# json_data: '{"destFabric":"nac-msd","sourceFabric":"nac-ndfc1"}' + +# https://rtp-ndfc1.cisco.com/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations/ +# GET +# + +# https://rtp-ndfc1.cisco.com/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd +# POST +# {"destFabric":"nac-msd","sourceFabric":"nac-ndfc1"} + +# https://rtp-ndfc1.cisco.com/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdExit +# POST +# {"destFabric":"nac-msd","sourceFabric":"nac-ndfc1"} + + diff --git a/roles/dtc/create/tasks/msd/child_fabrics.yml b/roles/dtc/create/tasks/msd/child_fabrics.yml new file mode 100644 index 00000000..e1514c0b --- /dev/null +++ b/roles/dtc/create/tasks/msd/child_fabrics.yml @@ -0,0 +1,42 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Manage Child Fabrics Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Fabric {{ MD.vxlan.name }}" + - "----------------------------------------------------------------" + +- name: Get Fabric Association Data from NDFC + cisco.dcnm.dcnm_rest: + method: GET + path: /appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations + register: fabric_associations + +- name: Move Child Fabrics To Fabric - {{ MD.vxlan.name }} + cisco.nac_dc_vxlan.dtc.move_child_fabrics: + fabric_associations: "{{ fabric_associations }}" + parent_fabric_name: "{{ MD_Extended.vxlan.name }}" + child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" + when: fabric_associations is defined diff --git a/roles/dtc/create/tasks/msd/fabric.yml b/roles/dtc/create/tasks/msd/fabric.yml index 27797fac..d0e1a04d 100644 --- a/roles/dtc/create/tasks/msd/fabric.yml +++ b/roles/dtc/create/tasks/msd/fabric.yml @@ -28,7 +28,7 @@ - "+ Manage Fabric {{ MD.vxlan.name }}" - "----------------------------------------------------------------" -- name: Manage fabric {{ MD.vxlan.name }} in NDFC +- name: Manage Fabric {{ MD.vxlan.name }} in NDFC cisco.dcnm.dcnm_fabric: state: merged config: diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index 12ea1f70..42533fa5 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -25,13 +25,23 @@ ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Calling MSD Role - [cisco.nac_dc_vxlan.dtc.create] +" + - "+ Calling Role - [cisco.nac_dc_vxlan.dtc.create] +" - "----------------------------------------------------------------" tags: "{{ nac_tags.create }}" # Tags defined in roles/common_global/vars/main.yml +- ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" + tags: "{{ nac_tags.create }}" + - name: Create NDFC MSD Fabric ansible.builtin.import_tasks: msd/fabric.yml # when: # - MD_Extended.vxlan.global is defined - # - changes_detected_fabric + # - changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" + +- name: Manage NDFC MSD Fabric Child Fabrics + ansible.builtin.import_tasks: msd/child_fabrics.yml + # when: + # - MD_Extended.vxlan.topology.switches | length > 0 + # - changes_detected_inventory + # tags: "{{ nac_tags.create_switches }}" From a1b5bbda65d6745465b37834c47589542918cfb4 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 3 Dec 2024 09:08:06 -0500 Subject: [PATCH 13/66] updated defaults --- roles/validate/files/defaults.yml | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/roles/validate/files/defaults.yml b/roles/validate/files/defaults.yml index 2f4ffc69..4ef1034b 100644 --- a/roles/validate/files/defaults.yml +++ b/roles/validate/files/defaults.yml @@ -210,16 +210,6 @@ factory_defaults: distance: 110 bfd: enabled: false - default_information_originate: - always: false - nssa: - default_information_originate: false - no_redistribution: false - no_summary: false - translate: - always: false - supress_fa: false - never: false bgp: best_path_as_path_relax: false graceful_restart: true @@ -280,4 +270,18 @@ factory_defaults: as_override: false route_reflector_client: false default_originate: false - next_hop_self: false \ No newline at end of file + next_hop_self: false + multisite: + anycast_gateway_mac: 20:20:00:00:00:aa + vtep_loopback_id: 100 + vtep_loopback_ip_range: 10.10.0.0/24 + dci_subnet_range: 10.10.1.0/24 + dci_subnet_mask: 30 + bgw_ip_tag: 54321 + overlay_ifc: direct_to_bgws + underlay_autoconfig: false + enable_bgp_send_community: false + enable_bgp_log_neighbor_change: false + enable_bgp_bfd: false + delay_restore: 300 + enable_bgp_password: false From 9070b839b513efdc0659e13b464f667290fbc102 Mon Sep 17 00:00:00 2001 From: mwiebe Date: Tue, 3 Dec 2024 13:14:08 -0500 Subject: [PATCH 14/66] Update prepare plugins --- .../action/common/prepare_plugins/prep_001_list_defaults.py | 3 ++- plugins/action/common/prepare_service_model.py | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py index 515906c6..1b4828cc 100644 --- a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py @@ -52,7 +52,6 @@ def set_list_default(self, parent_keys, target_key): # used by other plugins without having to check if the key exists. def prepare(self): self.model_data = self.kwargs['results']['model_extended'] - # -------------------------------------------------------------------- # Fabric Global List Defaults # -------------------------------------------------------------------- @@ -74,6 +73,8 @@ def prepare(self): # Check vxlan.topology list elements parent_keys = ['vxlan', 'topology'] dm_check = data_model_key_check(self.model_data, parent_keys) + if 'topology' in dm_check['keys_not_found']: + self.model_data['vxlan']['topology'] = {} if 'topology' in dm_check['keys_no_data']: self.model_data['vxlan']['topology'] = {'edge_connections': []} self.model_data['vxlan']['topology'] = {'fabric_links': []} diff --git a/plugins/action/common/prepare_service_model.py b/plugins/action/common/prepare_service_model.py index d546ca5c..c2bebc18 100644 --- a/plugins/action/common/prepare_service_model.py +++ b/plugins/action/common/prepare_service_model.py @@ -58,8 +58,6 @@ def run(self, tmp=None, task_vars=None): full_plugin_path = "ansible_collections.cisco.nac_dc_vxlan.plugins.action.common.prepare_plugins" glob_plugin_path = os.path.dirname(__file__) + "/prepare_plugins" - if fabric_type == 'MSD': - glob_plugin_path = os.path.dirname(__file__) + "/prepare_plugins/msd" plugin_prefix = "prep*.py" prepare_libs = set(x.stem for x in pathlib.Path.glob(pathlib.Path(glob_plugin_path), plugin_prefix)) From e7520ec582a95f6465ed5e9316d80c3a9a349e00 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Wed, 4 Dec 2024 19:26:11 -0500 Subject: [PATCH 15/66] more work on msd & shift to overlay key from overlay_services but with backward compat. --- plugins/action/common/nac_dc_validate.py | 74 +++++++-- .../prepare_plugins/prep_001_list_defaults.py | 49 ++++++ .../common/prepare_plugins/prep_101_fabric.py | 109 +++++++++++++ .../common/prepare_plugins/prep_101_global.py | 30 ---- .../prep_104_fabric_overlay_services.py | 50 ++++++ roles/dtc/common/tasks/main.yml | 10 +- roles/dtc/common/tasks/ndfc_fabric.yml | 1 + roles/dtc/common/tasks/sub_main_vxlan.yml | 2 +- roles/dtc/common/templates/ndfc_fabric.j2 | 10 +- .../advanced/dc_vxlan_fabric_advanced.j2 | 14 +- .../dc_vxlan_fabric/dc_vxlan_fabric_base.j2 | 4 +- roles/dtc/create/tasks/main.yml | 12 +- roles/dtc/create/tasks/sub_main_msd.yml | 3 +- .../rules/{enhanced_rules => common}/.gitkeep | 0 .../{required_rules => multisite}/.gitkeep | 0 .../files/rules/required_rules/vxlan/.gitkeep | 0 .../{required_rules/msd => vxlan}/.gitkeep | 0 .../vxlan/201_global_spanning_tree.py | 0 .../vxlan/202_global_underlay_mcast_trm.py | 0 .../vxlan/203_global_underlay_isis.py | 0 .../vxlan/301_topology_switch_serial.py | 0 .../vxlan/302_topology_switch_management.py | 0 .../vxlan/303_topology_switch_role.py | 0 ...pology_switch_interfaces_members_unique.py | 0 .../305_topology_switch_interfaces_vpc.py | 0 .../401_overlay_services_cross_reference.py | 53 +++++- .../vxlan/402_overlay_services_vrfs.py | 40 ++--- .../vxlan/403_overlay_services_networks.py | 14 +- .../vxlan/501_policy_cross_reference.py | 0 .../502_policy_vrf_lite_cross_reference.py | 0 roles/validate/tasks/main.yml | 22 +-- roles/validate/tasks/sub_main.yml | 152 ++++++++++++++++++ roles/validate/tasks/sub_main_vxlan.yml | 2 +- 33 files changed, 530 insertions(+), 121 deletions(-) create mode 100644 plugins/action/common/prepare_plugins/prep_101_fabric.py delete mode 100644 plugins/action/common/prepare_plugins/prep_101_global.py rename roles/validate/files/rules/{enhanced_rules => common}/.gitkeep (100%) rename roles/validate/files/rules/{required_rules => multisite}/.gitkeep (100%) delete mode 100644 roles/validate/files/rules/required_rules/vxlan/.gitkeep rename roles/validate/files/rules/{required_rules/msd => vxlan}/.gitkeep (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/201_global_spanning_tree.py (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/202_global_underlay_mcast_trm.py (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/203_global_underlay_isis.py (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/301_topology_switch_serial.py (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/302_topology_switch_management.py (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/303_topology_switch_role.py (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/304_topology_switch_interfaces_members_unique.py (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/305_topology_switch_interfaces_vpc.py (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/401_overlay_services_cross_reference.py (65%) rename roles/validate/files/rules/{required_rules => }/vxlan/402_overlay_services_vrfs.py (66%) rename roles/validate/files/rules/{required_rules => }/vxlan/403_overlay_services_networks.py (74%) rename roles/validate/files/rules/{required_rules => }/vxlan/501_policy_cross_reference.py (100%) rename roles/validate/files/rules/{required_rules => }/vxlan/502_policy_vrf_lite_cross_reference.py (100%) create mode 100644 roles/validate/tasks/sub_main.yml diff --git a/plugins/action/common/nac_dc_validate.py b/plugins/action/common/nac_dc_validate.py index 6e32f610..8f45aaaf 100644 --- a/plugins/action/common/nac_dc_validate.py +++ b/plugins/action/common/nac_dc_validate.py @@ -29,6 +29,7 @@ from ansible.errors import AnsibleError try: + from iac_validate.yaml import load_yaml_files import iac_validate.validator from iac_validate.cli.options import DEFAULT_SCHEMA except ImportError as imp_exc: @@ -37,6 +38,7 @@ IAC_VALIDATE_IMPORT_ERROR = None import os +from ...plugin_utils.helper_functions import data_model_key_check display = Display() @@ -77,18 +79,64 @@ def run(self, tmp=None, task_vars=None): if schema == '': schema = DEFAULT_SCHEMA - validator = iac_validate.validator.Validator(schema, rules) - if schema: - validator.validate_syntax([mdata]) - if rules: - validator.validate_semantics([mdata]) - - msg = "" - for error in validator.errors: - msg += error + "\n" - - if msg: - results['failed'] = True - results['msg'] = msg + rules_list = [] + if rules and task_vars['role_path'] in rules: + # Load in-memory data model using iac-validate + # Perform the load in this if block to avoid loading the data model multiple times when custom enhanced rules are provided + results['data'] = load_yaml_files([mdata]) + + # Introduce common directory to the rules list by default once vrf and network rules are updated + # rules_to_run.append(f'{rules}common') + parent_keys = ['vxlan', 'fabric'] + check = data_model_key_check(results['data'], parent_keys) + if 'fabric' in check['keys_found'] and 'fabric' in check['keys_data']: + if 'type' in results['data']['vxlan']['fabric']: + if results['data']['vxlan']['fabric']['type'] in ('VXLAN_EVPN'): + rules_list.append(f'{rules}vxlan/') + elif results['data']['vxlan']['fabric']['type'] in ('MSD', 'MCF'): + rules_list.append(f'{rules}multisite/') + else: + results['failed'] = True + results['msg'] = f"vxlan.fabric.type {results['data']['vxlan']['fabric']['type']} is not a supported fabric type." + else: + results['failed'] = True + results['msg'] = "vxlan.fabric.type is not defined in the data model." + else: + # This else block is to be removed after the deprecation of vxlan.global.fabric_type + parent_keys = ['vxlan', 'global'] + check = data_model_key_check(results['data'], parent_keys) + if 'global' in check['keys_found'] and 'global' in check['keys_data']: + if 'fabric_type' in results['data']['vxlan']['global']: + display.deprecated("Attempting to use vxlan.global.fabric_type due to vxlan.fabric.type not being found. vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric.type.") + + if results['data']['vxlan']['global']['fabric_type'] in ('VXLAN_EVPN'): + rules_list.append(f'{rules}vxlan/') + elif results['data']['vxlan']['global']['fabric_type'] in ('MSD', 'MCF'): + rules_list.append(f'{rules}multisite/') + else: + results['failed'] = True + results['msg'] = f"vxlan.fabric.type {results['data']['vxlan']['global']['fabric_type']} is not a supported fabric type." + else: + results['failed'] = True + results['msg'] = "vxlan.fabric.type is not defined in the data model." + else: + # Else block to pickup custom enhanced rules provided by the user + rules_list.append(f'{rules}') + + for rules_item in rules_list: + validator = iac_validate.validator.Validator(schema, rules_item) + if schema: + validator.validate_syntax([mdata]) + if rules_item: + validator.validate_semantics([mdata]) + + msg = "" + for error in validator.errors: + msg += error + "\n" + + if msg: + results['failed'] = True + results['msg'] = msg + break return results diff --git a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py index 515906c6..95872ddd 100644 --- a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py @@ -127,6 +127,55 @@ def prepare(self): # Fabric Overlay List Defaults # -------------------------------------------------------------------- + # Check vxlan.overlay list elements + parent_keys = ['vxlan', 'overlay'] + dm_check = data_model_key_check(self.model_data, parent_keys) + if 'overlay' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: + self.model_data['vxlan']['overlay'] = {'vrfs': []} + self.model_data['vxlan']['overlay'] = {'vrf_attach_groups': []} + self.model_data['vxlan']['overlay'] = {'networks': []} + self.model_data['vxlan']['overlay'] = {'network_attach_groups': []} + + # Check vxlan.overlay_services.vrfs list element + target_key = 'vrfs' + self.set_list_default(parent_keys, target_key) + + # Check vxlan.overlay.vrf_attach_groups list element + target_key = 'vrf_attach_groups' + self.set_list_default(parent_keys, target_key) + + # Check vxlan.overlay.vrf_attach_groups[index].switches list elements + list_index = 0 + for group in self.model_data['vxlan']['overlay']['vrf_attach_groups']: + dm_check = data_model_key_check(group, ['switches']) + if 'switches' in dm_check['keys_not_found'] or \ + 'switches' in dm_check['keys_no_data']: + self.model_data['vxlan']['overlay']['vrf_attach_groups'][list_index]['switches'] = [] + + list_index += 1 + + # Check vxlan.overlay.networks list element + target_key = 'networks' + self.set_list_default(parent_keys, target_key) + + # Check vxlan.overlay.network_attach_groups list element + target_key = 'network_attach_groups' + self.set_list_default(parent_keys, target_key) + + # Check vxlan.overlay.network_attach_groups[index].switches list elements + list_index = 0 + for group in self.model_data['vxlan']['overlay']['network_attach_groups']: + dm_check = data_model_key_check(group, ['switches']) + if 'switches' in dm_check['keys_not_found'] or \ + 'switches' in dm_check['keys_no_data']: + self.model_data['vxlan']['overlay']['network_attach_groups'][list_index]['switches'] = [] + + list_index += 1 + + # -------------------------------------------------------------------- + # Fabric Overlay List Defaults - Backwards Compatibility + # -------------------------------------------------------------------- + # Check vxlan.overlay_services list elements parent_keys = ['vxlan', 'overlay_services'] dm_check = data_model_key_check(self.model_data, parent_keys) diff --git a/plugins/action/common/prepare_plugins/prep_101_fabric.py b/plugins/action/common/prepare_plugins/prep_101_fabric.py new file mode 100644 index 00000000..d87085e2 --- /dev/null +++ b/plugins/action/common/prepare_plugins/prep_101_fabric.py @@ -0,0 +1,109 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +from ansible.utils.display import Display +from ....plugin_utils.helper_functions import data_model_key_check + +display = Display() + + +class PreparePlugin: + def __init__(self, **kwargs): + self.kwargs = kwargs + self.keys = [] + + def prepare(self): + model_data = self.kwargs['results']['model_extended'] + + parent_keys = ['vxlan', 'fabric'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'fabric' in dm_check['keys_not_found'] or 'fabric' in dm_check['keys_no_data']: + display.deprecated( + "Attempting to use vxlan.global.name and vxlan.global.fabric_type due to vxlan.fabric.name and vxlan.fabric.type not being found. " + "vxlan.global.name and vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric." + ) + + # Prepare the data model to ensure vxlan.fabric.name is set + # global_data_check = False + # parent_keys = ['vxlan', 'global'] + # dm_check = data_model_key_check(model_data, parent_keys) + # if 'global' in dm_check['keys_found'] and 'global' in dm_check['keys_data']: + # parent_keys = ['vxlan', 'global', 'name'] + # dm_check = data_model_key_check(model_data, parent_keys) + # if 'name' in dm_check['keys_found'] and 'name' in dm_check['keys_data']: + # model_data['vxlan']['fabric']['name'] = model_data['vxlan']['global']['name'] + # else: + # global_data_check = True + + # parent_keys = ['vxlan', 'global', 'fabric_type'] + # dm_check = data_model_key_check(model_data, parent_keys) + # if 'fabric_type' in dm_check['keys_found'] and 'fabric_type' in dm_check['keys_data']: + # model_data['vxlan']['fabric']['type'] = model_data['vxlan']['global']['fabric_type'] + # else: + # self.kwargs['results']['failed'] = True + # self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data." + # global_data_check = True + # else: + # self.kwargs['results']['failed'] = True + # self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data." + + # if global_data_check: + # self.kwargs['results']['failed'] = True + # self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data." + # else: + # parent_keys = ['vxlan', 'fabric', 'name'] + # dm_check = data_model_key_check(model_data, parent_keys) + # if 'name' in dm_check['keys_no_data'] or 'name' in dm_check['keys_not_found']: + # parent_keys = ['vxlan', 'global', 'name'] + # dm_check = data_model_key_check(model_data, parent_keys) + # if 'name' in dm_check['keys_data']: + # # Insert warning about deprecation and where found + # model_data['vxlan']['fabric']['name'] = model_data['vxlan']['global']['name'] + # else: + # self.kwargs['results']['failed'] = True + # self.kwargs['results']['msg'] = "vxlan.fabric.name is not set in the model data." + + # # Prepare the data model to ensure vxlan.fabric.type is set + # parent_keys = ['vxlan', 'fabric', 'type'] + # dm_check = data_model_key_check(model_data, parent_keys) + # if 'type' in dm_check['keys_no_data'] or 'name' in dm_check['keys_not_found']: + # parent_keys = ['vxlan', 'global', 'fabric_type'] + # dm_check = data_model_key_check(model_data, parent_keys) + # if 'fabric_type' in dm_check['keys_data']: + # # Insert warning about deprecation and where found + # model_data['vxlan']['fabric']['type'] = model_data['vxlan']['global']['fabric_type'] + # else: + # self.kwargs['results']['failed'] = True + # self.kwargs['results']['msg'] = "vxlan.fabric.type is not set in the model data." + + # 1 - no fabric key data model + # 2a - fabric key data model with no data (i.e. no name or type) > semantic valdiation failure with schema + # 2b - fabric key data model with no data (i.e. name or type) > check if we have global name and global fabric_type + + + # insert comment to indicate this is a oneoff check for fabric key as this should really be done in a rule, + # but fabric name and key are foundational for the collection so we need to ensure it is set. + # this prepare plugin also helps retain backwards compatibility with the global fabric name and fabric_type keys previously used. + + # Prepare the data model to ensure vxlan.fabric.name is set + + self.kwargs['results']['model_extended'] = model_data + return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_101_global.py b/plugins/action/common/prepare_plugins/prep_101_global.py deleted file mode 100644 index 1a675eb1..00000000 --- a/plugins/action/common/prepare_plugins/prep_101_global.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - -class PreparePlugin: - def __init__(self, **kwargs): - self.kwargs = kwargs - self.keys = [] - - def prepare(self): - model_data = self.kwargs['results']['model_extended'] - self.kwargs['results']['model_extended'] = model_data - return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py index b71c952b..e3bf2f22 100644 --- a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py +++ b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py @@ -29,6 +29,56 @@ def prepare(self): model_data = self.kwargs['results']['model_extended'] switches = model_data['vxlan']['topology']['switches'] + # Rebuild sm_data['vxlan']['overlay']['vrf_attach_groups'] into + # a structure that is easier to use. + vrf_grp_name_list = [] + model_data['vxlan']['overlay']['vrf_attach_groups_dict'] = {} + for grp in model_data['vxlan']['overlay']['vrf_attach_groups']: + model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']] = [] + vrf_grp_name_list.append(grp['name']) + for switch in grp['switches']: + model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']].append(switch) + # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP + for switch in model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']]: + if any(sw['name'] == switch['hostname'] for sw in switches): + found_switch = next((item for item in switches if item["name"] == switch['hostname'])) + if found_switch.get('management').get('management_ipv4_address'): + switch['hostname'] = found_switch['management']['management_ipv4_address'] + elif found_switch.get('management').get('management_ipv6_address'): + switch['hostname'] = found_switch['management']['management_ipv6_address'] + + # Remove vrf_attach_group from vrf if the group_name is not defined + for vrf in model_data['vxlan']['overlay']['vrfs']: + if 'vrf_attach_group' in vrf: + if vrf.get('vrf_attach_group') not in vrf_grp_name_list: + del vrf['vrf_attach_group'] + + # Rebuild sm_data['vxlan']['overlay']['network_attach_groups'] into + # a structure that is easier to use. + net_grp_name_list = [] + model_data['vxlan']['overlay']['network_attach_groups_dict'] = {} + for grp in model_data['vxlan']['overlay']['network_attach_groups']: + model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']] = [] + net_grp_name_list.append(grp['name']) + for switch in grp['switches']: + model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']].append(switch) + # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP + for switch in model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']]: + if any(sw['name'] == switch['hostname'] for sw in switches): + found_switch = next((item for item in switches if item["name"] == switch['hostname'])) + if found_switch.get('management').get('management_ipv4_address'): + switch['hostname'] = found_switch['management']['management_ipv4_address'] + elif found_switch.get('management').get('management_ipv6_address'): + switch['hostname'] = found_switch['management']['management_ipv6_address'] + + # Remove network_attach_group from net if the group_name is not defined + for net in model_data['vxlan']['overlay']['networks']: + if 'network_attach_group' in net: + if net.get('network_attach_group') not in net_grp_name_list: + del net['network_attach_group'] + + # Backwards compatibility for vxlan.overlay_services + # Rebuild sm_data['vxlan']['overlay_services']['vrf_attach_groups'] into # a structure that is easier to use. vrf_grp_name_list = [] diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index d219dee4..dda5ec0e 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -21,12 +21,12 @@ --- -- name: Import Role Tasks for MSD Fabric - ansible.builtin.import_tasks: sub_main_msd.yml - tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml - when: MD_Extended.vxlan.fabric_type == 'MSD' - - name: Import Role Tasks for VXLAN Fabric ansible.builtin.import_tasks: sub_main_vxlan.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml when: MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' + +- name: Import Role Tasks for MSD Fabric + ansible.builtin.import_tasks: sub_main_msd.yml + tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml + when: MD_Extended.vxlan.fabric_type == 'MSD' diff --git a/roles/dtc/common/tasks/ndfc_fabric.yml b/roles/dtc/common/tasks/ndfc_fabric.yml index 629a458b..bbfdba87 100644 --- a/roles/dtc/common/tasks/ndfc_fabric.yml +++ b/roles/dtc/common/tasks/ndfc_fabric.yml @@ -33,6 +33,7 @@ {{ MD.vxlan.name }}_ndfc_fabric.yml {% elif MD.vxlan.global.name is defined and MD.vxlan.global.name %} {{ MD.vxlan.global.name }}_ndfc_fabric.yml + {% endif %} delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index 9029aa98..dd01a62a 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -38,7 +38,7 @@ # -------------------------------------------------------------------- - name: Build Fabric Create Parameters - ansible.builtin.include_tasks: vxlan/ndfc_fabric.yml + ansible.builtin.include_tasks: ndfc_fabric.yml # -------------------------------------------------------------------- # Build NDFC Fabric Switch Inventory List From Template diff --git a/roles/dtc/common/templates/ndfc_fabric.j2 b/roles/dtc/common/templates/ndfc_fabric.j2 index 51e478ed..baf5aa26 100644 --- a/roles/dtc/common/templates/ndfc_fabric.j2 +++ b/roles/dtc/common/templates/ndfc_fabric.j2 @@ -3,17 +3,19 @@ {#- DO NOT EDIT MANUALLY #} {% set vxlan = MD_Extended.vxlan %} +{% if vxlan.global is defined %} {% set global = vxlan.global %} -{% set fabric_type = vxlan.global.fabric_type | default('VXLAN_EVPN') %} -{% if fabric_type == 'VXLAN_EVPN' or vxlan.fabric_type == 'VXLAN_EVPN' %} +{% endif %} +{% set fabric_type = vxlan.fabric_type | default('VXLAN_EVPN') %} +{% if fabric_type == 'VXLAN_EVPN' %} {# Include NDFC DC VXLAN EVPN Base Template #} {% include '/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2' %} -{% elif vxlan.fabric_type == 'MSD'%} +{% elif fabric_type == 'MSD'%} {# Include NDFC MSD Base Template #} -{% include '/ndfc_fabric/msd/msd_fabric_base.j2' %} +{% include '/ndfc_fabric/msd_fabric/msd_fabric_base.j2' %} {% else %} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/advanced/dc_vxlan_fabric_advanced.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/advanced/dc_vxlan_fabric_advanced.j2 index ce09372f..6b2c3584 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/advanced/dc_vxlan_fabric_advanced.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/advanced/dc_vxlan_fabric_advanced.j2 @@ -7,13 +7,13 @@ L2_HOST_INTF_MTU: {{ vxlan.underlay.general.layer2_host_interfacde_mtu | default(defaults.vxlan.underlay.general.layer2_host_interfacde_mtu) }} HOST_INTF_ADMIN_STATE: {{ vxlan.underlay.general.unshut_host_interfaces | default(defaults.vxlan.underlay.general.unshut_host_interfaces) }} {% if ndfc_version | cisco.nac_dc_vxlan.version_compare('12.2.2', '>=') %} - STP_ROOT_OPTION: {{ global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol) }} -{% if global.spanning_tree.root_bridge_protocol is defined and global.spanning_tree.root_bridge_protocol != 'unmanaged' %} -{% if (global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol)) == 'rpvst+' %} - STP_VLAN_RANGE: {{ ndfc_utils.convert_ranges(global.spanning_tree.vlan_range, defaults.vxlan.global.spanning_tree.vlan_range) }} -{% elif (global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol)) == 'mst' %} - MST_INSTANCE_RANGE: {{ ndfc_utils.convert_ranges(global.spanning_tree.mst_instance_range, defaults.vxlan.global.spanning_tree.mst_instance_range) }} + STP_ROOT_OPTION: {{ vxlan.global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol) }} +{% if vxlan.global.spanning_tree.root_bridge_protocol is defined and global.spanning_tree.root_bridge_protocol != 'unmanaged' %} +{% if (vxlan.global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol)) == 'rpvst+' %} + STP_VLAN_RANGE: {{ ndfc_utils.convert_ranges(vxlan.global.spanning_tree.vlan_range, defaults.vxlan.global.spanning_tree.vlan_range) }} +{% elif (vxlan.global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol)) == 'mst' %} + MST_INSTANCE_RANGE: {{ ndfc_utils.convert_ranges(vxlan.global.spanning_tree.mst_instance_range, defaults.vxlan.global.spanning_tree.mst_instance_range) }} {% endif %} - STP_BRIDGE_PRIORITY: {{ global.spanning_tree.bridge_priority | default(defaults.vxlan.global.spanning_tree.bridge_priority) }} + STP_BRIDGE_PRIORITY: {{ vxlan.global.spanning_tree.bridge_priority | default(defaults.vxlan.global.spanning_tree.bridge_priority) }} {% endif %} {% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 index ef4f95fb..fa2fd4e5 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 @@ -1,6 +1,6 @@ {# Auto-generated NDFC DC VXLAN EVPN Base config data structure for fabric {{ vxlan.global.name }} #} -- FABRIC_NAME: {{ global.name }} - FABRIC_TYPE: {{ fabric_type }} +- FABRIC_NAME: {{ vxlan.fabric.name }} + FABRIC_TYPE: {{ vxlan.fabric.type }} DEPLOY: True {# Include NDFC DC VXLAN EVPN General Template #} diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index f90755d4..a80afd39 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -21,16 +21,16 @@ --- +- name: Import MSD Role Tasks + ansible.builtin.import_tasks: sub_main_vxlan.yml + when: + - MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' + - changes_detected_fabric or changes_detected_inventory or changes_detected_vpc_peering or changes_detected_interfaces or changes_detected_link_vpc_peering or changes_detected_vrfs or changes_detected_networks or changes_detected_policy + - name: Import VxLAN Role Tasks ansible.builtin.import_tasks: sub_main_msd.yml when: MD_Extended.vxlan.fabric_type == 'MSD' -# - name: Import MSD Role Tasks -# ansible.builtin.import_tasks: sub_main_vxlan.yml -# when: -# - MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' -# - changes_detected_fabric or changes_detected_inventory or changes_detected_vpc_peering or changes_detected_interfaces or changes_detected_link_vpc_peering or changes_detected_vrfs or changes_detected_networks or changes_detected_policy - - name: Mark Stage Role Create Completed cisco.nac_dc_vxlan.common.run_map: stage: role_create_completed diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index dfe2e5ad..076326ad 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -35,7 +35,8 @@ - name: Create NDFC MSD Fabric ansible.builtin.import_tasks: msd/fabric.yml when: - - MD_Extended.vxlan.multisite is defined + - MD_Extended.vxlan.name is defined + - MD_Extended.vxlan.fabric_type == "MSD" - changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" diff --git a/roles/validate/files/rules/enhanced_rules/.gitkeep b/roles/validate/files/rules/common/.gitkeep similarity index 100% rename from roles/validate/files/rules/enhanced_rules/.gitkeep rename to roles/validate/files/rules/common/.gitkeep diff --git a/roles/validate/files/rules/required_rules/.gitkeep b/roles/validate/files/rules/multisite/.gitkeep similarity index 100% rename from roles/validate/files/rules/required_rules/.gitkeep rename to roles/validate/files/rules/multisite/.gitkeep diff --git a/roles/validate/files/rules/required_rules/vxlan/.gitkeep b/roles/validate/files/rules/required_rules/vxlan/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/roles/validate/files/rules/required_rules/msd/.gitkeep b/roles/validate/files/rules/vxlan/.gitkeep similarity index 100% rename from roles/validate/files/rules/required_rules/msd/.gitkeep rename to roles/validate/files/rules/vxlan/.gitkeep diff --git a/roles/validate/files/rules/required_rules/vxlan/201_global_spanning_tree.py b/roles/validate/files/rules/vxlan/201_global_spanning_tree.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/201_global_spanning_tree.py rename to roles/validate/files/rules/vxlan/201_global_spanning_tree.py diff --git a/roles/validate/files/rules/required_rules/vxlan/202_global_underlay_mcast_trm.py b/roles/validate/files/rules/vxlan/202_global_underlay_mcast_trm.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/202_global_underlay_mcast_trm.py rename to roles/validate/files/rules/vxlan/202_global_underlay_mcast_trm.py diff --git a/roles/validate/files/rules/required_rules/vxlan/203_global_underlay_isis.py b/roles/validate/files/rules/vxlan/203_global_underlay_isis.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/203_global_underlay_isis.py rename to roles/validate/files/rules/vxlan/203_global_underlay_isis.py diff --git a/roles/validate/files/rules/required_rules/vxlan/301_topology_switch_serial.py b/roles/validate/files/rules/vxlan/301_topology_switch_serial.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/301_topology_switch_serial.py rename to roles/validate/files/rules/vxlan/301_topology_switch_serial.py diff --git a/roles/validate/files/rules/required_rules/vxlan/302_topology_switch_management.py b/roles/validate/files/rules/vxlan/302_topology_switch_management.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/302_topology_switch_management.py rename to roles/validate/files/rules/vxlan/302_topology_switch_management.py diff --git a/roles/validate/files/rules/required_rules/vxlan/303_topology_switch_role.py b/roles/validate/files/rules/vxlan/303_topology_switch_role.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/303_topology_switch_role.py rename to roles/validate/files/rules/vxlan/303_topology_switch_role.py diff --git a/roles/validate/files/rules/required_rules/vxlan/304_topology_switch_interfaces_members_unique.py b/roles/validate/files/rules/vxlan/304_topology_switch_interfaces_members_unique.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/304_topology_switch_interfaces_members_unique.py rename to roles/validate/files/rules/vxlan/304_topology_switch_interfaces_members_unique.py diff --git a/roles/validate/files/rules/required_rules/vxlan/305_topology_switch_interfaces_vpc.py b/roles/validate/files/rules/vxlan/305_topology_switch_interfaces_vpc.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/305_topology_switch_interfaces_vpc.py rename to roles/validate/files/rules/vxlan/305_topology_switch_interfaces_vpc.py diff --git a/roles/validate/files/rules/required_rules/vxlan/401_overlay_services_cross_reference.py b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py similarity index 65% rename from roles/validate/files/rules/required_rules/vxlan/401_overlay_services_cross_reference.py rename to roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py index a368d6ad..b4e0f9f7 100644 --- a/roles/validate/files/rules/required_rules/vxlan/401_overlay_services_cross_reference.py +++ b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py @@ -14,6 +14,12 @@ def match(cls, inventory): vrf_attach_groups = None switch_keys = ['vxlan', 'topology', 'switches'] + network_keys = ['vxlan', 'overlay', 'networks'] + vrf_keys = ['vxlan', 'overlay', 'vrfs'] + network_attach_keys = ['vxlan', 'overlay', 'network_attach_groups'] + vrf_attach_keys = ['vxlan', 'overlay', 'vrf_attach_groups'] + + # For backwards compatibility network_keys = ['vxlan', 'overlay_services', 'networks'] vrf_keys = ['vxlan', 'overlay_services', 'vrfs'] network_attach_keys = ['vxlan', 'overlay_services', 'network_attach_groups'] @@ -46,6 +52,41 @@ def match(cls, inventory): # Ensure Network is not referencing a VRF that is not defined in the service model results = cls.cross_reference_vrfs_nets(sm_vrfs, sm_networks, results) + if sm_vrfs and vrf_attach_groups: + results = cls.cross_reference_switches(vrf_attach_groups, switches, 'vrf', results) + if sm_networks and network_attach_groups: + results = cls.cross_reference_switches(network_attach_groups, switches, 'network', results) + + # For backwards compatibility + sm_networks = None + sm_vrfs = None + network_attach_groups = None + vrf_attach_groups = None + + network_keys = ['vxlan', 'overlay_services', 'networks'] + vrf_keys = ['vxlan', 'overlay_services', 'vrfs'] + network_attach_keys = ['vxlan', 'overlay_services', 'network_attach_groups'] + vrf_attach_keys = ['vxlan', 'overlay_services', 'vrf_attach_groups'] + + check = cls.data_model_key_check(inventory, network_keys) + if 'networks' in check['keys_data']: + sm_networks = cls.safeget(inventory, network_keys) + + check = cls.data_model_key_check(inventory, vrf_keys) + if 'vrfs' in check['keys_data']: + sm_vrfs = cls.safeget(inventory, vrf_keys) + + check = cls.data_model_key_check(inventory, vrf_attach_keys) + if 'vrf_attach_groups' in check['keys_data']: + vrf_attach_groups = cls.safeget(inventory, vrf_attach_keys) + + check = cls.data_model_key_check(inventory, network_attach_keys) + if 'network_attach_groups' in check['keys_data']: + network_attach_groups = cls.safeget(inventory, network_attach_keys) + + # Ensure Network is not referencing a VRF that is not defined in the service model + results = cls.cross_reference_vrfs_nets(sm_vrfs, sm_networks, results) + if sm_vrfs and vrf_attach_groups: results = cls.cross_reference_switches(vrf_attach_groups, switches, 'vrf', results) if sm_networks and network_attach_groups: @@ -94,11 +135,11 @@ def cross_reference_vrfs_nets(cls, sm_vrfs, sm_networks, results): for net in sm_networks: if net.get("vrf_name") is not None: if net.get("vrf_name") not in vrf_names: - msg1 = "Network ({0}) is referencing VRF ({1})" - msg2 = " which is not defined in the service model. Add the VRF to the service model or remove the network from the service model" - results.append(msg1.format(net.get("name"), net.get("vrf_name"))) - results.append(msg2) - results.append(" and re-run the playbook") + results.append( + f"Network ({net.get('name')}) is referencing VRF ({net.get('vrf_name')}) " + "which is not defined in the service model. Add the VRF to the service model or remove the network from the service model " + "and re-run the playbook." + ) return results @@ -113,6 +154,6 @@ def cross_reference_switches(cls, attach_groups, switches, target, results): if not any(s.get('management').get('management_ipv6_address') == switch.get("hostname") for s in switches): ag = attach_group.get("name") hn = switch.get("hostname") - results.append("{0} attach group {1} hostname {2} does not match any switch in the topology".format(target, ag, hn)) + results.append(f"{target} attach group {ag} hostname {hn} does not match any switch in the topology.") return results diff --git a/roles/validate/files/rules/required_rules/vxlan/402_overlay_services_vrfs.py b/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py similarity index 66% rename from roles/validate/files/rules/required_rules/vxlan/402_overlay_services_vrfs.py rename to roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py index 714bd98b..a64bc7bd 100644 --- a/roles/validate/files/rules/required_rules/vxlan/402_overlay_services_vrfs.py +++ b/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py @@ -19,16 +19,18 @@ def match(cls, inventory): if inventory["vxlan"].get("underlay").get("multicast", None): fabric_trm_status = inventory["vxlan"]["underlay"]["multicast"].get("trm_enable", False) - if inventory["vxlan"].get("overlay_services", None): - if inventory["vxlan"].get("overlay_services").get("vrfs", None): - vrfs = inventory["vxlan"]["overlay_services"]["vrfs"] + if inventory["vxlan"].get("overlay", None) or inventory["vxlan"].get("overlay_services", None): + if inventory["vxlan"].get("overlay").get("vrfs", None): + vrfs = inventory["vxlan"]["overlay"]["vrfs"] + elif inventory["vxlan"].get("overlay_services").get("vrfs", None): + vrfs = inventory["vxlan"]["overlay_services"]["vrfs"] for vrf in vrfs: current_vrf_netflow_status = vrf.get("netflow_enable", None) if current_vrf_netflow_status is not None: if fabric_netflow_status is False and current_vrf_netflow_status is True: results.append( - f"For vxlan.overlay_services.vrfs.{vrf['name']}.netflow_enable to be enabled, " + f"For vxlan.overlay.vrfs.{vrf['name']}.netflow_enable to be enabled, " f"first vxlan.global.netflow.enable must be enabled (true)." ) break @@ -37,8 +39,8 @@ def match(cls, inventory): current_vrf_netflow_monitor = vrf.get("netflow_monitor", None) if current_vrf_netflow_monitor is None: results.append( - f"When vxlan.overlay_services.vrfs.{vrf['name']}.netflow_enable is enabled, " - f"then vxlan.overlay_services.vrfs.{vrf['name']}.netflow_monitor must be set " + f"When vxlan.overlay.vrfs.{vrf['name']}.netflow_enable is enabled, " + f"then vxlan.overlay.vrfs.{vrf['name']}.netflow_monitor must be set " "to a valid value from vxlan.global.netflow." ) break @@ -47,7 +49,7 @@ def match(cls, inventory): if current_vrf_trm_status is not None: if fabric_trm_status is False and current_vrf_trm_status is True: results.append( - f"For vxlan.overlay_services.vrfs.{vrf['name']}.trm_enable to be enabled, " + f"For vxlan.overlay.vrfs.{vrf['name']}.trm_enable to be enabled, " f"first vxlan.underlay.multicast.trm_enable must be enabled (true)." ) break @@ -62,8 +64,8 @@ def match(cls, inventory): if fabric_trm_status: if current_vrf_trm_no_rp and current_vrf_trm_underlay_mcast_ip is None: results.append( - f"When vxlan.overlay_services.vrfs.{vrf['name']}.no_rp is enabled (true), " - f"then vxlan.overlay_services.vrfs.{vrf['name']}.underlay_mcast_ip must be set." + f"When vxlan.overlay.vrfs.{vrf['name']}.no_rp is enabled (true), " + f"then vxlan.overlay.vrfs.{vrf['name']}.underlay_mcast_ip must be set." ) break @@ -72,27 +74,27 @@ def match(cls, inventory): current_vrf_trm_no_rp and current_vrf_trm_rp_loopback_id or current_vrf_trm_no_rp and current_vrf_trm_overlay_multicast_group): results.append( - f"When vxlan.overlay_services.vrfs.{vrf['name']}.no_rp is enabled (true), " - f"then vxlan.overlay_services.vrfs.{vrf['name']}.rp_external, " - f"vxlan.overlay_services.vrfs.{vrf['name']}.rp_address, " - f"vxlan.overlay_services.vrfs.{vrf['name']}.rp_loopback_id, " - f"vxlan.overlay_services.vrfs.{vrf['name']}.overlay_multicast_group must be disabled (false)." + f"When vxlan.overlay.vrfs.{vrf['name']}.no_rp is enabled (true), " + f"then vxlan.overlay.vrfs.{vrf['name']}.rp_external, " + f"vxlan.overlay.vrfs.{vrf['name']}.rp_address, " + f"vxlan.overlay.vrfs.{vrf['name']}.rp_loopback_id, " + f"vxlan.overlay.vrfs.{vrf['name']}.overlay_multicast_group must be disabled (false)." ) break if current_vrf_trm_rp_external and current_vrf_trm_rp_loopback_id: results.append( - f"When vxlan.overlay_services.vrfs.{vrf['name']}.rp_external is enabled (true), " - f"then vxlan.overlay_services.vrfs.{vrf['name']}.rp_loopback_id must be disabled (false)." + f"When vxlan.overlay.vrfs.{vrf['name']}.rp_external is enabled (true), " + f"then vxlan.overlay.vrfs.{vrf['name']}.rp_loopback_id must be disabled (false)." ) break if (current_vrf_trm_rp_external and current_vrf_trm_rp_address is None or current_vrf_trm_rp_external and current_vrf_trm_underlay_mcast_ip is None): results.append( - f"When vxlan.overlay_services.vrfs.{vrf['name']}.rp_external is enabled (true), " - f"then vxlan.overlay_services.vrfs.{vrf['name']}.rp_address and " - f"vxlan.overlay_services.vrfs.{vrf['name']}.underlay_mcast_ip must be set." + f"When vxlan.overlay.vrfs.{vrf['name']}.rp_external is enabled (true), " + f"then vxlan.overlay.vrfs.{vrf['name']}.rp_address and " + f"vxlan.overlay.vrfs.{vrf['name']}.underlay_mcast_ip must be set." ) break diff --git a/roles/validate/files/rules/required_rules/vxlan/403_overlay_services_networks.py b/roles/validate/files/rules/vxlan/403_overlay_services_networks.py similarity index 74% rename from roles/validate/files/rules/required_rules/vxlan/403_overlay_services_networks.py rename to roles/validate/files/rules/vxlan/403_overlay_services_networks.py index 1c2e27b0..97348cd9 100644 --- a/roles/validate/files/rules/required_rules/vxlan/403_overlay_services_networks.py +++ b/roles/validate/files/rules/vxlan/403_overlay_services_networks.py @@ -21,8 +21,10 @@ def match(cls, inventory): fabric_trm_status = inventory["vxlan"]["underlay"]["multicast"].get("trm_enable", False) if inventory.get("vxlan", None): - if inventory["vxlan"].get("overlay_services", None): - if inventory["vxlan"].get("overlay_services").get("networks", None): + if inventory["vxlan"].get("overlay", None) or inventory["vxlan"].get("overlay_services", None): + if inventory["vxlan"].get("overlay").get("networks", None): + networks = inventory["vxlan"]["overlay"]["networks"] + elif inventory["vxlan"].get("overlay_services").get("networks", None): networks = inventory["vxlan"]["overlay_services"]["networks"] for network in networks: @@ -30,7 +32,7 @@ def match(cls, inventory): if current_network_netflow_status is not None: if fabric_netflow_status is False and current_network_netflow_status is True: results.append( - f"For vxlan.overlay_services.networks.{network['name']}.netflow_enable to be enabled, " + f"For vxlan.overlay.networks.{network['name']}.netflow_enable to be enabled, " f"first vxlan.global.netflow.enable must be enabled (true)." ) break @@ -39,8 +41,8 @@ def match(cls, inventory): current_network_netflow_monitor = network.get("vlan_netflow_monitor", None) if current_network_netflow_monitor is None: results.append( - f"When vxlan.overlay_services.networks.{network['name']}.netflow_enable is enabled, " - f"then vxlan.overlay_services.networks.{network['name']}.vlan_netflow_monitor must be set " + f"When vxlan.overlay.networks.{network['name']}.netflow_enable is enabled, " + f"then vxlan.overlay.networks.{network['name']}.vlan_netflow_monitor must be set " "to a valid value from vxlan.global.netflow." ) break @@ -49,7 +51,7 @@ def match(cls, inventory): if current_network_trm_status is not None: if fabric_trm_status is False and current_network_trm_status is True: results.append( - f"For vxlan.overlay_services.networks.{network['name']}.trm_enable to be enabled, " + f"For vxlan.overlay.networks.{network['name']}.trm_enable to be enabled, " f"first vxlan.underlay.multicast.trm_enable must be enabled (true)." ) break diff --git a/roles/validate/files/rules/required_rules/vxlan/501_policy_cross_reference.py b/roles/validate/files/rules/vxlan/501_policy_cross_reference.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/501_policy_cross_reference.py rename to roles/validate/files/rules/vxlan/501_policy_cross_reference.py diff --git a/roles/validate/files/rules/required_rules/vxlan/502_policy_vrf_lite_cross_reference.py b/roles/validate/files/rules/vxlan/502_policy_vrf_lite_cross_reference.py similarity index 100% rename from roles/validate/files/rules/required_rules/vxlan/502_policy_vrf_lite_cross_reference.py rename to roles/validate/files/rules/vxlan/502_policy_vrf_lite_cross_reference.py diff --git a/roles/validate/tasks/main.yml b/roles/validate/tasks/main.yml index db816574..9d6e722c 100644 --- a/roles/validate/tasks/main.yml +++ b/roles/validate/tasks/main.yml @@ -22,19 +22,9 @@ --- - debug: msg="{{ nac_tags.all }}" -- name: Import Common Pre Role Tasks - ansible.builtin.import_tasks: sub_main_common_pre.yml +- name: Import Role Tasks + ansible.builtin.import_tasks: sub_main.yml tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml - -- name: Import MSD Fabric Role Tasks - ansible.builtin.import_tasks: sub_main_msd.yml - tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml - when: MD_Extended.vxlan.fabric_type == 'MSD' - -- name: Import VxLAN Fabric Role Tasks - ansible.builtin.import_tasks: sub_main_vxlan.yml - tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml - when: MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' # Problems with lower versions of python and ansible # Python 3.9.16 and Ansible 7.3.0 (Ansible-Core 2.14.4) # Could ignore errors and try again with tags specified as below as a work around ... @@ -57,16 +47,8 @@ # - role_deploy # - role_remove -- name: Import Common Post Role Tasks - ansible.builtin.import_tasks: sub_main_common_post.yml - tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml - - name: Mark Stage Role Validate Completed cisco.nac_dc_vxlan.common.run_map: stage: role_validate_completed register: run_map delegate_to: localhost - -- debug: msg="{{ MD }}" - -- debug: msg="{{ MD_Extended }}" \ No newline at end of file diff --git a/roles/validate/tasks/sub_main.yml b/roles/validate/tasks/sub_main.yml new file mode 100644 index 00000000..1d251656 --- /dev/null +++ b/roles/validate/tasks/sub_main.yml @@ -0,0 +1,152 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Role Entry Point - [cisco.nac_dc_vxlan.validate] + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Calling Role - [cisco.nac_dc_vxlan.validate] +" + - "----------------------------------------------------------------" + +- ansible.builtin.debug: msg="Role Path - {{ role_path }}" + +- ansible.builtin.debug: msg="Inventory Directory - {{ inventory_dir }}" + +- name: Validate NDFC Service Model Data + ansible.builtin.debug: msg="Calling Role Validate - nac_dc_vxlan.validate" + +- ansible.builtin.debug: msg="Workflow is Direct to Device (DTD)" + when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.nxos.nxos" + +- ansible.builtin.debug: msg="Workflow is Direct to Controller (DTC)" + when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.dcnm.dcnm" + +- name: Check for Schema Path Being Defined + ansible.builtin.set_fact: + schema_path: '' + when: schema_path is not defined + delegate_to: localhost + +- name: Check for Enhanced Roles Path Being Defined + ansible.builtin.set_fact: + enhanced_rules_path: '' + when: enhanced_rules_path is not defined + delegate_to: localhost + +- name: Perform Required Syntax and Semantic Model Validation + cisco.nac_dc_vxlan.common.nac_dc_validate: + schema: "{{ schema_path }}" + mdata: "{{ data_path }}" + rules: "{{ rules_path }}" + register: model_data + vars: + data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" + rules_path: "{{ role_path }}/files/rules/" + delegate_to: localhost + +- name: Perform Custom Enhanced Syntax and Semantic Model Validation + cisco.nac_dc_vxlan.common.nac_dc_validate: + schema: "{{ schema_path }}" + mdata: "{{ data_path }}" + rules: "{{ enhanced_rules_path }}" + vars: + data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" + when: enhanced_rules_path is defined and enhanced_rules_path + delegate_to: localhost + +- name: Stat Factory Defaults + ansible.builtin.stat: path="{{ role_path }}/files/defaults.yml" + register: factory_defaults_file + delegate_to: localhost + +- name: Include Factory Defaults if Available + ansible.builtin.include_vars: + file: "{{ role_path }}/files/defaults.yml" + when: factory_defaults_file.stat.exists + delegate_to: localhost + +- name: Merge factory and custom defaults + cisco.nac_dc_vxlan.common.merge_defaults: + factory_defaults: "{{ factory_defaults }}" + model_data: "{{ model_data['data'] }}" + register: defaults + delegate_to: localhost + +- name: Register Variable With Only Defaults from Previous Task + ansible.builtin.set_fact: + defaults: "{{ defaults['defaults'] }}" + delegate_to: localhost + +- name: Prepare Service Model + cisco.nac_dc_vxlan.common.prepare_service_model: + inventory_hostname: "{{ inventory_hostname }}" + hostvars: "{{ hostvars }}" + model_data: "{{ model_data['data'] }}" + default_values: "{{ defaults }}" + templates_path: "{{ role_path }}/../dtc/common/templates/" + register: smd + delegate_to: localhost + +- ansible.builtin.meta: end_play + +- name: Store Golden Service Model Data + ansible.builtin.set_fact: + MD: "{{ smd['model_golden'] }}" + delegate_to: localhost + +- name: Store Extended Service Model Data + ansible.builtin.set_fact: + MD_Extended: "{{ smd['model_extended'] }}" + delegate_to: localhost + +- name: Check Roles + cisco.nac_dc_vxlan.common.check_roles: + role_list: "{{ role_names }}" + register: check_roles + delegate_to: localhost + +- name: Read Run Map From Previous Run + cisco.nac_dc_vxlan.common.read_run_map: + model_data: "{{ MD_Extended }}" + register: run_map_read_result + delegate_to: localhost + +- name: Debug Run Map Read Result + ansible.builtin.debug: + msg: "{{ run_map_read_result }}" + delegate_to: localhost + +- name: Initialize Run Map + cisco.nac_dc_vxlan.common.run_map: + model_data: "{{ MD_Extended }}" + stage: starting_execution + register: run_map + delegate_to: localhost + +- name: Manage Previous Service Model Data Files + ansible.builtin.include_tasks: manage_model_files_previous.yml + when: check_roles['save_previous'] + +- name: Manage Current Service Model Data Files + ansible.builtin.include_tasks: manage_model_files_current.yml + when: check_roles['save_previous'] diff --git a/roles/validate/tasks/sub_main_vxlan.yml b/roles/validate/tasks/sub_main_vxlan.yml index c14bef23..75c64515 100644 --- a/roles/validate/tasks/sub_main_vxlan.yml +++ b/roles/validate/tasks/sub_main_vxlan.yml @@ -28,5 +28,5 @@ rules: "{{ rules_path }}" vars: data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - rules_path: "{{ role_path }}/files/rules/required_rules/vxlan/" + rules_path: "{{ role_path }}/files/rules/" delegate_to: localhost From f8217798e120adc3f36d6c465a1407dadd99877c Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Wed, 4 Dec 2024 22:19:46 -0500 Subject: [PATCH 16/66] updates for build and deployment of both single fabrics and msd fabrics --- .../common/prepare_plugins/prep_101_fabric.py | 117 +++++++++--------- .../prep_104_fabric_overlay_services.py | 12 +- plugins/action/common/read_run_map.py | 4 +- plugins/action/common/run_map.py | 5 +- roles/dtc/common/tasks/main.yml | 4 +- .../common/tasks/{ => msd}/ndfc_fabric.yml | 8 +- roles/dtc/common/tasks/sub_main_msd.yml | 2 +- roles/dtc/common/tasks/sub_main_vxlan.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_fabric.yml | 77 ++++++++++++ .../common/templates/ndfc_attach_networks.j2 | 34 +++-- .../dtc/common/templates/ndfc_attach_vrfs.j2 | 46 ++++--- roles/dtc/common/templates/ndfc_fabric.j2 | 8 +- .../advanced/dc_vxlan_fabric_advanced.j2 | 4 +- .../bootstrap/dc_vxlan_fabric_bootstrap.j2 | 26 ++-- .../dc_vxlan_fabric/dc_vxlan_fabric_base.j2 | 2 +- .../dc_vxlan_fabric_flow_monitor.j2 | 18 +-- .../general/dc_vxlan_fabric_general.j2 | 8 +- .../dc_vxlan_fabric_manageability.j2 | 14 +-- .../protocols/dc_vxlan_fabric_protocols.j2 | 2 +- .../dc_vxlan_fabric_replication.j2 | 2 +- .../resources/dc_vxlan_fabric_resources.j2 | 2 +- .../security/dc_vxlan_fabric_security.j2 | 2 +- .../vpc/dc_vxlan_fabric_vpc.j2 | 22 ++-- .../msd_fabric/dci/msd_fabric_dci.j2 | 2 +- .../msd_fabric/general/msd_fabric_general.j2 | 4 +- .../ndfc_fabric/msd_fabric/msd_fabric_base.j2 | 4 +- .../resources/msd_fabric_resources.j2 | 2 +- .../security/msd_fabric_security.j2 | 2 +- .../templates/ndfc_links_vpc_peering.j2 | 2 +- roles/dtc/create/tasks/main.yml | 9 +- roles/dtc/create/tasks/msd/child_fabrics.yml | 6 +- roles/dtc/create/tasks/msd/fabric.yml | 4 +- roles/dtc/create/tasks/sub_main_msd.yml | 4 +- roles/dtc/create/tasks/sub_main_vxlan.yml | 2 + roles/dtc/create/tasks/vxlan/devices.yml | 2 +- .../create/tasks/vxlan/devices_discovery.yml | 4 +- roles/dtc/create/tasks/vxlan/fabric.yml | 4 +- roles/dtc/create/tasks/vxlan/interfaces.yml | 20 +-- roles/dtc/create/tasks/vxlan/policies.yml | 4 +- roles/dtc/create/tasks/vxlan/vpc_peering.yml | 6 +- .../dtc/create/tasks/vxlan/vrfs_networks.yml | 6 +- roles/dtc/deploy/tasks/main.yml | 1 + roles/dtc/deploy/tasks/sub_main.yml | 8 +- roles/dtc/remove/tasks/main.yml | 14 ++- roles/dtc/remove/tasks/msd/.gitkeep | 0 .../tasks/sub_main_msd.yml} | 9 -- .../{sub_main.yml => sub_main_vxlan.yml} | 16 +-- roles/dtc/remove/tasks/vxlan/.gitkeep | 0 .../remove/tasks/{ => vxlan}/interfaces.yml | 2 +- roles/dtc/remove/tasks/{ => vxlan}/links.yml | 2 +- .../dtc/remove/tasks/{ => vxlan}/networks.yml | 2 +- roles/dtc/remove/tasks/{ => vxlan}/policy.yml | 2 +- .../dtc/remove/tasks/{ => vxlan}/switches.yml | 2 +- .../remove/tasks/{ => vxlan}/vpc_peers.yml | 2 +- roles/dtc/remove/tasks/{ => vxlan}/vrfs.yml | 2 +- roles/validate/files/defaults.yml | 2 +- roles/validate/tasks/main.yml | 1 + .../tasks/manage_model_files_current.yml | 6 +- .../tasks/manage_model_files_previous.yml | 10 +- roles/validate/tasks/sub_main.yml | 2 - roles/validate/tasks/sub_main_common_post.yml | 54 -------- roles/validate/tasks/sub_main_common_pre.yml | 90 -------------- roles/validate/tasks/sub_main_msd.yml | 32 ----- roles/validate/tasks/sub_main_vxlan.yml | 32 ----- 64 files changed, 338 insertions(+), 461 deletions(-) rename roles/dtc/common/tasks/{ => msd}/ndfc_fabric.yml (90%) create mode 100644 roles/dtc/common/tasks/vxlan/ndfc_fabric.yml create mode 100644 roles/dtc/remove/tasks/msd/.gitkeep rename roles/dtc/{create/tasks/vxlan/reset.yml => remove/tasks/sub_main_msd.yml} (79%) rename roles/dtc/remove/tasks/{sub_main.yml => sub_main_vxlan.yml} (86%) create mode 100644 roles/dtc/remove/tasks/vxlan/.gitkeep rename roles/dtc/remove/tasks/{ => vxlan}/interfaces.yml (98%) rename roles/dtc/remove/tasks/{ => vxlan}/links.yml (96%) rename roles/dtc/remove/tasks/{ => vxlan}/networks.yml (97%) rename roles/dtc/remove/tasks/{ => vxlan}/policy.yml (98%) rename roles/dtc/remove/tasks/{ => vxlan}/switches.yml (97%) rename roles/dtc/remove/tasks/{ => vxlan}/vpc_peers.yml (97%) rename roles/dtc/remove/tasks/{ => vxlan}/vrfs.yml (97%) delete mode 100644 roles/validate/tasks/sub_main_common_post.yml delete mode 100644 roles/validate/tasks/sub_main_common_pre.yml delete mode 100644 roles/validate/tasks/sub_main_msd.yml delete mode 100644 roles/validate/tasks/sub_main_vxlan.yml diff --git a/plugins/action/common/prepare_plugins/prep_101_fabric.py b/plugins/action/common/prepare_plugins/prep_101_fabric.py index d87085e2..e1dce5c4 100644 --- a/plugins/action/common/prepare_plugins/prep_101_fabric.py +++ b/plugins/action/common/prepare_plugins/prep_101_fabric.py @@ -33,77 +33,72 @@ def __init__(self, **kwargs): def prepare(self): model_data = self.kwargs['results']['model_extended'] + # Checking for fabric key in the data model. + # This type of check should be done in a rule, but fabric.name and fabric.type are foundational for the collection so we need to ensure it is set. + # This prepare plugin also helps retain backwards compatibility with global.name and global.fabric_type keys previously used. parent_keys = ['vxlan', 'fabric'] dm_check = data_model_key_check(model_data, parent_keys) if 'fabric' in dm_check['keys_not_found'] or 'fabric' in dm_check['keys_no_data']: display.deprecated( - "Attempting to use vxlan.global.name and vxlan.global.fabric_type due to vxlan.fabric.name and vxlan.fabric.type not being found. " + "Attempting to use vxlan.global.name and vxlan.global.fabric_type due to vxlan.fabric.name and vxlan.fabric.type not being defined. " "vxlan.global.name and vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric." ) - # Prepare the data model to ensure vxlan.fabric.name is set - # global_data_check = False - # parent_keys = ['vxlan', 'global'] - # dm_check = data_model_key_check(model_data, parent_keys) - # if 'global' in dm_check['keys_found'] and 'global' in dm_check['keys_data']: - # parent_keys = ['vxlan', 'global', 'name'] - # dm_check = data_model_key_check(model_data, parent_keys) - # if 'name' in dm_check['keys_found'] and 'name' in dm_check['keys_data']: - # model_data['vxlan']['fabric']['name'] = model_data['vxlan']['global']['name'] - # else: - # global_data_check = True - - # parent_keys = ['vxlan', 'global', 'fabric_type'] - # dm_check = data_model_key_check(model_data, parent_keys) - # if 'fabric_type' in dm_check['keys_found'] and 'fabric_type' in dm_check['keys_data']: - # model_data['vxlan']['fabric']['type'] = model_data['vxlan']['global']['fabric_type'] - # else: - # self.kwargs['results']['failed'] = True - # self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data." - # global_data_check = True - # else: - # self.kwargs['results']['failed'] = True - # self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data." - - # if global_data_check: - # self.kwargs['results']['failed'] = True - # self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data." - # else: - # parent_keys = ['vxlan', 'fabric', 'name'] - # dm_check = data_model_key_check(model_data, parent_keys) - # if 'name' in dm_check['keys_no_data'] or 'name' in dm_check['keys_not_found']: - # parent_keys = ['vxlan', 'global', 'name'] - # dm_check = data_model_key_check(model_data, parent_keys) - # if 'name' in dm_check['keys_data']: - # # Insert warning about deprecation and where found - # model_data['vxlan']['fabric']['name'] = model_data['vxlan']['global']['name'] - # else: - # self.kwargs['results']['failed'] = True - # self.kwargs['results']['msg'] = "vxlan.fabric.name is not set in the model data." + parent_keys = ['vxlan', 'global'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'global' in dm_check['keys_found'] and 'global' in dm_check['keys_data']: + model_data['vxlan'].update({'fabric': {}}) + parent_keys = ['vxlan', 'global', 'name'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'name' in dm_check['keys_found'] and 'name' in dm_check['keys_data']: + model_data['vxlan']['fabric'].update({'name': model_data['vxlan']['global']['name']}) + else: + self.kwargs['results']['failed'] = True + self.kwargs['results']['msg'] = "vxlan.global.name is not defined in the data model. Please set vxlan.fabric.name." - # # Prepare the data model to ensure vxlan.fabric.type is set - # parent_keys = ['vxlan', 'fabric', 'type'] - # dm_check = data_model_key_check(model_data, parent_keys) - # if 'type' in dm_check['keys_no_data'] or 'name' in dm_check['keys_not_found']: - # parent_keys = ['vxlan', 'global', 'fabric_type'] - # dm_check = data_model_key_check(model_data, parent_keys) - # if 'fabric_type' in dm_check['keys_data']: - # # Insert warning about deprecation and where found - # model_data['vxlan']['fabric']['type'] = model_data['vxlan']['global']['fabric_type'] - # else: - # self.kwargs['results']['failed'] = True - # self.kwargs['results']['msg'] = "vxlan.fabric.type is not set in the model data." + parent_keys = ['vxlan', 'global', 'fabric_type'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'fabric_type' in dm_check['keys_found'] and 'fabric_type' in dm_check['keys_data']: + model_data['vxlan']['fabric'].update({'type': model_data['vxlan']['global']['fabric_type']}) + else: + self.kwargs['results']['failed'] = True + self.kwargs['results']['msg'] = "vxlan.global.fabric_type is not defined in the data model. Please set vxlan.fabric.type." + else: + self.kwargs['results']['failed'] = True + self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data." - # 1 - no fabric key data model - # 2a - fabric key data model with no data (i.e. no name or type) > semantic valdiation failure with schema - # 2b - fabric key data model with no data (i.e. name or type) > check if we have global name and global fabric_type - - - # insert comment to indicate this is a oneoff check for fabric key as this should really be done in a rule, - # but fabric name and key are foundational for the collection so we need to ensure it is set. - # this prepare plugin also helps retain backwards compatibility with the global fabric name and fabric_type keys previously used. + else: + # Prepare the data model to ensure vxlan.fabric.name is set + parent_keys = ['vxlan', 'fabric', 'name'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'name' in dm_check['keys_no_data'] or 'name' in dm_check['keys_not_found']: + display.deprecated( + "Attempting to use vxlan.global.name due to vxlan.fabric.name not being defined. " + "vxlan.global.name is being deprecated. Please use vxlan.fabric." + ) + parent_keys = ['vxlan', 'global', 'name'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'name' in dm_check['keys_data']: + model_data['vxlan']['fabric'].update({'name': model_data['vxlan']['global']['name']}) + else: + self.kwargs['results']['failed'] = True + self.kwargs['results']['msg'] = "vxlan.fabric.name is not defined in the data model." - # Prepare the data model to ensure vxlan.fabric.name is set + # Prepare the data model to ensure vxlan.fabric.type is set + parent_keys = ['vxlan', 'fabric', 'type'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'type' in dm_check['keys_no_data'] or 'type' in dm_check['keys_not_found']: + display.deprecated( + "Attempting to use vxlan.global.type due to vxlan.fabric.type not being defined. " + "vxlan.global.type is being deprecated. Please use vxlan.fabric." + ) + parent_keys = ['vxlan', 'global', 'fabric_type'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'fabric_type' in dm_check['keys_data']: + model_data['vxlan']['fabric'].update({'type': model_data['vxlan']['global']['fabric_type']}) + else: + self.kwargs['results']['failed'] = True + self.kwargs['results']['msg'] = "vxlan.fabric.type is not defined in the data model." self.kwargs['results']['model_extended'] = model_data return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py index ba0c320c..0fad465c 100644 --- a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py +++ b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py @@ -43,9 +43,9 @@ def prepare(self): if any(sw['name'] == switch['hostname'] for sw in switches): found_switch = next((item for item in switches if item["name"] == switch['hostname'])) if found_switch.get('management').get('management_ipv4_address'): - switch['hostname'] = found_switch['management']['management_ipv4_address'] + switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] elif found_switch.get('management').get('management_ipv6_address'): - switch['hostname'] = found_switch['management']['management_ipv6_address'] + switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] # Remove vrf_attach_group from vrf if the group_name is not defined for vrf in model_data['vxlan']['overlay']['vrfs']: @@ -67,9 +67,9 @@ def prepare(self): if any(sw['name'] == switch['hostname'] for sw in switches): found_switch = next((item for item in switches if item["name"] == switch['hostname'])) if found_switch.get('management').get('management_ipv4_address'): - switch['hostname'] = found_switch['management']['management_ipv4_address'] + switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] elif found_switch.get('management').get('management_ipv6_address'): - switch['hostname'] = found_switch['management']['management_ipv6_address'] + switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] # Remove network_attach_group from net if the group_name is not defined for net in model_data['vxlan']['overlay']['networks']: @@ -93,9 +93,9 @@ def prepare(self): if any(sw['name'] == switch['hostname'] for sw in switches): found_switch = next((item for item in switches if item["name"] == switch['hostname'])) if found_switch.get('management').get('management_ipv4_address'): - switch['hostname'] = found_switch['management']['management_ipv4_address'] + switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] elif found_switch.get('management').get('management_ipv6_address'): - switch['hostname'] = found_switch['management']['management_ipv6_address'] + switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] # Remove vrf_attach_group from vrf if the group_name is not defined for vrf in model_data['vxlan']['overlay_services']['vrfs']: diff --git a/plugins/action/common/read_run_map.py b/plugins/action/common/read_run_map.py index b7c24448..6f3de7b4 100644 --- a/plugins/action/common/read_run_map.py +++ b/plugins/action/common/read_run_map.py @@ -39,8 +39,8 @@ def run(self, tmp=None, task_vars=None): results = super(ActionModule, self).run(tmp, task_vars) results['diff_run'] = True - model_data = task_vars['model_data']['data'] - fabric_name = model_data["vxlan"]["name"] + model_data = self._task.args.get('model_data') + fabric_name = model_data['vxlan']['fabric']['name'] if 'dtc' in task_vars['role_path']: common_role_path = os.path.dirname(task_vars['role_path']) diff --git a/plugins/action/common/run_map.py b/plugins/action/common/run_map.py index 0d4a7f7e..a8460f47 100644 --- a/plugins/action/common/run_map.py +++ b/plugins/action/common/run_map.py @@ -41,9 +41,10 @@ def run(self, tmp=None, task_vars=None): results = super(ActionModule, self).run(tmp, task_vars) results['failed'] = False - model_data = task_vars['model_data']['data'] + model_data = self._task.args.get('model_data') stage = self._task.args['stage'] - fabric_name = model_data["vxlan"]["name"] + + fabric_name = model_data['vxlan']['fabric']['name'] if 'dtc' in task_vars['role_path']: common_role_path = os.path.dirname(task_vars['role_path']) diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index dda5ec0e..67293f41 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -24,9 +24,9 @@ - name: Import Role Tasks for VXLAN Fabric ansible.builtin.import_tasks: sub_main_vxlan.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml - when: MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' + when: MD_Extended.vxlan.fabric.type == 'VXLAN_EVPN' - name: Import Role Tasks for MSD Fabric ansible.builtin.import_tasks: sub_main_msd.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml - when: MD_Extended.vxlan.fabric_type == 'MSD' + when: MD_Extended.vxlan.fabric.type == 'MSD' diff --git a/roles/dtc/common/tasks/ndfc_fabric.yml b/roles/dtc/common/tasks/msd/ndfc_fabric.yml similarity index 90% rename from roles/dtc/common/tasks/ndfc_fabric.yml rename to roles/dtc/common/tasks/msd/ndfc_fabric.yml index bbfdba87..a6ed2eea 100644 --- a/roles/dtc/common/tasks/ndfc_fabric.yml +++ b/roles/dtc/common/tasks/msd/ndfc_fabric.yml @@ -28,12 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: >- - {% if MD.vxlan.name is defined and MD.vxlan.name %} - {{ MD.vxlan.name }}_ndfc_fabric.yml - {% elif MD.vxlan.global.name is defined and MD.vxlan.global.name %} - {{ MD.vxlan.global.name }}_ndfc_fabric.yml - {% endif %} + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_fabric.yml" delegate_to: localhost - name: Stat Previous File If It Exists @@ -64,7 +59,6 @@ - ansible.builtin.set_fact: fabric_config: "{{ lookup('file', file_name) | from_yaml }}" - when: MD.vxlan.global or MD.vxlan.multisite delegate_to: localhost - name: Diff Previous and Current Data Files diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 74306c00..4796d44f 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -38,7 +38,7 @@ # -------------------------------------------------------------------- - name: Build Fabric Create Parameters - ansible.builtin.include_tasks: ndfc_fabric.yml + ansible.builtin.include_tasks: msd/ndfc_fabric.yml # -------------------------------------------------------------------- # Build NDFC Child Fabric Inventory List From Template diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index dd01a62a..9029aa98 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -38,7 +38,7 @@ # -------------------------------------------------------------------- - name: Build Fabric Create Parameters - ansible.builtin.include_tasks: ndfc_fabric.yml + ansible.builtin.include_tasks: vxlan/ndfc_fabric.yml # -------------------------------------------------------------------- # Build NDFC Fabric Switch Inventory List From Template diff --git a/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml b/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml new file mode 100644 index 00000000..a6ed2eea --- /dev/null +++ b/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml @@ -0,0 +1,77 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_fabric: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_fabric.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + # TODO: Add capability to overridde path variable above for CI/CD pipeline + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Fabric Creation Parameters From Template + ansible.builtin.template: + src: ndfc_fabric.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- ansible.builtin.set_fact: + fabric_config: "{{ lookup('file', file_name) | from_yaml }}" + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_fabric: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] diff --git a/roles/dtc/common/templates/ndfc_attach_networks.j2 b/roles/dtc/common/templates/ndfc_attach_networks.j2 index 4be242a0..96742c99 100644 --- a/roles/dtc/common/templates/ndfc_attach_networks.j2 +++ b/roles/dtc/common/templates/ndfc_attach_networks.j2 @@ -2,12 +2,17 @@ # This NDFC networks and switch attachments config data structure is auto-generated # DO NOT EDIT MANUALLY # -{% for net in MD_Extended.vxlan.overlay_services.networks %} +{% if MD_Extended.vxlan.overlay.networks is defined and MD_Extended.vxlan.overlay.networks %} +{% set networks = MD_Extended.vxlan.overlay.networks %} +{% elif MD_Extended.vxlan.overlay_services.networks is defined and MD_Extended.vxlan.overlay_services.networks %} +{% set networks = MD_Extended.vxlan.overlay_services.networks %} +{% endif %} +{% for net in networks %} - net_name: {{ net['name'] }} {# ------------------------------------------------------ #} {# Properties Section #} {# ------------------------------------------------------ #} - is_l2only: {{ net['is_l2_only'] | default(defaults.vxlan.overlay_services.networks.is_l2_only) }} + 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) }} @@ -30,7 +35,7 @@ secondary_ip_gw4: {{ net['secondary_ip_addresses'][3]['ip_address'] }} {% endif %} {% endif %} - arp_suppress: {{ net['arp_suppress'] | default(defaults.vxlan.overlay_services.networks.arp_supress) }} + arp_suppress: {{ net['arp_suppress'] | default(defaults.vxlan.overlay.networks.arp_supress) }} dhcp_loopback_id: {{ net['dhcp_loopback_id'] | default(omit) }} {% if net.dhcp_servers is defined %} {% if net.dhcp_servers | length == 1 %} @@ -51,25 +56,30 @@ {% endif %} {% endif %} gw_ipv6_subnet: {{ net['gw_ipv6_address'] | default(omit) }} - int_desc: {{ net['int_desc'] | default(defaults.vxlan.overlay_services.networks.net_description) }} - l3gw_on_border: {{ net['l3gw_on_border'] | default(defaults.vxlan.overlay_services.networks.l3gw_on_border) }} - mtu_l3intf: {{ net['mtu_l3intf'] | default(defaults.vxlan.overlay_services.networks.mtu_l3intf) }} + int_desc: {{ net['int_desc'] | default(defaults.vxlan.overlay.networks.net_description) }} + l3gw_on_border: {{ net['l3gw_on_border'] | default(defaults.vxlan.overlay.networks.l3gw_on_border) }} + mtu_l3intf: {{ net['mtu_l3intf'] | default(defaults.vxlan.overlay.networks.mtu_l3intf) }} {% if (MD.vxlan.underlay.general.replication_mode | lower) == 'multicast' %} - multicast_group_address: {{ net['multicast_group_address'] | default(defaults.vxlan.overlay_services.networks.multicast_group_address) }} + multicast_group_address: {{ net['multicast_group_address'] | default(defaults.vxlan.overlay.networks.multicast_group_address) }} {% endif %} - netflow_enable: {{ net['netflow_enable'] | default(defaults.vxlan.overlay_services.networks.netflow_enable) }} + netflow_enable: {{ net['netflow_enable'] | default(defaults.vxlan.overlay.networks.netflow_enable) }} {% if net['netflow_enable'] is defined and net['netflow_enable'] | bool %} vlan_nf_monitor: {{ net['vlan_netflow_monitor'] | default(omit) }} {% endif %} - route_target_both: {{ net['route_target_both'] | default(defaults.vxlan.overlay_services.networks.route_target_both) }} - route_tag: {{ net['route_tag'] | default(defaults.vxlan.overlay_services.networks.route_tag) }} - trm_enable: {{ net['trm_enable'] | default(defaults.vxlan.overlay_services.networks.trm_enable) }} + route_target_both: {{ net['route_target_both'] | default(defaults.vxlan.overlay.networks.route_target_both) }} + route_tag: {{ net['route_tag'] | default(defaults.vxlan.overlay.networks.route_tag) }} + trm_enable: {{ net['trm_enable'] | default(defaults.vxlan.overlay.networks.trm_enable) }} {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} {% if net['network_attach_group'] is defined %} attach: -{% for attach in MD_Extended.vxlan.overlay_services.network_attach_groups_dict[net['network_attach_group']] %} +{% if MD_Extended.vxlan.overlay.network_attach_groups_dict is defined and MD_Extended.vxlan.overlay.network_attach_groups_dict %} +{% set network_attach_groups_dict = MD_Extended.vxlan.overlay.network_attach_groups_dict %} +{% elif MD_Extended.vxlan.overlay_services.network_attach_groups_dict is defined and MD_Extended.vxlan.overlay_services.network_attach_groups_dict %} +{% set network_attach_groups_dict = MD_Extended.vxlan.overlay_services.network_attach_groups_dict %} +{% endif %} +{% for attach in network_attach_groups_dict[net['network_attach_group']] %} - ip_address: {{ attach['mgmt_ip_address'] }} ports: {{ attach['ports'] }} {% endfor %} diff --git a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 index c3c1dc42..d3d40fa6 100644 --- a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 @@ -2,7 +2,12 @@ # This NDFC VRFs and switch attachments config data structure is auto-generated # DO NOT EDIT MANUALLY # -{% for vrf in MD_Extended.vxlan.overlay_services.vrfs %} +{% if MD_Extended.vxlan.overlay.vrfs is defined and MD_Extended.vxlan.overlay.vrfs %} +{% set vrfs = MD_Extended.vxlan.overlay.vrfs %} +{% elif MD_Extended.vxlan.overlay_services.vrfs is defined and MD_Extended.vxlan.overlay_services.vrfs %} +{% set vrfs = MD_Extended.vxlan.overlay_services.vrfs %} +{% endif %} +{% for vrf in vrfs %} - vrf_name: {{ vrf['name'] }} {# ------------------------------------------------------ #} {# Properties Section #} @@ -10,46 +15,51 @@ 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_services.vrfs.vrf_intf_desc) }} - vrf_description: {{ vrf['vrf_description'] | default(defaults.vxlan.overlay_services.vrfs.vrf_description) }} - vrf_int_mtu: {{ vrf['vrf_int_mtu'] | default(defaults.vxlan.overlay_services.vrfs.vrf_int_mtu) }} - loopback_route_tag: {{ vrf['loopback_route_tag'] | default(defaults.vxlan.overlay_services.vrfs.loopback_route_tag) }} - max_bgp_paths: {{ vrf['max_bgp_paths'] | default(defaults.vxlan.overlay_services.vrfs.max_bgp_paths) }} - max_ibgp_paths: {{ vrf['max_ibgp_paths'] | default(defaults.vxlan.overlay_services.vrfs.max_ibgp_paths) }} - ipv6_linklocal_enable: {{ vrf['ipv6_linklocal_enable'] | default(defaults.vxlan.overlay_services.vrfs.ipv6_linklocal_enable) }} - adv_host_routes: {{ vrf['adv_host_routes'] | default(defaults.vxlan.overlay_services.vrfs.adv_host_routes) }} - adv_default_routes: {{ vrf['adv_default_routes'] | default(defaults.vxlan.overlay_services.vrfs.adv_default_routes) }} - static_default_route: {{ vrf['static_default_route'] | default(defaults.vxlan.overlay_services.vrfs.static_default_route) }} + 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) }} + 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) }} - disable_rt_auto: {{ vrf['disable_rt_auto'] | default(defaults.vxlan.overlay_services.vrfs.disable_rt_auto) }} + 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_mvpn_rt: {{ vrf['export_mvpn_rt'] | default(omit) }} export_vpn_rt: {{ vrf['export_vpn_rt'] | default(omit) }} import_evpn_rt: {{ vrf['import_evpn_rt'] | default(omit) }} 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_services.vrfs.netflow_enable) }} + 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_services.vrfs.no_rp) }} - trm_enable: {{ vrf['trm_enable'] | default(defaults.vxlan.overlay_services.vrfs.trm_enable) }} + 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_services.vrfs.trm_bgw_msite) }} + 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 %} - redist_direct_rmap: {{ vrf['redist_direct_routemap'] | default(defaults.vxlan.overlay_services.vrfs.redist_direct_routemap) }} + redist_direct_rmap: {{ vrf['redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.redist_direct_routemap) }} {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} {% if vrf['vrf_attach_group'] is defined %} attach: -{% for attach in MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict[vrf['vrf_attach_group']] %} +{% if MD_Extended.vxlan.overlay.vrf_attach_groups_dict is defined and MD_Extended.vxlan.overlay.vrf_attach_groups_dict %} +{% set vrf_attach_groups_dict = MD_Extended.vxlan.overlay.vrf_attach_groups_dict %} +{% elif MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict is defined and MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict %} +{% set vrf_attach_groups_dict = MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict %} +{% endif %} +{% for attach in vrf_attach_groups_dict[vrf['vrf_attach_group']] %} - ip_address: {{ attach['mgmt_ip_address'] }} {% endfor %} deploy: false diff --git a/roles/dtc/common/templates/ndfc_fabric.j2 b/roles/dtc/common/templates/ndfc_fabric.j2 index baf5aa26..5c1b576c 100644 --- a/roles/dtc/common/templates/ndfc_fabric.j2 +++ b/roles/dtc/common/templates/ndfc_fabric.j2 @@ -3,16 +3,12 @@ {#- DO NOT EDIT MANUALLY #} {% set vxlan = MD_Extended.vxlan %} -{% if vxlan.global is defined %} -{% set global = vxlan.global %} -{% endif %} -{% set fabric_type = vxlan.fabric_type | default('VXLAN_EVPN') %} -{% if fabric_type == 'VXLAN_EVPN' %} +{% if vxlan.fabric.type == 'VXLAN_EVPN' %} {# Include NDFC DC VXLAN EVPN Base Template #} {% include '/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2' %} -{% elif fabric_type == 'MSD'%} +{% elif vxlan.fabric.type == 'MSD'%} {# Include NDFC MSD Base Template #} {% include '/ndfc_fabric/msd_fabric/msd_fabric_base.j2' %} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/advanced/dc_vxlan_fabric_advanced.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/advanced/dc_vxlan_fabric_advanced.j2 index 6b2c3584..ef484b65 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/advanced/dc_vxlan_fabric_advanced.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/advanced/dc_vxlan_fabric_advanced.j2 @@ -1,4 +1,4 @@ -{# Auto-generated NDFC DC VXLAN EVPN Advanced config data structure for fabric {{ vxlan.global.name }} #} +{# Auto-generated NDFC DC VXLAN EVPN Advanced config data structure for fabric {{ vxlan.fabric.name }} #} OVERLAY_MODE: cli GRFIELD_DEBUG_FLAG: Enable ENABLE_PVLAN: false @@ -8,7 +8,7 @@ HOST_INTF_ADMIN_STATE: {{ vxlan.underlay.general.unshut_host_interfaces | default(defaults.vxlan.underlay.general.unshut_host_interfaces) }} {% if ndfc_version | cisco.nac_dc_vxlan.version_compare('12.2.2', '>=') %} STP_ROOT_OPTION: {{ vxlan.global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol) }} -{% if vxlan.global.spanning_tree.root_bridge_protocol is defined and global.spanning_tree.root_bridge_protocol != 'unmanaged' %} +{% if vxlan.global.spanning_tree.root_bridge_protocol is defined and vxlan.global.spanning_tree.root_bridge_protocol != 'unmanaged' %} {% if (vxlan.global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol)) == 'rpvst+' %} STP_VLAN_RANGE: {{ ndfc_utils.convert_ranges(vxlan.global.spanning_tree.vlan_range, defaults.vxlan.global.spanning_tree.vlan_range) }} {% elif (vxlan.global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol)) == 'mst' %} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/bootstrap/dc_vxlan_fabric_bootstrap.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/bootstrap/dc_vxlan_fabric_bootstrap.j2 index 13c6732a..116f4c99 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/bootstrap/dc_vxlan_fabric_bootstrap.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/bootstrap/dc_vxlan_fabric_bootstrap.j2 @@ -1,16 +1,16 @@ -{# Auto-generated NDFC DC VXLAN EVPN Bootstrap config data structure for fabric {{ vxlan.global.name }} #} -{% if global.bootstrap is defined %} -{% if global.bootstrap.enable_bootstrap is defined and global.bootstrap.enable_bootstrap %} - BOOTSTRAP_ENABLE: {{ global.bootstrap.enable_bootstrap }} - DHCP_ENABLE: {{ global.bootstrap.enable_local_dhcp_server }} - DHCP_IPV6_ENABLE: {{ global.bootstrap.dhcp_version }} - DHCP_START: {{ global.bootstrap.dhcp_v4.scope_start_address }} - DHCP_END: {{ global.bootstrap.dhcp_v4.scope_end_address }} - MGMT_GW: {{ global.bootstrap.dhcp_v4.switch_mgmt_default_gw }} - MGMT_PREFIX: {{ global.bootstrap.dhcp_v4.mgmt_prefix }} - BOOTSTRAP_MULTISUBNET: "{{ global.bootstrap.dhcp_v4.multi_subnet_scope }}" +{# Auto-generated NDFC DC VXLAN EVPN Bootstrap config data structure for fabric {{ vxlan.fabric.name }} #} +{% if vxlan.global.bootstrap is defined %} +{% if vxlan.global.bootstrap.enable_bootstrap is defined and vxlan.global.bootstrap.enable_bootstrap %} + BOOTSTRAP_ENABLE: {{ vxlan.global.bootstrap.enable_bootstrap }} + DHCP_ENABLE: {{ vxlan.global.bootstrap.enable_local_dhcp_server }} + DHCP_IPV6_ENABLE: {{ vxlan.global.bootstrap.dhcp_version }} + DHCP_START: {{ vxlan.global.bootstrap.dhcp_v4.scope_start_address }} + DHCP_END: {{ vxlan.global.bootstrap.dhcp_v4.scope_end_address }} + MGMT_GW: {{ vxlan.global.bootstrap.dhcp_v4.switch_mgmt_default_gw }} + MGMT_PREFIX: {{ vxlan.global.bootstrap.dhcp_v4.mgmt_prefix }} + BOOTSTRAP_MULTISUBNET: "{{ vxlan.global.bootstrap.dhcp_v4.multi_subnet_scope }}" {% endif %} -{% if global.bootstrap.enable_bootstrap is defined and not global.bootstrap.enable_bootstrap %} - BOOTSTRAP_ENABLE: {{ global.bootstrap.enable_bootstrap }} +{% if vxlan.global.bootstrap.enable_bootstrap is defined and not vxlan.global.bootstrap.enable_bootstrap %} + BOOTSTRAP_ENABLE: {{ vxlan.global.bootstrap.enable_bootstrap }} {% endif %} {% endif %} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 index fa2fd4e5..a8c59127 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 @@ -1,4 +1,4 @@ -{# Auto-generated NDFC DC VXLAN EVPN Base config data structure for fabric {{ vxlan.global.name }} #} +{# Auto-generated NDFC DC VXLAN EVPN Base config data structure for fabric {{ vxlan.fabric.name }} #} - FABRIC_NAME: {{ vxlan.fabric.name }} FABRIC_TYPE: {{ vxlan.fabric.type }} DEPLOY: True diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/flow_monitor/dc_vxlan_fabric_flow_monitor.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/flow_monitor/dc_vxlan_fabric_flow_monitor.j2 index cc3d2da4..765a5dc9 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/flow_monitor/dc_vxlan_fabric_flow_monitor.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/flow_monitor/dc_vxlan_fabric_flow_monitor.j2 @@ -1,26 +1,26 @@ -{# Auto-generated NDFC DC VXLAN EVPN Flow Monitor config data structure for fabric {{ vxlan.global.name }} #} - ENABLE_NETFLOW: {{ global.netflow.enable | default(defaults.vxlan.global.netflow.enable) }} -{% if global.netflow.enable is defined and global.netflow.enable | bool or defaults.vxlan.global.netflow.enable | bool %} -{% if global.netflow.exporter is defined %} +{# Auto-generated NDFC DC VXLAN EVPN Flow Monitor config data structure for fabric {{ vxlan.fabric.name }} #} + ENABLE_NETFLOW: {{ vxlan.global.netflow.enable | default(defaults.vxlan.global.netflow.enable) }} +{% if vxlan.global.netflow.enable is defined and vxlan.global.netflow.enable | bool or defaults.vxlan.global.netflow.enable | bool %} +{% if vxlan.global.netflow.exporter is defined %} {% set exporter_dict = dict() %} {% set _ = exporter_dict.update({ "NETFLOW_EXPORTER_LIST":[] }) %} -{% for e in global.netflow.exporter %} +{% for e in vxlan.global.netflow.exporter %} {% set _ = exporter_dict["NETFLOW_EXPORTER_LIST"].append(dict(EXPORTER_NAME=e.name,IP=e.ip_address,VRF=e.vrf | default(""), SRC_IF_NAME=e.source_interface,UDP_PORT=e.udp_port)) %} {% endfor %} NETFLOW_EXPORTER_LIST: "{{ exporter_dict | tojson | replace('"', '\\"') }}" {% endif %} -{% if global.netflow.record is defined %} +{% if vxlan.global.netflow.record is defined %} {% set record_dict = dict() %} {% set _ = record_dict.update({ "NETFLOW_RECORD_LIST":[] }) %} -{% for r in global.netflow.record %} +{% for r in vxlan.global.netflow.record %} {% set _ = record_dict["NETFLOW_RECORD_LIST"].append(dict(RECORD_NAME=r.name,RECORD_TEMPLATE =r.template,LAYER2_RECORD=r.layer2 | default(false) | string | lower)) %} {% endfor %} NETFLOW_RECORD_LIST: "{{ record_dict | tojson | replace('"', '\\"') }}" {% endif %} -{% if global.netflow.monitor is defined %} +{% if vxlan.global.netflow.monitor is defined %} {% set monitor_dict = dict() %} {% set _ = monitor_dict.update({ "NETFLOW_MONITOR_LIST":[] }) %} -{% for m in global.netflow.monitor %} +{% for m in vxlan.global.netflow.monitor %} {% set _ = monitor_dict["NETFLOW_MONITOR_LIST"].append(dict(MONITOR_NAME=m.name,RECORD_NAME=m.record,EXPORTER1=m.exporter1,EXPORTER2=m.exporter2 | default(""))) %} {% endfor %} NETFLOW_MONITOR_LIST: "{{ monitor_dict | tojson | replace('"', '\\"') }}" diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/general/dc_vxlan_fabric_general.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/general/dc_vxlan_fabric_general.j2 index a11946d8..a959ef13 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/general/dc_vxlan_fabric_general.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/general/dc_vxlan_fabric_general.j2 @@ -1,5 +1,5 @@ -{# Auto-generated NDFC DC VXLAN EVPN General config data structure for fabric {{ vxlan.global.name }} #} - BGP_AS: {{ global.bgp_asn }} +{# Auto-generated NDFC DC VXLAN EVPN General config data structure for fabric {{ vxlan.fabric.name }} #} + BGP_AS: {{ vxlan.global.bgp_asn }} UNDERLAY_IS_V6: {{ (vxlan.underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) }} {% if (vxlan.underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) == 'True' %} USE_LINK_LOCAL: {{ vxlan.underlay.ipv6.enable_ipv6_link_local_address | default(defaults.vxlan.underlay.ipv6.enable_ipv6_link_local_address | title) }} @@ -12,6 +12,6 @@ SUBNET_TARGET_MASK: {{ vxlan.underlay.general.subnet_mask | default(defaults.vxlan.underlay.general.subnet_mask) }} {% endif %} LINK_STATE_ROUTING: {{ vxlan.underlay.general.routing_protocol | default(defaults.vxlan.underlay.general.routing_protocol) }} - RR_COUNT: {{ global.route_reflectors | default(defaults.vxlan.global.route_reflectors) }} - ANYCAST_GW_MAC: {{ global.anycast_gateway_mac | default(defaults.vxlan.global.anycast_gateway_mac) }} + RR_COUNT: {{ vxlan.global.route_reflectors | default(defaults.vxlan.global.route_reflectors) }} + ANYCAST_GW_MAC: {{ vxlan.global.anycast_gateway_mac | default(defaults.vxlan.global.anycast_gateway_mac) }} {# #} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/manageability/dc_vxlan_fabric_manageability.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/manageability/dc_vxlan_fabric_manageability.j2 index bf36cf90..1e449b12 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/manageability/dc_vxlan_fabric_manageability.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/manageability/dc_vxlan_fabric_manageability.j2 @@ -1,8 +1,8 @@ -{# Auto-generated NDFC DC VXLAN EVPN Manageability config data structure for fabric {{ vxlan.global.name }} #} -{% if global.dns_servers is defined and global.dns_servers %} +{# Auto-generated NDFC DC VXLAN EVPN Manageability config data structure for fabric {{ vxlan.fabric.name }} #} +{% if vxlan.global.dns_servers is defined and vxlan.global.dns_servers %} {% set dns_server_ips = [] %} {% set dns_server_vrfs = [] %} -{% for dns in global.dns_servers %} +{% for dns in vxlan.global.dns_servers %} {% if dns.ip_address | string is defined and dns.ip_address %} {% set dns_ip = dns.ip_address | string %} {% set dns_server_ips = dns_server_ips.append(dns_ip) %} @@ -15,10 +15,10 @@ DNS_SERVER_IP_LIST: {{ dns_server_ips | join(',') | default(omit) }} DNS_SERVER_VRF: {{ dns_server_vrfs | join(',') | default(omit) }} {% endif %} -{% if global.ntp_servers is defined and global.ntp_servers %} +{% if vxlan.global.ntp_servers is defined and vxlan.global.ntp_servers %} {% set ntp_server_ips = [] %} {% set ntp_server_vrfs = [] %} -{% for ntp in global.ntp_servers %} +{% for ntp in vxlan.global.ntp_servers %} {% if ntp.ip_address is defined and ntp.ip_address %} {% set ntp_ip = ntp.ip_address | string %} {% set ntp_server_ips = ntp_server_ips.append(ntp_ip) %} @@ -31,11 +31,11 @@ NTP_SERVER_IP_LIST: {{ ntp_server_ips | join(',') | default(omit) }} NTP_SERVER_VRF: {{ ntp_server_vrfs | join(',') | default(omit) }} {% endif %} -{% if global.syslog_servers is defined and global.syslog_servers %} +{% if vxlan.global.syslog_servers is defined and vxlan.global.syslog_servers %} {% set syslog_server_ips = [] %} {% set syslog_server_vrfs = [] %} {% set syslog_server_sevs = [] %} -{% for syslog_server in global.syslog_servers %} +{% for syslog_server in vxlan.global.syslog_servers %} {% if syslog_server.ip_address is defined and syslog_server.ip_address %} {% set syslog_server_ip = syslog_server.ip_address | string %} {% set syslog_server_ips = syslog_server_ips.append(syslog_server_ip) %} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/protocols/dc_vxlan_fabric_protocols.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/protocols/dc_vxlan_fabric_protocols.j2 index a4f84999..87a89590 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/protocols/dc_vxlan_fabric_protocols.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/protocols/dc_vxlan_fabric_protocols.j2 @@ -1,4 +1,4 @@ -{# Auto-generated NDFC DC VXLAN EVPN Protocols config data structure for fabric {{ vxlan.global.name }} #} +{# Auto-generated NDFC DC VXLAN EVPN Protocols config data structure for fabric {{ vxlan.fabric.name }} #} BGP_LB_ID: {{ vxlan.underlay.general.underlay_routing_loopback_id | default(defaults.vxlan.underlay.general.underlay_routing_loopback_id) }} NVE_LB_ID: {{ vxlan.underlay.general.underlay_vtep_loopback_id | default(defaults.vxlan.underlay.general.underlay_vtep_loopback_id) }} LINK_STATE_ROUTING_TAG: {{ vxlan.underlay.general.underlay_routing_protocol_tag | default(defaults.vxlan.underlay.general.underlay_routing_protocol_tag) }} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/replication/dc_vxlan_fabric_replication.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/replication/dc_vxlan_fabric_replication.j2 index 295a4e1e..9d183070 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/replication/dc_vxlan_fabric_replication.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/replication/dc_vxlan_fabric_replication.j2 @@ -1,4 +1,4 @@ -{# Auto-generated NDFC DC VXLAN EVPN Replication config data structure for fabric {{ vxlan.global.name }} #} +{# Auto-generated NDFC DC VXLAN EVPN Replication config data structure for fabric {{ vxlan.fabric.name }} #} {% if (vxlan.underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) == 'False' %} REPLICATION_MODE: {{ vxlan.underlay.general.replication_mode | default(defaults.vxlan.underlay.general.replication_mode) | title }} {% endif %} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/resources/dc_vxlan_fabric_resources.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/resources/dc_vxlan_fabric_resources.j2 index 1aa0c046..3075edc5 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/resources/dc_vxlan_fabric_resources.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/resources/dc_vxlan_fabric_resources.j2 @@ -1,4 +1,4 @@ -{# Auto-generated NDFC DC VXLAN EVPN Resources config data structure for fabric {{ vxlan.global.name }} #} +{# Auto-generated NDFC DC VXLAN EVPN Resources config data structure for fabric {{ vxlan.fabric.name }} #} STATIC_UNDERLAY_IP_ALLOC: {{ (vxlan.underlay.general.manual_underlay_allocation | default(defaults.vxlan.underlay.general.manual_underlay_allocation) | title)}} {% if (vxlan.underlay.general.manual_underlay_allocation | default(defaults.vxlan.underlay.general.manual_underlay_allocation) | title) == 'False' %} {% if (vxlan.underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) == 'False' %} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/security/dc_vxlan_fabric_security.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/security/dc_vxlan_fabric_security.j2 index f23297b1..27e6be19 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/security/dc_vxlan_fabric_security.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/security/dc_vxlan_fabric_security.j2 @@ -1,2 +1,2 @@ -{# Auto-generated NDFC DC VXLAN EVPN Security config data structure for fabric {{ vxlan.global.name }} #} +{# Auto-generated NDFC DC VXLAN EVPN Security config data structure for fabric {{ vxlan.fabric.name }} #} ENABLE_SGT: false \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/vpc/dc_vxlan_fabric_vpc.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/vpc/dc_vxlan_fabric_vpc.j2 index 49105ed7..f281c218 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/vpc/dc_vxlan_fabric_vpc.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/vpc/dc_vxlan_fabric_vpc.j2 @@ -1,13 +1,13 @@ -{# Auto-generated NDFC DC VXLAN EVPN vPC config data structure for fabric {{ vxlan.global.name }} #} +{# Auto-generated NDFC DC VXLAN EVPN vPC config data structure for fabric {{ vxlan.fabric.name }} #} ENABLE_FABRIC_VPC_DOMAIN_ID: False - VPC_PEER_LINK_VLAN: {{ global.vpc.peer_link_vlan | default(defaults.vxlan.global.vpc.peer_link_vlan) }} - VPC_PEER_KEEP_ALIVE_OPTION: {{ global.vpc.peer_keep_alive | default(defaults.vxlan.global.vpc.peer_keep_alive) }} - VPC_AUTO_RECOVERY_TIME: {{ global.vpc.auto_recovery_time | default(defaults.vxlan.global.vpc.auto_recovery_time) }} - VPC_DELAY_RESTORE_TIME: {{ global.vpc.delay_restore_time | default(defaults.vxlan.global.vpc.delay_restore_time) }} - VPC_PEER_LINK_PO: {{ global.vpc.peer_link_port_channel_id | default(defaults.vxlan.global.vpc.peer_link_port_channel_id) }} - VPC_DOMAIN_ID_RANGE: {{ global.vpc.domain_id_range | default(defaults.vxlan.global.vpc.domain_id_range) }} - VPC_DELAY_RESTORE: {{ global.vpc.delay_restore_time | default(defaults.vxlan.global.vpc.delay_restore_time) }} - ADVERTISE_PIP_BGP: {{ (global.vpc.advertise_pip | default(defaults.vxlan.global.vpc.advertise_pip) | title) }} -{% if (global.vpc.advertise_pip | default(defaults.vxlan.global.vpc.advertise_pip) | title) == 'False' %} - ADVERTISE_PIP_ON_BORDER: {{ global.vpc.advertise_pip_border_only | default(defaults.vxlan.global.vpc.advertise_pip_border_only) | title }} + VPC_PEER_LINK_VLAN: {{ vxlan.global.vpc.peer_link_vlan | default(defaults.vxlan.global.vpc.peer_link_vlan) }} + VPC_PEER_KEEP_ALIVE_OPTION: {{ vxlan.global.vpc.peer_keep_alive | default(defaults.vxlan.global.vpc.peer_keep_alive) }} + VPC_AUTO_RECOVERY_TIME: {{ vxlan.global.vpc.auto_recovery_time | default(defaults.vxlan.global.vpc.auto_recovery_time) }} + VPC_DELAY_RESTORE_TIME: {{ vxlan.global.vpc.delay_restore_time | default(defaults.vxlan.global.vpc.delay_restore_time) }} + VPC_PEER_LINK_PO: {{ vxlan.global.vpc.peer_link_port_channel_id | default(defaults.vxlan.global.vpc.peer_link_port_channel_id) }} + VPC_DOMAIN_ID_RANGE: {{ vxlan.global.vpc.domain_id_range | default(defaults.vxlan.global.vpc.domain_id_range) }} + VPC_DELAY_RESTORE: {{ vxlan.global.vpc.delay_restore_time | default(defaults.vxlan.global.vpc.delay_restore_time) }} + ADVERTISE_PIP_BGP: {{ (vxlan.global.vpc.advertise_pip | default(defaults.vxlan.global.vpc.advertise_pip) | title) }} +{% if (vxlan.global.vpc.advertise_pip | default(defaults.vxlan.global.vpc.advertise_pip) | title) == 'False' %} + ADVERTISE_PIP_ON_BORDER: {{ vxlan.global.vpc.advertise_pip_border_only | default(defaults.vxlan.global.vpc.advertise_pip_border_only) | title }} {% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 index a06fccaa..e459e813 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 @@ -1,4 +1,4 @@ -{# Auto-generated NDFC MSD DCI config data structure for fabric {{ vxlan.name }} #} +{# Auto-generated NDFC MSD DCI config data structure for fabric {{ vxlan.fabric.name }} #} BORDER_GWY_CONNECTIONS: {{ vxlan.multisite.overlay_ifc | default(defaults.vxlan.multisite.overlay_ifc) }} MS_UNDERLAY_AUTOCONFIG: {{ vxlan.multisite.underlay_autoconfig | default(defaults.vxlan.multisite.underlay_autoconfig) }} ENABLE_BGP_SEND_COMM: {{ vxlan.multisite.enable_bgp_send_community | default(defaults.vxlan.multisite.enable_bgp_send_community) }} diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 index 1c4e92ca..baafab7c 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 @@ -1,6 +1,6 @@ -{# Auto-generated NDFC MSD General config data structure for fabric {{ vxlan.name }} #} +{# Auto-generated NDFC MSD General config data structure for fabric {{ vxlan.fabric.name }} #} ENABLE_PVLAN: false ANYCAST_GW_MAC: {{ vxlan.multisite.anycast_gateway_mac | default(defaults.vxlan.multisite.anycast_gateway_mac) }} - MS_LOOPBACK_ID: {{ vxlan.multisite.loopback_id | default(defaults.vxlan.multisite.loopback_id) }} + MS_LOOPBACK_ID: {{ vxlan.multisite.vtep_loopback_id | default(defaults.vxlan.multisite.vtep_loopback_id) }} BGW_ROUTING_TAG: {{ vxlan.multisite.bgw_ip_tag | default(defaults.vxlan.multisite.bgw_ip_tag) }} {# #} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 index 8f4d07d0..19ea1f87 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 @@ -1,5 +1,5 @@ -{# Auto-generated NDFC DC VXLAN EVPN Base config data structure for fabric {{ vxlan.name }} #} -- FABRIC_NAME: {{ vxlan.name }} +{# Auto-generated NDFC MultiSite Domain (MSD) Base config data structure for fabric {{ vxlan.fabric.name }} #} +- FABRIC_NAME: {{ vxlan.fabric.name }} FABRIC_TYPE: VXLAN_EVPN_MSD DEPLOY: True diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 index 31bd7dd8..8f7fd495 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 @@ -1,4 +1,4 @@ -{# Auto-generated NDFC MSD Resources config data structure for fabric {{ vxlan.name }} #} +{# Auto-generated NDFC MSD Resources config data structure for fabric {{ vxlan.fabric.name }} #} LOOPBACK100_IP_RANGE: {{ vxlan.multisite.vtep_loopback_ip_range | default(defaults.vxlan.multisite.vtep_loopback_ip_range) }} DCI_SUBNET_RANGE: {{ vxlan.multisite.dci_subnet_range | default(defaults.vxlan.multisite.dci_subnet_range) }} DCI_SUBNET_MASK: {{ vxlan.multisite.dci_subnet_mask | default(defaults.vxlan.multisite.dci_subnet_mask) }} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 index a7f56a61..80d69feb 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 @@ -1,2 +1,2 @@ -{# Auto-generated NDFC MSD Security config data structure for fabric {{ vxlan.name }} #} +{# Auto-generated NDFC MSD Security config data structure for fabric {{ vxlan.fabric.name }} #} ENABLE_SGT: false \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_links_vpc_peering.j2 b/roles/dtc/common/templates/ndfc_links_vpc_peering.j2 index bfa6a03d..2d179f36 100644 --- a/roles/dtc/common/templates/ndfc_links_vpc_peering.j2 +++ b/roles/dtc/common/templates/ndfc_links_vpc_peering.j2 @@ -8,7 +8,7 @@ {% set peer1_interface = peers['peer1_peerlink_interfaces'][interface_index] %} {% set peer2_interface = peers['peer2_peerlink_interfaces'][interface_index] %} {% if peer1_interface is defined and peer2_interface is defined %} -- dst_fabric : {{ MD_Extended.vxlan.global.name }} +- dst_fabric : {{ MD_Extended.vxlan.fabric.name }} template: int_pre_provision_intra_fabric_link src_interface: {{peer1_interface.name}} dst_interface: {{peer2_interface.name}} diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index a80afd39..be015e3b 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -21,18 +21,19 @@ --- -- name: Import MSD Role Tasks +- name: Import VXLAN Role Tasks ansible.builtin.import_tasks: sub_main_vxlan.yml when: - - MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN' + - MD_Extended.vxlan.fabric.type == 'VXLAN_EVPN' - changes_detected_fabric or changes_detected_inventory or changes_detected_vpc_peering or changes_detected_interfaces or changes_detected_link_vpc_peering or changes_detected_vrfs or changes_detected_networks or changes_detected_policy -- name: Import VxLAN Role Tasks +- name: Import MSD Role Tasks ansible.builtin.import_tasks: sub_main_msd.yml - when: MD_Extended.vxlan.fabric_type == 'MSD' + when: MD_Extended.vxlan.fabric.type == 'MSD' - name: Mark Stage Role Create Completed cisco.nac_dc_vxlan.common.run_map: + model_data: "{{ MD_Extended }}" stage: role_create_completed register: run_map delegate_to: localhost diff --git a/roles/dtc/create/tasks/msd/child_fabrics.yml b/roles/dtc/create/tasks/msd/child_fabrics.yml index e1514c0b..31677c76 100644 --- a/roles/dtc/create/tasks/msd/child_fabrics.yml +++ b/roles/dtc/create/tasks/msd/child_fabrics.yml @@ -25,7 +25,7 @@ ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Manage Fabric {{ MD.vxlan.name }}" + - "+ Manage Fabric {{ MD_Extended.vxlan.fabric.name }}" - "----------------------------------------------------------------" - name: Get Fabric Association Data from NDFC @@ -34,9 +34,9 @@ path: /appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations register: fabric_associations -- name: Move Child Fabrics To Fabric - {{ MD.vxlan.name }} +- name: Move Child Fabrics To Fabric - {{ MD_Extended.vxlan.fabric.name }} cisco.nac_dc_vxlan.dtc.move_child_fabrics: fabric_associations: "{{ fabric_associations }}" - parent_fabric_name: "{{ MD_Extended.vxlan.name }}" + parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" when: fabric_associations is defined diff --git a/roles/dtc/create/tasks/msd/fabric.yml b/roles/dtc/create/tasks/msd/fabric.yml index b157898f..e810c30d 100644 --- a/roles/dtc/create/tasks/msd/fabric.yml +++ b/roles/dtc/create/tasks/msd/fabric.yml @@ -25,10 +25,10 @@ ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Manage Fabric {{ MD.vxlan.name }}" + - "+ Manage Fabric {{ MD_Extended.vxlan.fabric.name }}" - "----------------------------------------------------------------" -- name: Manage Fabric {{ MD.vxlan.name }} in NDFC +- name: Manage Fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC cisco.dcnm.dcnm_fabric: state: merged config: "{{ fabric_config }}" diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index 076326ad..d9e6d51a 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -35,8 +35,8 @@ - name: Create NDFC MSD Fabric ansible.builtin.import_tasks: msd/fabric.yml when: - - MD_Extended.vxlan.name is defined - - MD_Extended.vxlan.fabric_type == "MSD" + - MD_Extended.vxlan.fabric.name is defined + - MD_Extended.vxlan.fabric.type == "MSD" - changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" diff --git a/roles/dtc/create/tasks/sub_main_vxlan.yml b/roles/dtc/create/tasks/sub_main_vxlan.yml index 855af8f2..494ecc9e 100644 --- a/roles/dtc/create/tasks/sub_main_vxlan.yml +++ b/roles/dtc/create/tasks/sub_main_vxlan.yml @@ -35,6 +35,8 @@ - name: Create NDFC Fabric ansible.builtin.import_tasks: vxlan/fabric.yml when: + - MD_Extended.vxlan.fabric.name is defined + - MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" - MD_Extended.vxlan.global is defined - changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" diff --git a/roles/dtc/create/tasks/vxlan/devices.yml b/roles/dtc/create/tasks/vxlan/devices.yml index 0c6e81b1..f823a989 100644 --- a/roles/dtc/create/tasks/vxlan/devices.yml +++ b/roles/dtc/create/tasks/vxlan/devices.yml @@ -25,7 +25,7 @@ ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Manage Devices Fabric {{ MD.vxlan.global.name }}" + - "+ Manage Devices Fabric {{ MD_Extended.vxlan.fabric.name }}" - "----------------------------------------------------------------" - name: Manage Devices Discovery diff --git a/roles/dtc/create/tasks/vxlan/devices_discovery.yml b/roles/dtc/create/tasks/vxlan/devices_discovery.yml index 60add0df..1b12ac32 100644 --- a/roles/dtc/create/tasks/vxlan/devices_discovery.yml +++ b/roles/dtc/create/tasks/vxlan/devices_discovery.yml @@ -21,9 +21,9 @@ --- -- name: Add NDFC Fabric Devices {{ MD.vxlan.global.name }} +- name: Add NDFC Fabric Devices {{ MD_Extended.vxlan.fabric.name }} cisco.dcnm.dcnm_inventory: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" config: "{{ updated_inv_config['updated_inv_list'] }}" deploy: false save: true diff --git a/roles/dtc/create/tasks/vxlan/fabric.yml b/roles/dtc/create/tasks/vxlan/fabric.yml index 2ec479a8..549e5785 100644 --- a/roles/dtc/create/tasks/vxlan/fabric.yml +++ b/roles/dtc/create/tasks/vxlan/fabric.yml @@ -25,10 +25,10 @@ ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Manage Fabric {{ MD.vxlan.global.name }}" + - "+ Manage Fabric {{ MD_Extended.vxlan.fabric.name }}" - "----------------------------------------------------------------" -- name: Manage fabric {{ MD.vxlan.global.name }} in NDFC +- name: Manage fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC cisco.dcnm.dcnm_fabric: state: merged config: "{{ fabric_config }}" diff --git a/roles/dtc/create/tasks/vxlan/interfaces.yml b/roles/dtc/create/tasks/vxlan/interfaces.yml index af086ecf..45d53709 100644 --- a/roles/dtc/create/tasks/vxlan/interfaces.yml +++ b/roles/dtc/create/tasks/vxlan/interfaces.yml @@ -25,7 +25,7 @@ ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Manage Fabric Interfaces {{ MD.vxlan.global.name }}" + - "+ Manage Fabric Interfaces {{ MD_Extended.vxlan.fabric.name }}" - "----------------------------------------------------------------" # -------------------------------------------------------------------- @@ -34,7 +34,7 @@ - name: Manage Access Portchannel Interface cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ interface_access_po }}" when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 @@ -45,7 +45,7 @@ - name: Manage Trunk Portchannel Interface cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ interface_trunk_po }}" when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 @@ -56,7 +56,7 @@ - name: Manage Interface Routed cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ interface_routed }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 @@ -67,7 +67,7 @@ - name: Manage Sub-interface Routed cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ sub_interface_routed }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 @@ -78,7 +78,7 @@ - name: Manage Interface Port-Channel Routed cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ interface_po_routed }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 @@ -89,7 +89,7 @@ - name: Manage NDFC Fabric Loopback cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ int_loopback_config }}" when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 @@ -100,7 +100,7 @@ - name: Manage Interface Trunk cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ interface_trunk }}" when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 @@ -111,7 +111,7 @@ - name: Manage Interface Access cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ interface_access }}" when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 @@ -122,7 +122,7 @@ - name: Manage NDFC Fabric vPCs cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ interface_vpc }}" when: MD_Extended.vxlan.topology.interfaces.modes.access_vpc.count > 0 or MD_Extended.vxlan.topology.interfaces.modes.trunk_vpc.count > 0 diff --git a/roles/dtc/create/tasks/vxlan/policies.yml b/roles/dtc/create/tasks/vxlan/policies.yml index c052c15a..3b9d2e49 100644 --- a/roles/dtc/create/tasks/vxlan/policies.yml +++ b/roles/dtc/create/tasks/vxlan/policies.yml @@ -25,7 +25,7 @@ ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Manage Policies Fabric {{ MD.vxlan.global.name }}" + - "+ Manage Policies Fabric {{ MD_Extended.vxlan.fabric.name }}" - "----------------------------------------------------------------" # -------------------------------------------------------------------- @@ -33,7 +33,7 @@ # -------------------------------------------------------------------- - name: Manage NDFC Fabric Policies cisco.dcnm.dcnm_policy: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" use_desc_as_key: true config: "{{ policy_config }}" deploy: false diff --git a/roles/dtc/create/tasks/vxlan/vpc_peering.yml b/roles/dtc/create/tasks/vxlan/vpc_peering.yml index a5ab3a56..bb97948b 100644 --- a/roles/dtc/create/tasks/vxlan/vpc_peering.yml +++ b/roles/dtc/create/tasks/vxlan/vpc_peering.yml @@ -25,7 +25,7 @@ ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Manage Fabric vPC Peers {{ MD.vxlan.global.name }}" + - "+ Manage Fabric vPC Peers {{ MD_Extended.vxlan.fabric.name }}" - "----------------------------------------------------------------" # -------------------------------------------------------------------- @@ -35,7 +35,7 @@ - name: Manage Intra Fabric Links for vpc peering cisco.dcnm.dcnm_links: state: replaced - src_fabric: "{{ MD_Extended.vxlan.global.name }}" + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" config: "{{ link_vpc_peering }}" vars: ansible_command_timeout: 3000 @@ -47,7 +47,7 @@ - name: Manage vPC Peering cisco.dcnm.dcnm_vpc_pair: - src_fabric: "{{ MD.vxlan.global.name }}" + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" deploy: false state: replaced config: "{{ vpc_peering }}" diff --git a/roles/dtc/create/tasks/vxlan/vrfs_networks.yml b/roles/dtc/create/tasks/vxlan/vrfs_networks.yml index ec1a19c8..025c486b 100644 --- a/roles/dtc/create/tasks/vxlan/vrfs_networks.yml +++ b/roles/dtc/create/tasks/vxlan/vrfs_networks.yml @@ -25,7 +25,7 @@ ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Manage VRFs and Networks Fabric {{ MD.vxlan.global.name }}" + - "+ Manage VRFs and Networks Fabric {{ MD_Extended.vxlan.fabric.name }}" - "----------------------------------------------------------------" # -------------------------------------------------------------------- @@ -33,7 +33,7 @@ # -------------------------------------------------------------------- - name: Manage NDFC Fabric VRFs cisco.dcnm.dcnm_vrf: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ vrf_config }}" register: manage_vrf_result @@ -48,7 +48,7 @@ # -------------------------------------------------------------------- - name: Manage NDFC Fabric Networks cisco.dcnm.dcnm_network: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced config: "{{ net_config }}" register: manage_network_result diff --git a/roles/dtc/deploy/tasks/main.yml b/roles/dtc/deploy/tasks/main.yml index 96c5ec4c..1e82ec4b 100644 --- a/roles/dtc/deploy/tasks/main.yml +++ b/roles/dtc/deploy/tasks/main.yml @@ -28,6 +28,7 @@ - name: Mark Stage Role Deploy Completed cisco.nac_dc_vxlan.common.run_map: + model_data: "{{ MD_Extended }}" stage: role_deploy_completed register: run_map delegate_to: localhost diff --git a/roles/dtc/deploy/tasks/sub_main.yml b/roles/dtc/deploy/tasks/sub_main.yml index e4199984..27464d91 100644 --- a/roles/dtc/deploy/tasks/sub_main.yml +++ b/roles/dtc/deploy/tasks/sub_main.yml @@ -30,16 +30,16 @@ - ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" -- name: Config-Save for Fabric {{ MD.vxlan.global.name }} +- name: Config-Save for Fabric {{ MD_Extended.vxlan.fabric.name }} cisco.dcnm.dcnm_rest: method: POST - path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD.vxlan.global.name }}/config-save" + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/config-save" when: MD_Extended.vxlan.topology.switches | length > 0 # TODO: Need to add logic to only save if changes are made -- name: Deploy for Fabric {{ MD.vxlan.global.name }} +- name: Deploy for Fabric {{ MD_Extended.vxlan.fabric.name }} cisco.dcnm.dcnm_rest: - path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD.vxlan.global.name }}/config-deploy?forceShowRun=false" + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/config-deploy?forceShowRun=false" method: POST vars: ansible_command_timeout: 3000 diff --git a/roles/dtc/remove/tasks/main.yml b/roles/dtc/remove/tasks/main.yml index 8cb4e2a7..0a0cdcce 100644 --- a/roles/dtc/remove/tasks/main.yml +++ b/roles/dtc/remove/tasks/main.yml @@ -21,12 +21,20 @@ --- -- name: Import Role Tasks - ansible.builtin.import_tasks: sub_main.yml - when: changes_detected_interfaces or changes_detected_networks or changes_detected_vrfs or changes_detected_vpc_peering or changes_detected_link_vpc_peering or changes_detected_inventory +- name: Import VXLAN Role Tasks + ansible.builtin.import_tasks: sub_main_vxlan.yml + when: + - MD_Extended.vxlan.fabric.type == 'VXLAN_EVPN' + - changes_detected_interfaces or changes_detected_networks or changes_detected_vrfs or changes_detected_vpc_peering or changes_detected_link_vpc_peering or changes_detected_inventory + +- name: Import MSD Role Tasks + ansible.builtin.import_tasks: sub_main_msd.yml + when: + - MD_Extended.vxlan.fabric.type == 'MSD' - name: Mark Stage Role Remove Completed cisco.nac_dc_vxlan.common.run_map: + model_data: "{{ MD_Extended }}" stage: role_remove_completed register: run_map delegate_to: localhost diff --git a/roles/dtc/remove/tasks/msd/.gitkeep b/roles/dtc/remove/tasks/msd/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/create/tasks/vxlan/reset.yml b/roles/dtc/remove/tasks/sub_main_msd.yml similarity index 79% rename from roles/dtc/create/tasks/vxlan/reset.yml rename to roles/dtc/remove/tasks/sub_main_msd.yml index b528fcd0..f4d2e7e6 100644 --- a/roles/dtc/create/tasks/vxlan/reset.yml +++ b/roles/dtc/remove/tasks/sub_main_msd.yml @@ -20,12 +20,3 @@ # SPDX-License-Identifier: MIT --- - -- name: Remove all devices from the NDFC fabric {{ fabric_name }} - cisco.dcnm.dcnm_inventory: - fabric: "{{ fabric_name }}" - state: deleted - config: "{{ lookup('file', 'ndfc_inventory.yml') | from_yaml }}" - vars: - ansible_command_timeout: 1000 - ansible_connect_timeout: 1000 diff --git a/roles/dtc/remove/tasks/sub_main.yml b/roles/dtc/remove/tasks/sub_main_vxlan.yml similarity index 86% rename from roles/dtc/remove/tasks/sub_main.yml rename to roles/dtc/remove/tasks/sub_main_vxlan.yml index 2e904699..397e124c 100644 --- a/roles/dtc/remove/tasks/sub_main.yml +++ b/roles/dtc/remove/tasks/sub_main_vxlan.yml @@ -35,48 +35,48 @@ - name: Get List of Fabric Switches from NDFC cisco.dcnm.dcnm_rest: method: GET - path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD.vxlan.global.name }}/inventory/switchesByFabric" + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/inventory/switchesByFabric" register: switch_list tags: "{{ nac_tags.remove }}" - name: Remove Fabric Policy - ansible.builtin.import_tasks: policy.yml + ansible.builtin.import_tasks: vxlan/policy.yml tags: "{{ nac_tags.remove_policy }}" when: - changes_detected_policy - name: Remove Fabric Interfaces - ansible.builtin.import_tasks: interfaces.yml + ansible.builtin.import_tasks: vxlan/interfaces.yml tags: "{{ nac_tags.remove_interfaces }}" when: - changes_detected_interfaces - name: Remove Fabric Networks - ansible.builtin.import_tasks: networks.yml + ansible.builtin.import_tasks: vxlan/networks.yml tags: "{{ nac_tags.remove_networks }}" when: - changes_detected_networks - name: Remove Fabric VRFs - ansible.builtin.import_tasks: vrfs.yml + ansible.builtin.import_tasks: vxlan/vrfs.yml tags: "{{ nac_tags.remove_vrfs }}" when: - changes_detected_vrfs - name: Remove Fabric Links - ansible.builtin.import_tasks: links.yml + ansible.builtin.import_tasks: vxlan/links.yml tags: "{{ nac_tags.remove_links }}" when: - changes_detected_link_vpc_peering - name: Remove Fabric vPC Peering - ansible.builtin.import_tasks: vpc_peers.yml + ansible.builtin.import_tasks: vxlan/vpc_peers.yml tags: "{{ nac_tags.remove_vpc_peers }}" when: - changes_detected_vpc_peering - name: Remove Fabric Switches - ansible.builtin.import_tasks: switches.yml + ansible.builtin.import_tasks: vxlan/switches.yml tags: "{{ nac_tags.remove_switches }}" when: - changes_detected_inventory diff --git a/roles/dtc/remove/tasks/vxlan/.gitkeep b/roles/dtc/remove/tasks/vxlan/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/remove/tasks/interfaces.yml b/roles/dtc/remove/tasks/vxlan/interfaces.yml similarity index 98% rename from roles/dtc/remove/tasks/interfaces.yml rename to roles/dtc/remove/tasks/vxlan/interfaces.yml index ab08d570..19c68e9c 100644 --- a/roles/dtc/remove/tasks/interfaces.yml +++ b/roles/dtc/remove/tasks/vxlan/interfaces.yml @@ -27,7 +27,7 @@ - name: Remove Unmanaged Fabric Interfaces cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: overridden config: "{{ interface_all }}" # deploy: false diff --git a/roles/dtc/remove/tasks/links.yml b/roles/dtc/remove/tasks/vxlan/links.yml similarity index 96% rename from roles/dtc/remove/tasks/links.yml rename to roles/dtc/remove/tasks/vxlan/links.yml index d547771a..7c3a35f6 100644 --- a/roles/dtc/remove/tasks/links.yml +++ b/roles/dtc/remove/tasks/vxlan/links.yml @@ -28,7 +28,7 @@ - name: Remove Intra Fabric Links for vPC Peering cisco.dcnm.dcnm_links: state: replaced - src_fabric: "{{ MD_Extended.vxlan.global.name }}" + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" config: "{{ link_vpc_peering }}" vars: ansible_command_timeout: 3000 diff --git a/roles/dtc/remove/tasks/networks.yml b/roles/dtc/remove/tasks/vxlan/networks.yml similarity index 97% rename from roles/dtc/remove/tasks/networks.yml rename to roles/dtc/remove/tasks/vxlan/networks.yml index 82487a74..706fa9ef 100644 --- a/roles/dtc/remove/tasks/networks.yml +++ b/roles/dtc/remove/tasks/vxlan/networks.yml @@ -27,7 +27,7 @@ - name: Remove Unmanaged Fabric Networks cisco.dcnm.dcnm_network: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: overridden config: "{{ net_config }}" vars: diff --git a/roles/dtc/remove/tasks/policy.yml b/roles/dtc/remove/tasks/vxlan/policy.yml similarity index 98% rename from roles/dtc/remove/tasks/policy.yml rename to roles/dtc/remove/tasks/vxlan/policy.yml index d203a5ad..26cf28f8 100644 --- a/roles/dtc/remove/tasks/policy.yml +++ b/roles/dtc/remove/tasks/vxlan/policy.yml @@ -37,7 +37,7 @@ - name: Remove Unmanaged NDFC Fabric Policy cisco.dcnm.dcnm_policy: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" use_desc_as_key: true config: "{{ unmanaged_policy_config.unmanaged_policies }}" deploy: true diff --git a/roles/dtc/remove/tasks/switches.yml b/roles/dtc/remove/tasks/vxlan/switches.yml similarity index 97% rename from roles/dtc/remove/tasks/switches.yml rename to roles/dtc/remove/tasks/vxlan/switches.yml index a3ab2de8..1094f199 100644 --- a/roles/dtc/remove/tasks/switches.yml +++ b/roles/dtc/remove/tasks/vxlan/switches.yml @@ -26,7 +26,7 @@ - name: Remove Unmanaged NDFC Fabric Devices cisco.dcnm.dcnm_inventory: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" config: "{{ updated_inv_config['updated_inv_list'] }}" deploy: true save: true diff --git a/roles/dtc/remove/tasks/vpc_peers.yml b/roles/dtc/remove/tasks/vxlan/vpc_peers.yml similarity index 97% rename from roles/dtc/remove/tasks/vpc_peers.yml rename to roles/dtc/remove/tasks/vxlan/vpc_peers.yml index 9c400a64..dc8e1dcb 100644 --- a/roles/dtc/remove/tasks/vpc_peers.yml +++ b/roles/dtc/remove/tasks/vxlan/vpc_peers.yml @@ -27,7 +27,7 @@ - name: Remove Unmanaged vPC Peering cisco.dcnm.dcnm_vpc_pair: - src_fabric: "{{ MD.vxlan.global.name }}" + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" deploy: true state: overridden config: "{{ vpc_peering }}" diff --git a/roles/dtc/remove/tasks/vrfs.yml b/roles/dtc/remove/tasks/vxlan/vrfs.yml similarity index 97% rename from roles/dtc/remove/tasks/vrfs.yml rename to roles/dtc/remove/tasks/vxlan/vrfs.yml index 87e39d7e..68bce074 100644 --- a/roles/dtc/remove/tasks/vrfs.yml +++ b/roles/dtc/remove/tasks/vxlan/vrfs.yml @@ -27,7 +27,7 @@ - name: Remove Unmanaged Fabric VRFs cisco.dcnm.dcnm_vrf: - fabric: "{{ MD.vxlan.global.name }}" + fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: overridden config: "{{ vrf_config }}" vars: diff --git a/roles/validate/files/defaults.yml b/roles/validate/files/defaults.yml index 4ef1034b..5b81d6c6 100644 --- a/roles/validate/files/defaults.yml +++ b/roles/validate/files/defaults.yml @@ -164,7 +164,7 @@ factory_defaults: isis: false authentication_enable: false authentication_key_id: 100 - overlay_services: + overlay: vrfs: vrf_description: "Configured by Ansible NetAsCode" vrf_intf_desc: "Configured by Ansible NetAsCode" diff --git a/roles/validate/tasks/main.yml b/roles/validate/tasks/main.yml index 9d6e722c..41525ac7 100644 --- a/roles/validate/tasks/main.yml +++ b/roles/validate/tasks/main.yml @@ -49,6 +49,7 @@ - name: Mark Stage Role Validate Completed cisco.nac_dc_vxlan.common.run_map: + model_data: "{{ MD_Extended }}" stage: role_validate_completed register: run_map delegate_to: localhost diff --git a/roles/validate/tasks/manage_model_files_current.yml b/roles/validate/tasks/manage_model_files_current.yml index 43030ab0..b6679e49 100644 --- a/roles/validate/tasks/manage_model_files_current.yml +++ b/roles/validate/tasks/manage_model_files_current.yml @@ -25,7 +25,7 @@ - name: Copy Service Model Data to Host ansible.builtin.copy: content: "{{ MD | to_nice_json }}" - dest: "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" + dest: "{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_golden.json" force: yes delegate_to: localhost @@ -33,14 +33,14 @@ - name: Copy Extended Service Model Data to Host ansible.builtin.copy: content: "{{ MD_Extended | to_nice_json }}" - dest: "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_extended.json" + dest: "{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_extended.json" force: yes delegate_to: localhost # Read current golden service model data into a variable called 'smd_golden_current' - name: Read Current Service Model Data from Host ansible.builtin.include_vars: - file: "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" + file: "{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_golden.json" register: smd_golden_current delegate_to: localhost diff --git a/roles/validate/tasks/manage_model_files_previous.yml b/roles/validate/tasks/manage_model_files_previous.yml index 59050292..2d2b30b9 100644 --- a/roles/validate/tasks/manage_model_files_previous.yml +++ b/roles/validate/tasks/manage_model_files_previous.yml @@ -29,31 +29,31 @@ # Check if golden and extended service model data files exist from previous runs - name: Stat the Golden Service Model Data - ansible.builtin.stat: path="{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" + ansible.builtin.stat: path="{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_golden.json" register: golden_stat delegate_to: localhost - name: Stat the Extended Service Model Data - ansible.builtin.stat: path="{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_extended.json" + ansible.builtin.stat: path="{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_extended.json" register: extended_stat delegate_to: localhost # Read and store previous golden service model data into a variable called 'smd_golden_previous' - name: Read Previous Golden Service Model Data from Host ansible.builtin.include_vars: - file: "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" + file: "{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_golden.json" register: smd_golden_previous when: golden_stat.stat.exists and check_roles['save_previous'] delegate_to: localhost # Rename golden file from previous run to append '_previous' to the filename - name: Move Golden Service Model Data Previous - ansible.builtin.command: mv "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden.json" "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_golden_previous.json" + ansible.builtin.command: mv "{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_golden.json" "{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_golden_previous.json" when: golden_stat.stat.exists and check_roles['save_previous'] delegate_to: localhost # Rename extended file from previous run to append '_previous' to the filename - name: Move Extended Service Model Data Previous - ansible.builtin.command: mv "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_extended.json" "{{ role_path }}/files/{{ MD.vxlan.name }}_service_model_extended_previous.json" + ansible.builtin.command: mv "{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_extended.json" "{{ role_path }}/files/{{ MD_Extended.vxlan.fabric.name }}_service_model_extended_previous.json" when: extended_stat.stat.exists and check_roles['save_previous'] delegate_to: localhost diff --git a/roles/validate/tasks/sub_main.yml b/roles/validate/tasks/sub_main.yml index 1d251656..64112202 100644 --- a/roles/validate/tasks/sub_main.yml +++ b/roles/validate/tasks/sub_main.yml @@ -107,8 +107,6 @@ register: smd delegate_to: localhost -- ansible.builtin.meta: end_play - - name: Store Golden Service Model Data ansible.builtin.set_fact: MD: "{{ smd['model_golden'] }}" diff --git a/roles/validate/tasks/sub_main_common_post.yml b/roles/validate/tasks/sub_main_common_post.yml deleted file mode 100644 index 351ff963..00000000 --- a/roles/validate/tasks/sub_main_common_post.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Check Roles - cisco.nac_dc_vxlan.common.check_roles: - role_list: "{{ role_names }}" - register: check_roles - delegate_to: localhost - -- name: Read Run Map From Previous Run - cisco.nac_dc_vxlan.common.read_run_map: - model_data: "{{ MD_Extended }}" - register: run_map_read_result - delegate_to: localhost - -- name: Debug Run Map Read Result - ansible.builtin.debug: - msg: "{{ run_map_read_result }}" - delegate_to: localhost - -- name: Initialize Run Map - cisco.nac_dc_vxlan.common.run_map: - model_data: "{{ MD_Extended }}" - stage: starting_execution - register: run_map - delegate_to: localhost - -- name: Manage Previous Service Model Data Files - ansible.builtin.include_tasks: manage_model_files_previous.yml - when: check_roles['save_previous'] - -- name: Manage Current Service Model Data Files - ansible.builtin.include_tasks: manage_model_files_current.yml - when: check_roles['save_previous'] diff --git a/roles/validate/tasks/sub_main_common_pre.yml b/roles/validate/tasks/sub_main_common_pre.yml deleted file mode 100644 index a75c5e52..00000000 --- a/roles/validate/tasks/sub_main_common_pre.yml +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Role Entry Point - [cisco.nac_dc_vxlan.validate] - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Calling Role - [cisco.nac_dc_vxlan.validate] +" - - "----------------------------------------------------------------" - -- ansible.builtin.debug: msg="Role Path - {{ role_path }}" - -- ansible.builtin.debug: msg="Inventory Directory - {{ inventory_dir }}" - -- name: Validate NDFC Service Model Data - ansible.builtin.debug: msg="Calling Role Validate - nac_dc_vxlan.validate" - -- ansible.builtin.debug: msg="Workflow is Direct to Controller (DTC)" - when: hostvars[inventory_hostname]['ansible_network_os'] == "cisco.dcnm.dcnm" - -- name: Load Data Model - cisco.nac_dc_vxlan.common.nac_dc_load: - mdata: "{{ data_path }}" - register: model_data - vars: - data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - delegate_to: localhost - -- name: Stat Factory Defaults - ansible.builtin.stat: path="{{ role_path }}/files/defaults.yml" - register: factory_defaults_file - delegate_to: localhost - -- name: Include Factory Defaults if Available - ansible.builtin.include_vars: - file: "{{ role_path }}/files/defaults.yml" - when: factory_defaults_file.stat.exists - delegate_to: localhost - -- name: Merge factory and custom defaults - cisco.nac_dc_vxlan.common.merge_defaults: - factory_defaults: "{{ factory_defaults }}" - model_data: "{{ model_data['data'] }}" - register: defaults - delegate_to: localhost - -- name: Register Variable With Only Defaults from Previous Task - ansible.builtin.set_fact: - defaults: "{{ defaults['defaults'] }}" - delegate_to: localhost - -- name: Prepare Service Model - cisco.nac_dc_vxlan.common.prepare_service_model: - inventory_hostname: "{{ inventory_hostname }}" - hostvars: "{{ hostvars }}" - model_data: "{{ model_data['data'] }}" - default_values: "{{ defaults }}" - templates_path: "{{ role_path }}/../dtc/common/templates/" - register: smd - delegate_to: localhost - -- name: Store Golden Service Model Data - ansible.builtin.set_fact: - MD: "{{ smd['model_golden'] }}" - delegate_to: localhost - -- name: Store Extended Service Model Data - ansible.builtin.set_fact: - MD_Extended: "{{ smd['model_extended'] }}" - delegate_to: localhost diff --git a/roles/validate/tasks/sub_main_msd.yml b/roles/validate/tasks/sub_main_msd.yml deleted file mode 100644 index 400d755c..00000000 --- a/roles/validate/tasks/sub_main_msd.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Perform Required Syntax and Semantic Model Validation for MSD Fabric - cisco.nac_dc_vxlan.common.nac_dc_validate: - schema: "{{ schema_path }}" - mdata: "{{ data_path }}" - rules: "{{ rules_path }}" - vars: - data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - rules_path: "{{ role_path }}/files/rules/required_rules/msd/" - delegate_to: localhost diff --git a/roles/validate/tasks/sub_main_vxlan.yml b/roles/validate/tasks/sub_main_vxlan.yml deleted file mode 100644 index 75c64515..00000000 --- a/roles/validate/tasks/sub_main_vxlan.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Perform Required Syntax and Semantic Model Validation for VXLAN Fabric - cisco.nac_dc_vxlan.common.nac_dc_validate: - schema: "{{ schema_path }}" - mdata: "{{ data_path }}" - rules: "{{ rules_path }}" - vars: - data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - rules_path: "{{ role_path }}/files/rules/" - delegate_to: localhost From 73abf697e7af0718cfa42239dd0d290600d79d30 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 5 Dec 2024 10:57:38 -0500 Subject: [PATCH 17/66] chagnes from review with mike --- roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml | 2 +- .../401_overlay_services_cross_reference.py | 85 ++++++++++--------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml index da83cfce..a0949307 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_attach_vrfs.yml" + file_name: "{{ MD.vxlan.global.name }}_ndfc_attach_vrfs.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py index b4e0f9f7..3a7cf6db 100644 --- a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py +++ b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py @@ -14,16 +14,18 @@ def match(cls, inventory): vrf_attach_groups = None switch_keys = ['vxlan', 'topology', 'switches'] - network_keys = ['vxlan', 'overlay', 'networks'] - vrf_keys = ['vxlan', 'overlay', 'vrfs'] - network_attach_keys = ['vxlan', 'overlay', 'network_attach_groups'] - vrf_attach_keys = ['vxlan', 'overlay', 'vrf_attach_groups'] - # For backwards compatibility - network_keys = ['vxlan', 'overlay_services', 'networks'] - vrf_keys = ['vxlan', 'overlay_services', 'vrfs'] - network_attach_keys = ['vxlan', 'overlay_services', 'network_attach_groups'] - vrf_attach_keys = ['vxlan', 'overlay_services', 'vrf_attach_groups'] + # Remove the check for overlay_services after deprecation + # Remove lines 21 - 23 + overlay_key = 'overlay' + check = cls.data_model_key_check(inventory, ['vxlan']) + if 'overlay_services' in check['keys_found'] and 'overlay_services' in check['keys_data']: + overlay_key = 'overlay_services' + + network_keys = ['vxlan', f'{overlay_key}', 'networks'] + vrf_keys = ['vxlan', f'{overlay_key}', 'vrfs'] + network_attach_keys = ['vxlan', f'{overlay_key}', 'network_attach_groups'] + vrf_attach_keys = ['vxlan', f'{overlay_key}', 'vrf_attach_groups'] # Check if vrfs, network and switch data is defined in the service model check = cls.data_model_key_check(inventory, switch_keys) @@ -58,39 +60,40 @@ def match(cls, inventory): results = cls.cross_reference_switches(network_attach_groups, switches, 'network', results) # For backwards compatibility - sm_networks = None - sm_vrfs = None - network_attach_groups = None - vrf_attach_groups = None + # Lines 54 - 88 will be removed after the deprecation in a future release + # sm_networks = None + # sm_vrfs = None + # network_attach_groups = None + # vrf_attach_groups = None - network_keys = ['vxlan', 'overlay_services', 'networks'] - vrf_keys = ['vxlan', 'overlay_services', 'vrfs'] - network_attach_keys = ['vxlan', 'overlay_services', 'network_attach_groups'] - vrf_attach_keys = ['vxlan', 'overlay_services', 'vrf_attach_groups'] - - check = cls.data_model_key_check(inventory, network_keys) - if 'networks' in check['keys_data']: - sm_networks = cls.safeget(inventory, network_keys) - - check = cls.data_model_key_check(inventory, vrf_keys) - if 'vrfs' in check['keys_data']: - sm_vrfs = cls.safeget(inventory, vrf_keys) - - check = cls.data_model_key_check(inventory, vrf_attach_keys) - if 'vrf_attach_groups' in check['keys_data']: - vrf_attach_groups = cls.safeget(inventory, vrf_attach_keys) - - check = cls.data_model_key_check(inventory, network_attach_keys) - if 'network_attach_groups' in check['keys_data']: - network_attach_groups = cls.safeget(inventory, network_attach_keys) - - # Ensure Network is not referencing a VRF that is not defined in the service model - results = cls.cross_reference_vrfs_nets(sm_vrfs, sm_networks, results) - - if sm_vrfs and vrf_attach_groups: - results = cls.cross_reference_switches(vrf_attach_groups, switches, 'vrf', results) - if sm_networks and network_attach_groups: - results = cls.cross_reference_switches(network_attach_groups, switches, 'network', results) + # network_keys = ['vxlan', 'overlay_services', 'networks'] + # vrf_keys = ['vxlan', 'overlay_services', 'vrfs'] + # network_attach_keys = ['vxlan', 'overlay_services', 'network_attach_groups'] + # vrf_attach_keys = ['vxlan', 'overlay_services', 'vrf_attach_groups'] + + # check = cls.data_model_key_check(inventory, network_keys) + # if 'networks' in check['keys_data']: + # sm_networks = cls.safeget(inventory, network_keys) + + # check = cls.data_model_key_check(inventory, vrf_keys) + # if 'vrfs' in check['keys_data']: + # sm_vrfs = cls.safeget(inventory, vrf_keys) + + # check = cls.data_model_key_check(inventory, vrf_attach_keys) + # if 'vrf_attach_groups' in check['keys_data']: + # vrf_attach_groups = cls.safeget(inventory, vrf_attach_keys) + + # check = cls.data_model_key_check(inventory, network_attach_keys) + # if 'network_attach_groups' in check['keys_data']: + # network_attach_groups = cls.safeget(inventory, network_attach_keys) + + # # Ensure Network is not referencing a VRF that is not defined in the service model + # results = cls.cross_reference_vrfs_nets(sm_vrfs, sm_networks, results) + + # if sm_vrfs and vrf_attach_groups: + # results = cls.cross_reference_switches(vrf_attach_groups, switches, 'vrf', results) + # if sm_networks and network_attach_groups: + # results = cls.cross_reference_switches(network_attach_groups, switches, 'network', results) return results From becfbd5cfb01cdefad7bd2ccde3610eced67976b Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 5 Dec 2024 13:19:12 -0500 Subject: [PATCH 18/66] update fabric name reference to use extended --- plugins/action/dtc/get_poap_data.py | 2 +- roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_inventory.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_networks.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_policy.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/plugins/action/dtc/get_poap_data.py b/plugins/action/dtc/get_poap_data.py index 31a48e87..c6ace50a 100644 --- a/plugins/action/dtc/get_poap_data.py +++ b/plugins/action/dtc/get_poap_data.py @@ -66,7 +66,7 @@ def __init__(self, params): self.task_vars = params['task_vars'] self.tmp = params['tmp'] - self.fabric_name = self.model_data['vxlan']['global']['name'] + self.fabric_name = self.model_data['vxlan']['fabric']['name'] self.switches = self.model_data['vxlan']['topology']['switches'] self.poap_supported_switches = False self.preprovision_supported_switches = False diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml index b83285ee..ba50dea1 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_access.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_access.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml index a03c57f8..2e5b2b6f 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_access_po.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_access_po.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml index a23f0579..392934c7 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_all.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_all.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml index cb7284bd..d720d5f6 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_loopback_interfaces.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_loopback_interfaces.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml index 24bc6373..7fb2af33 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_po_routed.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_po_routed.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml index 32bddef0..4c2f9068 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_routed.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_routed.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml index ca1edf7d..073f02ce 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_trunk.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_trunk.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml index f3b807d9..b97086ac 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_trunk_po.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_trunk_po.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml index efd1d385..5554d65d 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_vpc.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_vpc.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml b/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml index df01b160..db6667a4 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml @@ -33,7 +33,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_inventory.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_inventory.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml b/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml index 691e2d1f..1102baf1 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_link_vpc_peering.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_link_vpc_peering.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_networks.yml b/roles/dtc/common/tasks/vxlan/ndfc_networks.yml index 595cf45b..5437b7c2 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_networks.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_networks.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_attach_networks.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_attach_networks.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_policy.yml b/roles/dtc/common/tasks/vxlan/ndfc_policy.yml index 66d01169..f8eb9712 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_policy.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_policy.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_policy.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_policy.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml index 3c828214..9677853e 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_sub_interface_routed.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_sub_interface_routed.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml b/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml index bd53f0ac..261d4899 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_vpc_peering.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_vpc_peering.yml" delegate_to: localhost - name: Stat Previous File If It Exists diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml index a0949307..2ea68d17 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml @@ -28,7 +28,7 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD.vxlan.global.name }}_ndfc_attach_vrfs.yml" + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_attach_vrfs.yml" delegate_to: localhost - name: Stat Previous File If It Exists From b6cbb56ed556c4f8ea7c663a1e22c5261dad2d67 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 5 Dec 2024 17:15:57 -0500 Subject: [PATCH 19/66] updats to msite templates --- .../msd_fabric/dci/msd_fabric_dci.j2 | 22 ++++++++++--------- .../msd_fabric/general/msd_fabric_general.j2 | 4 ++++ .../ndfc_fabric/msd_fabric/msd_fabric_base.j2 | 9 ++++++++ .../resources/msd_fabric_resources.j2 | 12 +++++++--- .../security/msd_fabric_security.j2 | 2 +- roles/validate/files/defaults.yml | 17 +++++++++----- 6 files changed, 46 insertions(+), 20 deletions(-) diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 index e459e813..8867c152 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 @@ -1,12 +1,14 @@ {# Auto-generated NDFC MSD DCI config data structure for fabric {{ vxlan.fabric.name }} #} - BORDER_GWY_CONNECTIONS: {{ vxlan.multisite.overlay_ifc | default(defaults.vxlan.multisite.overlay_ifc) }} - MS_UNDERLAY_AUTOCONFIG: {{ vxlan.multisite.underlay_autoconfig | default(defaults.vxlan.multisite.underlay_autoconfig) }} - ENABLE_BGP_SEND_COMM: {{ vxlan.multisite.enable_bgp_send_community | default(defaults.vxlan.multisite.enable_bgp_send_community) }} - ENABLE_BGP_LOG_NEIGHBOR_CHANGE: {{ vxlan.multisite.enable_bgp_log_neighbor_change | default(defaults.vxlan.multisite.enable_bgp_log_neighbor_change) }} - ENABLE_BGP_BFD: {{ vxlan.multisite.enable_bgp_bfd | default(defaults.vxlan.multisite.enable_bgp_bfd) }} - DELAY_RESTORE: {{ vxlan.multisite.delay_restore | default(defaults.vxlan.multisite.delay_restore) }} - MS_IFC_BGP_PASSWORD_ENABLE: {{ vxlan.multisite.enable_bgp_password | default(defaults.vxlan.multisite.enable_bgp_password) }} -{% if vxlan.multisite.enable_bgp_password is defined and vxlan.multisite.enable_bgp_password %} - MS_IFC_BGP_PASSWORD: {{ vxlan.multisite.bgp_password }} - MS_IFC_BGP_AUTH_KEY_TYPE: {{ vxlan.multisite.bgp_auth_key_type | default(defaults.vxlan.multisite.bgp_auth_key_type) }} + BORDER_GWY_CONNECTIONS: {{ vxlan.multisite.overlay_ifc | default(defaults.vxlan.multisite.overlay_ifc) }} + MS_UNDERLAY_AUTOCONFIG: {{ vxlan.multisite.underlay_autoconfig | default(defaults.vxlan.multisite.underlay_autoconfig) }} +{% if vxlan.multisite.underlay_autoconfig | default(defaults.vxlan.multisite.underlay_autoconfig) %} + ENABLE_BGP_SEND_COMM: {{ vxlan.multisite.enable_bgp_send_community | default(defaults.vxlan.multisite.enable_bgp_send_community) }} + ENABLE_BGP_LOG_NEIGHBOR_CHANGE: {{ vxlan.multisite.enable_bgp_log_neighbor_change | default(defaults.vxlan.multisite.enable_bgp_log_neighbor_change) | lower }} + ENABLE_BGP_BFD: {{ vxlan.multisite.enable_bgp_bfd | default(defaults.vxlan.multisite.enable_bgp_bfd) }} +{% endif %} + DELAY_RESTORE: {{ vxlan.multisite.delay_restore | default(defaults.vxlan.multisite.delay_restore) }} + MS_IFC_BGP_PASSWORD_ENABLE: {{ vxlan.multisite.enable_ebgp_password | default(defaults.vxlan.multisite.enable_ebgp_password) }} +{% if vxlan.multisite.enable_ebgp_password | default(defaults.vxlan.multisite.enable_ebgp_password) %} + MS_IFC_BGP_PASSWORD: {{ vxlan.multisite.ebgp_password }} + MS_IFC_BGP_AUTH_KEY_TYPE: {{ vxlan.multisite.ebgp_password_encryption_type | default(defaults.vxlan.multisite.ebgp_password_encryption_type) }} {% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 index baafab7c..07b9c871 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 @@ -1,6 +1,10 @@ {# Auto-generated NDFC MSD General config data structure for fabric {{ vxlan.fabric.name }} #} + VXLAN_UNDERLAY_IS_V6: False +{% if not vxlan.multisite.enable_ipv6_underlay | default(defaults.vxlan.multisite.enable_ipv6_underlay) %} ENABLE_PVLAN: false +{% endif %} ANYCAST_GW_MAC: {{ vxlan.multisite.anycast_gateway_mac | default(defaults.vxlan.multisite.anycast_gateway_mac) }} MS_LOOPBACK_ID: {{ vxlan.multisite.vtep_loopback_id | default(defaults.vxlan.multisite.vtep_loopback_id) }} BGW_ROUTING_TAG: {{ vxlan.multisite.bgw_ip_tag | default(defaults.vxlan.multisite.bgw_ip_tag) }} + TOR_AUTO_DEPLOY: False {# #} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 index 19ea1f87..ba997f3d 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 @@ -5,3 +5,12 @@ {# Include NDFC DC VXLAN EVPN General Template #} {% include '/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2' %} + +{# Include NDFC DC VXLAN EVPN DCI Template #} +{% include '/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2' %} + +{# Include NDFC DC VXLAN EVPN Security Template #} +{% include '/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2' %} + +{# Include NDFC DC VXLAN EVPN Resources Template #} +{% include '/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2' %} diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 index 8f7fd495..73496073 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 @@ -1,4 +1,10 @@ {# Auto-generated NDFC MSD Resources config data structure for fabric {{ vxlan.fabric.name }} #} - LOOPBACK100_IP_RANGE: {{ vxlan.multisite.vtep_loopback_ip_range | default(defaults.vxlan.multisite.vtep_loopback_ip_range) }} - DCI_SUBNET_RANGE: {{ vxlan.multisite.dci_subnet_range | default(defaults.vxlan.multisite.dci_subnet_range) }} - DCI_SUBNET_MASK: {{ vxlan.multisite.dci_subnet_mask | default(defaults.vxlan.multisite.dci_subnet_mask) }} \ No newline at end of file +{% if not defaults.vxlan.multisite.enable_ipv6_underlay %} + LOOPBACK100_IP_RANGE: {{ vxlan.multisite.ipv4_vtep_loopback_range | default(defaults.vxlan.multisite.ipv4_vtep_loopback_range) }} + DCI_SUBNET_RANGE: {{ vxlan.multisite.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.ipv4_dci_subnet_range) }} + DCI_SUBNET_MASK: {{ vxlan.multisite.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.ipv4_dci_subnet_mask) }} +{% else %} + LOOPBACK100_IPV6_RANGE: {{ vxlan.multisite.ipv6_vtep_loopback_range | default(defaults.vxlan.multisite.ipv6_vtep_loopback_range) }} + V6_DCI_SUBNET_RANGE: {{ vxlan.multisite.ipv6_dci_subnet_range | default(defaults.vxlan.multisite.ipv6_dci_subnet_range) }} + V6_DCI_SUBNET_TARGET_MASK: {{ vxlan.multisite.ipv6_dci_subnet_mask | default(defaults.vxlan.multisite.ipv6_dci_subnet_mask) }} +{% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 index 80d69feb..a38f6b56 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 @@ -1,2 +1,2 @@ {# Auto-generated NDFC MSD Security config data structure for fabric {{ vxlan.fabric.name }} #} - ENABLE_SGT: false \ No newline at end of file + ENABLE_SGT: false \ No newline at end of file diff --git a/roles/validate/files/defaults.yml b/roles/validate/files/defaults.yml index 5b81d6c6..5918c7cd 100644 --- a/roles/validate/files/defaults.yml +++ b/roles/validate/files/defaults.yml @@ -272,16 +272,21 @@ factory_defaults: default_originate: false next_hop_self: false multisite: + enable_ipv6_underlay: false anycast_gateway_mac: 20:20:00:00:00:aa vtep_loopback_id: 100 - vtep_loopback_ip_range: 10.10.0.0/24 - dci_subnet_range: 10.10.1.0/24 - dci_subnet_mask: 30 + ipv4_vtep_loopback_range: 10.10.0.0/24 + ipv4_dci_subnet_range: 10.10.1.0/24 + ipv4_dci_subnet_mask: 30 + ipv6_vtep_loopback_range: fd00::a10:0/120 + ipv6_dci_subnet_range: fd00::a11:0/120 + ipv6_dci_subnet_mask: 126 bgw_ip_tag: 54321 - overlay_ifc: direct_to_bgws - underlay_autoconfig: false + overlay_ifc: Direct_To_BGWS + underlay_autoconfig: true enable_bgp_send_community: false enable_bgp_log_neighbor_change: false enable_bgp_bfd: false delay_restore: 300 - enable_bgp_password: false + enable_ebgp_password: false + enable_trm: false From 1e7af3360e6685a8ab00dedb2ccd5ac9d8ba56a8 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 5 Dec 2024 20:23:45 -0500 Subject: [PATCH 20/66] update to msd tempaltes and add conditional to only run child fabrics if defined --- plugins/filter/quote.py | 85 +++++++++++++++++++ .../msd_fabric/general/msd_fabric_general.j2 | 2 +- .../resources/msd_fabric_resources.j2 | 2 +- .../security/msd_fabric_security.j2 | 2 +- roles/dtc/create/tasks/sub_main_msd.yml | 4 +- 5 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 plugins/filter/quote.py diff --git a/plugins/filter/quote.py b/plugins/filter/quote.py new file mode 100644 index 00000000..9203ea35 --- /dev/null +++ b/plugins/filter/quote.py @@ -0,0 +1,85 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +DOCUMENTATION = r""" + name: quote + version_added: "0.4.0" + short_description: Quote + description: + - Quote a string or integer. + positional: item + options: + item: + description: Item to quote. + required: true +""" + +EXAMPLES = r""" + + quoted: "{{ var1 | cisco.nac_dc_vxlan.quote() }}" + # => True + +""" + +RETURN = r""" + _value: + description: + - A string value. + type: str +""" + +import operator +from jinja2.runtime import Undefined +from jinja2.exceptions import UndefinedError + +from packaging.version import Version + +from ansible.module_utils.six import string_types +from ansible.errors import AnsibleFilterError, AnsibleFilterTypeError +from ansible.module_utils.common.text.converters import to_native + + +def quote(item): + # if not isinstance(version1, (string_types, Undefined)): + # raise AnsibleFilterTypeError(f"Can only check string versions, however version1 is: {type(version1)}") + + # if not isinstance(version2, (string_types, Undefined)): + # raise AnsibleFilterTypeError(f"Can only check string versions, however version2 is: {type(version2)}") + + # if not isinstance(op, (string_types, Undefined)) and op not in SUPPORTED_COMPARISON_OPERATORS: + # raise AnsibleFilterError(f"Unsupported operator {op} type. Supported operators are: {SUPPORTED_COMPARISON_OPERATORS}") + + try: + return f'"{item}"' + except UndefinedError: + raise + except Exception as e: + raise AnsibleFilterError("Unable handle version: %s" % to_native(e), orig_exc=e) + + +# ---- Ansible filters ---- +class FilterModule(object): + """ Quote filter """ + + def filters(self): + return { + "quote": quote + } diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 index 07b9c871..362e2257 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 @@ -6,5 +6,5 @@ ANYCAST_GW_MAC: {{ vxlan.multisite.anycast_gateway_mac | default(defaults.vxlan.multisite.anycast_gateway_mac) }} MS_LOOPBACK_ID: {{ vxlan.multisite.vtep_loopback_id | default(defaults.vxlan.multisite.vtep_loopback_id) }} BGW_ROUTING_TAG: {{ vxlan.multisite.bgw_ip_tag | default(defaults.vxlan.multisite.bgw_ip_tag) }} - TOR_AUTO_DEPLOY: False + TOR_AUTO_DEPLOY: false {# #} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 index 73496073..dc5d0db3 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 @@ -2,7 +2,7 @@ {% if not defaults.vxlan.multisite.enable_ipv6_underlay %} LOOPBACK100_IP_RANGE: {{ vxlan.multisite.ipv4_vtep_loopback_range | default(defaults.vxlan.multisite.ipv4_vtep_loopback_range) }} DCI_SUBNET_RANGE: {{ vxlan.multisite.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.ipv4_dci_subnet_range) }} - DCI_SUBNET_MASK: {{ vxlan.multisite.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.ipv4_dci_subnet_mask) }} + DCI_SUBNET_TARGET_MASK: {{ vxlan.multisite.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.ipv4_dci_subnet_mask) }} {% else %} LOOPBACK100_IPV6_RANGE: {{ vxlan.multisite.ipv6_vtep_loopback_range | default(defaults.vxlan.multisite.ipv6_vtep_loopback_range) }} V6_DCI_SUBNET_RANGE: {{ vxlan.multisite.ipv6_dci_subnet_range | default(defaults.vxlan.multisite.ipv6_dci_subnet_range) }} diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 index a38f6b56..715734a7 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/security/msd_fabric_security.j2 @@ -1,2 +1,2 @@ {# Auto-generated NDFC MSD Security config data structure for fabric {{ vxlan.fabric.name }} #} - ENABLE_SGT: false \ No newline at end of file + ENABLE_SGT: "off" \ No newline at end of file diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index d9e6d51a..8ee865a5 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -42,7 +42,7 @@ - name: Manage NDFC MSD Fabric Child Fabrics ansible.builtin.import_tasks: msd/child_fabrics.yml - # when: - # - MD_Extended.vxlan.topology.switches | length > 0 + when: + - MD_Extended.vxlan.multisite.child_fabrics is defined and MD_Extended.vxlan.multisite.child_fabrics | length > 0 # - changes_detected_inventory # tags: "{{ nac_tags.create_switches }}" From 48019b0c950b33952dee8ac2335b2e6b533d6c79 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Sun, 8 Dec 2024 21:40:14 -0500 Subject: [PATCH 21/66] first commit from hospital --- plugins/action/common/nac_dc_validate.py | 2 + ...ild_fabrics.py => manage_child_fabrics.py} | 1 - .../dtc/update_switch_hostname_policy.py | 8 +- roles/dtc/common/tasks/isn/ndfc_fabric.yml | 77 +++++++++++++ roles/dtc/common/tasks/isn/ndfc_inventory.yml | 105 ++++++++++++++++++ roles/dtc/common/tasks/main.yml | 5 + roles/dtc/common/tasks/msd/ndfc_networks.yml | 83 ++++++++++++++ roles/dtc/common/tasks/msd/ndfc_vrfs.yml | 83 ++++++++++++++ roles/dtc/common/tasks/sub_main_isn.yml | 48 ++++++++ .../dtc/common/tasks/vxlan/ndfc_networks.yml | 4 +- roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml | 4 +- roles/dtc/common/templates/ndfc_fabric.j2 | 7 +- .../templates/ndfc_fabric/isn_fabric/.gitkeep | 0 .../ndfc_fabric/isn_fabric/advanced/.gitkeep | 0 .../advanced/isn_fabric_advanced.j2 | 10 ++ .../ndfc_fabric/isn_fabric/bootstrap/.gitkeep | 0 .../bootstrap/isn_fabric_bootstrap.j2 | 19 ++++ .../isn_fabric/flow_monitor/.gitkeep | 0 .../flow_monitor/isn_fabric_flow_monitor.j2 | 28 +++++ .../ndfc_fabric/isn_fabric/general/.gitkeep | 0 .../isn_fabric/general/isn_fabric_general.j2 | 4 + .../ndfc_fabric/isn_fabric/isn_fabric_base.j2 | 19 ++++ .../ndfc_fabric/isn_fabric/resources/.gitkeep | 0 .../resources/isn_fabric_resources.j2 | 2 + .../ndfc_fabric/isn_fabric/temp.json | 86 ++++++++++++++ roles/dtc/common/templates/ndfc_inventory.j2 | 50 +++------ .../common/templates/ndfc_inventory/.gitkeep | 0 .../ndfc_inventory/dc_vxlan_fabric/.gitkeep | 0 .../dc_vxlan_fabric_inventory.j2 | 32 ++++++ .../ndfc_inventory/isn_fabric/.gitkeep | 0 .../isn_fabric/isn_fabric_inventory.j2 | 33 ++++++ roles/dtc/create/tasks/isn/devices.yml | 32 ++++++ .../create/tasks/isn/devices_discovery.yml | 60 ++++++++++ roles/dtc/create/tasks/isn/fabric.yml | 34 ++++++ roles/dtc/create/tasks/main.yml | 4 + roles/dtc/create/tasks/msd/child_fabrics.yml | 9 +- roles/dtc/create/tasks/msd/vrfs_networks.yml | 58 ++++++++++ roles/dtc/create/tasks/sub_main_isn.yml | 48 ++++++++ roles/dtc/create/tasks/sub_main_msd.yml | 10 ++ roles/dtc/create/tasks/sub_main_vxlan.yml | 9 +- .../dtc/create/tasks/vxlan/vrfs_networks.yml | 17 ++- roles/dtc/deploy/tasks/sub_main.yml | 10 +- roles/dtc/remove/tasks/msd/child_fabrics.yml | 0 roles/dtc/remove/tasks/msd/networks.yml | 45 ++++++++ roles/dtc/remove/tasks/msd/vrfs.yml | 45 ++++++++ roles/dtc/remove/tasks/sub_main_msd.yml | 12 ++ roles/validate/files/defaults.yml | 10 ++ roles/validate/files/rules/isn/.gitkeep | 0 48 files changed, 1055 insertions(+), 58 deletions(-) rename plugins/action/dtc/{move_child_fabrics.py => manage_child_fabrics.py} (99%) create mode 100644 roles/dtc/common/tasks/isn/ndfc_fabric.yml create mode 100644 roles/dtc/common/tasks/isn/ndfc_inventory.yml create mode 100644 roles/dtc/common/tasks/msd/ndfc_networks.yml create mode 100644 roles/dtc/common/tasks/msd/ndfc_vrfs.yml create mode 100644 roles/dtc/common/tasks/sub_main_isn.yml create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/advanced/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/advanced/isn_fabric_advanced.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/general/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/general/isn_fabric_general.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/resources/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/resources/isn_fabric_resources.j2 create mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/temp.json create mode 100644 roles/dtc/common/templates/ndfc_inventory/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_inventory/dc_vxlan_fabric/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_inventory/dc_vxlan_fabric/dc_vxlan_fabric_inventory.j2 create mode 100644 roles/dtc/common/templates/ndfc_inventory/isn_fabric/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2 create mode 100644 roles/dtc/create/tasks/isn/devices.yml create mode 100644 roles/dtc/create/tasks/isn/devices_discovery.yml create mode 100644 roles/dtc/create/tasks/isn/fabric.yml create mode 100644 roles/dtc/create/tasks/msd/vrfs_networks.yml create mode 100644 roles/dtc/create/tasks/sub_main_isn.yml create mode 100644 roles/dtc/remove/tasks/msd/child_fabrics.yml create mode 100644 roles/dtc/remove/tasks/msd/networks.yml create mode 100644 roles/dtc/remove/tasks/msd/vrfs.yml create mode 100644 roles/validate/files/rules/isn/.gitkeep diff --git a/plugins/action/common/nac_dc_validate.py b/plugins/action/common/nac_dc_validate.py index 8f45aaaf..1a9fc3b4 100644 --- a/plugins/action/common/nac_dc_validate.py +++ b/plugins/action/common/nac_dc_validate.py @@ -95,6 +95,8 @@ def run(self, tmp=None, task_vars=None): rules_list.append(f'{rules}vxlan/') elif results['data']['vxlan']['fabric']['type'] in ('MSD', 'MCF'): rules_list.append(f'{rules}multisite/') + elif results['data']['vxlan']['fabric']['type'] in ('ISN'): + rules_list.append(f'{rules}isn/') else: results['failed'] = True results['msg'] = f"vxlan.fabric.type {results['data']['vxlan']['fabric']['type']} is not a supported fabric type." diff --git a/plugins/action/dtc/move_child_fabrics.py b/plugins/action/dtc/manage_child_fabrics.py similarity index 99% rename from plugins/action/dtc/move_child_fabrics.py rename to plugins/action/dtc/manage_child_fabrics.py index 7163d029..1e7eb14e 100644 --- a/plugins/action/dtc/move_child_fabrics.py +++ b/plugins/action/dtc/manage_child_fabrics.py @@ -70,7 +70,6 @@ def run(self, tmp=None, task_vars=None): # https://rtp-ndfc1.cisco.com/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations/ # GET -# # https://rtp-ndfc1.cisco.com/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd # POST diff --git a/plugins/action/dtc/update_switch_hostname_policy.py b/plugins/action/dtc/update_switch_hostname_policy.py index f52891b2..574dfe75 100644 --- a/plugins/action/dtc/update_switch_hostname_policy.py +++ b/plugins/action/dtc/update_switch_hostname_policy.py @@ -49,7 +49,13 @@ def run(self, tmp=None, task_vars=None): template_name=template_name ) - switch_match = next((item for item in model_data["vxlan"]["topology"]["switches"] if item["serial_number"] == switch_serial_number)) + dm_switches = [] + if model_data["vxlan"]["fabric"]["type"] in ('VXLAN_EVPN'): + dm_switches = model_data["vxlan"]["topology"]["switches"] + elif model_data["vxlan"]["fabric"]["type"] in ('ISN'): + dm_switches = model_data["vxlan"]["multisite"]["isn"]["topology"]["switches"] + + switch_match = next((item for item in dm_switches if item["serial_number"] == switch_serial_number)) if policy_match["nvPairs"]["SWITCH_NAME"] != switch_match["name"]: policy_match["nvPairs"]["SWITCH_NAME"] = switch_match["name"] diff --git a/roles/dtc/common/tasks/isn/ndfc_fabric.yml b/roles/dtc/common/tasks/isn/ndfc_fabric.yml new file mode 100644 index 00000000..a6ed2eea --- /dev/null +++ b/roles/dtc/common/tasks/isn/ndfc_fabric.yml @@ -0,0 +1,77 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_fabric: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_fabric.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + # TODO: Add capability to overridde path variable above for CI/CD pipeline + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Fabric Creation Parameters From Template + ansible.builtin.template: + src: ndfc_fabric.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- ansible.builtin.set_fact: + fabric_config: "{{ lookup('file', file_name) | from_yaml }}" + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_fabric: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/isn/ndfc_inventory.yml b/roles/dtc/common/tasks/isn/ndfc_inventory.yml new file mode 100644 index 00000000..bcaae060 --- /dev/null +++ b/roles/dtc/common/tasks/isn/ndfc_inventory.yml @@ -0,0 +1,105 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Get POAP Data From POAP Enabled Devices + cisco.nac_dc_vxlan.dtc.get_poap_data: + model_data: "{{ MD_Extended }}" + register: poap_data + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_inventory: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_inventory.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Set Path For Inventory File Lookup + ansible.builtin.set_fact: + inv_file_path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Build Fabric Switch Inventory List From Template + ansible.builtin.template: + src: ndfc_inventory.j2 + dest: "{{ inv_file_path }}" + delegate_to: localhost + +- name: Create Empty inv_config Var + ansible.builtin.set_fact: + inv_config: [] + delegate_to: localhost + +- name: Set inv_config Var + ansible.builtin.set_fact: + inv_config: "{{ lookup('file', file_name) | from_yaml }}" + when: (MD_Extended.vxlan.multisite.isn.topology.switches | default([])) | length > 0 + delegate_to: localhost + +- name: Retrieve NDFC Device Username and Password from Group Vars and update inv_config + cisco.nac_dc_vxlan.common.get_credentials: + inv_list: "{{ inv_config }}" + register: updated_inv_config + no_log: true + +- name: Credential Retrieval Failed + ansible.builtin.fail: + msg: "{{ updated_inv_config }}" + when: updated_inv_config['retrieve_failed'] + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_inventory: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index 67293f41..425e2cfd 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -26,6 +26,11 @@ tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml when: MD_Extended.vxlan.fabric.type == 'VXLAN_EVPN' +- name: Import Role Tasks for ISN Fabric + ansible.builtin.import_tasks: sub_main_isn.yml + tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml + when: MD_Extended.vxlan.fabric.type == 'ISN' + - name: Import Role Tasks for MSD Fabric ansible.builtin.import_tasks: sub_main_msd.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml diff --git a/roles/dtc/common/tasks/msd/ndfc_networks.yml b/roles/dtc/common/tasks/msd/ndfc_networks.yml new file mode 100644 index 00000000..0f024b8f --- /dev/null +++ b/roles/dtc/common/tasks/msd/ndfc_networks.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_networks: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_attach_networks.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Networks Attach List From Template + ansible.builtin.template: + src: ndfc_attach_networks.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set net_config Var + ansible.builtin.set_fact: + net_config: [] + delegate_to: localhost + +- name: Set net_config Var + ansible.builtin.set_fact: + net_config: "{{ lookup('file', file_name) | from_yaml }}" + when: (MD_Extended.vxlan.multisite.overlay.networks | default([])) | length > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_networks: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/msd/ndfc_vrfs.yml b/roles/dtc/common/tasks/msd/ndfc_vrfs.yml new file mode 100644 index 00000000..ce693ece --- /dev/null +++ b/roles/dtc/common/tasks/msd/ndfc_vrfs.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_vrfs: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_attach_vrfs.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build VRFs Attach List From Template + ansible.builtin.template: + src: ndfc_attach_vrfs.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Create Empty vrf_config Var + ansible.builtin.set_fact: + vrf_config: [] + delegate_to: localhost + +- name: Set vrf_config Var + ansible.builtin.set_fact: + vrf_config: "{{ lookup('file', file_name) | from_yaml }}" + when: (MD_Extended.vxlan.multisite.overlay.vrfs | default([])) | length > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_vrfs: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/sub_main_isn.yml b/roles/dtc/common/tasks/sub_main_isn.yml new file mode 100644 index 00000000..c7640485 --- /dev/null +++ b/roles/dtc/common/tasks/sub_main_isn.yml @@ -0,0 +1,48 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- ansible.builtin.fail: msg="Service Model Not Defined. Role cisco.nac_dc_vxlan.validate Must Be Called First" + when: MD is undefined + delegate_to: localhost + +# -------------------------------------------------------------------- +# Remove all files from the previous run if run_map requires it +# -------------------------------------------------------------------- +- name: Cleanup Files from Previous Run if run_map requires it + ansible.builtin.include_tasks: cleanup_files.yml + when: + - not run_map_read_result.diff_run or ((force_run_all is defined) and (force_run_all is true|bool)) + +# -------------------------------------------------------------------- +# Build Create Fabric Parameter List From Template +# -------------------------------------------------------------------- + +- name: Build Fabric Create Parameters + ansible.builtin.include_tasks: isn/ndfc_fabric.yml + +# -------------------------------------------------------------------- +# Build NDFC Fabric Switch Inventory List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Switch Inventory List From Template + ansible.builtin.include_tasks: isn/ndfc_inventory.yml diff --git a/roles/dtc/common/tasks/vxlan/ndfc_networks.yml b/roles/dtc/common/tasks/vxlan/ndfc_networks.yml index 5437b7c2..ef9714cf 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_networks.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_networks.yml @@ -64,7 +64,9 @@ - name: Set net_config Var ansible.builtin.set_fact: net_config: "{{ lookup('file', file_name) | from_yaml }}" - when: (MD_Extended.vxlan.overlay_services.networks | default([])) | length > 0 + when: > + (MD_Extended.vxlan.overlay.networks | default([])) | length > 0 or + (MD_Extended.vxlan.overlay_services.networks | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml index 2ea68d17..ac9a3be0 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml @@ -64,7 +64,9 @@ - name: Set vrf_config Var ansible.builtin.set_fact: vrf_config: "{{ lookup('file', file_name) | from_yaml }}" - when: (MD_Extended.vxlan.overlay_services.vrfs | default([])) | length > 0 + when: > + (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 or + (MD_Extended.vxlan.overlay_services.vrfs | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files diff --git a/roles/dtc/common/templates/ndfc_fabric.j2 b/roles/dtc/common/templates/ndfc_fabric.j2 index 5c1b576c..2ffbcc15 100644 --- a/roles/dtc/common/templates/ndfc_fabric.j2 +++ b/roles/dtc/common/templates/ndfc_fabric.j2 @@ -13,7 +13,10 @@ {# Include NDFC MSD Base Template #} {% include '/ndfc_fabric/msd_fabric/msd_fabric_base.j2' %} -{% else %} +{% elif vxlan.fabric.type == 'ISN'%} -{# Supported fabric types are: DC VXLAN EVPN, MSD #} +{# Include NDFC ISN Base Template #} +{% include '/ndfc_fabric/isn_fabric/isn_fabric_base.j2' %} + +{# Supported fabric types are: DC VXLAN EVPN, MSD, and ISN #} {% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/advanced/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/advanced/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/advanced/isn_fabric_advanced.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/advanced/isn_fabric_advanced.j2 new file mode 100644 index 00000000..ea5a13cc --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/advanced/isn_fabric_advanced.j2 @@ -0,0 +1,10 @@ +{# Auto-generated NDFC ISN Advanced config data structure for fabric {{ vxlan.fabric.name }} #} + POWER_REDUNDANCY_MODE: ps-redundant +{# Not supporting these features in ISN currently #} +{# Most of these features are supported only on Cisco NX-OS switches #} +{# Some of these features are supported only on Cisco Catalyst 9000 switches #} + MPLS_HANDOFF: false + AAA_REMOTE_IP_ENABLED: false + INBAND_MGMT: false + FEATURE_PTP: false +{# #} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2 new file mode 100644 index 00000000..73889b0b --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2 @@ -0,0 +1,19 @@ +{# Auto-generated NDFC ISN Bootstrap config data structure for fabric {{ vxlan.fabric.name }} #} +{# Most of these features are supported only on Cisco NX-OS switches #} +{# Some of these features are supported only on Cisco Catalyst 9000 switches #} +{% if vxlan.multisite.isn.bootstrap is defined %} +{% if (vxlan.multisite.isn.bootstrap.enable_bootstrap is defined and vxlan.multisite.isn.bootstrap.enable_bootstrap | bool) or defaults.vxlan.multisite.isn.bootstrap.enable_bootstrap | bool %} + BOOTSTRAP_ENABLE: {{ vxlan.multisite.isn.bootstrap.enable_bootstrap | default(defaults.vxlan.multisite.isn.bootstrap.enable_bootstrap) | bool }} + INBAND_ENABLE: {{ vxlan.multisite.isn.bootstrap.enable_inband | default(defaults.vxlan.multisite.isn.bootstrap.enable_inband) | bool }} + DHCP_ENABLE: {{ vxlan.multisite.isn.bootstrap.enable_local_dhcp_server | default(defaults.vxlan.multisite.isn.bootstrap.enable_local_dhcp_server) | bool }} + DHCP_IPV6_ENABLE: {{ vxlan.multisite.isn.bootstrap.dhcp_version | default(defaults.vxlan.multisite.isn.bootstrap.dhcp_version) }} + DHCP_START: {{ vxlan.multisite.isn.bootstrap.dhcp_v4.scope_start_address }} + DHCP_END: {{ vxlan.multisite.isn.bootstrap.dhcp_v4.scope_end_address }} + MGMT_GW: {{ vxlan.multisite.isn.bootstrap.dhcp_v4.switch_mgmt_default_gw }} + MGMT_PREFIX: {{ vxlan.multisite.isn.bootstrap.dhcp_v4.mgmt_prefix }} + BOOTSTRAP_MULTISUBNET: "{{ vxlan.multisite.isn.bootstrap.dhcp_v4.multi_subnet_scope }}" + ENABLE_AAA: {{ vxlan.multisite.isn.bootstrap.enable_aaa | default(defaults.vxlan.multisite.isn.bootstrap.enable_aaa) | bool }} +{% endif %} +{% else %} + BOOTSTRAP_ENABLE: false +{% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2 new file mode 100644 index 00000000..75e95771 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2 @@ -0,0 +1,28 @@ +{# Auto-generated NDFC ISN Flow Monitor config data structure for fabric {{ vxlan.fabric.name }} #} + ENABLE_NETFLOW: {{ vxlan.multisite.isn.netflow.enable | default(defaults.vxlan.multisite.isn.netflow.enable) }} +{% if vxlan.multisite.isn.netflow.enable is defined and vxlan.multisite.isn.netflow.enable | bool or defaults.vxlan.multisite.isn.netflow.enable | bool %} +{% if vxlan.multisite.isn.netflow.exporter is defined %} +{% set exporter_dict = dict() %} +{% set _ = exporter_dict.update({ "NETFLOW_EXPORTER_LIST":[] }) %} +{% for e in vxlan.multisite.isn.netflow.exporter %} +{% set _ = exporter_dict["NETFLOW_EXPORTER_LIST"].append(dict(EXPORTER_NAME=e.name,IP=e.ip_address,VRF=e.vrf | default(""), SRC_IF_NAME=e.source_interface,UDP_PORT=e.udp_port)) %} +{% endfor %} + NETFLOW_EXPORTER_LIST: "{{ exporter_dict | tojson | replace('"', '\\"') }}" +{% endif %} +{% if vxlan.multisite.isn.netflow.record is defined %} +{% set record_dict = dict() %} +{% set _ = record_dict.update({ "NETFLOW_RECORD_LIST":[] }) %} +{% for r in vxlan.multisite.isn.netflow.record %} +{% set _ = record_dict["NETFLOW_RECORD_LIST"].append(dict(RECORD_NAME=r.name,RECORD_TEMPLATE =r.template,LAYER2_RECORD=r.layer2 | default(false) | string | lower)) %} +{% endfor %} + NETFLOW_RECORD_LIST: "{{ record_dict | tojson | replace('"', '\\"') }}" +{% endif %} +{% if vxlan.multisite.isn.netflow.monitor is defined %} +{% set monitor_dict = dict() %} +{% set _ = monitor_dict.update({ "NETFLOW_MONITOR_LIST":[] }) %} +{% for m in vxlan.multisite.isn.netflow.monitor %} +{% set _ = monitor_dict["NETFLOW_MONITOR_LIST"].append(dict(MONITOR_NAME=m.name,RECORD_NAME=m.record,EXPORTER1=m.exporter1,EXPORTER2=m.exporter2 | default(""))) %} +{% endfor %} + NETFLOW_MONITOR_LIST: "{{ monitor_dict | tojson | replace('"', '\\"') }}" +{% endif %} +{% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/general/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/general/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/general/isn_fabric_general.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/general/isn_fabric_general.j2 new file mode 100644 index 00000000..b74cf2d7 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/general/isn_fabric_general.j2 @@ -0,0 +1,4 @@ +{# Auto-generated NDFC ISN General config data structure for fabric {{ vxlan.fabric.name }} #} + BGP_AS: {{ vxlan.multisite.isn.bgp_asn }} + IS_READ_ONLY: false +{# #} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 new file mode 100644 index 00000000..b7ad1e74 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 @@ -0,0 +1,19 @@ +{# Auto-generated NDFC ISN Base config data structure for fabric {{ vxlan.fabric.name }} #} +- FABRIC_NAME: {{ vxlan.fabric.name }} + FABRIC_TYPE: ISN + DEPLOY: True + +{# Include NDFC ISN General Template #} +{% include '/ndfc_fabric/isn_fabric/general/isn_fabric_general.j2' %} + +{# Include NDFC ISN Advanced Template #} +{% include '/ndfc_fabric/isn_fabric/advanced/isn_fabric_advanced.j2' %} + +{# Include NDFC ISN Resources Template #} +{% include '/ndfc_fabric/isn_fabric/resources/isn_fabric_resources.j2' %} + +{# Include NDFC ISN Bootstrap Template #} +{# {% include '/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2' %} #} + +{# Include NDFC ISN Flow Monitor Template #} +{% include '/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2' %} diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/resources/.gitkeep b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/resources/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/resources/isn_fabric_resources.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/resources/isn_fabric_resources.j2 new file mode 100644 index 00000000..693ada97 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/resources/isn_fabric_resources.j2 @@ -0,0 +1,2 @@ +{# Auto-generated NDFC ISN Resources config data structure for fabric {{ vxlan.fabric.name }} #} + SUBINTERFACE_RANGE: {{ vxlan.multisite.isn.sub_int_range | default(defaults.vxlan.multisite.isn.sub_int_range) | title }} diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/temp.json b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/temp.json new file mode 100644 index 00000000..215a2d90 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/temp.json @@ -0,0 +1,86 @@ +{ + "fabricName": "ISN", + "templateName": "External_Fabric", + "nvPairs": { + "FABRIC_NAME": "ISN", + "BGP_AS": "65000", + "PM_ENABLE": "false", + "EXT_FABRIC_TYPE": "Multi-Site External Network", + "PM_ENABLE_PREV": "false", + "INBAND_MGMT_PREV": "false", + "FEATURE_PTP_INTERNAL": "false", + "DEPLOYMENT_FREEZE": "false", + "LOOPBACK0_IP_RANGE": "10.1.0.0/22", + "FABRIC_TYPE": "External", + "FF": "External", + "MSO_SITE_ID": "", + "MSO_CONTROLER_ID": "", + "MSO_SITE_GROUP_NAME": "", + "PREMSO_PARENT_FABRIC": "", + "MSO_CONNECTIVITY_DEPLOYED": "", + "INBAND_ENABLE_PREV": "false", + "DCI_SUBNET_RANGE": "10.10.1.0/24", + "DCI_SUBNET_TARGET_MASK": "30", + "ENABLE_NETFLOW_PREV": "", + "ALLOW_NXC": "true", + "ALLOW_NXC_PREV": "", + "OVERWRITE_GLOBAL_NXC": "false", + "NXC_DEST_VRF": "management", + "NXC_SRC_INTF": "", + "NXC_PROXY_SERVER": "", + "NXC_PROXY_PORT": "8080", + "DHCP_START_INTERNAL": "", + "DHCP_END_INTERNAL": "", + "MGMT_GW_INTERNAL": "", + "MGMT_PREFIX_INTERNAL": "", + "BOOTSTRAP_MULTISUBNET_INTERNAL": "", + "MGMT_V6PREFIX_INTERNAL": "", + "DHCP_IPV6_ENABLE_INTERNAL": "", + "DOMAIN_NAME_INTERNAL": "", + "PNP_ENABLE_INTERNAL": "", + "POWER_REDUNDANCY_MODE": "ps-redundant", + "MPLS_HANDOFF": "false", + "MPLS_LB_ID": "", + "AAA_REMOTE_IP_ENABLED": "false", + "SNMP_SERVER_HOST_TRAP": "true", + "CDP_ENABLE": "false", + "ENABLE_NXAPI": "false", + "NXAPI_HTTPS_PORT": "", + "ENABLE_NXAPI_HTTP": false, + "NXAPI_HTTP_PORT": "", + "INBAND_MGMT": "false", + "FEATURE_PTP": "false", + "PTP_LB_ID": "", + "PTP_DOMAIN_ID": "", + "ENABLE_RT_INTF_STATS": "false", + "INTF_STAT_LOAD_INTERVAL": "", + "FABRIC_FREEFORM": "", + "AAA_SERVER_CONF": "", + "SUBINTERFACE_RANGE": "2-511", + "MPLS_LOOPBACK_IP_RANGE": "", + "enableRealTimeBackup": "", + "enableScheduledBackup": "", + "scheduledTime": "", + "INBAND_ENABLE": false, + "DHCP_ENABLE": false, + "PNP_ENABLE": false, + "DHCP_IPV6_ENABLE": "", + "DOMAIN_NAME": "", + "DHCP_START": "", + "DHCP_END": "", + "MGMT_GW": "", + "MGMT_PREFIX": "", + "MGMT_V6PREFIX": "", + "ENABLE_AAA": false, + "BOOTSTRAP_CONF": "", + "BOOTSTRAP_CONF_XE": "", + "BOOTSTRAP_MULTISUBNET": "", + "ENABLE_NETFLOW": "false", + "NETFLOW_EXPORTER_LIST": "", + "NETFLOW_RECORD_LIST": "", + "NETFLOW_MONITOR_LIST": "", + "NETFLOW_SAMPLER_LIST": "", + "IS_READ_ONLY": false, + "BOOTSTRAP_ENABLE": "false" + } +} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory.j2 index 7d2b89bf..895f8505 100644 --- a/roles/dtc/common/templates/ndfc_inventory.j2 +++ b/roles/dtc/common/templates/ndfc_inventory.j2 @@ -1,35 +1,17 @@ --- -# This NDFC switch inventory config data structure is auto-generated -# DO NOT EDIT MANUALLY -# -{% set poap_data = poap_data['poap_data'] %} -{% for switch in MD_Extended.vxlan.topology.switches %} -{% if switch.management.management_ipv4_address is defined %} -- seed_ip: {{ switch['management']['management_ipv4_address'] }} -{% elif switch.management.management_ipv6_address is defined %} -- seed_ip: {{ switch['management']['management_ipv6_address'] }} -{% endif %} - auth_proto: {{ MD['vxlan']['global']['auth_proto'] | default(defaults.vxlan.global.auth_proto) }} - user_name: PLACE_HOLDER_USERNAME - password: PLACE_HOLDER_PASSWORD - max_hops: 0 # this is the default value as it is not defined into the data model - role: {{ switch['role'] }} - preserve_config: false -{% if MD_Extended.vxlan.global.bootstrap is defined %} -{% if MD_Extended.vxlan.global.bootstrap.enable_bootstrap is defined and MD_Extended.vxlan.global.bootstrap.enable_bootstrap %} -{% if switch.poap is defined and switch.poap.bootstrap %} -{% if poap_data[switch['serial_number']] is defined %} -{% set pdata = poap_data[switch['serial_number']] %} - poap: - - serial_number: {{ switch['serial_number'] }} - hostname: {{ switch['name'] }} - model: {{ pdata['model'] }} - version: {{ pdata['version'] }} - config_data: - modulesModel: {{ pdata['modulesModel'] }} - gateway: {{ pdata['gateway'] }} -{% endif %} -{% endif %} -{% endif %} -{% endif %} -{% endfor %} \ No newline at end of file +{#- This NDFC fabric config data structure is auto-generated #} +{#- DO NOT EDIT MANUALLY #} + +{% set vxlan = MD_Extended.vxlan %} +{% if vxlan.fabric.type == 'VXLAN_EVPN' %} + +{# Include NDFC DC VXLAN EVPN Base Template #} +{% include '/ndfc_inventory/dc_vxlan_fabric/dc_vxlan_fabric_inventory.j2' %} + +{% elif vxlan.fabric.type == 'ISN'%} + +{# Include NDFC ISN Base Template #} +{% include '/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2' %} + +{# Supported fabric types are: DC VXLAN EVPN and ISN #} +{% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_inventory/.gitkeep b/roles/dtc/common/templates/ndfc_inventory/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_inventory/dc_vxlan_fabric/.gitkeep b/roles/dtc/common/templates/ndfc_inventory/dc_vxlan_fabric/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_inventory/dc_vxlan_fabric/dc_vxlan_fabric_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory/dc_vxlan_fabric/dc_vxlan_fabric_inventory.j2 new file mode 100644 index 00000000..e2482e42 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_inventory/dc_vxlan_fabric/dc_vxlan_fabric_inventory.j2 @@ -0,0 +1,32 @@ +{# Auto-generated NDFC DC VXLAN EVPN Inventory config data structure for fabric {{ vxlan.fabric.name }} #} +{% set poap_data = poap_data['poap_data'] %} +{% for switch in MD_Extended.vxlan.topology.switches %} +{% if switch.management.management_ipv4_address is defined %} +- seed_ip: {{ switch['management']['management_ipv4_address'] }} +{% elif switch.management.management_ipv6_address is defined %} +- seed_ip: {{ switch['management']['management_ipv6_address'] }} +{% endif %} + auth_proto: {{ MD['vxlan']['global']['auth_proto'] | default(defaults.vxlan.global.auth_proto) }} + user_name: PLACE_HOLDER_USERNAME + password: PLACE_HOLDER_PASSWORD + max_hops: 0 # this is the default value as it is not defined into the data model + role: {{ switch['role'] }} + preserve_config: false +{% if MD_Extended.vxlan.global.bootstrap is defined %} +{% if MD_Extended.vxlan.global.bootstrap.enable_bootstrap is defined and MD_Extended.vxlan.global.bootstrap.enable_bootstrap %} +{% if switch.poap is defined and switch.poap.bootstrap %} +{% if poap_data[switch['serial_number']] is defined %} +{% set pdata = poap_data[switch['serial_number']] %} + poap: + - serial_number: {{ switch['serial_number'] }} + hostname: {{ switch['name'] }} + model: {{ pdata['model'] }} + version: {{ pdata['version'] }} + config_data: + modulesModel: {{ pdata['modulesModel'] }} + gateway: {{ pdata['gateway'] }} +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_inventory/isn_fabric/.gitkeep b/roles/dtc/common/templates/ndfc_inventory/isn_fabric/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2 new file mode 100644 index 00000000..dbe6eb18 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2 @@ -0,0 +1,33 @@ +{# Auto-generated NDFC ISN Inventory config data structure for fabric {{ vxlan.fabric.name }} #} +{% set poap_data = poap_data['poap_data'] %} +{% for switch in MD_Extended.vxlan.multisite.isn.topology.switches %} +{% if switch.management.management_ipv4_address is defined %} +- seed_ip: {{ switch['management']['management_ipv4_address'] }} +{% elif switch.management.management_ipv6_address is defined %} +- seed_ip: {{ switch['management']['management_ipv6_address'] }} +{% endif %} + deviceType: NX-OS + auth_proto: {{ MD['vxlan']['global']['auth_proto'] | default(defaults.vxlan.global.auth_proto) }} + user_name: PLACE_HOLDER_USERNAME + password: PLACE_HOLDER_PASSWORD + max_hops: 0 # this is the default value as it is not defined into the data model + role: core_router + preserve_config: true +{% if MD_Extended.vxlan.multisite.isn.bootstrap is defined %} +{% if MD_Extended.vxlan.multisite.isn.bootstrap.enable_bootstrap is defined and MD_Extended.vxlan.multisite.isn.bootstrap.enable_bootstrap %} +{% if switch.poap is defined and switch.poap.bootstrap %} +{% if poap_data[switch['serial_number']] is defined %} +{% set pdata = poap_data[switch['serial_number']] %} + poap: + - serial_number: {{ switch['serial_number'] }} + hostname: {{ switch['name'] }} + model: {{ pdata['model'] }} + version: {{ pdata['version'] }} + config_data: + modulesModel: {{ pdata['modulesModel'] }} + gateway: {{ pdata['gateway'] }} +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} \ No newline at end of file diff --git a/roles/dtc/create/tasks/isn/devices.yml b/roles/dtc/create/tasks/isn/devices.yml new file mode 100644 index 00000000..fc7dee54 --- /dev/null +++ b/roles/dtc/create/tasks/isn/devices.yml @@ -0,0 +1,32 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Manage Devices Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Devices Fabric {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +- name: Manage Devices Discovery + ansible.builtin.include_tasks: devices_discovery.yml diff --git a/roles/dtc/create/tasks/isn/devices_discovery.yml b/roles/dtc/create/tasks/isn/devices_discovery.yml new file mode 100644 index 00000000..11ed62d4 --- /dev/null +++ b/roles/dtc/create/tasks/isn/devices_discovery.yml @@ -0,0 +1,60 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Add NDFC Fabric Devices {{ MD_Extended.vxlan.fabric.name }} + cisco.dcnm.dcnm_inventory: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: "{{ updated_inv_config['updated_inv_list'] }}" + deploy: false + save: true + state: merged + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: MD_Extended.vxlan.multisite.isn.topology.switches | length > 0 + +- name: Create List of Switch Serial Numbers from Data Model + ansible.builtin.set_fact: + md_serial_numbers: "{{ MD_Extended.vxlan.multisite.isn.topology.switches | map(attribute='serial_number') | list }}" + delegate_to: localhost + +- name: Build Switch Hostname Policy Payload from Data Model Update + cisco.nac_dc_vxlan.dtc.update_switch_hostname_policy: + model_data: "{{ MD_Extended }}" + switch_serial_numbers: "{{ md_serial_numbers }}" + template_name: host_11_1 + register: results +# do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest + +- name: Join List of Switch Hostname Policy IDs from NDFC + ansible.builtin.set_fact: + policy_ids: "{{ results.policy_update.values() | map(attribute='policyId') | list | join('%2C') }}" + when: results.policy_update | length > 0 + delegate_to: localhost + +- name: Update Switch Hostname Policy in NDFC + cisco.dcnm.dcnm_rest: + method: PUT + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/policies/{{ policy_ids }}/bulk" + json_data: "{{ results.policy_update.values() | list | to_json }}" + when: results.policy_update | length > 0 diff --git a/roles/dtc/create/tasks/isn/fabric.yml b/roles/dtc/create/tasks/isn/fabric.yml new file mode 100644 index 00000000..e810c30d --- /dev/null +++ b/roles/dtc/create/tasks/isn/fabric.yml @@ -0,0 +1,34 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Manage Fabric Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Fabric {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +- name: Manage Fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC + cisco.dcnm.dcnm_fabric: + state: merged + config: "{{ fabric_config }}" diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index be015e3b..997264de 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -27,6 +27,10 @@ - MD_Extended.vxlan.fabric.type == 'VXLAN_EVPN' - changes_detected_fabric or changes_detected_inventory or changes_detected_vpc_peering or changes_detected_interfaces or changes_detected_link_vpc_peering or changes_detected_vrfs or changes_detected_networks or changes_detected_policy +- name: Import ISN Role Tasks + ansible.builtin.import_tasks: sub_main_isn.yml + when: MD_Extended.vxlan.fabric.type == 'ISN' + - name: Import MSD Role Tasks ansible.builtin.import_tasks: sub_main_msd.yml when: MD_Extended.vxlan.fabric.type == 'MSD' diff --git a/roles/dtc/create/tasks/msd/child_fabrics.yml b/roles/dtc/create/tasks/msd/child_fabrics.yml index 31677c76..f124150b 100644 --- a/roles/dtc/create/tasks/msd/child_fabrics.yml +++ b/roles/dtc/create/tasks/msd/child_fabrics.yml @@ -34,9 +34,12 @@ path: /appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations register: fabric_associations -- name: Move Child Fabrics To Fabric - {{ MD_Extended.vxlan.fabric.name }} - cisco.nac_dc_vxlan.dtc.move_child_fabrics: +- ansible.builtin.debug: + var: fabric_associations + +- name: Add Child Fabrics To Fabric - {{ MD_Extended.vxlan.fabric.name }} + cisco.nac_dc_vxlan.dtc.manage_child_fabrics: fabric_associations: "{{ fabric_associations }}" parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" - when: fabric_associations is defined + when: fabric_associations is defined and fabric_associations diff --git a/roles/dtc/create/tasks/msd/vrfs_networks.yml b/roles/dtc/create/tasks/msd/vrfs_networks.yml new file mode 100644 index 00000000..2be757e4 --- /dev/null +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -0,0 +1,58 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Manage VRFs and Networks Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage VRFs and Networks Fabric {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +# -------------------------------------------------------------------- +# Manage VRF Configuration on NDFC +# -------------------------------------------------------------------- +- name: Manage NDFC Fabric VRFs + cisco.dcnm.dcnm_vrf: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vrf_config }}" + register: manage_vrf_result + when: + - MD_Extended.vxlan.multisite.overlay.vrfs is defined + - MD_Extended.vxlan.multisite.overlay.vrfs + - changes_detected_vrfs + + +# -------------------------------------------------------------------- +# Manage Network Configuration on NDFC +# -------------------------------------------------------------------- +- name: Manage NDFC Fabric Networks + cisco.dcnm.dcnm_network: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ net_config }}" + register: manage_network_result + when: + - MD_Extended.vxlan.multisite.overlay.networks is defined + - MD_Extended.vxlan.multisite.overlay.networks + - changes_detected_networks diff --git a/roles/dtc/create/tasks/sub_main_isn.yml b/roles/dtc/create/tasks/sub_main_isn.yml new file mode 100644 index 00000000..e7d799d2 --- /dev/null +++ b/roles/dtc/create/tasks/sub_main_isn.yml @@ -0,0 +1,48 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.create] + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Calling Role - [cisco.nac_dc_vxlan.dtc.create] +" + - "----------------------------------------------------------------" + tags: "{{ nac_tags.create }}" # Tags defined in roles/common_global/vars/main.yml + +- ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" + tags: "{{ nac_tags.create }}" + +- name: Create NDFC ISN Fabric + ansible.builtin.import_tasks: isn/fabric.yml + when: + - MD_Extended.vxlan.fabric.name is defined + - MD_Extended.vxlan.fabric.type == "ISN" + - changes_detected_fabric + tags: "{{ nac_tags.create_fabric }}" + +- name: Manage NDFC ISN Fabric Switches + ansible.builtin.import_tasks: isn/devices.yml + when: + - MD_Extended.vxlan.multisite.isn.topology.switches | length > 0 + - changes_detected_inventory + tags: "{{ nac_tags.create_switches }}" diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index 8ee865a5..10af9cdb 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -46,3 +46,13 @@ - MD_Extended.vxlan.multisite.child_fabrics is defined and MD_Extended.vxlan.multisite.child_fabrics | length > 0 # - changes_detected_inventory # tags: "{{ nac_tags.create_switches }}" + +- ansible.builtin.meta: end_play + +- name: Manage NDFC Fabric VRFs and Networks + ansible.builtin.import_tasks: msd/vrfs_networks.yml + when: > + MD_Extended.vxlan.multisite.overlay is defined and + MD_Extended.vxlan.multisite.topology.switches | length > 0 and + (changes_detected_vrfs or changes_detected_networks) + tags: "{{ nac_tags.create_vrfs_networks }}" diff --git a/roles/dtc/create/tasks/sub_main_vxlan.yml b/roles/dtc/create/tasks/sub_main_vxlan.yml index 494ecc9e..ac7415ae 100644 --- a/roles/dtc/create/tasks/sub_main_vxlan.yml +++ b/roles/dtc/create/tasks/sub_main_vxlan.yml @@ -64,14 +64,15 @@ - name: Manage NDFC Fabric VRFs and Networks ansible.builtin.import_tasks: vxlan/vrfs_networks.yml - when: - - (MD.vxlan.overlay_services is defined) and (MD_Extended.vxlan.topology.switches | length > 0) - - changes_detected_vrfs or changes_detected_networks + when: > + (MD_Extended.vxlan.overlay_services is defined or MD_Extended.vxlan.overlay is defined) and + MD_Extended.vxlan.topology.switches | length > 0 and + (changes_detected_vrfs or changes_detected_networks) tags: "{{ nac_tags.create_vrfs_networks }}" - name: Manage NDFC Fabric Policies ansible.builtin.import_tasks: vxlan/policies.yml - when: + when: - (MD_Extended.vxlan.policy is defined) and (MD_Extended.vxlan.policy.policies | length > 0) - changes_detected_policy tags: "{{ nac_tags.create_policy }}" diff --git a/roles/dtc/create/tasks/vxlan/vrfs_networks.yml b/roles/dtc/create/tasks/vxlan/vrfs_networks.yml index 025c486b..9e6b27c3 100644 --- a/roles/dtc/create/tasks/vxlan/vrfs_networks.yml +++ b/roles/dtc/create/tasks/vxlan/vrfs_networks.yml @@ -37,11 +37,10 @@ state: replaced config: "{{ vrf_config }}" register: manage_vrf_result - when: - - MD.vxlan.overlay_services.vrfs is defined - - MD.vxlan.overlay_services.vrfs - - changes_detected_vrfs - + when: > + (MD_Extended.vxlan.overlay.vrfs is defined and MD_Extended.vxlan.overlay.vrfs) or + (MD_Extended.vxlan.overlay_services.vrfs is defined and MD_Extended.vxlan.overlay_services.vrfs) and + changes_detected_vrfs # -------------------------------------------------------------------- # Manage Network Configuration on NDFC @@ -52,7 +51,7 @@ state: replaced config: "{{ net_config }}" register: manage_network_result - when: - - MD.vxlan.overlay_services.networks is defined - - MD.vxlan.overlay_services.networks - - changes_detected_networks + when: > + (MD_Extended.vxlan.overlay.networks is defined and MD_Extended.vxlan.overlay.networks) or + (MD_Extended.vxlan.overlay_services.networks is defined and MD_Extended.vxlan.overlay_services.networks) and + changes_detected_networks diff --git a/roles/dtc/deploy/tasks/sub_main.yml b/roles/dtc/deploy/tasks/sub_main.yml index 27464d91..7c176ea8 100644 --- a/roles/dtc/deploy/tasks/sub_main.yml +++ b/roles/dtc/deploy/tasks/sub_main.yml @@ -34,7 +34,10 @@ cisco.dcnm.dcnm_rest: method: POST path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/config-save" - when: MD_Extended.vxlan.topology.switches | length > 0 + when: > + (MD_Extended.vxlan.topology.switches is defined and MD_Extended.vxlan.topology.switches | length > 0) or + (MD_Extended.vxlan.multisite.isn.topology.switches is defined and MD_Extended.vxlan.multisite.isn.topology.switches | length > 0) or + MD_Extended.vxlan.fabric.type == 'MSD' # TODO: Need to add logic to only save if changes are made - name: Deploy for Fabric {{ MD_Extended.vxlan.fabric.name }} @@ -44,5 +47,8 @@ vars: ansible_command_timeout: 3000 ansible_connect_timeout: 3000 - when: MD_Extended.vxlan.topology.switches | length > 0 + when: > + (MD_Extended.vxlan.topology.switches is defined and MD_Extended.vxlan.topology.switches | length > 0) or + (MD_Extended.vxlan.multisite.isn.topology.switches is defined and MD_Extended.vxlan.multisite.isn.topology.switches | length > 0) or + MD_Extended.vxlan.fabric.type == 'MSD' # TODO: Need to add logic to only deploy if changes are made diff --git a/roles/dtc/remove/tasks/msd/child_fabrics.yml b/roles/dtc/remove/tasks/msd/child_fabrics.yml new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/remove/tasks/msd/networks.yml b/roles/dtc/remove/tasks/msd/networks.yml new file mode 100644 index 00000000..706fa9ef --- /dev/null +++ b/roles/dtc/remove/tasks/msd/networks.yml @@ -0,0 +1,45 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT +--- + +- ansible.builtin.debug: msg="Removing Unmanaged Fabric Networks. This could take several minutes..." + when: + - switch_list.response.DATA | length > 0 + - (network_delete_mode is defined) and (network_delete_mode is true|bool) + +- name: Remove Unmanaged Fabric Networks + cisco.dcnm.dcnm_network: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: overridden + config: "{{ net_config }}" + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: + - switch_list.response.DATA | length > 0 + - (network_delete_mode is defined) and (network_delete_mode is true|bool) + +- ansible.builtin.debug: + msg: + - "---------------------------------------------------------------------------------------------------------------" + - "+ SKIPPING Remove Unmanaged Fabric Networks task because network_delete_mode flag is set to False +" + - "---------------------------------------------------------------------------------------------------------------" + when: not ((network_delete_mode is defined) and (network_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/msd/vrfs.yml b/roles/dtc/remove/tasks/msd/vrfs.yml new file mode 100644 index 00000000..68bce074 --- /dev/null +++ b/roles/dtc/remove/tasks/msd/vrfs.yml @@ -0,0 +1,45 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT +--- + +- ansible.builtin.debug: msg="Removing Unmanaged Fabric VRFs. This could take several minutes..." + when: + - switch_list.response.DATA | length > 0 + - (vrf_delete_mode is defined) and (vrf_delete_mode is true|bool) + +- name: Remove Unmanaged Fabric VRFs + cisco.dcnm.dcnm_vrf: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: overridden + config: "{{ vrf_config }}" + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: + - switch_list.response.DATA | length > 0 + - (vrf_delete_mode is defined) and (vrf_delete_mode is true|bool) + +- ansible.builtin.debug: + msg: + - "--------------------------------------------------------------------------------------------------------" + - "+ SKIPPING Remove Unmanaged Fabric VRFs task because vrf_delete_mode flag is set to False +" + - "--------------------------------------------------------------------------------------------------------" + when: not ((vrf_delete_mode is defined) and (vrf_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/sub_main_msd.yml b/roles/dtc/remove/tasks/sub_main_msd.yml index f4d2e7e6..26558c58 100644 --- a/roles/dtc/remove/tasks/sub_main_msd.yml +++ b/roles/dtc/remove/tasks/sub_main_msd.yml @@ -20,3 +20,15 @@ # SPDX-License-Identifier: MIT --- + +- name: Remove Fabric Networks + ansible.builtin.import_tasks: msd/networks.yml + tags: "{{ nac_tags.remove_networks }}" + when: + - changes_detected_networks + +- name: Remove Fabric VRFs + ansible.builtin.import_tasks: msd/vrfs.yml + tags: "{{ nac_tags.remove_vrfs }}" + when: + - changes_detected_vrfs diff --git a/roles/validate/files/defaults.yml b/roles/validate/files/defaults.yml index 5918c7cd..452e5a8a 100644 --- a/roles/validate/files/defaults.yml +++ b/roles/validate/files/defaults.yml @@ -290,3 +290,13 @@ factory_defaults: delay_restore: 300 enable_ebgp_password: false enable_trm: false + isn: + sub_int_range: 2-511 + bootstrap: + enable_bootstrap: false + enable_inband: false + enable_local_dhcp_server: false + dhcp_version: DHCPv4 + enable_aaa: false + netflow: + enable: false diff --git a/roles/validate/files/rules/isn/.gitkeep b/roles/validate/files/rules/isn/.gitkeep new file mode 100644 index 00000000..e69de29b From 15655e75d29a736588ec0bb78ccb87bd7574a62c Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Mon, 9 Dec 2024 00:26:44 -0500 Subject: [PATCH 22/66] updates for remove child fabrics and isn --- plugins/action/dtc/manage_child_fabrics.py | 98 ++++++++++++++++--- .../dtc/update_switch_hostname_policy.py | 1 + .../ndfc_fabric/isn_fabric/temp.json | 86 ---------------- roles/dtc/create/tasks/msd/child_fabrics.yml | 1 + roles/dtc/create/tasks/sub_main_msd.yml | 4 - roles/dtc/remove/tasks/msd/child_fabrics.yml | 42 ++++++++ roles/dtc/remove/tasks/sub_main_msd.yml | 24 +++-- 7 files changed, 143 insertions(+), 113 deletions(-) delete mode 100644 roles/dtc/common/templates/ndfc_fabric/isn_fabric/temp.json diff --git a/plugins/action/dtc/manage_child_fabrics.py b/plugins/action/dtc/manage_child_fabrics.py index 1e7eb14e..e2793bfc 100644 --- a/plugins/action/dtc/manage_child_fabrics.py +++ b/plugins/action/dtc/manage_child_fabrics.py @@ -39,6 +39,7 @@ def run(self, tmp=None, task_vars=None): fabric_associations = self._task.args['fabric_associations'].get('response').get('DATA') parent_fabric_name = self._task.args['parent_fabric_name'] child_fabrics = self._task.args['child_fabrics'] + operation = self._task.args['operation'] # Build a list of child fabrics that are associated with the parent fabric associated_child_fabrics = [] @@ -46,19 +47,49 @@ def run(self, tmp=None, task_vars=None): if fabric.get('fabricParent') == parent_fabric_name: associated_child_fabrics.append(fabric.get('fabricName')) - for fabric in child_fabrics: - if fabric.get('name') not in associated_child_fabrics: - json_data = '{"destFabric":"%s","sourceFabric":"%s"}' % (parent_fabric_name, fabric.get('name')) - add_fabric_result = self._execute_module( - module_name="cisco.dcnm.dcnm_rest", - module_args={ - "method": "POST", - "path": f"/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd", - "json_data": json_data - }, - task_vars=task_vars, - tmp=tmp - ) + if operation == 'add': + for fabric in child_fabrics: + if fabric.get('name') not in associated_child_fabrics: + json_data = '{"destFabric":"%s","sourceFabric":"%s"}' % (parent_fabric_name, fabric.get('name')) + add_fabric_result = self._execute_module( + module_name="cisco.dcnm.dcnm_rest", + module_args={ + "method": "POST", + "path": f"/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd", + "json_data": json_data + }, + task_vars=task_vars, + tmp=tmp + ) + + if add_fabric_result.get('failed'): + results['failed'] = True + results['msg'] = f"{add_fabric_result['msg']['MESSAGE']}: {add_fabric_result['msg']['DATA']}" + break + + results['changed'] = True + + if operation == 'remove': + for associated_child_fabric in associated_child_fabrics: + if not any(associated_child_fabric == child_fabric['name'] for child_fabric in child_fabrics): + json_data = '{"destFabric":"%s","sourceFabric":"%s"}' % (parent_fabric_name, associated_child_fabric) + remove_fabric_result = self._execute_module( + module_name="cisco.dcnm.dcnm_rest", + module_args={ + "method": "POST", + "path": f"/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdExit", + "json_data": json_data + }, + task_vars=task_vars, + tmp=tmp + ) + + if remove_fabric_result.get('failed'): + results['failed'] = True + results['msg'] = f"{remove_fabric_result['msg']['MESSAGE']}: {remove_fabric_result['msg']['DATA']}" + break + + results['changed'] = True return results @@ -70,6 +101,47 @@ def run(self, tmp=None, task_vars=None): # https://rtp-ndfc1.cisco.com/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations/ # GET +# Response: +# "response": { +# "DATA": [ +# { +# "fabricId": 2, +# "fabricName": "nac-fabric1", +# "fabricParent": "None", +# "fabricState": "standalone", +# "fabricTechnology": "VXLANFabric", +# "fabricType": "Switch_Fabric" +# }, +# { +# "fabricId": 3, +# "fabricName": "nac-fabric2", +# "fabricParent": "nac-msd1", +# "fabricState": "member", +# "fabricTechnology": "VXLANFabric", +# "fabricType": "Switch_Fabric" +# }, +# { +# "fabricId": 4, +# "fabricName": "nac-isn1", +# "fabricParent": "None", +# "fabricState": "standalone", +# "fabricTechnology": "External", +# "fabricType": "External" +# }, +# { +# "fabricId": 5, +# "fabricName": "nac-msd1", +# "fabricParent": "None", +# "fabricState": "msd", +# "fabricTechnology": "VXLANFabric", +# "fabricType": "MSD" +# } +# ], +# "MESSAGE": "OK", +# "METHOD": "GET", +# "REQUEST_PATH": "https://10.15.0.110:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations", +# "RETURN_CODE": 200 +# } # https://rtp-ndfc1.cisco.com/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd # POST diff --git a/plugins/action/dtc/update_switch_hostname_policy.py b/plugins/action/dtc/update_switch_hostname_policy.py index 574dfe75..f660e99b 100644 --- a/plugins/action/dtc/update_switch_hostname_policy.py +++ b/plugins/action/dtc/update_switch_hostname_policy.py @@ -58,6 +58,7 @@ def run(self, tmp=None, task_vars=None): switch_match = next((item for item in dm_switches if item["serial_number"] == switch_serial_number)) if policy_match["nvPairs"]["SWITCH_NAME"] != switch_match["name"]: + results['changed'] = True policy_match["nvPairs"]["SWITCH_NAME"] = switch_match["name"] policy_update.update({switch_serial_number: policy_match}) diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/temp.json b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/temp.json deleted file mode 100644 index 215a2d90..00000000 --- a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/temp.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "fabricName": "ISN", - "templateName": "External_Fabric", - "nvPairs": { - "FABRIC_NAME": "ISN", - "BGP_AS": "65000", - "PM_ENABLE": "false", - "EXT_FABRIC_TYPE": "Multi-Site External Network", - "PM_ENABLE_PREV": "false", - "INBAND_MGMT_PREV": "false", - "FEATURE_PTP_INTERNAL": "false", - "DEPLOYMENT_FREEZE": "false", - "LOOPBACK0_IP_RANGE": "10.1.0.0/22", - "FABRIC_TYPE": "External", - "FF": "External", - "MSO_SITE_ID": "", - "MSO_CONTROLER_ID": "", - "MSO_SITE_GROUP_NAME": "", - "PREMSO_PARENT_FABRIC": "", - "MSO_CONNECTIVITY_DEPLOYED": "", - "INBAND_ENABLE_PREV": "false", - "DCI_SUBNET_RANGE": "10.10.1.0/24", - "DCI_SUBNET_TARGET_MASK": "30", - "ENABLE_NETFLOW_PREV": "", - "ALLOW_NXC": "true", - "ALLOW_NXC_PREV": "", - "OVERWRITE_GLOBAL_NXC": "false", - "NXC_DEST_VRF": "management", - "NXC_SRC_INTF": "", - "NXC_PROXY_SERVER": "", - "NXC_PROXY_PORT": "8080", - "DHCP_START_INTERNAL": "", - "DHCP_END_INTERNAL": "", - "MGMT_GW_INTERNAL": "", - "MGMT_PREFIX_INTERNAL": "", - "BOOTSTRAP_MULTISUBNET_INTERNAL": "", - "MGMT_V6PREFIX_INTERNAL": "", - "DHCP_IPV6_ENABLE_INTERNAL": "", - "DOMAIN_NAME_INTERNAL": "", - "PNP_ENABLE_INTERNAL": "", - "POWER_REDUNDANCY_MODE": "ps-redundant", - "MPLS_HANDOFF": "false", - "MPLS_LB_ID": "", - "AAA_REMOTE_IP_ENABLED": "false", - "SNMP_SERVER_HOST_TRAP": "true", - "CDP_ENABLE": "false", - "ENABLE_NXAPI": "false", - "NXAPI_HTTPS_PORT": "", - "ENABLE_NXAPI_HTTP": false, - "NXAPI_HTTP_PORT": "", - "INBAND_MGMT": "false", - "FEATURE_PTP": "false", - "PTP_LB_ID": "", - "PTP_DOMAIN_ID": "", - "ENABLE_RT_INTF_STATS": "false", - "INTF_STAT_LOAD_INTERVAL": "", - "FABRIC_FREEFORM": "", - "AAA_SERVER_CONF": "", - "SUBINTERFACE_RANGE": "2-511", - "MPLS_LOOPBACK_IP_RANGE": "", - "enableRealTimeBackup": "", - "enableScheduledBackup": "", - "scheduledTime": "", - "INBAND_ENABLE": false, - "DHCP_ENABLE": false, - "PNP_ENABLE": false, - "DHCP_IPV6_ENABLE": "", - "DOMAIN_NAME": "", - "DHCP_START": "", - "DHCP_END": "", - "MGMT_GW": "", - "MGMT_PREFIX": "", - "MGMT_V6PREFIX": "", - "ENABLE_AAA": false, - "BOOTSTRAP_CONF": "", - "BOOTSTRAP_CONF_XE": "", - "BOOTSTRAP_MULTISUBNET": "", - "ENABLE_NETFLOW": "false", - "NETFLOW_EXPORTER_LIST": "", - "NETFLOW_RECORD_LIST": "", - "NETFLOW_MONITOR_LIST": "", - "NETFLOW_SAMPLER_LIST": "", - "IS_READ_ONLY": false, - "BOOTSTRAP_ENABLE": "false" - } -} \ No newline at end of file diff --git a/roles/dtc/create/tasks/msd/child_fabrics.yml b/roles/dtc/create/tasks/msd/child_fabrics.yml index f124150b..61afd99a 100644 --- a/roles/dtc/create/tasks/msd/child_fabrics.yml +++ b/roles/dtc/create/tasks/msd/child_fabrics.yml @@ -42,4 +42,5 @@ fabric_associations: "{{ fabric_associations }}" parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" + operation: add when: fabric_associations is defined and fabric_associations diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index 10af9cdb..271c0981 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -44,10 +44,6 @@ ansible.builtin.import_tasks: msd/child_fabrics.yml when: - MD_Extended.vxlan.multisite.child_fabrics is defined and MD_Extended.vxlan.multisite.child_fabrics | length > 0 - # - changes_detected_inventory - # tags: "{{ nac_tags.create_switches }}" - -- ansible.builtin.meta: end_play - name: Manage NDFC Fabric VRFs and Networks ansible.builtin.import_tasks: msd/vrfs_networks.yml diff --git a/roles/dtc/remove/tasks/msd/child_fabrics.yml b/roles/dtc/remove/tasks/msd/child_fabrics.yml index e69de29b..2dea537f 100644 --- a/roles/dtc/remove/tasks/msd/child_fabrics.yml +++ b/roles/dtc/remove/tasks/msd/child_fabrics.yml @@ -0,0 +1,42 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- ansible.builtin.debug: msg="Removing Unmanaged Child Fabrics. This could take several minutes..." + when: + - MD_Extended.vxlan.multisite.child_fabrics is defined + - MD_Extended.vxlan.multisite.child_fabrics | length > 0 + - (child_fabric_delete_mode is defined) and (child_fabric_delete_mode is true|bool) + +- name: Get Fabric Association Data from NDFC + cisco.dcnm.dcnm_rest: + method: GET + path: /appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations + register: fabric_associations + +- name: Remove Unmanaged Child Fabrics from NDFC + cisco.nac_dc_vxlan.dtc.manage_child_fabrics: + fabric_associations: "{{ fabric_associations }}" + parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" + child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" + operation: remove + when: fabric_associations is defined and fabric_associations diff --git a/roles/dtc/remove/tasks/sub_main_msd.yml b/roles/dtc/remove/tasks/sub_main_msd.yml index 26558c58..072e61f5 100644 --- a/roles/dtc/remove/tasks/sub_main_msd.yml +++ b/roles/dtc/remove/tasks/sub_main_msd.yml @@ -21,14 +21,18 @@ --- -- name: Remove Fabric Networks - ansible.builtin.import_tasks: msd/networks.yml - tags: "{{ nac_tags.remove_networks }}" - when: - - changes_detected_networks +# - name: Remove Fabric Networks +# ansible.builtin.import_tasks: msd/networks.yml +# tags: "{{ nac_tags.remove_networks }}" +# when: +# - changes_detected_networks -- name: Remove Fabric VRFs - ansible.builtin.import_tasks: msd/vrfs.yml - tags: "{{ nac_tags.remove_vrfs }}" - when: - - changes_detected_vrfs +# - name: Remove Fabric VRFs +# ansible.builtin.import_tasks: msd/vrfs.yml +# tags: "{{ nac_tags.remove_vrfs }}" +# when: +# - changes_detected_vrfs + +- name: Remove Child Fabrics + ansible.builtin.import_tasks: msd/child_fabrics.yml + # tags: "{{ nac_tags.remove_child_fabrics }}" From 13c8ba607d25d53935018e465cdc2a7ae700d6d1 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 10 Dec 2024 20:51:14 -0500 Subject: [PATCH 23/66] updates to current msd workflow --- .../prepare_plugins/prep_001_list_defaults.py | 55 +++++++ .../prep_103_topology_switches.py | 1 + .../prep_104_fabric_overlay.py | 140 ++++++++++++++++++ .../prep_104_fabric_overlay_services.py | 131 ---------------- .../prep_106_topology_vpc_interfaces.py | 1 + plugins/action/dtc/map_msd_inventory.py | 58 ++++++++ roles/dtc/common/tasks/sub_main_msd.yml | 24 +++ .../common/templates/ndfc_attach_networks.j2 | 102 ++----------- .../dtc/common/templates/ndfc_attach_vrfs.j2 | 81 ++-------- .../msd_fabric/general/msd_fabric_general.j2 | 2 +- roles/dtc/common/templates/ndfc_inventory.j2 | 2 +- .../common/templates/ndfc_networks/.gitkeep | 0 .../dc_vxlan_fabric_networks.j2 | 86 +++++++++++ .../msd_fabric/msd_fabric_networks.j2 | 56 +++++++ roles/dtc/common/templates/ndfc_vrfs/.gitkeep | 0 .../dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 | 65 ++++++++ .../ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 | 42 ++++++ roles/dtc/create/tasks/msd/vrfs_networks.yml | 1 - roles/dtc/create/tasks/sub_main_msd.yml | 8 +- roles/dtc/remove/tasks/main.yml | 1 + roles/dtc/remove/tasks/sub_main_msd.yml | 38 +++-- .../401_overlay_services_cross_reference.py | 8 +- 22 files changed, 597 insertions(+), 305 deletions(-) create mode 100644 plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py delete mode 100644 plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py create mode 100644 plugins/action/dtc/map_msd_inventory.py create mode 100644 roles/dtc/common/templates/ndfc_networks/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 create mode 100644 roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2 create mode 100644 roles/dtc/common/templates/ndfc_vrfs/.gitkeep create mode 100644 roles/dtc/common/templates/ndfc_vrfs/dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 create mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 diff --git a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py index 1fd9566b..8798874a 100644 --- a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py @@ -222,6 +222,61 @@ def prepare(self): list_index += 1 + # -------------------------------------------------------------------- + # Multisite Fabric Overlay List Defaults + # -------------------------------------------------------------------- + + # Check vxlan.multisite list elements + parent_keys = ['vxlan', 'multisite'] + dm_check = data_model_key_check(self.model_data, parent_keys) + if 'multisite' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: + self.model_data['vxlan'] = {'multisite': {}} + + # Check vxlan.multisite.overlay list elements + parent_keys = ['vxlan', 'multisite', 'overlay'] + dm_check = data_model_key_check(self.model_data, parent_keys) + if 'overlay' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: + self.model_data['vxlan']['multisite']['overlay'] = {'vrfs': []} + self.model_data['vxlan']['multisite']['overlay'] = {'vrf_attach_groups': []} + self.model_data['vxlan']['multisite']['overlay'] = {'networks': []} + self.model_data['vxlan']['multisite']['overlay'] = {'network_attach_groups': []} + + # Check vxlan.multisite.overlay_services.vrfs list element + target_key = 'vrfs' + self.set_list_default(parent_keys, target_key) + + # Check vxlan.multisite.overlay.vrf_attach_groups list element + target_key = 'vrf_attach_groups' + self.set_list_default(parent_keys, target_key) + + # Check vxlan.multisite.overlay.vrf_attach_groups[index].switches list elements + list_index = 0 + for group in self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups']: + dm_check = data_model_key_check(group, ['switches']) + if 'switches' in dm_check['keys_not_found'] or \ + 'switches' in dm_check['keys_no_data']: + self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'][list_index]['switches'] = [] + + list_index += 1 + + # Check vxlan.multisite.overlay.networks list element + target_key = 'networks' + self.set_list_default(parent_keys, target_key) + + # Check vxlan.multisite.overlay.network_attach_groups list element + target_key = 'network_attach_groups' + self.set_list_default(parent_keys, target_key) + + # Check vxlan.multisite.overlay.network_attach_groups[index].switches list elements + list_index = 0 + for group in self.model_data['vxlan']['multisite']['overlay']['network_attach_groups']: + dm_check = data_model_key_check(group, ['switches']) + if 'switches' in dm_check['keys_not_found'] or \ + 'switches' in dm_check['keys_no_data']: + self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'][list_index]['switches'] = [] + + list_index += 1 + # -------------------------------------------------------------------- # Fabric Policy List Defaults # -------------------------------------------------------------------- diff --git a/plugins/action/common/prepare_plugins/prep_103_topology_switches.py b/plugins/action/common/prepare_plugins/prep_103_topology_switches.py index bbcf5c34..7abce4c6 100644 --- a/plugins/action/common/prepare_plugins/prep_103_topology_switches.py +++ b/plugins/action/common/prepare_plugins/prep_103_topology_switches.py @@ -18,6 +18,7 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # SPDX-License-Identifier: MIT + from ....plugin_utils.helper_functions import hostname_to_ip_mapping diff --git a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py new file mode 100644 index 00000000..33a27755 --- /dev/null +++ b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py @@ -0,0 +1,140 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +from ....plugin_utils.helper_functions import data_model_key_check + + +class PreparePlugin: + def __init__(self, **kwargs): + self.kwargs = kwargs + self.keys = [] + + def prepare(self): + model_data = self.kwargs['results']['model_extended'] + switches = model_data['vxlan']['topology']['switches'] + + # Remove the check for overlay_services after deprecation + # Remove lines 32-37 + overlay_key = 'overlay' + check = data_model_key_check(model_data, ['vxlan']) + if 'overlay_services' in check['keys_found'] and 'overlay_services' in check['keys_data']: + overlay_key = 'overlay_services' + + if model_data['vxlan']['fabric']['type'] in ('VXLAN_EVPN'): + # Rebuild sm_data['vxlan'][overlay_key]['vrf_attach_groups'] into + # a structure that is easier to use. + vrf_grp_name_list = [] + model_data['vxlan'][overlay_key]['vrf_attach_groups_dict'] = {} + for grp in model_data['vxlan'][overlay_key]['vrf_attach_groups']: + model_data['vxlan'][overlay_key]['vrf_attach_groups_dict'][grp['name']] = [] + vrf_grp_name_list.append(grp['name']) + for switch in grp['switches']: + model_data['vxlan'][overlay_key]['vrf_attach_groups_dict'][grp['name']].append(switch) + # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP + for switch in model_data['vxlan'][overlay_key]['vrf_attach_groups_dict'][grp['name']]: + if any(sw['name'] == switch['hostname'] for sw in switches): + found_switch = next((item for item in switches if item["name"] == switch['hostname'])) + if found_switch.get('management').get('management_ipv4_address'): + switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] + elif found_switch.get('management').get('management_ipv6_address'): + switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] + + # Remove vrf_attach_group from vrf if the group_name is not defined + for vrf in model_data['vxlan'][overlay_key]['vrfs']: + if 'vrf_attach_group' in vrf: + if vrf.get('vrf_attach_group') not in vrf_grp_name_list: + del vrf['vrf_attach_group'] + + # Rebuild sm_data['vxlan'][overlay_key]['network_attach_groups'] into + # a structure that is easier to use. + net_grp_name_list = [] + model_data['vxlan'][overlay_key]['network_attach_groups_dict'] = {} + for grp in model_data['vxlan'][overlay_key]['network_attach_groups']: + model_data['vxlan'][overlay_key]['network_attach_groups_dict'][grp['name']] = [] + net_grp_name_list.append(grp['name']) + for switch in grp['switches']: + model_data['vxlan'][overlay_key]['network_attach_groups_dict'][grp['name']].append(switch) + # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP + for switch in model_data['vxlan'][overlay_key]['network_attach_groups_dict'][grp['name']]: + if any(sw['name'] == switch['hostname'] for sw in switches): + found_switch = next((item for item in switches if item["name"] == switch['hostname'])) + if found_switch.get('management').get('management_ipv4_address'): + switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] + elif found_switch.get('management').get('management_ipv6_address'): + switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] + + # Remove network_attach_group from net if the group_name is not defined + for net in model_data['vxlan'][overlay_key]['networks']: + if 'network_attach_group' in net: + if net.get('network_attach_group') not in net_grp_name_list: + del net['network_attach_group'] + + if model_data['vxlan']['fabric']['type'] in ('MSD', 'MCF'): + # Rebuild sm_data['vxlan']['multisite']['overlay']['vrf_attach_groups'] into + # a structure that is easier to use. + vrf_grp_name_list = [] + model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'] = {} + for grp in model_data['vxlan']['multisite']['overlay']['vrf_attach_groups']: + model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'][grp['name']] = [] + vrf_grp_name_list.append(grp['name']) + for switch in grp['switches']: + model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'][grp['name']].append(switch) + # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP + for switch in model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'][grp['name']]: + if any(sw['name'] == switch['hostname'] for sw in switches): + found_switch = next((item for item in switches if item["name"] == switch['hostname'])) + if found_switch.get('management').get('management_ipv4_address'): + switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] + elif found_switch.get('management').get('management_ipv6_address'): + switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] + + # Remove vrf_attach_group from vrf if the group_name is not defined + for vrf in model_data['vxlan']['multisite']['overlay']['vrfs']: + if 'vrf_attach_group' in vrf: + if vrf.get('vrf_attach_group') not in vrf_grp_name_list: + del vrf['vrf_attach_group'] + + # Rebuild sm_data['vxlan'][overlay_key]['network_attach_groups'] into + # a structure that is easier to use. + net_grp_name_list = [] + model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'] = {} + for grp in model_data['vxlan']['multisite']['overlay']['network_attach_groups']: + model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'][grp['name']] = [] + net_grp_name_list.append(grp['name']) + for switch in grp['switches']: + model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'][grp['name']].append(switch) + # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP + for switch in model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'][grp['name']]: + if any(sw['name'] == switch['hostname'] for sw in switches): + found_switch = next((item for item in switches if item["name"] == switch['hostname'])) + if found_switch.get('management').get('management_ipv4_address'): + switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] + elif found_switch.get('management').get('management_ipv6_address'): + switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] + + # Remove network_attach_group from net if the group_name is not defined + for net in model_data['vxlan']['multisite']['overlay']['networks']: + if 'network_attach_group' in net: + if net.get('network_attach_group') not in net_grp_name_list: + del net['network_attach_group'] + + self.kwargs['results']['model_extended'] = model_data + return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py deleted file mode 100644 index 0fad465c..00000000 --- a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - - -class PreparePlugin: - def __init__(self, **kwargs): - self.kwargs = kwargs - self.keys = [] - - def prepare(self): - model_data = self.kwargs['results']['model_extended'] - switches = model_data['vxlan']['topology']['switches'] - - # Rebuild sm_data['vxlan']['overlay']['vrf_attach_groups'] into - # a structure that is easier to use. - vrf_grp_name_list = [] - model_data['vxlan']['overlay']['vrf_attach_groups_dict'] = {} - for grp in model_data['vxlan']['overlay']['vrf_attach_groups']: - model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']] = [] - vrf_grp_name_list.append(grp['name']) - for switch in grp['switches']: - model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']].append(switch) - # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP - for switch in model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']]: - if any(sw['name'] == switch['hostname'] for sw in switches): - found_switch = next((item for item in switches if item["name"] == switch['hostname'])) - if found_switch.get('management').get('management_ipv4_address'): - switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] - elif found_switch.get('management').get('management_ipv6_address'): - switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] - - # Remove vrf_attach_group from vrf if the group_name is not defined - for vrf in model_data['vxlan']['overlay']['vrfs']: - if 'vrf_attach_group' in vrf: - if vrf.get('vrf_attach_group') not in vrf_grp_name_list: - del vrf['vrf_attach_group'] - - # Rebuild sm_data['vxlan']['overlay']['network_attach_groups'] into - # a structure that is easier to use. - net_grp_name_list = [] - model_data['vxlan']['overlay']['network_attach_groups_dict'] = {} - for grp in model_data['vxlan']['overlay']['network_attach_groups']: - model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']] = [] - net_grp_name_list.append(grp['name']) - for switch in grp['switches']: - model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']].append(switch) - # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP - for switch in model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']]: - if any(sw['name'] == switch['hostname'] for sw in switches): - found_switch = next((item for item in switches if item["name"] == switch['hostname'])) - if found_switch.get('management').get('management_ipv4_address'): - switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] - elif found_switch.get('management').get('management_ipv6_address'): - switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] - - # Remove network_attach_group from net if the group_name is not defined - for net in model_data['vxlan']['overlay']['networks']: - if 'network_attach_group' in net: - if net.get('network_attach_group') not in net_grp_name_list: - del net['network_attach_group'] - - # Backwards compatibility for vxlan.overlay_services - - # Rebuild sm_data['vxlan']['overlay_services']['vrf_attach_groups'] into - # a structure that is easier to use. - vrf_grp_name_list = [] - model_data['vxlan']['overlay_services']['vrf_attach_groups_dict'] = {} - for grp in model_data['vxlan']['overlay_services']['vrf_attach_groups']: - model_data['vxlan']['overlay_services']['vrf_attach_groups_dict'][grp['name']] = [] - vrf_grp_name_list.append(grp['name']) - for switch in grp['switches']: - model_data['vxlan']['overlay_services']['vrf_attach_groups_dict'][grp['name']].append(switch) - # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP - for switch in model_data['vxlan']['overlay_services']['vrf_attach_groups_dict'][grp['name']]: - if any(sw['name'] == switch['hostname'] for sw in switches): - found_switch = next((item for item in switches if item["name"] == switch['hostname'])) - if found_switch.get('management').get('management_ipv4_address'): - switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] - elif found_switch.get('management').get('management_ipv6_address'): - switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] - - # Remove vrf_attach_group from vrf if the group_name is not defined - for vrf in model_data['vxlan']['overlay_services']['vrfs']: - if 'vrf_attach_group' in vrf: - if vrf.get('vrf_attach_group') not in vrf_grp_name_list: - del vrf['vrf_attach_group'] - - # Rebuild sm_data['vxlan']['overlay_services']['network_attach_groups'] into - # a structure that is easier to use. - net_grp_name_list = [] - model_data['vxlan']['overlay_services']['network_attach_groups_dict'] = {} - for grp in model_data['vxlan']['overlay_services']['network_attach_groups']: - model_data['vxlan']['overlay_services']['network_attach_groups_dict'][grp['name']] = [] - net_grp_name_list.append(grp['name']) - for switch in grp['switches']: - model_data['vxlan']['overlay_services']['network_attach_groups_dict'][grp['name']].append(switch) - # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP - for switch in model_data['vxlan']['overlay_services']['network_attach_groups_dict'][grp['name']]: - if any(sw['name'] == switch['hostname'] for sw in switches): - found_switch = next((item for item in switches if item["name"] == switch['hostname'])) - if found_switch.get('management').get('management_ipv4_address'): - switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] - elif found_switch.get('management').get('management_ipv6_address'): - switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] - - # Remove network_attach_group from net if the group_name is not defined - for net in model_data['vxlan']['overlay_services']['networks']: - if 'network_attach_group' in net: - if net.get('network_attach_group') not in net_grp_name_list: - del net['network_attach_group'] - - self.kwargs['results']['model_extended'] = model_data - return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py b/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py index 1a2cdfaf..ecd7b360 100644 --- a/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py +++ b/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py @@ -22,6 +22,7 @@ # Group vPC interfaces by vpc_peers, vpc_id and switch_name # This helps in identifying vPC interfaces for a given vpc_peer, vpc_id and switch_name # Reduces the need to loop through all interfaces to find vPC interfaces in Jinja2 templates + class PreparePlugin: def __init__(self, **kwargs): self.kwargs = kwargs diff --git a/plugins/action/dtc/map_msd_inventory.py b/plugins/action/dtc/map_msd_inventory.py new file mode 100644 index 00000000..0b421194 --- /dev/null +++ b/plugins/action/dtc/map_msd_inventory.py @@ -0,0 +1,58 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible.utils.display import Display +from ansible.plugins.action import ActionBase + +display = Display() + + +class ActionModule(ActionBase): + + def run(self, tmp=None, task_vars=None): + results = super(ActionModule, self).run(tmp, task_vars) + results['failed'] = False + + parent_fabric_name = self._task.args['parent_fabric_name'] + + msd_inventory = self._execute_module( + module_name="cisco.dcnm.dcnm_inventory", + module_args={ + "fabric": parent_fabric_name, + "state": "query" + }, + task_vars=task_vars, + tmp=tmp + ) + + msd_switches = {} + for switch in msd_inventory.get('response', []): + msd_switches.update({switch['hostName']: switch['ipAddress']}) + msd_switches.update({switch['ipAddress']: switch['ipAddress']}) + + results['msd_switches'] = msd_switches + + return results diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 4796d44f..953af22c 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -46,3 +46,27 @@ - name: Build NDFC Child Fabric Inventory List From Template ansible.builtin.include_tasks: msd/ndfc_children.yml + +- name: Get Switch Inventory from MSD Fabric + cisco.nac_dc_vxlan.dtc.map_msd_inventory: + parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" + register: msd_inventory + +- name: Set MSD Switches List + ansible.builtin.set_fact: + msd_switches: "{{ msd_inventory.msd_switches }}" + when: msd_inventory.msd_switches is defined + +# -------------------------------------------------------------------- +# Build NDFC Fabric VRFs Attach List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric VRFs Attach List From Template + ansible.builtin.include_tasks: msd/ndfc_vrfs.yml + +# -------------------------------------------------------------------- +# Build NDFC Fabric Networks Attach List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Networks Attach List From Template + ansible.builtin.include_tasks: msd/ndfc_networks.yml diff --git a/roles/dtc/common/templates/ndfc_attach_networks.j2 b/roles/dtc/common/templates/ndfc_attach_networks.j2 index 96742c99..03088f88 100644 --- a/roles/dtc/common/templates/ndfc_attach_networks.j2 +++ b/roles/dtc/common/templates/ndfc_attach_networks.j2 @@ -1,89 +1,17 @@ --- -# This NDFC networks and switch attachments config data structure is auto-generated -# DO NOT EDIT MANUALLY -# -{% if MD_Extended.vxlan.overlay.networks is defined and MD_Extended.vxlan.overlay.networks %} -{% set networks = MD_Extended.vxlan.overlay.networks %} -{% elif MD_Extended.vxlan.overlay_services.networks is defined and MD_Extended.vxlan.overlay_services.networks %} -{% set networks = MD_Extended.vxlan.overlay_services.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) }} - dhcp_loopback_id: {{ net['dhcp_loopback_id'] | default(omit) }} -{% if net.dhcp_servers is defined %} -{% if net.dhcp_servers | length == 1 %} - dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} - dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} -{% elif net.dhcp_servers | length == 2 %} - dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} - dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} - dhcp_srvr2_ip: {{ net['dhcp_servers'][1]['ip_address'] }} - dhcp_srvr2_vrf: {{ net['dhcp_servers'][1]['vrf'] }} -{% elif net.dhcp_servers | length == 3 %} - dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} - dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} - dhcp_srvr2_ip: {{ net['dhcp_servers'][1]['ip_address'] }} - dhcp_srvr2_vrf: {{ net['dhcp_servers'][1]['vrf'] }} - dhcp_srvr3_ip: {{ net['dhcp_servers'][2]['ip_address'] }} - dhcp_srvr3_vrf: {{ net['dhcp_servers'][2]['vrf'] }} -{% endif %} -{% endif %} - gw_ipv6_subnet: {{ net['gw_ipv6_address'] | default(omit) }} - int_desc: {{ net['int_desc'] | default(defaults.vxlan.overlay.networks.net_description) }} - l3gw_on_border: {{ net['l3gw_on_border'] | default(defaults.vxlan.overlay.networks.l3gw_on_border) }} - mtu_l3intf: {{ net['mtu_l3intf'] | default(defaults.vxlan.overlay.networks.mtu_l3intf) }} -{% if (MD.vxlan.underlay.general.replication_mode | lower) == 'multicast' %} - multicast_group_address: {{ net['multicast_group_address'] | default(defaults.vxlan.overlay.networks.multicast_group_address) }} -{% endif %} - netflow_enable: {{ net['netflow_enable'] | default(defaults.vxlan.overlay.networks.netflow_enable) }} -{% if net['netflow_enable'] is defined and net['netflow_enable'] | bool %} - vlan_nf_monitor: {{ net['vlan_netflow_monitor'] | default(omit) }} -{% endif %} - route_target_both: {{ net['route_target_both'] | default(defaults.vxlan.overlay.networks.route_target_both) }} - route_tag: {{ net['route_tag'] | default(defaults.vxlan.overlay.networks.route_tag) }} - trm_enable: {{ net['trm_enable'] | default(defaults.vxlan.overlay.networks.trm_enable) }} -{# ------------------------------------------------------ #} -{# Attach Group Section #} -{# ------------------------------------------------------ #} -{% if net['network_attach_group'] is defined %} - attach: -{% if MD_Extended.vxlan.overlay.network_attach_groups_dict is defined and MD_Extended.vxlan.overlay.network_attach_groups_dict %} -{% set network_attach_groups_dict = MD_Extended.vxlan.overlay.network_attach_groups_dict %} -{% elif MD_Extended.vxlan.overlay_services.network_attach_groups_dict is defined and MD_Extended.vxlan.overlay_services.network_attach_groups_dict %} -{% set network_attach_groups_dict = MD_Extended.vxlan.overlay_services.network_attach_groups_dict %} -{% endif %} -{% for attach in network_attach_groups_dict[net['network_attach_group']] %} - - ip_address: {{ attach['mgmt_ip_address'] }} - ports: {{ attach['ports'] }} -{% endfor %} - deploy: false -{% endif %} +{#- This NDFC fabric networks data structure is auto-generated #} +{#- DO NOT EDIT MANUALLY #} -{% endfor %} +{% set vxlan = MD_Extended.vxlan %} +{% if vxlan.fabric.type == 'VXLAN_EVPN' %} + +{# Include NDFC DC VXLAN EVPN Base Template #} +{% include '/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2' %} + +{% elif vxlan.fabric.type == 'MSD'%} + +{# Include NDFC MSD Base Template #} +{% include '/ndfc_networks/msd_fabric/msd_fabric_networks.j2' %} + +{# Supported fabric types are: DC VXLAN EVPN and MSDs #} +{% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 index d3d40fa6..8c227bef 100644 --- a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 @@ -1,68 +1,17 @@ --- -# This NDFC VRFs and switch attachments config data structure is auto-generated -# DO NOT EDIT MANUALLY -# -{% if MD_Extended.vxlan.overlay.vrfs is defined and MD_Extended.vxlan.overlay.vrfs %} -{% set vrfs = MD_Extended.vxlan.overlay.vrfs %} -{% elif MD_Extended.vxlan.overlay_services.vrfs is defined and MD_Extended.vxlan.overlay_services.vrfs %} -{% set vrfs = MD_Extended.vxlan.overlay_services.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) }} - 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) }} - 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_mvpn_rt: {{ vrf['export_mvpn_rt'] | default(omit) }} - export_vpn_rt: {{ vrf['export_vpn_rt'] | default(omit) }} - import_evpn_rt: {{ vrf['import_evpn_rt'] | default(omit) }} - 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) }} -{% 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 %} - redist_direct_rmap: {{ vrf['redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.redist_direct_routemap) }} -{# ------------------------------------------------------ #} -{# Attach Group Section #} -{# ------------------------------------------------------ #} -{% if vrf['vrf_attach_group'] is defined %} - attach: -{% if MD_Extended.vxlan.overlay.vrf_attach_groups_dict is defined and MD_Extended.vxlan.overlay.vrf_attach_groups_dict %} -{% set vrf_attach_groups_dict = MD_Extended.vxlan.overlay.vrf_attach_groups_dict %} -{% elif MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict is defined and MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict %} -{% set vrf_attach_groups_dict = MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict %} -{% endif %} -{% for attach in vrf_attach_groups_dict[vrf['vrf_attach_group']] %} - - ip_address: {{ attach['mgmt_ip_address'] }} -{% endfor %} - deploy: false -{% endif %} +{#- This NDFC fabric vrfs config data structure is auto-generated #} +{#- DO NOT EDIT MANUALLY #} -{% endfor %} +{% set vxlan = MD_Extended.vxlan %} +{% if vxlan.fabric.type == 'VXLAN_EVPN' %} + +{# Include NDFC DC VXLAN EVPN Base Template #} +{% include '/ndfc_vrfs/dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2' %} + +{% elif vxlan.fabric.type == 'MSD'%} + +{# Include NDFC MSD Base Template #} +{% include '/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2' %} + +{# Supported fabric types are: DC VXLAN EVPN and ISN #} +{% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 index 362e2257..a593cfa1 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 @@ -1,5 +1,5 @@ {# Auto-generated NDFC MSD General config data structure for fabric {{ vxlan.fabric.name }} #} - VXLAN_UNDERLAY_IS_V6: False + VXLAN_UNDERLAY_IS_V6: {{ vxlan.multisite.enable_ipv6_underlay | default(defaults.vxlan.multisite.enable_ipv6_underlay) }} {% if not vxlan.multisite.enable_ipv6_underlay | default(defaults.vxlan.multisite.enable_ipv6_underlay) %} ENABLE_PVLAN: false {% endif %} diff --git a/roles/dtc/common/templates/ndfc_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory.j2 index 895f8505..9bae159b 100644 --- a/roles/dtc/common/templates/ndfc_inventory.j2 +++ b/roles/dtc/common/templates/ndfc_inventory.j2 @@ -1,5 +1,5 @@ --- -{#- This NDFC fabric config data structure is auto-generated #} +{#- This NDFC fabric inventory config data structure is auto-generated #} {#- DO NOT EDIT MANUALLY #} {% set vxlan = MD_Extended.vxlan %} diff --git a/roles/dtc/common/templates/ndfc_networks/.gitkeep b/roles/dtc/common/templates/ndfc_networks/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 new file mode 100644 index 00000000..68c5ea7b --- /dev/null +++ b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 @@ -0,0 +1,86 @@ +{# Auto-generated NDFC DC VXLAN EVPN VRFs config data structure for fabric {{ vxlan.fabric.name }} #} +{% if MD_Extended.vxlan.overlay.networks is defined and MD_Extended.vxlan.overlay.networks %} +{% set networks = MD_Extended.vxlan.overlay.networks %} +{% elif MD_Extended.vxlan.overlay_services.networks is defined and MD_Extended.vxlan.overlay_services.networks %} +{% set networks = MD_Extended.vxlan.overlay_services.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) }} + dhcp_loopback_id: {{ net['dhcp_loopback_id'] | default(omit) }} +{% if net.dhcp_servers is defined %} +{% if net.dhcp_servers | length == 1 %} + dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} + dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} +{% elif net.dhcp_servers | length == 2 %} + dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} + dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} + dhcp_srvr2_ip: {{ net['dhcp_servers'][1]['ip_address'] }} + dhcp_srvr2_vrf: {{ net['dhcp_servers'][1]['vrf'] }} +{% elif net.dhcp_servers | length == 3 %} + dhcp_srvr1_ip: {{ net['dhcp_servers'][0]['ip_address'] }} + dhcp_srvr1_vrf: {{ net['dhcp_servers'][0]['vrf'] }} + dhcp_srvr2_ip: {{ net['dhcp_servers'][1]['ip_address'] }} + dhcp_srvr2_vrf: {{ net['dhcp_servers'][1]['vrf'] }} + dhcp_srvr3_ip: {{ net['dhcp_servers'][2]['ip_address'] }} + dhcp_srvr3_vrf: {{ net['dhcp_servers'][2]['vrf'] }} +{% endif %} +{% endif %} + gw_ipv6_subnet: {{ net['gw_ipv6_address'] | default(omit) }} + int_desc: {{ net['int_desc'] | default(defaults.vxlan.overlay.networks.net_description) }} + l3gw_on_border: {{ net['l3gw_on_border'] | default(defaults.vxlan.overlay.networks.l3gw_on_border) }} + mtu_l3intf: {{ net['mtu_l3intf'] | default(defaults.vxlan.overlay.networks.mtu_l3intf) }} +{% if (MD.vxlan.underlay.general.replication_mode | lower) == 'multicast' %} + multicast_group_address: {{ net['multicast_group_address'] | default(defaults.vxlan.overlay.networks.multicast_group_address) }} +{% endif %} + netflow_enable: {{ net['netflow_enable'] | default(defaults.vxlan.overlay.networks.netflow_enable) }} +{% if net['netflow_enable'] is defined and net['netflow_enable'] | bool %} + vlan_nf_monitor: {{ net['vlan_netflow_monitor'] | default(omit) }} +{% endif %} + route_target_both: {{ net['route_target_both'] | default(defaults.vxlan.overlay.networks.route_target_both) }} + route_tag: {{ net['route_tag'] | default(defaults.vxlan.overlay.networks.route_tag) }} + trm_enable: {{ net['trm_enable'] | default(defaults.vxlan.overlay.networks.trm_enable) }} +{# ------------------------------------------------------ #} +{# Attach Group Section #} +{# ------------------------------------------------------ #} +{% if net['network_attach_group'] is defined %} + attach: +{% if MD_Extended.vxlan.overlay.network_attach_groups_dict is defined and MD_Extended.vxlan.overlay.network_attach_groups_dict %} +{% set network_attach_groups_dict = MD_Extended.vxlan.overlay.network_attach_groups_dict %} +{% elif MD_Extended.vxlan.overlay_services.network_attach_groups_dict is defined and MD_Extended.vxlan.overlay_services.network_attach_groups_dict %} +{% set network_attach_groups_dict = MD_Extended.vxlan.overlay_services.network_attach_groups_dict %} +{% endif %} +{% for attach in network_attach_groups_dict[net['network_attach_group']] %} + - ip_address: {{ attach['mgmt_ip_address'] }} + ports: {{ attach['ports'] }} +{% endfor %} + deploy: false +{% endif %} + +{% endfor %} 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 new file mode 100644 index 00000000..41792ede --- /dev/null +++ b/roles/dtc/common/templates/ndfc_networks/msd_fabric/msd_fabric_networks.j2 @@ -0,0 +1,56 @@ +{# 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) }} + route_tag: {{ net['route_tag'] | default(defaults.vxlan.overlay.networks.route_tag) }} +{# ------------------------------------------------------ #} +{# Attach Group Section #} +{# ------------------------------------------------------ #} +{% if net['network_attach_group'] is defined %} + attach: +{% if MD_Extended.vxlan.multisite.overlay.network_attach_groups_dict is defined and MD_Extended.vxlan.multisite.overlay.network_attach_groups_dict %} +{% set network_attach_groups_dict = MD_Extended.vxlan.multisite.overlay.network_attach_groups_dict %} +{% endif %} +{% for attach in network_attach_groups_dict[net['network_attach_group']] %} + - ip_address: {{ msd_switches[attach['hostname']] }} + ports: {{ attach['ports'] }} +{% endfor %} + deploy: false +{% endif %} + +{% endfor %} diff --git a/roles/dtc/common/templates/ndfc_vrfs/.gitkeep b/roles/dtc/common/templates/ndfc_vrfs/.gitkeep new file mode 100644 index 00000000..e69de29b 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 new file mode 100644 index 00000000..7e24e666 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_vrfs/dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 @@ -0,0 +1,65 @@ +{# Auto-generated NDFC DC VXLAN EVPN VRFs config data structure for fabric {{ vxlan.fabric.name }} #} +{% if MD_Extended.vxlan.overlay.vrfs is defined and MD_Extended.vxlan.overlay.vrfs %} +{% set vrfs = MD_Extended.vxlan.overlay.vrfs %} +{% elif MD_Extended.vxlan.overlay_services.vrfs is defined and MD_Extended.vxlan.overlay_services.vrfs %} +{% set vrfs = MD_Extended.vxlan.overlay_services.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) }} + 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) }} + 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_mvpn_rt: {{ vrf['export_mvpn_rt'] | default(omit) }} + export_vpn_rt: {{ vrf['export_vpn_rt'] | default(omit) }} + import_evpn_rt: {{ vrf['import_evpn_rt'] | default(omit) }} + 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) }} +{% 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 %} + redist_direct_rmap: {{ vrf['redist_direct_routemap'] | default(defaults.vxlan.overlay.vrfs.redist_direct_routemap) }} +{# ------------------------------------------------------ #} +{# Attach Group Section #} +{# ------------------------------------------------------ #} +{% if vrf['vrf_attach_group'] is defined %} + attach: +{% if MD_Extended.vxlan.overlay.vrf_attach_groups_dict is defined and MD_Extended.vxlan.overlay.vrf_attach_groups_dict %} +{% set vrf_attach_groups_dict = MD_Extended.vxlan.overlay.vrf_attach_groups_dict %} +{% elif MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict is defined and MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict %} +{% set vrf_attach_groups_dict = MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict %} +{% endif %} +{% for attach in vrf_attach_groups_dict[vrf['vrf_attach_group']] %} + - ip_address: {{ attach['mgmt_ip_address'] }} +{% endfor %} + deploy: false +{% endif %} + +{% 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 new file mode 100644 index 00000000..65f245e8 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 @@ -0,0 +1,42 @@ +{# 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 %} +{% 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) }} +{# ------------------------------------------------------ #} +{# Attach Group Section #} +{# ------------------------------------------------------ #} +{% if vrf['vrf_attach_group'] is defined %} + attach: +{% if MD_Extended.vxlan.multisite.overlay.vrf_attach_groups_dict is defined and MD_Extended.vxlan.multisite.overlay.vrf_attach_groups_dict %} +{% set vrf_attach_groups_dict = MD_Extended.vxlan.multisite.overlay.vrf_attach_groups_dict %} +{% endif %} +{% for attach in vrf_attach_groups_dict[vrf['vrf_attach_group']] %} + - ip_address: {{ msd_switches[attach['hostname']] }} +{% 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 2be757e4..46ba1fee 100644 --- a/roles/dtc/create/tasks/msd/vrfs_networks.yml +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -42,7 +42,6 @@ - MD_Extended.vxlan.multisite.overlay.vrfs - changes_detected_vrfs - # -------------------------------------------------------------------- # Manage Network Configuration on NDFC # -------------------------------------------------------------------- diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index 271c0981..396fe573 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -47,8 +47,8 @@ - name: Manage NDFC Fabric VRFs and Networks ansible.builtin.import_tasks: msd/vrfs_networks.yml - when: > - MD_Extended.vxlan.multisite.overlay is defined and - MD_Extended.vxlan.multisite.topology.switches | length > 0 and - (changes_detected_vrfs or changes_detected_networks) + when: + - MD_Extended.vxlan.multisite.overlay is defined + - MD_Extended.vxlan.multisite.overlay + - (changes_detected_vrfs or changes_detected_networks) tags: "{{ nac_tags.create_vrfs_networks }}" diff --git a/roles/dtc/remove/tasks/main.yml b/roles/dtc/remove/tasks/main.yml index 0a0cdcce..b7cd6c7f 100644 --- a/roles/dtc/remove/tasks/main.yml +++ b/roles/dtc/remove/tasks/main.yml @@ -31,6 +31,7 @@ ansible.builtin.import_tasks: sub_main_msd.yml when: - MD_Extended.vxlan.fabric.type == 'MSD' + - changes_detected_interfaces or changes_detected_networks or changes_detected_vrfs or changes_detected_vpc_peering or changes_detected_link_vpc_peering or changes_detected_inventory - name: Mark Stage Role Remove Completed cisco.nac_dc_vxlan.common.run_map: diff --git a/roles/dtc/remove/tasks/sub_main_msd.yml b/roles/dtc/remove/tasks/sub_main_msd.yml index 072e61f5..bdec899e 100644 --- a/roles/dtc/remove/tasks/sub_main_msd.yml +++ b/roles/dtc/remove/tasks/sub_main_msd.yml @@ -21,17 +21,35 @@ --- -# - name: Remove Fabric Networks -# ansible.builtin.import_tasks: msd/networks.yml -# tags: "{{ nac_tags.remove_networks }}" -# when: -# - changes_detected_networks +- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.remove] + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Calling Role - [cisco.nac_dc_vxlan.dtc.remove] +" + - "----------------------------------------------------------------" + tags: "{{ nac_tags.remove }}" # Tags defined in roles/common_global/vars/main.yml -# - name: Remove Fabric VRFs -# ansible.builtin.import_tasks: msd/vrfs.yml -# tags: "{{ nac_tags.remove_vrfs }}" -# when: -# - changes_detected_vrfs +- ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" + tags: "{{ nac_tags.remove }}" + +- name: Get List of Fabric Switches from NDFC + cisco.dcnm.dcnm_rest: + method: GET + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/inventory/switchesByFabric" + register: switch_list + tags: "{{ nac_tags.remove }}" + +- name: Remove Fabric Networks + ansible.builtin.import_tasks: msd/networks.yml + tags: "{{ nac_tags.remove_networks }}" + when: + - changes_detected_networks + +- name: Remove Fabric VRFs + ansible.builtin.import_tasks: msd/vrfs.yml + tags: "{{ nac_tags.remove_vrfs }}" + when: + - changes_detected_vrfs - name: Remove Child Fabrics ansible.builtin.import_tasks: msd/child_fabrics.yml diff --git a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py index 3a7cf6db..d57354c3 100644 --- a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py +++ b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py @@ -22,10 +22,10 @@ def match(cls, inventory): if 'overlay_services' in check['keys_found'] and 'overlay_services' in check['keys_data']: overlay_key = 'overlay_services' - network_keys = ['vxlan', f'{overlay_key}', 'networks'] - vrf_keys = ['vxlan', f'{overlay_key}', 'vrfs'] - network_attach_keys = ['vxlan', f'{overlay_key}', 'network_attach_groups'] - vrf_attach_keys = ['vxlan', f'{overlay_key}', 'vrf_attach_groups'] + network_keys = ['vxlan', overlay_key, 'networks'] + vrf_keys = ['vxlan', overlay_key, 'vrfs'] + network_attach_keys = ['vxlan', overlay_key, 'network_attach_groups'] + vrf_attach_keys = ['vxlan', overlay_key, 'vrf_attach_groups'] # Check if vrfs, network and switch data is defined in the service model check = cls.data_model_key_check(inventory, switch_keys) From 12196094a9c7c7842a2b6dc90d643cd5d89b9be3 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 10 Dec 2024 21:34:39 -0500 Subject: [PATCH 24/66] update github templates --- .github/ISSUE_TEMPLATE/bug_report.yml | 4 +++- .github/ISSUE_TEMPLATE/documentation_report.yml | 4 +++- .github/ISSUE_TEMPLATE/feature_request.yml | 4 +++- .github/pull_request_template.md | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 9f9c517c..8f9a48ff 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -76,12 +76,14 @@ body: label: Which section of the data model is this issue related to? multiple: false options: + - vxlan.fabric - vxlan.global - vxlan.topology - vxlan.underlay - - vxlan.overlay_services + - vxlan.overlay - vxlan.overlay_extensions - vxlan.policy + - vxlan.multisite - defaults.vxlan - other validations: diff --git a/.github/ISSUE_TEMPLATE/documentation_report.yml b/.github/ISSUE_TEMPLATE/documentation_report.yml index bc22f8e6..de9f9e19 100644 --- a/.github/ISSUE_TEMPLATE/documentation_report.yml +++ b/.github/ISSUE_TEMPLATE/documentation_report.yml @@ -41,12 +41,14 @@ body: label: Which section of the data model is the documentation update related? multiple: false options: + - vxlan.fabric - vxlan.global - vxlan.topology - vxlan.underlay - - vxlan.overlay_services + - vxlan.overlay - vxlan.overlay_extensions - vxlan.policy + - vxlan.multisite - defaults.vxlan - other validations: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index c1ff8586..ce9bdf89 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -50,12 +50,14 @@ body: label: Which section of the data model is the new feature related? multiple: false options: + - vxlan.fabric - vxlan.global - vxlan.topology - vxlan.underlay - - vxlan.overlay_services + - vxlan.overlay - vxlan.overlay_extensions - vxlan.policy + - vxlan.multisite - defaults.vxlan - other validations: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a9cbc8ff..39e02a3f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -16,12 +16,14 @@ ## Related Data Model Element +* [ ] vxlan.fabric * [ ] vxlan.global * [ ] vxlan.topology * [ ] vxlan.underlay -* [ ] vxlan.overlay_services +* [ ] vxlan.overlay * [ ] vxlan.overlay_extensions * [ ] vxlan.policy +* [ ] vxlan.multisite * [ ] defaults.vxlan * [ ] other From a33823f6fb9ebf3068f6a9d9162e01ca45f9dfea Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 10 Dec 2024 21:53:46 -0500 Subject: [PATCH 25/66] fix pipeline errors --- plugins/action/common/nac_dc_load.py | 73 ---------------- plugins/action/common/nac_dc_validate.py | 8 +- .../common/prepare_plugins/prep_101_fabric.py | 12 ++- .../prep_104_fabric_overlay.py | 4 +- plugins/action/dtc/manage_child_fabrics.py | 8 +- .../dtc/update_switch_hostname_policy.py | 2 +- plugins/filter/quote.py | 85 ------------------- .../401_overlay_services_cross_reference.py | 4 +- .../rules/vxlan/402_overlay_services_vrfs.py | 2 +- tests/sanity/ignore-2.14.txt | 6 +- tests/sanity/ignore-2.15.txt | 6 +- tests/sanity/ignore-2.16.txt | 6 +- 12 files changed, 35 insertions(+), 181 deletions(-) delete mode 100644 plugins/action/common/nac_dc_load.py delete mode 100644 plugins/filter/quote.py diff --git a/plugins/action/common/nac_dc_load.py b/plugins/action/common/nac_dc_load.py deleted file mode 100644 index 2b5154ba..00000000 --- a/plugins/action/common/nac_dc_load.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - -from __future__ import absolute_import, division, print_function - - -__metaclass__ = type - -from ansible.utils.display import Display -from ansible.plugins.action import ActionBase -from ansible.errors import AnsibleError - -try: - from iac_validate.yaml import load_yaml_files - from iac_validate.cli.options import DEFAULT_SCHEMA -except ImportError as imp_exc: - IAC_VALIDATE_IMPORT_ERROR = imp_exc -else: - IAC_VALIDATE_IMPORT_ERROR = None - -import os - -display = Display() - - -class ActionModule(ActionBase): - - def run(self, tmp=None, task_vars=None): - results = super(ActionModule, self).run(tmp, task_vars) - results['failed'] = False - results['msg'] = None - results['data'] = {} - - if IAC_VALIDATE_IMPORT_ERROR: - raise AnsibleError('iac-validate not found and must be installed. Please pip install iac-validate.') from IAC_VALIDATE_IMPORT_ERROR - - mdata = self._task.args.get('mdata') - - # Verify That Data Sources Exists - if mdata and not os.path.exists(mdata): - results['failed'] = True - results['msg'] = "The data directory ({0}) for this fabric does not appear to exist!".format(mdata) - - return results - - if len(os.listdir(mdata)) == 0: - results['failed'] = True - results['msg'] = "The data directory ({0}) for this fabric is empty!".format(mdata) - - return results - - # Return Merged Model Data - results['data'] = load_yaml_files([mdata]) - - return results diff --git a/plugins/action/common/nac_dc_validate.py b/plugins/action/common/nac_dc_validate.py index 1a9fc3b4..5b4271a3 100644 --- a/plugins/action/common/nac_dc_validate.py +++ b/plugins/action/common/nac_dc_validate.py @@ -109,8 +109,12 @@ def run(self, tmp=None, task_vars=None): check = data_model_key_check(results['data'], parent_keys) if 'global' in check['keys_found'] and 'global' in check['keys_data']: if 'fabric_type' in results['data']['vxlan']['global']: - display.deprecated("Attempting to use vxlan.global.fabric_type due to vxlan.fabric.type not being found. vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric.type.") - + deprecated_msg = ( + "Attempting to use vxlan.global.fabric_type due to vxlan.fabric.type not being found. " + "vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric.type." + ) + display.deprecated(msg=deprecated_msg, version='1.0.0') + if results['data']['vxlan']['global']['fabric_type'] in ('VXLAN_EVPN'): rules_list.append(f'{rules}vxlan/') elif results['data']['vxlan']['global']['fabric_type'] in ('MSD', 'MCF'): diff --git a/plugins/action/common/prepare_plugins/prep_101_fabric.py b/plugins/action/common/prepare_plugins/prep_101_fabric.py index e1dce5c4..9940d471 100644 --- a/plugins/action/common/prepare_plugins/prep_101_fabric.py +++ b/plugins/action/common/prepare_plugins/prep_101_fabric.py @@ -39,10 +39,12 @@ def prepare(self): parent_keys = ['vxlan', 'fabric'] dm_check = data_model_key_check(model_data, parent_keys) if 'fabric' in dm_check['keys_not_found'] or 'fabric' in dm_check['keys_no_data']: - display.deprecated( - "Attempting to use vxlan.global.name and vxlan.global.fabric_type due to vxlan.fabric.name and vxlan.fabric.type not being defined. " + deprecated_msg = ( + "Attempting to use vxlan.global.name and vxlan.global.fabric_type due to " + "vxlan.fabric.name and vxlan.fabric.type not being defined. " "vxlan.global.name and vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric." ) + display.deprecated(msg=deprecated_msg, version="1.0.0") parent_keys = ['vxlan', 'global'] dm_check = data_model_key_check(model_data, parent_keys) @@ -72,10 +74,11 @@ def prepare(self): parent_keys = ['vxlan', 'fabric', 'name'] dm_check = data_model_key_check(model_data, parent_keys) if 'name' in dm_check['keys_no_data'] or 'name' in dm_check['keys_not_found']: - display.deprecated( + deprecated_msg = ( "Attempting to use vxlan.global.name due to vxlan.fabric.name not being defined. " "vxlan.global.name is being deprecated. Please use vxlan.fabric." ) + display.deprecated(msg=deprecated_msg, version="1.0.0") parent_keys = ['vxlan', 'global', 'name'] dm_check = data_model_key_check(model_data, parent_keys) if 'name' in dm_check['keys_data']: @@ -88,10 +91,11 @@ def prepare(self): parent_keys = ['vxlan', 'fabric', 'type'] dm_check = data_model_key_check(model_data, parent_keys) if 'type' in dm_check['keys_no_data'] or 'type' in dm_check['keys_not_found']: - display.deprecated( + deprecated_msg = ( "Attempting to use vxlan.global.type due to vxlan.fabric.type not being defined. " "vxlan.global.type is being deprecated. Please use vxlan.fabric." ) + display.deprecated(msg=deprecated_msg, version="1.0.0") parent_keys = ['vxlan', 'global', 'fabric_type'] dm_check = data_model_key_check(model_data, parent_keys) if 'fabric_type' in dm_check['keys_data']: diff --git a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py index 33a27755..9c1ad87f 100644 --- a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py +++ b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py @@ -34,7 +34,7 @@ def prepare(self): # Remove the check for overlay_services after deprecation # Remove lines 32-37 overlay_key = 'overlay' - check = data_model_key_check(model_data, ['vxlan']) + check = data_model_key_check(model_data, ['vxlan']) if 'overlay_services' in check['keys_found'] and 'overlay_services' in check['keys_data']: overlay_key = 'overlay_services' @@ -86,7 +86,7 @@ def prepare(self): if 'network_attach_group' in net: if net.get('network_attach_group') not in net_grp_name_list: del net['network_attach_group'] - + if model_data['vxlan']['fabric']['type'] in ('MSD', 'MCF'): # Rebuild sm_data['vxlan']['multisite']['overlay']['vrf_attach_groups'] into # a structure that is easier to use. diff --git a/plugins/action/dtc/manage_child_fabrics.py b/plugins/action/dtc/manage_child_fabrics.py index e2793bfc..b69e4744 100644 --- a/plugins/action/dtc/manage_child_fabrics.py +++ b/plugins/action/dtc/manage_child_fabrics.py @@ -55,7 +55,7 @@ def run(self, tmp=None, task_vars=None): module_name="cisco.dcnm.dcnm_rest", module_args={ "method": "POST", - "path": f"/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd", + "path": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd", "json_data": json_data }, task_vars=task_vars, @@ -68,7 +68,7 @@ def run(self, tmp=None, task_vars=None): break results['changed'] = True - + if operation == 'remove': for associated_child_fabric in associated_child_fabrics: if not any(associated_child_fabric == child_fabric['name'] for child_fabric in child_fabrics): @@ -77,7 +77,7 @@ def run(self, tmp=None, task_vars=None): module_name="cisco.dcnm.dcnm_rest", module_args={ "method": "POST", - "path": f"/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdExit", + "path": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdExit", "json_data": json_data }, task_vars=task_vars, @@ -150,5 +150,3 @@ def run(self, tmp=None, task_vars=None): # https://rtp-ndfc1.cisco.com/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdExit # POST # {"destFabric":"nac-msd","sourceFabric":"nac-ndfc1"} - - diff --git a/plugins/action/dtc/update_switch_hostname_policy.py b/plugins/action/dtc/update_switch_hostname_policy.py index f660e99b..2b841e3b 100644 --- a/plugins/action/dtc/update_switch_hostname_policy.py +++ b/plugins/action/dtc/update_switch_hostname_policy.py @@ -54,7 +54,7 @@ def run(self, tmp=None, task_vars=None): dm_switches = model_data["vxlan"]["topology"]["switches"] elif model_data["vxlan"]["fabric"]["type"] in ('ISN'): dm_switches = model_data["vxlan"]["multisite"]["isn"]["topology"]["switches"] - + switch_match = next((item for item in dm_switches if item["serial_number"] == switch_serial_number)) if policy_match["nvPairs"]["SWITCH_NAME"] != switch_match["name"]: diff --git a/plugins/filter/quote.py b/plugins/filter/quote.py deleted file mode 100644 index 9203ea35..00000000 --- a/plugins/filter/quote.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - -DOCUMENTATION = r""" - name: quote - version_added: "0.4.0" - short_description: Quote - description: - - Quote a string or integer. - positional: item - options: - item: - description: Item to quote. - required: true -""" - -EXAMPLES = r""" - - quoted: "{{ var1 | cisco.nac_dc_vxlan.quote() }}" - # => True - -""" - -RETURN = r""" - _value: - description: - - A string value. - type: str -""" - -import operator -from jinja2.runtime import Undefined -from jinja2.exceptions import UndefinedError - -from packaging.version import Version - -from ansible.module_utils.six import string_types -from ansible.errors import AnsibleFilterError, AnsibleFilterTypeError -from ansible.module_utils.common.text.converters import to_native - - -def quote(item): - # if not isinstance(version1, (string_types, Undefined)): - # raise AnsibleFilterTypeError(f"Can only check string versions, however version1 is: {type(version1)}") - - # if not isinstance(version2, (string_types, Undefined)): - # raise AnsibleFilterTypeError(f"Can only check string versions, however version2 is: {type(version2)}") - - # if not isinstance(op, (string_types, Undefined)) and op not in SUPPORTED_COMPARISON_OPERATORS: - # raise AnsibleFilterError(f"Unsupported operator {op} type. Supported operators are: {SUPPORTED_COMPARISON_OPERATORS}") - - try: - return f'"{item}"' - except UndefinedError: - raise - except Exception as e: - raise AnsibleFilterError("Unable handle version: %s" % to_native(e), orig_exc=e) - - -# ---- Ansible filters ---- -class FilterModule(object): - """ Quote filter """ - - def filters(self): - return { - "quote": quote - } diff --git a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py index d57354c3..01068590 100644 --- a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py +++ b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py @@ -18,7 +18,7 @@ def match(cls, inventory): # Remove the check for overlay_services after deprecation # Remove lines 21 - 23 overlay_key = 'overlay' - check = cls.data_model_key_check(inventory, ['vxlan']) + check = cls.data_model_key_check(inventory, ['vxlan']) if 'overlay_services' in check['keys_found'] and 'overlay_services' in check['keys_data']: overlay_key = 'overlay_services' @@ -65,7 +65,7 @@ def match(cls, inventory): # sm_vrfs = None # network_attach_groups = None # vrf_attach_groups = None - + # network_keys = ['vxlan', 'overlay_services', 'networks'] # vrf_keys = ['vxlan', 'overlay_services', 'vrfs'] # network_attach_keys = ['vxlan', 'overlay_services', 'network_attach_groups'] diff --git a/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py b/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py index a64bc7bd..9441a018 100644 --- a/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py +++ b/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py @@ -23,7 +23,7 @@ def match(cls, inventory): if inventory["vxlan"].get("overlay").get("vrfs", None): vrfs = inventory["vxlan"]["overlay"]["vrfs"] elif inventory["vxlan"].get("overlay_services").get("vrfs", None): - vrfs = inventory["vxlan"]["overlay_services"]["vrfs"] + vrfs = inventory["vxlan"]["overlay_services"]["vrfs"] for vrf in vrfs: current_vrf_netflow_status = vrf.get("netflow_enable", None) diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index d81804d6..9ee98627 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_global.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_107_vrf_lites.py action-plugin-docs # action plugin has no matching module to provide documentation @@ -19,6 +19,8 @@ plugins/action/dtc/diff_model_changes.py action-plugin-docs # action plugin has plugins/action/dtc/update_switch_hostname_policy.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/unmanaged_policy.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/get_poap_data.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/dtc/manage_child_fabrics.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/dtc/map_msd_inventory.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtd/prepare_service_model.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/test/inventory.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py import-3.10!skip diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index d81804d6..9ee98627 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_global.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_107_vrf_lites.py action-plugin-docs # action plugin has no matching module to provide documentation @@ -19,6 +19,8 @@ plugins/action/dtc/diff_model_changes.py action-plugin-docs # action plugin has plugins/action/dtc/update_switch_hostname_policy.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/unmanaged_policy.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/get_poap_data.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/dtc/manage_child_fabrics.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/dtc/map_msd_inventory.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtd/prepare_service_model.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/test/inventory.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py import-3.10!skip diff --git a/tests/sanity/ignore-2.16.txt b/tests/sanity/ignore-2.16.txt index d81804d6..9ee98627 100644 --- a/tests/sanity/ignore-2.16.txt +++ b/tests/sanity/ignore-2.16.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_global.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_104_fabric_overlay_services.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_107_vrf_lites.py action-plugin-docs # action plugin has no matching module to provide documentation @@ -19,6 +19,8 @@ plugins/action/dtc/diff_model_changes.py action-plugin-docs # action plugin has plugins/action/dtc/update_switch_hostname_policy.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/unmanaged_policy.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/get_poap_data.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/dtc/manage_child_fabrics.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/dtc/map_msd_inventory.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtd/prepare_service_model.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/test/inventory.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py import-3.10!skip From 4eb8d41b36f2aee7748260516a8115592f69e90f Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 10 Dec 2024 21:59:43 -0500 Subject: [PATCH 26/66] fix pipeline errors --- tests/sanity/ignore-2.14.txt | 2 ++ tests/sanity/ignore-2.15.txt | 2 ++ tests/sanity/ignore-2.16.txt | 2 ++ 3 files changed, 6 insertions(+) diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 9ee98627..b884a59c 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -1,7 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 9ee98627..b884a59c 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -1,7 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.16.txt b/tests/sanity/ignore-2.16.txt index 9ee98627..b884a59c 100644 --- a/tests/sanity/ignore-2.16.txt +++ b/tests/sanity/ignore-2.16.txt @@ -1,7 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation From 898fc202586106e046febee40737971db7e66169 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Wed, 11 Dec 2024 02:25:26 -0500 Subject: [PATCH 27/66] fix deprecation error in pipeline --- tests/sanity/ignore-2.14.txt | 4 ++-- tests/sanity/ignore-2.15.txt | 4 ++-- tests/sanity/ignore-2.16.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index b884a59c..30491e76 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index b884a59c..30491e76 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.16.txt b/tests/sanity/ignore-2.16.txt index b884a59c..30491e76 100644 --- a/tests/sanity/ignore-2.16.txt +++ b/tests/sanity/ignore-2.16.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation From b0cb580a8df3fa3bd90f33d031d8a5fdcfd33135 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Wed, 11 Dec 2024 02:36:49 -0500 Subject: [PATCH 28/66] fix deprecation error in pipeline --- tests/sanity/ignore-2.14.txt | 4 ++-- tests/sanity/ignore-2.15.txt | 4 ++-- tests/sanity/ignore-2.16.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 30491e76..e7a8e178 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name!skip plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate!skip plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 30491e76..e7a8e178 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name!skip plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate!skip plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.16.txt b/tests/sanity/ignore-2.16.txt index 30491e76..e7a8e178 100644 --- a/tests/sanity/ignore-2.16.txt +++ b/tests/sanity/ignore-2.16.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name!skip plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate # No collection name found in call to Display.deprecated or AnsibleModule.deprecate +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate!skip plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation From 58bb54ab6251981d301bb81142da68428ffadbce Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Wed, 11 Dec 2024 03:03:10 -0500 Subject: [PATCH 29/66] fix deprecation error in pipeline --- tests/sanity/ignore-2.14.txt | 4 ++-- tests/sanity/ignore-2.15.txt | 4 ++-- tests/sanity/ignore-2.16.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index e7a8e178..912544ad 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name!skip +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate!skip +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index e7a8e178..912544ad 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name!skip +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate!skip +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.16.txt b/tests/sanity/ignore-2.16.txt index e7a8e178..912544ad 100644 --- a/tests/sanity/ignore-2.16.txt +++ b/tests/sanity/ignore-2.16.txt @@ -1,9 +1,9 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name!skip +plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name: No collection name found in call to Display.deprecated or AnsibleModule.deprecate!skip +plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation From 9ccf7226fa3a68d12f75baa7e843b3d5d4f011ac Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Thu, 12 Dec 2024 20:17:13 +0000 Subject: [PATCH 30/66] Fix prep_001 plugin for multisite --- .../action/common/prepare_plugins/prep_001_list_defaults.py | 3 ++- roles/validate/tasks/main.yml | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py index 8798874a..83c34be0 100644 --- a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py @@ -52,6 +52,7 @@ def set_list_default(self, parent_keys, target_key): # used by other plugins without having to check if the key exists. def prepare(self): self.model_data = self.kwargs['results']['model_extended'] + # -------------------------------------------------------------------- # Fabric Global List Defaults # -------------------------------------------------------------------- @@ -230,7 +231,7 @@ def prepare(self): parent_keys = ['vxlan', 'multisite'] dm_check = data_model_key_check(self.model_data, parent_keys) if 'multisite' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: - self.model_data['vxlan'] = {'multisite': {}} + self.model_data['vxlan']['multisite'] = {} # Check vxlan.multisite.overlay list elements parent_keys = ['vxlan', 'multisite', 'overlay'] diff --git a/roles/validate/tasks/main.yml b/roles/validate/tasks/main.yml index 41525ac7..e112592e 100644 --- a/roles/validate/tasks/main.yml +++ b/roles/validate/tasks/main.yml @@ -20,8 +20,6 @@ # SPDX-License-Identifier: MIT --- -- debug: msg="{{ nac_tags.all }}" - - name: Import Role Tasks ansible.builtin.import_tasks: sub_main.yml tags: "{{ nac_tags.validate_role }}" # Tags defined in roles/common_global/vars/main.yml From 2e64830afd0a7f6900f4eb9f712a954a658943dc Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Fri, 13 Dec 2024 03:06:41 +0000 Subject: [PATCH 31/66] Workflow fixes --- roles/dtc/common/tasks/sub_main_msd.yml | 1 - .../dc_vxlan_fabric_networks.j2 | 2 + .../msd_fabric/msd_fabric_networks.j2 | 3 + .../dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 | 2 + .../ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 | 3 + roles/dtc/remove/tasks/main.yml | 2 +- roles/dtc/remove/tasks/sub_main_msd.yml | 2 + .../rules/vxlan/402_overlay_services_vrfs.py | 47 ++++++++++++-- .../vxlan/403_overlay_services_networks.py | 63 +++++++++++++++++-- 9 files changed, 113 insertions(+), 12 deletions(-) diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 953af22c..db88946a 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -55,7 +55,6 @@ - name: Set MSD Switches List ansible.builtin.set_fact: msd_switches: "{{ msd_inventory.msd_switches }}" - when: msd_inventory.msd_switches is defined # -------------------------------------------------------------------- # Build NDFC Fabric VRFs Attach List From Template diff --git a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 index 68c5ea7b..988c99b5 100644 --- a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 +++ b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 @@ -1,4 +1,6 @@ {# Auto-generated NDFC DC VXLAN EVPN VRFs config data structure for fabric {{ vxlan.fabric.name }} #} +{# TODO: Remove lines 3-8. When we get here we should be normalized around overlay, not overlay_services#} +{% set networks = [] %} {% if MD_Extended.vxlan.overlay.networks is defined and MD_Extended.vxlan.overlay.networks %} {% set networks = MD_Extended.vxlan.overlay.networks %} {% elif MD_Extended.vxlan.overlay_services.networks is defined and MD_Extended.vxlan.overlay_services.networks %} 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 41792ede..04062bd4 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 @@ -41,6 +41,8 @@ {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} +{# Don't need to attach vrfs if there are no msd_switches #} +{% if msd_switches|length > 0 %} {% if net['network_attach_group'] is defined %} attach: {% if MD_Extended.vxlan.multisite.overlay.network_attach_groups_dict is defined and MD_Extended.vxlan.multisite.overlay.network_attach_groups_dict %} @@ -52,5 +54,6 @@ {% endfor %} deploy: false {% endif %} +{% endif %} {% endfor %} 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 7e24e666..ad37341b 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 @@ -1,4 +1,6 @@ {# Auto-generated NDFC DC VXLAN EVPN VRFs config data structure for fabric {{ vxlan.fabric.name }} #} +{# TODO: Remove lines 3-8. When we get here we should be normalized around overlay, not overlay_services#} +{% set vrfs = [] %} {% if MD_Extended.vxlan.overlay.vrfs is defined and MD_Extended.vxlan.overlay.vrfs %} {% set vrfs = MD_Extended.vxlan.overlay.vrfs %} {% elif MD_Extended.vxlan.overlay_services.vrfs is defined and MD_Extended.vxlan.overlay_services.vrfs %} 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 65f245e8..1eb61cbc 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 @@ -28,6 +28,8 @@ {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} +{# Don't need to attach vrfs if there are no msd_switches #} +{% if msd_switches|length > 0 %} {% if vrf['vrf_attach_group'] is defined %} attach: {% if MD_Extended.vxlan.multisite.overlay.vrf_attach_groups_dict is defined and MD_Extended.vxlan.multisite.overlay.vrf_attach_groups_dict %} @@ -38,5 +40,6 @@ {% endfor %} deploy: false {% endif %} +{% endif %} {% endfor %} diff --git a/roles/dtc/remove/tasks/main.yml b/roles/dtc/remove/tasks/main.yml index b7cd6c7f..c9f755aa 100644 --- a/roles/dtc/remove/tasks/main.yml +++ b/roles/dtc/remove/tasks/main.yml @@ -31,7 +31,7 @@ ansible.builtin.import_tasks: sub_main_msd.yml when: - MD_Extended.vxlan.fabric.type == 'MSD' - - changes_detected_interfaces or changes_detected_networks or changes_detected_vrfs or changes_detected_vpc_peering or changes_detected_link_vpc_peering or changes_detected_inventory + # - changes_detected_interfaces or changes_detected_networks or changes_detected_vrfs - name: Mark Stage Role Remove Completed cisco.nac_dc_vxlan.common.run_map: diff --git a/roles/dtc/remove/tasks/sub_main_msd.yml b/roles/dtc/remove/tasks/sub_main_msd.yml index bdec899e..4efd9228 100644 --- a/roles/dtc/remove/tasks/sub_main_msd.yml +++ b/roles/dtc/remove/tasks/sub_main_msd.yml @@ -39,12 +39,14 @@ register: switch_list tags: "{{ nac_tags.remove }}" +# These are not working right... investigate - name: Remove Fabric Networks ansible.builtin.import_tasks: msd/networks.yml tags: "{{ nac_tags.remove_networks }}" when: - changes_detected_networks +# These are not working right... investigate - name: Remove Fabric VRFs ansible.builtin.import_tasks: msd/vrfs.yml tags: "{{ nac_tags.remove_vrfs }}" diff --git a/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py b/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py index 9441a018..ec2fcf1d 100644 --- a/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py +++ b/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py @@ -19,12 +19,22 @@ def match(cls, inventory): if inventory["vxlan"].get("underlay").get("multicast", None): fabric_trm_status = inventory["vxlan"]["underlay"]["multicast"].get("trm_enable", False) - if inventory["vxlan"].get("overlay", None) or inventory["vxlan"].get("overlay_services", None): - if inventory["vxlan"].get("overlay").get("vrfs", None): - vrfs = inventory["vxlan"]["overlay"]["vrfs"] - elif inventory["vxlan"].get("overlay_services").get("vrfs", None): + vrf_keys = ['vxlan', 'overlay', 'vrfs'] + check = cls.data_model_key_check(inventory, vrf_keys) + if 'vrfs' in check['keys_data']: + vrfs = inventory["vxlan"]["overlay"]["vrfs"] + else: + vrf_keys = ['vxlan', 'overlay_services', 'vrfs'] + check = cls.data_model_key_check(inventory, vrf_keys) + if 'vrfs' in check['keys_data']: vrfs = inventory["vxlan"]["overlay_services"]["vrfs"] + # if inventory["vxlan"].get("overlay", None) or inventory["vxlan"].get("overlay_services", None): + # if inventory["vxlan"].get("overlay").get("vrfs", None): + # vrfs = inventory["vxlan"]["overlay"]["vrfs"] + # elif inventory["vxlan"].get("overlay_services").get("vrfs", None): + # vrfs = inventory["vxlan"]["overlay_services"]["vrfs"] + for vrf in vrfs: current_vrf_netflow_status = vrf.get("netflow_enable", None) if current_vrf_netflow_status is not None: @@ -99,3 +109,32 @@ def match(cls, inventory): break return results + + + @classmethod + def data_model_key_check(cls, tested_object, keys): + dm_key_dict = {'keys_found': [], 'keys_not_found': [], 'keys_data': [], 'keys_no_data': []} + for key in keys: + if tested_object and key in tested_object: + dm_key_dict['keys_found'].append(key) + tested_object = tested_object[key] + if tested_object: + dm_key_dict['keys_data'].append(key) + else: + dm_key_dict['keys_no_data'].append(key) + else: + dm_key_dict['keys_not_found'].append(key) + return dm_key_dict + + @classmethod + def safeget(cls, dict, keys): + # Utility function to safely get nested dictionary values + for key in keys: + if dict is None: + return None + if key in dict: + dict = dict[key] + else: + return None + + return dict diff --git a/roles/validate/files/rules/vxlan/403_overlay_services_networks.py b/roles/validate/files/rules/vxlan/403_overlay_services_networks.py index 97348cd9..daf4c7ac 100644 --- a/roles/validate/files/rules/vxlan/403_overlay_services_networks.py +++ b/roles/validate/files/rules/vxlan/403_overlay_services_networks.py @@ -15,17 +15,40 @@ def match(cls, inventory): if inventory["vxlan"].get("global").get("netflow", None): fabric_netflow_status = inventory["vxlan"]["global"]["netflow"].get("enable", False) + # Uncomment 19-22 when verified to work and remove line 13-16. + # netflow_keys = ['vxlan', 'global', 'netflow', 'enable'] + # check = cls.data_model_key_check(inventory, netflow_keys) + # if 'enable' in check['keys_data']: + # fabric_netflow_status = cls.safeget(inventory, netflow_keys) + + if inventory.get("vxlan", None): if inventory["vxlan"].get("underlay", None): if inventory["vxlan"].get("underlay").get("multicast", None): fabric_trm_status = inventory["vxlan"]["underlay"]["multicast"].get("trm_enable", False) - if inventory.get("vxlan", None): - if inventory["vxlan"].get("overlay", None) or inventory["vxlan"].get("overlay_services", None): - if inventory["vxlan"].get("overlay").get("networks", None): - networks = inventory["vxlan"]["overlay"]["networks"] - elif inventory["vxlan"].get("overlay_services").get("networks", None): - networks = inventory["vxlan"]["overlay_services"]["networks"] + # Uncomment 31-34 when verified to work and remove line 25-28. + # trm_keys = ['vxlan', 'underlay', 'multicast', 'trm_enabled'] + # check = cls.data_model_key_check(inventory, trm_keys) + # if 'trm_enable' in check['keys_data']: + # fabric_trm_status = cls.safeget(inventory, trm_keys) + + network_keys = ['vxlan', 'overlay', 'networks'] + check = cls.data_model_key_check(inventory, network_keys) + if 'networks' in check['keys_data']: + networks = inventory["vxlan"]["overlay"]["networks"] + else: + network_keys = ['vxlan', 'overlay_services', 'networks'] + check = cls.data_model_key_check(inventory, network_keys) + if 'networks' in check['keys_data']: + networks = inventory["vxlan"]["overlay_services"]["networks"] + + # if inventory.get("vxlan", None): + # if inventory["vxlan"].get("overlay", None) or inventory["vxlan"].get("overlay_services", None): + # if inventory["vxlan"].get("overlay").get("networks", None): + # networks = inventory["vxlan"]["overlay"]["networks"] + # elif inventory["vxlan"].get("overlay_services").get("networks", None): + # networks = inventory["vxlan"]["overlay_services"]["networks"] for network in networks: current_network_netflow_status = network.get("netflow_enable", None) @@ -57,3 +80,31 @@ def match(cls, inventory): break return results + + @classmethod + def data_model_key_check(cls, tested_object, keys): + dm_key_dict = {'keys_found': [], 'keys_not_found': [], 'keys_data': [], 'keys_no_data': []} + for key in keys: + if tested_object and key in tested_object: + dm_key_dict['keys_found'].append(key) + tested_object = tested_object[key] + if tested_object: + dm_key_dict['keys_data'].append(key) + else: + dm_key_dict['keys_no_data'].append(key) + else: + dm_key_dict['keys_not_found'].append(key) + return dm_key_dict + + @classmethod + def safeget(cls, dict, keys): + # Utility function to safely get nested dictionary values + for key in keys: + if dict is None: + return None + if key in dict: + dict = dict[key] + else: + return None + + return dict From 58dd0f0e03b54d933bb859b8fab0a1619272fdaa Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Fri, 20 Dec 2024 21:27:27 +0000 Subject: [PATCH 32/66] Fix list defaults bug --- .../prepare_plugins/prep_001_list_defaults.py | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py index 83c34be0..474a1231 100644 --- a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py @@ -74,13 +74,11 @@ def prepare(self): # Check vxlan.topology list elements parent_keys = ['vxlan', 'topology'] dm_check = data_model_key_check(self.model_data, parent_keys) - if 'topology' in dm_check['keys_not_found']: - self.model_data['vxlan']['topology'] = {} - if 'topology' in dm_check['keys_no_data']: - self.model_data['vxlan']['topology'] = {'edge_connections': []} - self.model_data['vxlan']['topology'] = {'fabric_links': []} - self.model_data['vxlan']['topology'] = {'switches': []} - self.model_data['vxlan']['topology'] = {'vpc_peers': []} + if ('topology' in dm_check['keys_no_data']) or ('topology' in dm_check['keys_not_found']): + self.model_data['vxlan']['topology']['edge_connections'] = [] + self.model_data['vxlan']['topology']['fabric_links'] = [] + self.model_data['vxlan']['topology']['switches'] = [] + self.model_data['vxlan']['topology']['vpc_peers'] = [] # Check vxlan.topology.fabric_links list element target_key = 'fabric_links' @@ -133,10 +131,10 @@ def prepare(self): parent_keys = ['vxlan', 'overlay'] dm_check = data_model_key_check(self.model_data, parent_keys) if 'overlay' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay'] = {'vrfs': []} - self.model_data['vxlan']['overlay'] = {'vrf_attach_groups': []} - self.model_data['vxlan']['overlay'] = {'networks': []} - self.model_data['vxlan']['overlay'] = {'network_attach_groups': []} + self.model_data['vxlan']['overlay']['vrfs'] = [] + self.model_data['vxlan']['overlay']['vrf_attach_groups'] = [] + self.model_data['vxlan']['overlay']['networks'] = [] + self.model_data['vxlan']['overlay']['network_attach_groups'] = [] # Check vxlan.overlay_services.vrfs list element target_key = 'vrfs' @@ -182,10 +180,10 @@ def prepare(self): parent_keys = ['vxlan', 'overlay_services'] dm_check = data_model_key_check(self.model_data, parent_keys) if 'overlay_services' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay_services'] = {'vrfs': []} - self.model_data['vxlan']['overlay_services'] = {'vrf_attach_groups': []} - self.model_data['vxlan']['overlay_services'] = {'networks': []} - self.model_data['vxlan']['overlay_services'] = {'network_attach_groups': []} + self.model_data['vxlan']['overlay_services']['vrfs'] = [] + self.model_data['vxlan']['overlay_services']['vrf_attach_groups'] = [] + self.model_data['vxlan']['overlay_services']['networks'] = [] + self.model_data['vxlan']['overlay_services']['network_attach_groups'] = [] # Check vxlan.overlay_services.vrfs list element target_key = 'vrfs' @@ -237,10 +235,10 @@ def prepare(self): parent_keys = ['vxlan', 'multisite', 'overlay'] dm_check = data_model_key_check(self.model_data, parent_keys) if 'overlay' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: - self.model_data['vxlan']['multisite']['overlay'] = {'vrfs': []} - self.model_data['vxlan']['multisite']['overlay'] = {'vrf_attach_groups': []} - self.model_data['vxlan']['multisite']['overlay'] = {'networks': []} - self.model_data['vxlan']['multisite']['overlay'] = {'network_attach_groups': []} + self.model_data['vxlan']['multisite']['overlay']['vrfs'] = [] + self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'] = [] + self.model_data['vxlan']['multisite']['overlay']['networks'] = [] + self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'] = [] # Check vxlan.multisite.overlay_services.vrfs list element target_key = 'vrfs' From e7ef318ecfd9a9965abd4a5177808ecf6f49d2c9 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Sat, 21 Dec 2024 05:48:24 +0000 Subject: [PATCH 33/66] Prepare plugin refactor --- ...{prep_101_fabric.py => prep_001_fabric.py} | 21 + .../prepare_plugins/prep_001_list_defaults.py | 308 -------------- .../prepare_plugins/prep_002_list_defaults.py | 395 ++++++++++++++++++ .../common/prepare_plugins/prep_999_verify.py | 65 +++ plugins/plugin_utils/data_model_keys.py | 67 +++ 5 files changed, 548 insertions(+), 308 deletions(-) rename plugins/action/common/prepare_plugins/{prep_101_fabric.py => prep_001_fabric.py} (84%) delete mode 100644 plugins/action/common/prepare_plugins/prep_001_list_defaults.py create mode 100644 plugins/action/common/prepare_plugins/prep_002_list_defaults.py create mode 100644 plugins/action/common/prepare_plugins/prep_999_verify.py create mode 100644 plugins/plugin_utils/data_model_keys.py diff --git a/plugins/action/common/prepare_plugins/prep_101_fabric.py b/plugins/action/common/prepare_plugins/prep_001_fabric.py similarity index 84% rename from plugins/action/common/prepare_plugins/prep_101_fabric.py rename to plugins/action/common/prepare_plugins/prep_001_fabric.py index 9940d471..497e3b7a 100644 --- a/plugins/action/common/prepare_plugins/prep_101_fabric.py +++ b/plugins/action/common/prepare_plugins/prep_001_fabric.py @@ -33,6 +33,13 @@ def __init__(self, **kwargs): def prepare(self): model_data = self.kwargs['results']['model_extended'] + # !!! WARNING !!! + # ------------------------------------------------------------------------------------------ + # If you are debugging problems with the data model and sections are missing make sure + # you don't have any data files with only the toplevel vxlan: key. This can cause problems + # where IaC validate removes sections of the model data, like the vxlan.underlay section + # ------------------------------------------------------------------------------------------ + # Checking for fabric key in the data model. # This type of check should be done in a rule, but fabric.name and fabric.type are foundational for the collection so we need to ensure it is set. # This prepare plugin also helps retain backwards compatibility with global.name and global.fabric_type keys previously used. @@ -104,5 +111,19 @@ def prepare(self): self.kwargs['results']['failed'] = True self.kwargs['results']['msg'] = "vxlan.fabric.type is not defined in the data model." + + # Replace 'overlay_services' key with 'overlay' + parent_keys = ['vxlan', 'overlay_services'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'overlay_services' in dm_check['keys_found']: + deprecated_msg = ( + "vxlan.overlay_services is being deprecated. " + "Please use vxlan.overlay instead" + ) + display.deprecated(msg=deprecated_msg, version="1.0.0") + model_data['vxlan']['overlay'] = model_data['vxlan']['overlay_services'] + del model_data['vxlan']['overlay_services'] + + self.kwargs['results']['model_extended'] = model_data return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py b/plugins/action/common/prepare_plugins/prep_001_list_defaults.py deleted file mode 100644 index 474a1231..00000000 --- a/plugins/action/common/prepare_plugins/prep_001_list_defaults.py +++ /dev/null @@ -1,308 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - - -from ....plugin_utils.helper_functions import data_model_key_check - - -def update_nested_dict(nested_dict, keys, new_value): - if len(keys) == 1: - nested_dict[keys[0]] = new_value - else: - key = keys[0] - if key in nested_dict: - update_nested_dict(nested_dict[key], keys[1:], new_value) - - -class PreparePlugin: - def __init__(self, **kwargs): - self.kwargs = kwargs - self.keys = [] - - def set_list_default(self, parent_keys, target_key): - keys = parent_keys + [target_key] - dm_check = data_model_key_check(self.model_data, keys) - if target_key in dm_check['keys_not_found'] or \ - target_key in dm_check['keys_no_data']: - update_nested_dict(self.model_data, keys, []) - - # The prepare method is used to default each list or nested list - # in the model data to an empty list if the key for the list does - # not exist or data under they key does not exist. - # - # This is to ensure that the model data is consistent and can be - # used by other plugins without having to check if the key exists. - def prepare(self): - self.model_data = self.kwargs['results']['model_extended'] - - # -------------------------------------------------------------------- - # Fabric Global List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.global list elements - parent_keys = ['vxlan', 'global'] - target_key = 'dns_servers' - self.set_list_default(parent_keys, target_key) - - # keys = ['vxlan', 'global', 'ntp_servers'] - parent_keys = ['vxlan', 'global'] - target_key = 'ntp_servers' - self.set_list_default(parent_keys, target_key) - - # -------------------------------------------------------------------- - # Fabric Topology List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.topology list elements - parent_keys = ['vxlan', 'topology'] - dm_check = data_model_key_check(self.model_data, parent_keys) - if ('topology' in dm_check['keys_no_data']) or ('topology' in dm_check['keys_not_found']): - self.model_data['vxlan']['topology']['edge_connections'] = [] - self.model_data['vxlan']['topology']['fabric_links'] = [] - self.model_data['vxlan']['topology']['switches'] = [] - self.model_data['vxlan']['topology']['vpc_peers'] = [] - - # Check vxlan.topology.fabric_links list element - target_key = 'fabric_links' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.topology.edge_connections list element - target_key = 'edge_connections' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.topology.switches list element - target_key = 'switches' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.topology.vpc_peers list element - target_key = 'vpc_peers' - self.set_list_default(parent_keys, target_key) - - # -------------------------------------------------------------------- - # Fabric Topology Switches Freeforms List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.topology.switches[index].freeforms list elements - list_index = 0 - for switch in self.model_data['vxlan']['topology']['switches']: - dm_check = data_model_key_check(switch, ['freeforms']) - if 'freeforms' in dm_check['keys_not_found'] or \ - 'freeforms' in dm_check['keys_no_data']: - self.model_data['vxlan']['topology']['switches'][list_index]['freeforms'] = [] - - list_index += 1 - - # -------------------------------------------------------------------- - # Fabric Topology Switches Interfaces List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.topology.switches[index].interfaces list elements - list_index = 0 - for switch in self.model_data['vxlan']['topology']['switches']: - dm_check = data_model_key_check(switch, ['interfaces']) - if 'interfaces' in dm_check['keys_not_found'] or 'interfaces' in dm_check['keys_no_data']: - self.model_data['vxlan']['topology']['switches'][list_index]['interfaces'] = [] - - list_index += 1 - - # -------------------------------------------------------------------- - # Fabric Overlay List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.overlay list elements - parent_keys = ['vxlan', 'overlay'] - dm_check = data_model_key_check(self.model_data, parent_keys) - if 'overlay' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay']['vrfs'] = [] - self.model_data['vxlan']['overlay']['vrf_attach_groups'] = [] - self.model_data['vxlan']['overlay']['networks'] = [] - self.model_data['vxlan']['overlay']['network_attach_groups'] = [] - - # Check vxlan.overlay_services.vrfs list element - target_key = 'vrfs' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.overlay.vrf_attach_groups list element - target_key = 'vrf_attach_groups' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.overlay.vrf_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['overlay']['vrf_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay']['vrf_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # Check vxlan.overlay.networks list element - target_key = 'networks' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.overlay.network_attach_groups list element - target_key = 'network_attach_groups' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.overlay.network_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['overlay']['network_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay']['network_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # -------------------------------------------------------------------- - # Fabric Overlay List Defaults - Backwards Compatibility - # -------------------------------------------------------------------- - - # Check vxlan.overlay_services list elements - parent_keys = ['vxlan', 'overlay_services'] - dm_check = data_model_key_check(self.model_data, parent_keys) - if 'overlay_services' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay_services']['vrfs'] = [] - self.model_data['vxlan']['overlay_services']['vrf_attach_groups'] = [] - self.model_data['vxlan']['overlay_services']['networks'] = [] - self.model_data['vxlan']['overlay_services']['network_attach_groups'] = [] - - # Check vxlan.overlay_services.vrfs list element - target_key = 'vrfs' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.overlay_services.vrf_attach_groups list element - target_key = 'vrf_attach_groups' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.overlay_services.vrf_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['overlay_services']['vrf_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay_services']['vrf_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # Check vxlan.overlay_services.networks list element - target_key = 'networks' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.overlay_services.network_attach_groups list element - target_key = 'network_attach_groups' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.overlay_services.network_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['overlay_services']['network_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay_services']['network_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # -------------------------------------------------------------------- - # Multisite Fabric Overlay List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.multisite list elements - parent_keys = ['vxlan', 'multisite'] - dm_check = data_model_key_check(self.model_data, parent_keys) - if 'multisite' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: - self.model_data['vxlan']['multisite'] = {} - - # Check vxlan.multisite.overlay list elements - parent_keys = ['vxlan', 'multisite', 'overlay'] - dm_check = data_model_key_check(self.model_data, parent_keys) - if 'overlay' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: - self.model_data['vxlan']['multisite']['overlay']['vrfs'] = [] - self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'] = [] - self.model_data['vxlan']['multisite']['overlay']['networks'] = [] - self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'] = [] - - # Check vxlan.multisite.overlay_services.vrfs list element - target_key = 'vrfs' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.multisite.overlay.vrf_attach_groups list element - target_key = 'vrf_attach_groups' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.multisite.overlay.vrf_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # Check vxlan.multisite.overlay.networks list element - target_key = 'networks' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.multisite.overlay.network_attach_groups list element - target_key = 'network_attach_groups' - self.set_list_default(parent_keys, target_key) - - # Check vxlan.multisite.overlay.network_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['multisite']['overlay']['network_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # -------------------------------------------------------------------- - # Fabric Policy List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.policy list elements - parent_keys = ['vxlan', 'policy'] - dm_check = data_model_key_check(self.model_data, parent_keys) - if 'policy' in dm_check['keys_not_found'] or 'policy' in dm_check['keys_no_data']: - self.model_data['vxlan']['policy'] = {} - self.model_data['vxlan']['policy'].update({'policies': []}) - self.model_data['vxlan']['policy'].update({'groups': []}) - self.model_data['vxlan']['policy'].update({'switches': []}) - - parent_keys = ['vxlan', 'policy', 'policies'] - dm_check = data_model_key_check(self.model_data, parent_keys) - if 'policies' in dm_check['keys_not_found'] or 'policies' in dm_check['keys_no_data']: - self.model_data['vxlan']['policy']['policies'] = [] - - parent_keys = ['vxlan', 'policy', 'groups'] - dm_check = data_model_key_check(self.model_data, parent_keys) - if 'groups' in dm_check['keys_not_found'] or 'groups' in dm_check['keys_no_data']: - self.model_data['vxlan']['policy']['groups'] = [] - - parent_keys = ['vxlan', 'policy', 'switches'] - dm_check = data_model_key_check(self.model_data, parent_keys) - if 'switches' in dm_check['keys_not_found'] or 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['policy']['switches'] = [] - - self.kwargs['results']['model_extended'] = self.model_data - return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py new file mode 100644 index 00000000..24e1b250 --- /dev/null +++ b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py @@ -0,0 +1,395 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + + +from ....plugin_utils.helper_functions import data_model_key_check +from ....plugin_utils.data_model_keys import model_keys + + +def update_nested_dict(nested_dict, keys, new_value): + if len(keys) == 1: + nested_dict[keys[0]] = new_value + else: + key = keys[0] + if key in nested_dict: + update_nested_dict(nested_dict[key], keys[1:], new_value) + + +class PreparePlugin: + def __init__(self, **kwargs): + self.kwargs = kwargs + self.keys = [] + + def set_list_default(self, parent_keys, target_key): + keys = parent_keys + [target_key] + dm_check = data_model_key_check(self.model_data, keys) + if target_key in dm_check['keys_not_found'] or \ + target_key in dm_check['keys_no_data']: + update_nested_dict(self.model_data, keys, []) + + # The prepare method is used to default each list or nested list + # in the model data to an empty list if the key for the list does + # not exist or data under they key does not exist. + # + # This is to ensure that the model data is consistent and can be + # used by other plugins without having to check if the key exists. + def prepare(self): + self.model_data = self.kwargs['results']['model_extended'] + + # -------------------------------------------------------------------- + # Fabric Global List Defaults + # -------------------------------------------------------------------- + from pprint import pprint + + paths = [ + 'global.dns_servers', + 'global.ntp_servers', + 'global.syslog_servers', + 'global.netflow', + 'global.netflow.exporter', + 'global.netflow.record', + 'global.netflow.monitor', + 'topology', + 'topology.edge_connections', + 'topology.fabric_links', + 'topology.switches', + 'topology.vpc_peers', + 'overlay', + 'overlay.vrfs', + 'overlay.vrf_attach_groups', + 'overlay.networks', + 'overlay.network_attach_groups', + 'multisite', + 'multisite.overlay', + 'multisite.overlay.vrfs', + 'multisite.overlay.vrf_attach_groups', + 'multisite.overlay.networks', + 'multisite.overlay.network_attach_groups', + 'policy', + 'policy.policies', + 'policy.groups', + 'policy.switches' + ] + for path in paths: + # Get all but the last 2 elements of model_keys[path] + path_type = model_keys[path][-1] + parent_keys = model_keys[path][:-2] + target_key = model_keys[path][-2] + if path_type == 'KEY': + dm_check = data_model_key_check(self.model_data, parent_keys + [target_key]) + if target_key in dm_check['keys_not_found'] or target_key in dm_check['keys_no_data']: + update_nested_dict(self.model_data, parent_keys + [target_key], {}) + if path_type == 'LIST': + self.set_list_default(parent_keys, target_key) + + # -------------------------------------------------------------------- + # Fabric Topology Switches Freeforms List Defaults + # -------------------------------------------------------------------- + + # Check vxlan.topology.switches[index].freeforms list elements + list_index = 0 + for switch in self.model_data['vxlan']['topology']['switches']: + dm_check = data_model_key_check(switch, ['freeforms']) + if 'freeforms' in dm_check['keys_not_found'] or \ + 'freeforms' in dm_check['keys_no_data']: + self.model_data['vxlan']['topology']['switches'][list_index]['freeforms'] = [] + + list_index += 1 + + # -------------------------------------------------------------------- + # Fabric Topology Switches Interfaces List Defaults + # -------------------------------------------------------------------- + + # Check vxlan.topology.switches[index].interfaces list elements + list_index = 0 + for switch in self.model_data['vxlan']['topology']['switches']: + dm_check = data_model_key_check(switch, ['interfaces']) + if 'interfaces' in dm_check['keys_not_found'] or 'interfaces' in dm_check['keys_no_data']: + self.model_data['vxlan']['topology']['switches'][list_index]['interfaces'] = [] + + list_index += 1 + + # Check vxlan.overlay.vrf_attach_groups[index].switches list elements + list_index = 0 + for group in self.model_data['vxlan']['overlay']['vrf_attach_groups']: + dm_check = data_model_key_check(group, ['switches']) + if 'switches' in dm_check['keys_not_found'] or \ + 'switches' in dm_check['keys_no_data']: + self.model_data['vxlan']['overlay']['vrf_attach_groups'][list_index]['switches'] = [] + + list_index += 1 + + # Check vxlan.overlay.network_attach_groups[index].switches list elements + list_index = 0 + for group in self.model_data['vxlan']['overlay']['network_attach_groups']: + dm_check = data_model_key_check(group, ['switches']) + if 'switches' in dm_check['keys_not_found'] or \ + 'switches' in dm_check['keys_no_data']: + self.model_data['vxlan']['overlay']['network_attach_groups'][list_index]['switches'] = [] + + list_index += 1 + + # Check vxlan.multisite.overlay.vrf_attach_groups[index].switches list elements + list_index = 0 + for group in self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups']: + dm_check = data_model_key_check(group, ['switches']) + if 'switches' in dm_check['keys_not_found'] or \ + 'switches' in dm_check['keys_no_data']: + self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'][list_index]['switches'] = [] + + list_index += 1 + + # Check vxlan.multisite.overlay.network_attach_groups[index].switches list elements + list_index = 0 + for group in self.model_data['vxlan']['multisite']['overlay']['network_attach_groups']: + dm_check = data_model_key_check(group, ['switches']) + if 'switches' in dm_check['keys_not_found'] or \ + 'switches' in dm_check['keys_no_data']: + self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'][list_index]['switches'] = [] + + list_index += 1 + + # # Check vxlan.global list elements + # parent_keys = ['vxlan', 'global'] + # target_key = 'dns_servers' + # self.set_list_default(parent_keys, target_key) + + # # keys = ['vxlan', 'global', 'ntp_servers'] + # parent_keys = ['vxlan', 'global'] + # target_key = 'ntp_servers' + # self.set_list_default(parent_keys, target_key) + + # # keys = ['vxlan', 'global', 'syslog_servers'] + # parent_keys = ['vxlan', 'global'] + # target_key = 'syslog_servers' + # self.set_list_default(parent_keys, target_key) + + # -------------------------------------------------------------------- + # Fabric Topology List Defaults + # -------------------------------------------------------------------- + + # # Check vxlan.topology list elements + # parent_keys = ['vxlan', 'topology'] + # dm_check = data_model_key_check(self.model_data, parent_keys) + # if 'topology' in dm_check['keys_not_found'] or 'topology' in dm_check['keys_no_data']: + # self.model_data['vxlan']['topology'] = {} + # self.model_data['vxlan']['topology']['edge_connections'] = [] + # self.model_data['vxlan']['topology']['fabric_links'] = [] + # self.model_data['vxlan']['topology']['switches'] = [] + # self.model_data['vxlan']['topology']['vpc_peers'] = [] + + + # # Check vxlan.topology.fabric_links list element + # target_key = 'fabric_links' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.topology.edge_connections list element + # target_key = 'edge_connections' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.topology.switches list element + # target_key = 'switches' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.topology.vpc_peers list element + # target_key = 'vpc_peers' + # self.set_list_default(parent_keys, target_key) + + + # -------------------------------------------------------------------- + # Fabric Overlay List Defaults + # -------------------------------------------------------------------- + + # # Check vxlan.overlay list elements + # parent_keys = ['vxlan', 'overlay'] + + # if 'overlay' in dm_check['keys_not_found'] or 'overlay' in dm_check['keys_no_data']: + # self.model_data['vxlan']['overlay'] = {} + + # check_keys = parent_keys + ['vrfs'] + # dm_check = data_model_key_check(self.model_data, check_keys) + # if 'vrfs' in dm_check['keys_not_found'] or 'vrfs' in dm_check['keys_no_data']: + # self.model_data['vxlan']['overlay']['vrfs'] = [] + # self.model_data['vxlan']['overlay']['vrf_attach_groups'] = [] + + # check_keys = parent_keys + ['networks'] + # dm_check = data_model_key_check(self.model_data, check_keys) + # if 'networks' in dm_check['keys_not_found'] or 'networks' in dm_check['keys_no_data']: + # self.model_data['vxlan']['overlay']['networks'] = [] + # self.model_data['vxlan']['overlay']['network_attach_groups'] = [] + + # # Check vxlan.overlay.vrfs list element + # target_key = 'vrfs' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.overlay.vrf_attach_groups list element + # target_key = 'vrf_attach_groups' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.overlay.networks list element + # target_key = 'networks' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.overlay.network_attach_groups list element + # target_key = 'network_attach_groups' + # self.set_list_default(parent_keys, target_key) + + + # # MWIEBE: SHOULD NOT NEED THIS ANYMORE + # # -------------------------------------------------------------------- + # # Fabric Overlay List Defaults - Backwards Compatibility + # # -------------------------------------------------------------------- + + # # Check vxlan.overlay_services list elements + # parent_keys = ['vxlan', 'overlay_services'] + # dm_check = data_model_key_check(self.model_data, parent_keys) + # if 'overlay_services' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: + # self.model_data['vxlan']['overlay_services']['vrfs'] = [] + # self.model_data['vxlan']['overlay_services']['vrf_attach_groups'] = [] + # self.model_data['vxlan']['overlay_services']['networks'] = [] + # self.model_data['vxlan']['overlay_services']['network_attach_groups'] = [] + + # # Check vxlan.overlay_services.vrfs list element + # target_key = 'vrfs' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.overlay_services.vrf_attach_groups list element + # target_key = 'vrf_attach_groups' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.overlay_services.vrf_attach_groups[index].switches list elements + # list_index = 0 + # for group in self.model_data['vxlan']['overlay_services']['vrf_attach_groups']: + # dm_check = data_model_key_check(group, ['switches']) + # if 'switches' in dm_check['keys_not_found'] or \ + # 'switches' in dm_check['keys_no_data']: + # self.model_data['vxlan']['overlay_services']['vrf_attach_groups'][list_index]['switches'] = [] + + # list_index += 1 + + # # Check vxlan.overlay_services.networks list element + # target_key = 'networks' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.overlay_services.network_attach_groups list element + # target_key = 'network_attach_groups' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.overlay_services.network_attach_groups[index].switches list elements + # list_index = 0 + # for group in self.model_data['vxlan']['overlay_services']['network_attach_groups']: + # dm_check = data_model_key_check(group, ['switches']) + # if 'switches' in dm_check['keys_not_found'] or \ + # 'switches' in dm_check['keys_no_data']: + # self.model_data['vxlan']['overlay_services']['network_attach_groups'][list_index]['switches'] = [] + + # list_index += 1 + + # -------------------------------------------------------------------- + # Multisite Fabric Overlay List Defaults + # -------------------------------------------------------------------- + + # # Check vxlan.overlay list elements + # parent_keys = ['vxlan', 'multisite', 'overlay'] + # dm_check = data_model_key_check(self.model_data, parent_keys) + + # if 'multisite' in dm_check['keys_not_found'] or 'multisite' in dm_check['keys_no_data']: + # self.model_data['vxlan']['multisite'] = {} + # self.model_data['vxlan']['multisite']['overlay'] = {} + + # if 'overlay' in dm_check['keys_not_found'] or 'overlay' in dm_check['keys_no_data']: + # self.model_data['vxlan']['multisite']['overlay'] = {} + + # check_keys = parent_keys + ['vrfs'] + # dm_check = data_model_key_check(self.model_data, check_keys) + # if 'vrfs' in dm_check['keys_not_found'] or 'vrfs' in dm_check['keys_no_data']: + # self.model_data['vxlan']['multisite']['overlay']['vrfs'] = [] + # self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'] = [] + + # check_keys = parent_keys + ['networks'] + # dm_check = data_model_key_check(self.model_data, check_keys) + # if 'networks' in dm_check['keys_not_found'] or 'networks' in dm_check['keys_no_data']: + # self.model_data['vxlan']['multisite']['overlay']['networks'] = [] + # self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'] = [] + + # # Check vxlan.multisite list elements + # parent_keys = ['vxlan', 'multisite'] + # dm_check = data_model_key_check(self.model_data, parent_keys) + # if 'multisite' in dm_check['keys_not_found'] or 'multisite' in dm_check['keys_no_data']: + # self.model_data['vxlan']['multisite'] = {} + + # # Check vxlan.multisite.overlay list elements + # parent_keys = ['vxlan', 'multisite', 'overlay'] + # dm_check = data_model_key_check(self.model_data, parent_keys) + # if 'overlay' in dm_check['keys_not_found'] or 'overlay' in dm_check['keys_no_data']: + # self.model_data['vxlan']['multisite']['overlay'] = {} + # self.model_data['vxlan']['multisite']['overlay']['vrfs'] = [] + # self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'] = [] + # self.model_data['vxlan']['multisite']['overlay']['networks'] = [] + # self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'] = [] + + # # Check vxlan.multisite.overlay.vrfs list element + # target_key = 'vrfs' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.multisite.overlay.vrf_attach_groups list element + # target_key = 'vrf_attach_groups' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.multisite.overlay.networks list element + # target_key = 'networks' + # self.set_list_default(parent_keys, target_key) + + # # Check vxlan.multisite.overlay.network_attach_groups list element + # target_key = 'network_attach_groups' + # self.set_list_default(parent_keys, target_key) + + + # -------------------------------------------------------------------- + # Fabric Policy List Defaults + # -------------------------------------------------------------------- + + # # Check vxlan.policy list elements + # parent_keys = ['vxlan', 'policy'] + # dm_check = data_model_key_check(self.model_data, parent_keys) + # if 'policy' in dm_check['keys_not_found'] or 'policy' in dm_check['keys_no_data']: + # self.model_data['vxlan']['policy'] = {} + # self.model_data['vxlan']['policy'].update({'policies': []}) + # self.model_data['vxlan']['policy'].update({'groups': []}) + # self.model_data['vxlan']['policy'].update({'switches': []}) + + # parent_keys = ['vxlan', 'policy', 'policies'] + # dm_check = data_model_key_check(self.model_data, parent_keys) + # if 'policies' in dm_check['keys_not_found'] or 'policies' in dm_check['keys_no_data']: + # self.model_data['vxlan']['policy']['policies'] = [] + + # parent_keys = ['vxlan', 'policy', 'groups'] + # dm_check = data_model_key_check(self.model_data, parent_keys) + # if 'groups' in dm_check['keys_not_found'] or 'groups' in dm_check['keys_no_data']: + # self.model_data['vxlan']['policy']['groups'] = [] + + # parent_keys = ['vxlan', 'policy', 'switches'] + # dm_check = data_model_key_check(self.model_data, parent_keys) + # if 'switches' in dm_check['keys_not_found'] or 'switches' in dm_check['keys_no_data']: + # self.model_data['vxlan']['policy']['switches'] = [] + + self.kwargs['results']['model_extended'] = self.model_data + return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_999_verify.py b/plugins/action/common/prepare_plugins/prep_999_verify.py new file mode 100644 index 00000000..206100e4 --- /dev/null +++ b/plugins/action/common/prepare_plugins/prep_999_verify.py @@ -0,0 +1,65 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +from ansible.utils.display import Display +from ....plugin_utils.helper_functions import data_model_key_check +from ....plugin_utils.data_model_keys import model_keys + +display = Display() + + +class PreparePlugin: + def __init__(self, **kwargs): + self.kwargs = kwargs + self.keys = [] + + + def prepare(self): + model_data = self.kwargs['results']['model_extended'] + self.kwargs['results']['failed'] = False + self.kwargs['results']['msg'] = None + fail_msg = "Mandatory key ({}) not found in prepared data model!" + fail_msg += " There is either a bug in one of the prepare plugins or" + fail_msg += " the data was not included in the data model." + fail_msg += " Data Model Section: ({})" + + + # This prepare plugin serves as a final sanity check after all of the + # previous prepare plugins have been called to transform the model data. + # + # This plugin ensures the following: + # * All keys required for this collection to function are present (not accidentally overwritten) + # * List items that were present before the prepare plugins ran are still present + for key in model_keys.keys(): + dm_check = data_model_key_check(model_data, model_keys[key]) + # model_keys['policy.policies'] = [root_key, 'policy', 'policies', 'LIST'] + # Get 2nd to last item from the python list above + # model_keys[key][-2] - Gets 'policies' + if model_keys[key][-2] in dm_check['keys_not_found']: + self.kwargs['results']['failed'] = True + self.kwargs['results']['msg'] = fail_msg.format(key, model_keys[key]) + return self.kwargs['results'] + + + import epdb ; epdb.set_trace() + + # We don't need to pass any data back in this plugin because we don't modify any data. + return self.kwargs['results'] diff --git a/plugins/plugin_utils/data_model_keys.py b/plugins/plugin_utils/data_model_keys.py new file mode 100644 index 00000000..e91ddd4a --- /dev/null +++ b/plugins/plugin_utils/data_model_keys.py @@ -0,0 +1,67 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +# This is an example file for help functions that can be called by +# our various action plugins for common routines. +# +# For example in prepare_serice_model.py we can do the following: +# from ..helper_functions import do_something + +root_key = 'vxlan' + +model_keys = {} +model_keys['fabric.name'] = [root_key, 'fabric', 'name', 'KEY'] +model_keys['fabric.type'] = [root_key, 'fabric', 'type', 'KEY'] + +model_keys['global'] = [root_key, 'global', 'KEY'] +model_keys['global.dns_servers'] = [root_key, 'global', 'dns_servers', 'LIST'] +model_keys['global.ntp_servers'] = [root_key, 'global', 'ntp_servers', 'LIST'] +model_keys['global.syslog_servers'] = [root_key, 'global', 'syslog_servers', 'LIST'] +model_keys['global.netflow'] = [root_key, 'global', 'netflow', 'KEY'] +model_keys['global.netflow.exporter'] = [root_key, 'global', 'netflow', 'exporter', 'LIST'] +model_keys['global.netflow.record'] = [root_key, 'global', 'netflow', 'record', 'LIST'] +model_keys['global.netflow.monitor'] = [root_key, 'global', 'netflow', 'monitor', 'LIST'] +# --- +model_keys['underlay'] = [root_key, 'underlay', 'KEY'] +# --- +model_keys['topology'] = [root_key, 'topology', 'KEY'] +model_keys['topology.edge_connections'] = [root_key, 'topology', 'edge_connections', 'LIST'] +model_keys['topology.fabric_links'] = [root_key, 'topology', 'fabric_links', 'LIST'] +model_keys['topology.switches'] = [root_key, 'topology', 'switches', 'LIST'] +model_keys['topology.vpc_peers'] = [root_key, 'topology', 'vpc_peers', 'LIST'] +# --- +model_keys['overlay'] = [root_key, 'overlay', 'KEY'] +model_keys['overlay.vrfs'] = [root_key, 'overlay', 'vrfs', 'LIST'] +model_keys['overlay.vrf_attach_groups'] = [root_key, 'overlay', 'vrf_attach_groups', 'LIST'] +model_keys['overlay.networks'] = [root_key, 'overlay', 'networks', 'LIST'] +model_keys['overlay.network_attach_groups'] = [root_key, 'overlay', 'network_attach_groups', 'LIST'] +# --- +model_keys['multisite'] = [root_key, 'multisite', 'KEY'] +model_keys['multisite.overlay'] = [root_key, 'multisite', 'overlay', 'KEY'] +model_keys['multisite.overlay.vrfs'] = [root_key, 'multisite', 'overlay', 'vrfs', 'LIST'] +model_keys['multisite.overlay.vrf_attach_groups'] = [root_key, 'multisite', 'overlay', 'vrf_attach_groups', 'LIST'] +model_keys['multisite.overlay.networks'] = [root_key, 'multisite', 'overlay', 'networks', 'LIST'] +model_keys['multisite.overlay.network_attach_groups'] = [root_key, 'multisite', 'overlay', 'network_attach_groups', 'LIST'] +# --- +model_keys['policy'] = [root_key, 'policy', 'KEY'] +model_keys['policy.policies'] = [root_key, 'policy', 'policies', 'LIST'] +model_keys['policy.groups'] = [root_key, 'policy', 'groups', 'LIST'] +model_keys['policy.switches'] = [root_key, 'policy', 'switches', 'LIST'] From e7ee3ff04a127ee44a79a1de991a219899d3ee33 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Sun, 22 Dec 2024 17:55:50 +0000 Subject: [PATCH 34/66] More refactoring --- .../common/prepare_plugins/prep_001_fabric.py | 12 +- .../prepare_plugins/prep_002_list_defaults.py | 252 ++---------------- .../prep_104_fabric_overlay.py | 37 ++- .../common/prepare_plugins/prep_999_verify.py | 5 +- .../action/common/prepare_service_model.py | 6 +- plugins/plugin_utils/data_model_keys.py | 3 + roles/dtc/common/tasks/main.yml | 2 +- roles/dtc/common/tasks/msd/ndfc_vrfs.yml | 3 +- roles/dtc/common/tasks/sub_main_isn.yml | 24 ++ roles/dtc/common/tasks/sub_main_msd.yml | 26 ++ roles/dtc/common/tasks/sub_main_vxlan.yml | 82 ++++-- .../common/tasks/vxlan/ndfc_interface_all.yml | 2 - .../dtc/common/tasks/vxlan/ndfc_networks.yml | 3 +- roles/dtc/common/tasks/vxlan/ndfc_policy.yml | 2 +- .../common/tasks/vxlan/ndfc_vpc_peering.yml | 2 +- roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml | 6 +- .../templates/ndfc_attach_vrfs_loopbacks.j2 | 4 +- .../dc_vxlan_fabric_networks.j2 | 5 - .../dc_vxlan_fabric/dc_vxlan_fabric_vrfs.j2 | 5 - .../create/tasks/isn/devices_discovery.yml | 2 +- roles/dtc/create/tasks/isn/fabric.yml | 2 +- roles/dtc/create/tasks/main.yml | 33 ++- roles/dtc/create/tasks/msd/fabric.yml | 2 +- roles/dtc/create/tasks/msd/vrfs_networks.yml | 16 +- roles/dtc/create/tasks/sub_main_isn.yml | 4 +- roles/dtc/create/tasks/sub_main_msd.yml | 4 +- roles/dtc/create/tasks/sub_main_vxlan.yml | 20 +- .../create/tasks/vxlan/devices_discovery.yml | 4 +- roles/dtc/create/tasks/vxlan/fabric.yml | 2 +- roles/dtc/create/tasks/vxlan/interfaces.yml | 20 +- roles/dtc/create/tasks/vxlan/links.yml | 4 +- roles/dtc/create/tasks/vxlan/policies.yml | 2 +- roles/dtc/create/tasks/vxlan/vpc_peering.yml | 4 +- .../dtc/create/tasks/vxlan/vrfs_networks.yml | 33 ++- roles/dtc/deploy/tasks/main.yml | 16 +- roles/dtc/remove/tasks/main.yml | 17 +- roles/dtc/remove/tasks/msd/networks.yml | 2 +- roles/dtc/remove/tasks/msd/vrfs.yml | 2 +- roles/dtc/remove/tasks/sub_main_msd.yml | 4 +- roles/dtc/remove/tasks/sub_main_vxlan.yml | 14 +- roles/dtc/remove/tasks/vxlan/interfaces.yml | 2 +- roles/dtc/remove/tasks/vxlan/links.yml | 4 +- roles/dtc/remove/tasks/vxlan/networks.yml | 2 +- roles/dtc/remove/tasks/vxlan/switches.yml | 2 +- roles/dtc/remove/tasks/vxlan/vpc_peers.yml | 2 +- roles/dtc/remove/tasks/vxlan/vrfs.yml | 2 +- .../fabric_empty_example/networks.yaml | 2 +- .../examples/fabric_empty_example/vrfs.yaml | 2 +- .../fabric_full_large_example/networks.yaml | 2 +- .../fabric_full_large_example/vrfs.yaml | 2 +- .../networks.yaml | 2 +- .../vrfs.yaml | 2 +- .../networks.yaml | 2 +- .../vrfs.yaml | 2 +- .../networks.yaml | 2 +- .../vrfs.yaml | 2 +- .../networks.yaml | 2 +- .../vrfs.yaml | 2 +- .../networks.yaml | 2 +- .../vrfs.yaml | 2 +- .../networks.yaml | 2 +- .../vrfs.yaml | 2 +- .../networks.yaml | 2 +- .../fabric_full_small_sha_example/vrfs.yaml | 2 +- 64 files changed, 344 insertions(+), 394 deletions(-) diff --git a/plugins/action/common/prepare_plugins/prep_001_fabric.py b/plugins/action/common/prepare_plugins/prep_001_fabric.py index 497e3b7a..2e9742c1 100644 --- a/plugins/action/common/prepare_plugins/prep_001_fabric.py +++ b/plugins/action/common/prepare_plugins/prep_001_fabric.py @@ -40,6 +40,14 @@ def prepare(self): # where IaC validate removes sections of the model data, like the vxlan.underlay section # ------------------------------------------------------------------------------------------ + if not bool(model_data): + msg = 'Model data is empty! It is possible there is no data in host_vars or there' + msg += ' might be a bug in the model data. Please check host_vars for this fabric.' + msg += ' Possible reasons: duplicate keys, unsupported keys, invalid yaml etc...' + self.kwargs['results']['failed'] = True + self.kwargs['results']['msg'] = msg + return self.kwargs['results'] + # Checking for fabric key in the data model. # This type of check should be done in a rule, but fabric.name and fabric.type are foundational for the collection so we need to ensure it is set. # This prepare plugin also helps retain backwards compatibility with global.name and global.fabric_type keys previously used. @@ -112,7 +120,9 @@ def prepare(self): self.kwargs['results']['msg'] = "vxlan.fabric.type is not defined in the data model." - # Replace 'overlay_services' key with 'overlay' + # For backwards compatibility, replace 'overlay_services' key with 'overlay' + # NOTE: No prepare plugin, jinja2 template or ansible task should reference 'overlay_services' after this replacement. + # NOTE: Rules are different since rules run BEFORE prepare plugins parent_keys = ['vxlan', 'overlay_services'] dm_check = data_model_key_check(model_data, parent_keys) if 'overlay_services' in dm_check['keys_found']: diff --git a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py index 24e1b250..6d8280ad 100644 --- a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py @@ -19,10 +19,12 @@ # # SPDX-License-Identifier: MIT - +from ansible.utils.display import Display from ....plugin_utils.helper_functions import data_model_key_check from ....plugin_utils.data_model_keys import model_keys +display = Display() + def update_nested_dict(nested_dict, keys, new_value): if len(keys) == 1: @@ -63,10 +65,14 @@ def prepare(self): 'global.dns_servers', 'global.ntp_servers', 'global.syslog_servers', + 'global.spanning_tree', + 'global.spanning_tree.vlan_range', + 'global.spanning_tree.mst_instance_range', 'global.netflow', 'global.netflow.exporter', 'global.netflow.record', 'global.netflow.monitor', + 'underlay', 'topology', 'topology.edge_connections', 'topology.fabric_links', @@ -100,6 +106,13 @@ def prepare(self): if path_type == 'LIST': self.set_list_default(parent_keys, target_key) + # -------------------------------------------------------------------- + # The following sections deal with more difficult nexted list + # structures where there is a list_index in the middle of the dict. + # There may be a way to reduce the amount of code but for now leaving + # it as is. + # -------------------------------------------------------------------- + # -------------------------------------------------------------------- # Fabric Topology Switches Freeforms List Defaults # -------------------------------------------------------------------- @@ -127,6 +140,10 @@ def prepare(self): list_index += 1 + # -------------------------------------------------------------------- + # Fabric Overlay vrf and network attach group List Defaults + # -------------------------------------------------------------------- + # Check vxlan.overlay.vrf_attach_groups[index].switches list elements list_index = 0 for group in self.model_data['vxlan']['overlay']['vrf_attach_groups']: @@ -167,229 +184,16 @@ def prepare(self): list_index += 1 - # # Check vxlan.global list elements - # parent_keys = ['vxlan', 'global'] - # target_key = 'dns_servers' - # self.set_list_default(parent_keys, target_key) - - # # keys = ['vxlan', 'global', 'ntp_servers'] - # parent_keys = ['vxlan', 'global'] - # target_key = 'ntp_servers' - # self.set_list_default(parent_keys, target_key) - - # # keys = ['vxlan', 'global', 'syslog_servers'] - # parent_keys = ['vxlan', 'global'] - # target_key = 'syslog_servers' - # self.set_list_default(parent_keys, target_key) - - # -------------------------------------------------------------------- - # Fabric Topology List Defaults - # -------------------------------------------------------------------- - - # # Check vxlan.topology list elements - # parent_keys = ['vxlan', 'topology'] - # dm_check = data_model_key_check(self.model_data, parent_keys) - # if 'topology' in dm_check['keys_not_found'] or 'topology' in dm_check['keys_no_data']: - # self.model_data['vxlan']['topology'] = {} - # self.model_data['vxlan']['topology']['edge_connections'] = [] - # self.model_data['vxlan']['topology']['fabric_links'] = [] - # self.model_data['vxlan']['topology']['switches'] = [] - # self.model_data['vxlan']['topology']['vpc_peers'] = [] - - - # # Check vxlan.topology.fabric_links list element - # target_key = 'fabric_links' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.topology.edge_connections list element - # target_key = 'edge_connections' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.topology.switches list element - # target_key = 'switches' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.topology.vpc_peers list element - # target_key = 'vpc_peers' - # self.set_list_default(parent_keys, target_key) - - - # -------------------------------------------------------------------- - # Fabric Overlay List Defaults - # -------------------------------------------------------------------- - - # # Check vxlan.overlay list elements - # parent_keys = ['vxlan', 'overlay'] - - # if 'overlay' in dm_check['keys_not_found'] or 'overlay' in dm_check['keys_no_data']: - # self.model_data['vxlan']['overlay'] = {} - - # check_keys = parent_keys + ['vrfs'] - # dm_check = data_model_key_check(self.model_data, check_keys) - # if 'vrfs' in dm_check['keys_not_found'] or 'vrfs' in dm_check['keys_no_data']: - # self.model_data['vxlan']['overlay']['vrfs'] = [] - # self.model_data['vxlan']['overlay']['vrf_attach_groups'] = [] - - # check_keys = parent_keys + ['networks'] - # dm_check = data_model_key_check(self.model_data, check_keys) - # if 'networks' in dm_check['keys_not_found'] or 'networks' in dm_check['keys_no_data']: - # self.model_data['vxlan']['overlay']['networks'] = [] - # self.model_data['vxlan']['overlay']['network_attach_groups'] = [] - - # # Check vxlan.overlay.vrfs list element - # target_key = 'vrfs' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.overlay.vrf_attach_groups list element - # target_key = 'vrf_attach_groups' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.overlay.networks list element - # target_key = 'networks' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.overlay.network_attach_groups list element - # target_key = 'network_attach_groups' - # self.set_list_default(parent_keys, target_key) - - - # # MWIEBE: SHOULD NOT NEED THIS ANYMORE - # # -------------------------------------------------------------------- - # # Fabric Overlay List Defaults - Backwards Compatibility - # # -------------------------------------------------------------------- - - # # Check vxlan.overlay_services list elements - # parent_keys = ['vxlan', 'overlay_services'] - # dm_check = data_model_key_check(self.model_data, parent_keys) - # if 'overlay_services' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']: - # self.model_data['vxlan']['overlay_services']['vrfs'] = [] - # self.model_data['vxlan']['overlay_services']['vrf_attach_groups'] = [] - # self.model_data['vxlan']['overlay_services']['networks'] = [] - # self.model_data['vxlan']['overlay_services']['network_attach_groups'] = [] - - # # Check vxlan.overlay_services.vrfs list element - # target_key = 'vrfs' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.overlay_services.vrf_attach_groups list element - # target_key = 'vrf_attach_groups' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.overlay_services.vrf_attach_groups[index].switches list elements - # list_index = 0 - # for group in self.model_data['vxlan']['overlay_services']['vrf_attach_groups']: - # dm_check = data_model_key_check(group, ['switches']) - # if 'switches' in dm_check['keys_not_found'] or \ - # 'switches' in dm_check['keys_no_data']: - # self.model_data['vxlan']['overlay_services']['vrf_attach_groups'][list_index]['switches'] = [] - - # list_index += 1 - - # # Check vxlan.overlay_services.networks list element - # target_key = 'networks' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.overlay_services.network_attach_groups list element - # target_key = 'network_attach_groups' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.overlay_services.network_attach_groups[index].switches list elements - # list_index = 0 - # for group in self.model_data['vxlan']['overlay_services']['network_attach_groups']: - # dm_check = data_model_key_check(group, ['switches']) - # if 'switches' in dm_check['keys_not_found'] or \ - # 'switches' in dm_check['keys_no_data']: - # self.model_data['vxlan']['overlay_services']['network_attach_groups'][list_index]['switches'] = [] - - # list_index += 1 - - # -------------------------------------------------------------------- - # Multisite Fabric Overlay List Defaults - # -------------------------------------------------------------------- - - # # Check vxlan.overlay list elements - # parent_keys = ['vxlan', 'multisite', 'overlay'] - # dm_check = data_model_key_check(self.model_data, parent_keys) - - # if 'multisite' in dm_check['keys_not_found'] or 'multisite' in dm_check['keys_no_data']: - # self.model_data['vxlan']['multisite'] = {} - # self.model_data['vxlan']['multisite']['overlay'] = {} - - # if 'overlay' in dm_check['keys_not_found'] or 'overlay' in dm_check['keys_no_data']: - # self.model_data['vxlan']['multisite']['overlay'] = {} - - # check_keys = parent_keys + ['vrfs'] - # dm_check = data_model_key_check(self.model_data, check_keys) - # if 'vrfs' in dm_check['keys_not_found'] or 'vrfs' in dm_check['keys_no_data']: - # self.model_data['vxlan']['multisite']['overlay']['vrfs'] = [] - # self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'] = [] - - # check_keys = parent_keys + ['networks'] - # dm_check = data_model_key_check(self.model_data, check_keys) - # if 'networks' in dm_check['keys_not_found'] or 'networks' in dm_check['keys_no_data']: - # self.model_data['vxlan']['multisite']['overlay']['networks'] = [] - # self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'] = [] - - # # Check vxlan.multisite list elements - # parent_keys = ['vxlan', 'multisite'] - # dm_check = data_model_key_check(self.model_data, parent_keys) - # if 'multisite' in dm_check['keys_not_found'] or 'multisite' in dm_check['keys_no_data']: - # self.model_data['vxlan']['multisite'] = {} - - # # Check vxlan.multisite.overlay list elements - # parent_keys = ['vxlan', 'multisite', 'overlay'] - # dm_check = data_model_key_check(self.model_data, parent_keys) - # if 'overlay' in dm_check['keys_not_found'] or 'overlay' in dm_check['keys_no_data']: - # self.model_data['vxlan']['multisite']['overlay'] = {} - # self.model_data['vxlan']['multisite']['overlay']['vrfs'] = [] - # self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'] = [] - # self.model_data['vxlan']['multisite']['overlay']['networks'] = [] - # self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'] = [] - - # # Check vxlan.multisite.overlay.vrfs list element - # target_key = 'vrfs' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.multisite.overlay.vrf_attach_groups list element - # target_key = 'vrf_attach_groups' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.multisite.overlay.networks list element - # target_key = 'networks' - # self.set_list_default(parent_keys, target_key) - - # # Check vxlan.multisite.overlay.network_attach_groups list element - # target_key = 'network_attach_groups' - # self.set_list_default(parent_keys, target_key) - - - # -------------------------------------------------------------------- - # Fabric Policy List Defaults - # -------------------------------------------------------------------- - - # # Check vxlan.policy list elements - # parent_keys = ['vxlan', 'policy'] - # dm_check = data_model_key_check(self.model_data, parent_keys) - # if 'policy' in dm_check['keys_not_found'] or 'policy' in dm_check['keys_no_data']: - # self.model_data['vxlan']['policy'] = {} - # self.model_data['vxlan']['policy'].update({'policies': []}) - # self.model_data['vxlan']['policy'].update({'groups': []}) - # self.model_data['vxlan']['policy'].update({'switches': []}) - - # parent_keys = ['vxlan', 'policy', 'policies'] - # dm_check = data_model_key_check(self.model_data, parent_keys) - # if 'policies' in dm_check['keys_not_found'] or 'policies' in dm_check['keys_no_data']: - # self.model_data['vxlan']['policy']['policies'] = [] - - # parent_keys = ['vxlan', 'policy', 'groups'] - # dm_check = data_model_key_check(self.model_data, parent_keys) - # if 'groups' in dm_check['keys_not_found'] or 'groups' in dm_check['keys_no_data']: - # self.model_data['vxlan']['policy']['groups'] = [] - - # parent_keys = ['vxlan', 'policy', 'switches'] - # dm_check = data_model_key_check(self.model_data, parent_keys) - # if 'switches' in dm_check['keys_not_found'] or 'switches' in dm_check['keys_no_data']: - # self.model_data['vxlan']['policy']['switches'] = [] + # Before returning check to see if global or underlay data is present and + # generate a warning if they are empty. There might actualy be data but + # one of the other model files might have a bug or everything except the + # top level vxlan key is commented out. + if not bool(self.model_data['vxlan']['underlay']): + msg = '((vxlan.underlay)) data is empty! Check your host_vars model data.' + display.warning(msg=msg, formatted=True) + if not bool(self.model_data['vxlan']['global']): + msg = '((vxlan.global)) data is empty! Check your host_vars model data.' + display.warning(msg=msg, formatted=True) self.kwargs['results']['model_extended'] = self.model_data return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py index 9c1ad87f..4e9f2697 100644 --- a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py +++ b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py @@ -31,25 +31,18 @@ def prepare(self): model_data = self.kwargs['results']['model_extended'] switches = model_data['vxlan']['topology']['switches'] - # Remove the check for overlay_services after deprecation - # Remove lines 32-37 - overlay_key = 'overlay' - check = data_model_key_check(model_data, ['vxlan']) - if 'overlay_services' in check['keys_found'] and 'overlay_services' in check['keys_data']: - overlay_key = 'overlay_services' - if model_data['vxlan']['fabric']['type'] in ('VXLAN_EVPN'): - # Rebuild sm_data['vxlan'][overlay_key]['vrf_attach_groups'] into + # Rebuild sm_data['vxlan']['overlay']['vrf_attach_groups'] into # a structure that is easier to use. vrf_grp_name_list = [] - model_data['vxlan'][overlay_key]['vrf_attach_groups_dict'] = {} - for grp in model_data['vxlan'][overlay_key]['vrf_attach_groups']: - model_data['vxlan'][overlay_key]['vrf_attach_groups_dict'][grp['name']] = [] + model_data['vxlan']['overlay']['vrf_attach_groups_dict'] = {} + for grp in model_data['vxlan']['overlay']['vrf_attach_groups']: + model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']] = [] vrf_grp_name_list.append(grp['name']) for switch in grp['switches']: - model_data['vxlan'][overlay_key]['vrf_attach_groups_dict'][grp['name']].append(switch) + model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']].append(switch) # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP - for switch in model_data['vxlan'][overlay_key]['vrf_attach_groups_dict'][grp['name']]: + for switch in model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']]: if any(sw['name'] == switch['hostname'] for sw in switches): found_switch = next((item for item in switches if item["name"] == switch['hostname'])) if found_switch.get('management').get('management_ipv4_address'): @@ -58,22 +51,22 @@ def prepare(self): switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] # Remove vrf_attach_group from vrf if the group_name is not defined - for vrf in model_data['vxlan'][overlay_key]['vrfs']: + for vrf in model_data['vxlan']['overlay']['vrfs']: if 'vrf_attach_group' in vrf: if vrf.get('vrf_attach_group') not in vrf_grp_name_list: del vrf['vrf_attach_group'] - # Rebuild sm_data['vxlan'][overlay_key]['network_attach_groups'] into + # Rebuild sm_data['vxlan']['overlay']['network_attach_groups'] into # a structure that is easier to use. net_grp_name_list = [] - model_data['vxlan'][overlay_key]['network_attach_groups_dict'] = {} - for grp in model_data['vxlan'][overlay_key]['network_attach_groups']: - model_data['vxlan'][overlay_key]['network_attach_groups_dict'][grp['name']] = [] + model_data['vxlan']['overlay']['network_attach_groups_dict'] = {} + for grp in model_data['vxlan']['overlay']['network_attach_groups']: + model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']] = [] net_grp_name_list.append(grp['name']) for switch in grp['switches']: - model_data['vxlan'][overlay_key]['network_attach_groups_dict'][grp['name']].append(switch) + model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']].append(switch) # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP - for switch in model_data['vxlan'][overlay_key]['network_attach_groups_dict'][grp['name']]: + for switch in model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']]: if any(sw['name'] == switch['hostname'] for sw in switches): found_switch = next((item for item in switches if item["name"] == switch['hostname'])) if found_switch.get('management').get('management_ipv4_address'): @@ -82,7 +75,7 @@ def prepare(self): switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] # Remove network_attach_group from net if the group_name is not defined - for net in model_data['vxlan'][overlay_key]['networks']: + for net in model_data['vxlan']['overlay']['networks']: if 'network_attach_group' in net: if net.get('network_attach_group') not in net_grp_name_list: del net['network_attach_group'] @@ -112,7 +105,7 @@ def prepare(self): if vrf.get('vrf_attach_group') not in vrf_grp_name_list: del vrf['vrf_attach_group'] - # Rebuild sm_data['vxlan'][overlay_key]['network_attach_groups'] into + # Rebuild sm_data['vxlan']['overlay']['network_attach_groups'] into # a structure that is easier to use. net_grp_name_list = [] model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'] = {} diff --git a/plugins/action/common/prepare_plugins/prep_999_verify.py b/plugins/action/common/prepare_plugins/prep_999_verify.py index 206100e4..97e62a33 100644 --- a/plugins/action/common/prepare_plugins/prep_999_verify.py +++ b/plugins/action/common/prepare_plugins/prep_999_verify.py @@ -59,7 +59,10 @@ def prepare(self): return self.kwargs['results'] - import epdb ; epdb.set_trace() + # from pprint import pprint + # md = model_data + # import epdb ; epdb.set_trace() + # pprint(md) # We don't need to pass any data back in this plugin because we don't modify any data. return self.kwargs['results'] diff --git a/plugins/action/common/prepare_service_model.py b/plugins/action/common/prepare_service_model.py index c2bebc18..c61764d3 100644 --- a/plugins/action/common/prepare_service_model.py +++ b/plugins/action/common/prepare_service_model.py @@ -54,7 +54,6 @@ def run(self, tmp=None, task_vars=None): sm_data = self._task.args['model_data'] # results['model_extended'] contains the data that can be extended by the plugins results['model_extended'] = copy.deepcopy(sm_data) - fabric_type = sm_data.get('vxlan').get('fabric_type', None) full_plugin_path = "ansible_collections.cisco.nac_dc_vxlan.plugins.action.common.prepare_plugins" glob_plugin_path = os.path.dirname(__file__) + "/prepare_plugins" @@ -86,6 +85,11 @@ def run(self, tmp=None, task_vars=None): templates_path=tp, results=results).prepare() + if results.get('failed'): + # Check each plugin for failureds and break out of the loop early + # if a failure is encounterd. + break + if results['failed']: # If there is a failure, remove the model data to make the failure message more readable results_copy = results.copy() diff --git a/plugins/plugin_utils/data_model_keys.py b/plugins/plugin_utils/data_model_keys.py index e91ddd4a..d10b6a41 100644 --- a/plugins/plugin_utils/data_model_keys.py +++ b/plugins/plugin_utils/data_model_keys.py @@ -39,6 +39,9 @@ model_keys['global.netflow.exporter'] = [root_key, 'global', 'netflow', 'exporter', 'LIST'] model_keys['global.netflow.record'] = [root_key, 'global', 'netflow', 'record', 'LIST'] model_keys['global.netflow.monitor'] = [root_key, 'global', 'netflow', 'monitor', 'LIST'] +model_keys['global.spanning_tree'] = [root_key, 'global', 'spanning_tree', 'KEY'] +model_keys['global.spanning_tree.vlan_range'] = [root_key, 'global', 'spanning_tree', 'vlan_range', 'LIST'] +model_keys['global.spanning_tree.mst_instance_range'] = [root_key, 'global', 'spanning_tree', 'mst_instance_range', 'LIST'] # --- model_keys['underlay'] = [root_key, 'underlay', 'KEY'] # --- diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index 425e2cfd..bbb3cdff 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -34,4 +34,4 @@ - name: Import Role Tasks for MSD Fabric ansible.builtin.import_tasks: sub_main_msd.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml - when: MD_Extended.vxlan.fabric.type == 'MSD' + when: MD_Extended.vxlan.fabric.type == 'MSD' \ No newline at end of file diff --git a/roles/dtc/common/tasks/msd/ndfc_vrfs.yml b/roles/dtc/common/tasks/msd/ndfc_vrfs.yml index f414ee03..9923d716 100644 --- a/roles/dtc/common/tasks/msd/ndfc_vrfs.yml +++ b/roles/dtc/common/tasks/msd/ndfc_vrfs.yml @@ -102,6 +102,5 @@ ansible.builtin.set_fact: vrf_attach_config: "{{ lookup('file', file_name) | from_yaml }}" when: > - (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 or - (MD_Extended.vxlan.overlay_services.vrfs | default([])) | length > 0 + (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 delegate_to: localhost \ No newline at end of file diff --git a/roles/dtc/common/tasks/sub_main_isn.yml b/roles/dtc/common/tasks/sub_main_isn.yml index 7ef97fb1..b9b47486 100644 --- a/roles/dtc/common/tasks/sub_main_isn.yml +++ b/roles/dtc/common/tasks/sub_main_isn.yml @@ -46,3 +46,27 @@ - name: Build NDFC Fabric Switch Inventory List From Template ansible.builtin.import_tasks: isn/ndfc_inventory.yml + +# -------------------------------------------------------------------- +# Save Local Variables To NameSpace Dict For Use Elsewhere +# -------------------------------------------------------------------- +- name: Save Local Variables With Namespace Context + ansible.builtin.set_fact: + vars_common_isn: + changes_detected_fabric: "{{ changes_detected_fabric }}" + changes_detected_inventory: "{{ changes_detected_inventory }}" + fabric_config: "{{ fabric_config }}" + inv_config: "{{ inv_config }}" + poap_data: "{{ poap_data }}" + updated_inv_config: "{{ updated_inv_config }}" + +- name: Run Diff Flags + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Fabric Changes Detected - [ {{ vars_common_isn.changes_detected_fabric }} ]" + - "+ Inventory Changes Detected - [ {{ vars_common_isn.changes_detected_inventory }} ]" + - "+ ----- Run Map -----" + - "+ Run Map Diff Run - [ {{ run_map_read_result.diff_run }} ]" + - "+ Force Run Flag - [ {{ force_run_all }} ]" + - "----------------------------------------------------------------" diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 34d30888..3507c8b3 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -69,3 +69,29 @@ - name: Build NDFC Fabric Networks Attach List From Template ansible.builtin.import_tasks: msd/ndfc_networks.yml + +# -------------------------------------------------------------------- +# Save Local Variables To NameSpace Dict For Use Elsewhere +# -------------------------------------------------------------------- +- name: Save Local Variables With Namespace Context + ansible.builtin.set_fact: + vars_common_msd: + changes_detected_fabric: "{{ changes_detected_fabric }}" + changes_detected_vrfs: "{{ changes_detected_vrfs }}" + changes_detected_networks: "{{ changes_detected_networks }}" + fabric_config: "{{ fabric_config }}" + net_config: "{{ net_config }}" + vrf_config: "{{ vrf_config }}" + vrf_attach_config: "{{ vrf_attach_config }}" + +- name: Run Diff Flags + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Fabric Changes Detected - [ {{ vars_common_msd.changes_detected_fabric }} ]" + - "+ VRFs Changes Detected - [ {{ vars_common_msd.changes_detected_vrfs }} ]" + - "+ Networks Changes Detected - [ {{ vars_common_msd.changes_detected_networks }} ]" + - "+ ----- Run Map -----" + - "+ Run Map Diff Run - [ {{ run_map_read_result.diff_run }} ]" + - "+ Force Run Flag - [ {{ force_run_all }} ]" + - "----------------------------------------------------------------" diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index e4e9234f..b82b5621 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -159,31 +159,77 @@ - name: Build Fabric Links List From Template ansible.builtin.import_tasks: vxlan/ndfc_fabric_links.yml +# -------------------------------------------------------------------- +# Save Local Variables To NameSpace Dict For Use Elsewhere +# -------------------------------------------------------------------- +- name: Save Local Variables With Namespace Context + ansible.builtin.set_fact: + vars_common_vxlan: + changes_detected_fabric: "{{ changes_detected_fabric }}" + changes_detected_fabric_links: "{{ changes_detected_fabric_links }}" + changes_detected_interface_access_po: "{{ changes_detected_interface_access_po }}" + changes_detected_interface_access: "{{ changes_detected_interface_access }}" + changes_detected_interfaces: "{{ changes_detected_interfaces }}" + changes_detected_interface_loopback: "{{ changes_detected_interface_loopback }}" + changes_detected_interface_po_routed: "{{ changes_detected_interface_po_routed }}" + changes_detected_interface_routed: "{{ changes_detected_interface_routed }}" + changes_detected_interface_trunk_po: "{{ changes_detected_interface_trunk_po }}" + changes_detected_interface_trunk: "{{ changes_detected_interface_trunk }}" + changes_detected_interface_vpc: "{{ changes_detected_interface_vpc }}" + changes_detected_link_vpc_peering: "{{ changes_detected_link_vpc_peering }}" + changes_detected_networks: "{{ changes_detected_networks }}" + changes_detected_policy: "{{ changes_detected_policy }}" + changes_detected_sub_interface_routed: "{{ changes_detected_sub_interface_routed }}" + changes_detected_vpc_peering: "{{ changes_detected_vpc_peering }}" + changes_detected_vrfs: "{{ changes_detected_vrfs }}" + fabric_config: "{{ fabric_config }}" + fabric_links: "{{ fabric_links }}" + interface_access_po: "{{ interface_access_po }}" + interface_access: "{{ interface_access }}" + interface_all: "{{ interface_all }}" + int_loopback_config: "{{ int_loopback_config }}" + interface_po_routed: "{{ interface_po_routed }}" + interface_routed: "{{ interface_routed }}" + interface_trunk_po: "{{ interface_trunk_po }}" + interface_trunk: "{{ interface_trunk }}" + interface_vpc: "{{ interface_vpc }}" + inv_config: "{{ inv_config }}" + link_vpc_peering: "{{ link_vpc_peering }}" + net_config: "{{ net_config }}" + poap_data: "{{ poap_data }}" + policy_config: "{{ policy_config }}" + sub_interface_routed: "{{ sub_interface_routed }}" + updated_inv_config: "{{ updated_inv_config }}" + vpc_peering: "{{ vpc_peering }}" + vrf_config: "{{ vrf_config }}" + vrf_attach_config: "{{ vrf_attach_config }}" + + - name: Run Diff Flags ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Fabric Changes Detected - [ {{ changes_detected_fabric }} ]" - - "+ Inventory Changes Detected - [ {{ changes_detected_inventory }} ]" - - "+ vPC Link Peer Changes Detected - [ {{ changes_detected_link_vpc_peering }} ]" - - "+ vPC Peer Changes Detected - [ {{ changes_detected_vpc_peering }} ]" + - "+ Fabric Changes Detected - [ {{ vars_common_vxlan.changes_detected_fabric }} ]" + - "+ Inventory Changes Detected - [ {{ vars_common_vxlan.changes_detected_inventory }} ]" + - "+ vPC Link Peer Changes Detected - [ {{ vars_common_vxlan.changes_detected_link_vpc_peering }} ]" + - "+ vPC Peer Changes Detected - [ {{ vars_common_vxlan.changes_detected_vpc_peering }} ]" - "+ ----- Interfaces -----" - - "+ Interface vPC Changes Detected - [ {{ changes_detected_interface_vpc }} ]" - - "+ Interface Access Changes Detected - [ {{ changes_detected_interface_access }} ]" - - "+ Interface Access PO Changes Detected - [ {{ changes_detected_interface_access_po }} ]" - - "+ Interface Loopback Changes Detected - [ {{ changes_detected_interface_loopback }} ]" - - "+ Interface PO Routed Changes Detected - [ {{ changes_detected_interface_po_routed }} ]" - - "+ Interface Routed Changes Detected - [ {{ changes_detected_interface_routed }} ]" - - "+ Interface Trunk Changes Detected - [ {{ changes_detected_interface_trunk }} ]" - - "+ Interface Trunk PO Changes Detected - [ {{ changes_detected_interface_trunk_po }} ]" - - "+ Sub Interface Routed Changes Detected - [ {{ changes_detected_sub_interface_routed }} ]" + - "+ Interface vPC Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_vpc }} ]" + - "+ Interface Access Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_access }} ]" + - "+ Interface Access PO Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_access_po }} ]" + - "+ Interface Loopback Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_loopback }} ]" + - "+ Interface PO Routed Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_po_routed }} ]" + - "+ Interface Routed Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_routed }} ]" + - "+ Interface Trunk Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_trunk }} ]" + - "+ Interface Trunk PO Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_trunk_po }} ]" + - "+ Sub Interface Routed Changes Detected - [ {{ vars_common_vxlan.changes_detected_sub_interface_routed }} ]" - "+ ----- All Interfaces -----" - - "+ All Interfaces Changes Detected - [ {{ changes_detected_interfaces }} ]" + - "+ All Interfaces Changes Detected - [ {{ vars_common_vxlan.changes_detected_interfaces }} ]" - "+ ----- All Interfaces -----" - - "+ VRFs Changes Detected - [ {{ changes_detected_vrfs }} ]" - - "+ Networks Changes Detected - [ {{ changes_detected_networks }} ]" - - "+ Policy Changes Detected - [ {{ changes_detected_policy }} ]" - - "+ Fabric Links Changes Detected - [ {{ changes_detected_fabric_links }} ]" + - "+ VRFs Changes Detected - [ {{ vars_common_vxlan.changes_detected_vrfs }} ]" + - "+ Networks Changes Detected - [ {{ vars_common_vxlan.changes_detected_networks }} ]" + - "+ Policy Changes Detected - [ {{ vars_common_vxlan.changes_detected_policy }} ]" + - "+ Fabric Links Changes Detected - [ {{ vars_common_vxlan.changes_detected_fabric_links }} ]" - "+ ----- Run Map -----" - "+ Run Map Diff Run - [ {{ run_map_read_result.diff_run }} ]" - "+ Force Run Flag - [ {{ force_run_all }} ]" diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml index 392934c7..ff904775 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml @@ -81,5 +81,3 @@ when: - file_diff_result.file_data_changed - check_roles['save_previous'] - -# ansible_run_tags \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_networks.yml b/roles/dtc/common/tasks/vxlan/ndfc_networks.yml index ef9714cf..797d1149 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_networks.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_networks.yml @@ -65,8 +65,7 @@ ansible.builtin.set_fact: net_config: "{{ lookup('file', file_name) | from_yaml }}" when: > - (MD_Extended.vxlan.overlay.networks | default([])) | length > 0 or - (MD_Extended.vxlan.overlay_services.networks | default([])) | length > 0 + (MD_Extended.vxlan.overlay.networks | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files diff --git a/roles/dtc/common/tasks/vxlan/ndfc_policy.yml b/roles/dtc/common/tasks/vxlan/ndfc_policy.yml index f8eb9712..1203bb7b 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_policy.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_policy.yml @@ -75,4 +75,4 @@ delegate_to: localhost when: - file_diff_result.file_data_changed - - check_roles['save_previous'] + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml b/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml index 354c33d7..261d4899 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml @@ -80,4 +80,4 @@ delegate_to: localhost when: - file_diff_result.file_data_changed - - check_roles['save_previous'] + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml index 3468e5b5..30c72ff5 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml @@ -65,8 +65,7 @@ ansible.builtin.set_fact: vrf_config: "{{ lookup('file', file_name) | from_yaml }}" when: > - (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 or - (MD_Extended.vxlan.overlay_services.vrfs | default([])) | length > 0 + (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files @@ -104,6 +103,5 @@ ansible.builtin.set_fact: vrf_attach_config: "{{ lookup('file', file_name) | from_yaml }}" when: > - (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 or - (MD_Extended.vxlan.overlay_services.vrfs | default([])) | length > 0 + (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 delegate_to: localhost \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_attach_vrfs_loopbacks.j2 b/roles/dtc/common/templates/ndfc_attach_vrfs_loopbacks.j2 index 97f9e21d..7b64ca08 100644 --- a/roles/dtc/common/templates/ndfc_attach_vrfs_loopbacks.j2 +++ b/roles/dtc/common/templates/ndfc_attach_vrfs_loopbacks.j2 @@ -1,11 +1,11 @@ [ - {% for vrf in MD_Extended.vxlan.overlay_services.vrfs %} + {% for vrf in MD_Extended.vxlan.overlay.vrfs %} {% if vrf['vrf_attach_group'] is defined %} { "vrfName": "{{ vrf["name"] }}", "lanAttachList": [ - {% for attach in MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict[vrf["vrf_attach_group"]] %} + {% for attach in MD_Extended.vxlan.overlay.vrf_attach_groups_dict[vrf["vrf_attach_group"]] %} { "fabric": "{{ MD_Extended.vxlan.fabric.name }}", "vrfName": "{{ vrf["name"] }}", diff --git a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 index 29db305b..d00ad13b 100644 --- a/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 +++ b/roles/dtc/common/templates/ndfc_networks/dc_vxlan_fabric/dc_vxlan_fabric_networks.j2 @@ -1,10 +1,7 @@ {# Auto-generated NDFC DC VXLAN EVPN VRFs config data structure for fabric {{ vxlan.fabric.name }} #} -{# TODO: Remove lines 3-8. When we get here we should be normalized around overlay, not overlay_services#} {% set networks = [] %} {% if MD_Extended.vxlan.overlay.networks is defined and MD_Extended.vxlan.overlay.networks %} {% set networks = MD_Extended.vxlan.overlay.networks %} -{% elif MD_Extended.vxlan.overlay_services.networks is defined and MD_Extended.vxlan.overlay_services.networks %} -{% set networks = MD_Extended.vxlan.overlay_services.networks %} {% endif %} {% for net in networks %} - net_name: {{ net['name'] }} @@ -75,8 +72,6 @@ attach: {% if MD_Extended.vxlan.overlay.network_attach_groups_dict is defined and MD_Extended.vxlan.overlay.network_attach_groups_dict %} {% set network_attach_groups_dict = MD_Extended.vxlan.overlay.network_attach_groups_dict %} -{% elif MD_Extended.vxlan.overlay_services.network_attach_groups_dict is defined and MD_Extended.vxlan.overlay_services.network_attach_groups_dict %} -{% set network_attach_groups_dict = MD_Extended.vxlan.overlay_services.network_attach_groups_dict %} {% endif %} {% for attach in network_attach_groups_dict[net['network_attach_group']] %} - ip_address: {{ attach['mgmt_ip_address'] }} 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 b8bd09af..b27f9b8b 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 @@ -1,10 +1,7 @@ {# Auto-generated NDFC DC VXLAN EVPN VRFs config data structure for fabric {{ vxlan.fabric.name }} #} -{# TODO: Remove lines 3-8. When we get here we should be normalized around overlay, not overlay_services#} {% set vrfs = [] %} {% if MD_Extended.vxlan.overlay.vrfs is defined and MD_Extended.vxlan.overlay.vrfs %} {% set vrfs = MD_Extended.vxlan.overlay.vrfs %} -{% elif MD_Extended.vxlan.overlay_services.vrfs is defined and MD_Extended.vxlan.overlay_services.vrfs %} -{% set vrfs = MD_Extended.vxlan.overlay_services.vrfs %} {% endif %} {% for vrf in vrfs %} - vrf_name: {{ vrf['name'] }} @@ -55,8 +52,6 @@ attach: {% if MD_Extended.vxlan.overlay.vrf_attach_groups_dict is defined and MD_Extended.vxlan.overlay.vrf_attach_groups_dict %} {% set vrf_attach_groups_dict = MD_Extended.vxlan.overlay.vrf_attach_groups_dict %} -{% elif MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict is defined and MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict %} -{% set vrf_attach_groups_dict = MD_Extended.vxlan.overlay_services.vrf_attach_groups_dict %} {% endif %} {% for attach in vrf_attach_groups_dict[vrf['vrf_attach_group']] %} - ip_address: {{ attach['mgmt_ip_address'] }} diff --git a/roles/dtc/create/tasks/isn/devices_discovery.yml b/roles/dtc/create/tasks/isn/devices_discovery.yml index 11ed62d4..7374085b 100644 --- a/roles/dtc/create/tasks/isn/devices_discovery.yml +++ b/roles/dtc/create/tasks/isn/devices_discovery.yml @@ -24,7 +24,7 @@ - name: Add NDFC Fabric Devices {{ MD_Extended.vxlan.fabric.name }} cisco.dcnm.dcnm_inventory: fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ updated_inv_config['updated_inv_list'] }}" + config: "{{ vars_common_isn.updated_inv_config['updated_inv_list'] }}" deploy: false save: true state: merged diff --git a/roles/dtc/create/tasks/isn/fabric.yml b/roles/dtc/create/tasks/isn/fabric.yml index e810c30d..0b17956e 100644 --- a/roles/dtc/create/tasks/isn/fabric.yml +++ b/roles/dtc/create/tasks/isn/fabric.yml @@ -31,4 +31,4 @@ - name: Manage Fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC cisco.dcnm.dcnm_fabric: state: merged - config: "{{ fabric_config }}" + config: "{{ vars_common_isn.fabric_config }}" diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index ccf1471c..05f98ba1 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -23,23 +23,40 @@ - name: Import VXLAN Role Tasks ansible.builtin.import_tasks: sub_main_vxlan.yml - when: - - MD_Extended.vxlan.fabric.type == 'VXLAN_EVPN' - - changes_detected_fabric or changes_detected_inventory or changes_detected_vpc_peering or changes_detected_interfaces or changes_detected_link_vpc_peering or changes_detected_vrfs or changes_detected_networks or changes_detected_policy + when: > + (MD_Extended.vxlan.fabric.type == 'VXLAN_EVPN') and + (vars_common_vxlan.changes_detected_fabric) or + (vars_common_vxlan.changes_detected_inventory) or + (vars_common_vxlan.changes_detected_vpc_peering) or + (vars_common_vxlan.changes_detected_interfaces) or + (vars_common_vxlan.changes_detected_link_vpc_peering) or + (vars_common_vxlan.changes_detected_vrfs) or + (vars_common_vxlan.changes_detected_networks) or + (vars_common_vxlan.changes_detected_policy) - name: Import ISN Role Tasks ansible.builtin.import_tasks: sub_main_isn.yml - when: MD_Extended.vxlan.fabric.type == 'ISN' + when: > + (MD_Extended.vxlan.fabric.type == 'ISN') and + (vars_common_isn.changes_detected_fabric) or + (vars_common_isn.changes_detected_inventory) - name: Import MSD Role Tasks ansible.builtin.import_tasks: sub_main_msd.yml - when: MD_Extended.vxlan.fabric.type == 'MSD' + when: > + (MD_Extended.vxlan.fabric.type == 'MSD') and + (vars_common_msd.changes_detected_fabric) or + (vars_common_msd.changes_detected_vrfs) or + (vars_common_msd.changes_detected_networks) +# Check with Matt and Pete on External Fabrics - name: Import Role Tasks External Fabric ansible.builtin.import_tasks: sub_main_external.yml - when: - - changes_detected_inventory or changes_detected_interfaces or changes_detected_policy - - MD_Extended.vxlan.global.fabric_type == 'External' + when: > + (MD_Extended.vxlan.global.fabric_type == 'External') and + (changes_detected_inventory) or + (changes_detected_interfaces) or + (changes_detected_policy) - name: Mark Stage Role Create Completed cisco.nac_dc_vxlan.common.run_map: diff --git a/roles/dtc/create/tasks/msd/fabric.yml b/roles/dtc/create/tasks/msd/fabric.yml index e810c30d..7141b379 100644 --- a/roles/dtc/create/tasks/msd/fabric.yml +++ b/roles/dtc/create/tasks/msd/fabric.yml @@ -31,4 +31,4 @@ - name: Manage Fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC cisco.dcnm.dcnm_fabric: state: merged - config: "{{ fabric_config }}" + config: "{{ vars_common_msd.fabric_config }}" diff --git a/roles/dtc/create/tasks/msd/vrfs_networks.yml b/roles/dtc/create/tasks/msd/vrfs_networks.yml index f2cb35d6..f67605ef 100644 --- a/roles/dtc/create/tasks/msd/vrfs_networks.yml +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -35,12 +35,12 @@ cisco.dcnm.dcnm_vrf: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ vrf_config }}" + config: "{{ vars_common_msd.vrf_config }}" register: manage_vrf_result when: - MD_Extended.vxlan.multisite.overlay.vrfs is defined - MD_Extended.vxlan.multisite.overlay.vrfs - - changes_detected_vrfs + - vars_common_msd.changes_detected_vrfs # -------------------------------------------------------------------- # Manage Loopback VRF attachments on NDFC @@ -49,11 +49,11 @@ cisco.dcnm.dcnm_rest: path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/top-down/v2/fabrics/{{ MD_Extended.vxlan.fabric.name }}/vrfs/attachments" method: "POST" - json_data: "{{ vrf_attach_config | to_json}}" + json_data: "{{ vars_common_msd.vrf_attach_config | to_json}}" when: - - MD_Extended.vxlan.overlay_services.vrfs is defined - - MD_Extended.vxlan.overlay_services.vrfs - - changes_detected_vrfs + - MD_Extended.vxlan.overlay.vrfs is defined + - MD_Extended.vxlan.overlay.vrfs + - vars_common_msd.changes_detected_vrfs # -------------------------------------------------------------------- # Manage Network Configuration on NDFC @@ -62,9 +62,9 @@ cisco.dcnm.dcnm_network: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ net_config }}" + config: "{{ vars_common_msd.net_config }}" register: manage_network_result when: - MD_Extended.vxlan.multisite.overlay.networks is defined - MD_Extended.vxlan.multisite.overlay.networks - - changes_detected_networks + - vars_common_msd.changes_detected_networks diff --git a/roles/dtc/create/tasks/sub_main_isn.yml b/roles/dtc/create/tasks/sub_main_isn.yml index e7d799d2..b67d04de 100644 --- a/roles/dtc/create/tasks/sub_main_isn.yml +++ b/roles/dtc/create/tasks/sub_main_isn.yml @@ -37,12 +37,12 @@ when: - MD_Extended.vxlan.fabric.name is defined - MD_Extended.vxlan.fabric.type == "ISN" - - changes_detected_fabric + - vars_common_isn.changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" - name: Manage NDFC ISN Fabric Switches ansible.builtin.import_tasks: isn/devices.yml when: - MD_Extended.vxlan.multisite.isn.topology.switches | length > 0 - - changes_detected_inventory + - vars_common_isn.changes_detected_inventory tags: "{{ nac_tags.create_switches }}" diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index 396fe573..4111180d 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -37,7 +37,7 @@ when: - MD_Extended.vxlan.fabric.name is defined - MD_Extended.vxlan.fabric.type == "MSD" - - changes_detected_fabric + - vars_common_msd.changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" - name: Manage NDFC MSD Fabric Child Fabrics @@ -50,5 +50,5 @@ when: - MD_Extended.vxlan.multisite.overlay is defined - MD_Extended.vxlan.multisite.overlay - - (changes_detected_vrfs or changes_detected_networks) + - (vars_common_msd.changes_detected_vrfs or vars_common_msd.changes_detected_networks) tags: "{{ nac_tags.create_vrfs_networks }}" diff --git a/roles/dtc/create/tasks/sub_main_vxlan.yml b/roles/dtc/create/tasks/sub_main_vxlan.yml index 379a49fd..aa4bc319 100644 --- a/roles/dtc/create/tasks/sub_main_vxlan.yml +++ b/roles/dtc/create/tasks/sub_main_vxlan.yml @@ -38,48 +38,48 @@ - MD_Extended.vxlan.fabric.name is defined - MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" - MD_Extended.vxlan.global is defined - - changes_detected_fabric + - vars_common_vxlan.changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" - name: Manage NDFC Fabric Switches ansible.builtin.import_tasks: vxlan/devices.yml when: - MD_Extended.vxlan.topology.switches | length > 0 - - changes_detected_inventory + - vars_common_vxlan.changes_detected_inventory tags: "{{ nac_tags.create_switches }}" - name: Manage VPC Peering ansible.builtin.import_tasks: vxlan/vpc_peering.yml when: - MD_Extended.vxlan.topology.vpc_peers | length > 0 - - changes_detected_vpc_peering + - vars_common_vxlan.changes_detected_vpc_peering tags: "{{ nac_tags.create_vpc_peers }}" - name: Manage NDFC Fabric Interfaces ansible.builtin.import_tasks: vxlan/interfaces.yml when: - (MD_Extended.vxlan.topology.interfaces.modes.all.count >0) and (MD_Extended.vxlan.topology.switches | length > 0) - - changes_detected_interfaces + - vars_common_vxlan.changes_detected_interfaces tags: "{{ nac_tags.create_interfaces }}" - name: Manage NDFC Fabric VRFs and Networks ansible.builtin.import_tasks: vxlan/vrfs_networks.yml - when: > - (MD_Extended.vxlan.overlay_services is defined or MD_Extended.vxlan.overlay is defined) and - MD_Extended.vxlan.topology.switches | length > 0 and - (changes_detected_vrfs or changes_detected_networks) + when: + - MD_Extended.vxlan.overlay is defined + - MD_Extended.vxlan.topology.switches | length > 0 + - vars_common_vxlan.changes_detected_vrfs or vars_common_vxlan.changes_detected_networks tags: "{{ nac_tags.create_vrfs_networks }}" - name: Manage NDFC Fabric Intra Links ansible.builtin.import_tasks: vxlan/links.yml when: - MD_Extended.vxlan.topology.fabric_links | length > 0 - - changes_detected_fabric_links + - vars_common_vxlan.changes_detected_fabric_links tags: "{{ nac_tags.create_links }}" - name: Manage NDFC Fabric Policies ansible.builtin.import_tasks: vxlan/policies.yml when: - (MD_Extended.vxlan.policy is defined) and (MD_Extended.vxlan.policy.policies | length > 0) - - changes_detected_policy + - vars_common_vxlan.changes_detected_policy tags: "{{ nac_tags.create_policy }}" diff --git a/roles/dtc/create/tasks/vxlan/devices_discovery.yml b/roles/dtc/create/tasks/vxlan/devices_discovery.yml index 1b12ac32..dde9eaff 100644 --- a/roles/dtc/create/tasks/vxlan/devices_discovery.yml +++ b/roles/dtc/create/tasks/vxlan/devices_discovery.yml @@ -24,7 +24,7 @@ - name: Add NDFC Fabric Devices {{ MD_Extended.vxlan.fabric.name }} cisco.dcnm.dcnm_inventory: fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ updated_inv_config['updated_inv_list'] }}" + config: "{{ vars_common_vxlan.updated_inv_config['updated_inv_list'] }}" deploy: false save: true state: merged @@ -57,4 +57,4 @@ method: PUT path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/policies/{{ policy_ids }}/bulk" json_data: "{{ results.policy_update.values() | list | to_json }}" - when: results.policy_update | length > 0 + when: results.policy_update | length > 0 \ No newline at end of file diff --git a/roles/dtc/create/tasks/vxlan/fabric.yml b/roles/dtc/create/tasks/vxlan/fabric.yml index 549e5785..dfb042c9 100644 --- a/roles/dtc/create/tasks/vxlan/fabric.yml +++ b/roles/dtc/create/tasks/vxlan/fabric.yml @@ -31,4 +31,4 @@ - name: Manage fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC cisco.dcnm.dcnm_fabric: state: merged - config: "{{ fabric_config }}" + config: "{{ vars_common_vxlan.fabric_config }}" diff --git a/roles/dtc/create/tasks/vxlan/interfaces.yml b/roles/dtc/create/tasks/vxlan/interfaces.yml index 49c00566..8b2a7c21 100644 --- a/roles/dtc/create/tasks/vxlan/interfaces.yml +++ b/roles/dtc/create/tasks/vxlan/interfaces.yml @@ -36,7 +36,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ interface_access_po }}" + config: "{{ vars_common_vxlan.interface_access_po }}" when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 # -------------------------------------------------------------------- @@ -47,7 +47,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ interface_trunk_po }}" + config: "{{ vars_common_vxlan.interface_trunk_po }}" when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 # -------------------------------------------------------------------- @@ -58,7 +58,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ interface_routed }}" + config: "{{ vars_common_vxlan.interface_routed }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 # -------------------------------------------------------------------- @@ -69,7 +69,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ sub_interface_routed }}" + config: "{{ vars_common_vxlan.sub_interface_routed }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 # -------------------------------------------------------------------- @@ -80,7 +80,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ interface_po_routed }}" + config: "{{ vars_common_vxlan.interface_po_routed }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 # -------------------------------------------------------------------- @@ -91,7 +91,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ int_loopback_config }}" + config: "{{ vars_common_vxlan.int_loopback_config }}" when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 # -------------------------------------------------------------------- @@ -102,7 +102,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ interface_trunk }}" + config: "{{ vars_common_vxlan.interface_trunk }}" when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 # -------------------------------------------------------------------- @@ -113,7 +113,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ interface_access }}" + config: "{{ vars_common_vxlan.interface_access }}" when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 # -------------------------------------------------------------------- @@ -124,7 +124,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ interface_vpc }}" + config: "{{ vars_common_vxlan.interface_vpc }}" when: MD_Extended.vxlan.topology.interfaces.modes.access_vpc.count > 0 or MD_Extended.vxlan.topology.interfaces.modes.trunk_vpc.count > 0 ## Will discuss with team and switchover to the below code and remove the above code @@ -136,7 +136,7 @@ # cisco.dcnm.dcnm_interface: # fabric: "{{ MD_Extended.vxlan.fabric.name }}" # state: replaced -# config: "{{ interface_all }}" +# config: "{{ vars_common_vxlan.interface_all }}" # vars: # ansible_command_timeout: 3000 # ansible_connect_timeout: 3000 diff --git a/roles/dtc/create/tasks/vxlan/links.yml b/roles/dtc/create/tasks/vxlan/links.yml index 807db637..e292c721 100644 --- a/roles/dtc/create/tasks/vxlan/links.yml +++ b/roles/dtc/create/tasks/vxlan/links.yml @@ -43,7 +43,7 @@ - name: Create a list of links that already exist cisco.nac_dc_vxlan.dtc.existing_links_check: existing_links: "{{ result_links.response }}" - fabric_links: "{{ fabric_links }}" + fabric_links: "{{ vars_common_vxlan.fabric_links }}" register: not_required_links when: result_links.response is defined @@ -55,7 +55,7 @@ - name: remove unwanted links from required links input ansible.builtin.set_fact: - required_links: "{{ fabric_links | difference(not_required_links['not_required_links']) }}" + required_links: "{{ vars_common_vxlan.fabric_links | difference(not_required_links['not_required_links']) }}" # -------------------------------------------------------------------- # Manage VRF Configuration on NDFC # -------------------------------------------------------------------- diff --git a/roles/dtc/create/tasks/vxlan/policies.yml b/roles/dtc/create/tasks/vxlan/policies.yml index 3b9d2e49..d0e660c6 100644 --- a/roles/dtc/create/tasks/vxlan/policies.yml +++ b/roles/dtc/create/tasks/vxlan/policies.yml @@ -35,7 +35,7 @@ cisco.dcnm.dcnm_policy: fabric: "{{ MD_Extended.vxlan.fabric.name }}" use_desc_as_key: true - config: "{{ policy_config }}" + config: "{{ vars_common_vxlan.policy_config }}" deploy: false state: merged register: manage_policies_result diff --git a/roles/dtc/create/tasks/vxlan/vpc_peering.yml b/roles/dtc/create/tasks/vxlan/vpc_peering.yml index 725db029..02448332 100644 --- a/roles/dtc/create/tasks/vxlan/vpc_peering.yml +++ b/roles/dtc/create/tasks/vxlan/vpc_peering.yml @@ -36,7 +36,7 @@ cisco.dcnm.dcnm_links: state: replaced src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ link_vpc_peering }}" + config: "{{ vars_common_vxlan.link_vpc_peering }}" vars: ansible_command_timeout: 3000 ansible_connect_timeout: 3000 @@ -51,4 +51,4 @@ src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" deploy: false state: replaced - config: "{{ vpc_peering }}" + config: "{{ vars_common_vxlan.vpc_peering }}" diff --git a/roles/dtc/create/tasks/vxlan/vrfs_networks.yml b/roles/dtc/create/tasks/vxlan/vrfs_networks.yml index 9e6b27c3..9170c0fe 100644 --- a/roles/dtc/create/tasks/vxlan/vrfs_networks.yml +++ b/roles/dtc/create/tasks/vxlan/vrfs_networks.yml @@ -35,12 +35,25 @@ cisco.dcnm.dcnm_vrf: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ vrf_config }}" + config: "{{ vars_common_vxlan.vrf_config }}" register: manage_vrf_result - when: > - (MD_Extended.vxlan.overlay.vrfs is defined and MD_Extended.vxlan.overlay.vrfs) or - (MD_Extended.vxlan.overlay_services.vrfs is defined and MD_Extended.vxlan.overlay_services.vrfs) and - changes_detected_vrfs + when: + - MD_Extended.vxlan.overlay.vrfs is defined + - MD_Extended.vxlan.overlay.vrfs + - vars_common_vxlan.changes_detected_vrfs + +# -------------------------------------------------------------------- +# Manage Loopback VRF attachments on NDFC +# -------------------------------------------------------------------- +- name: Attach VRF Loopbacks per VRF + cisco.dcnm.dcnm_rest: + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/top-down/v2/fabrics/{{ MD_Extended.vxlan.fabric.name }}/vrfs/attachments" + method: "POST" + json_data: "{{ vars_common_vxlan.vrf_attach_config | to_json}}" + when: + - MD_Extended.vxlan.overlay.vrfs is defined + - MD_Extended.vxlan.overlay.vrfs + - vars_common_vxlan.changes_detected_vrfs # -------------------------------------------------------------------- # Manage Network Configuration on NDFC @@ -49,9 +62,9 @@ cisco.dcnm.dcnm_network: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: replaced - config: "{{ net_config }}" + config: "{{ vars_common_vxlan.net_config }}" register: manage_network_result - when: > - (MD_Extended.vxlan.overlay.networks is defined and MD_Extended.vxlan.overlay.networks) or - (MD_Extended.vxlan.overlay_services.networks is defined and MD_Extended.vxlan.overlay_services.networks) and - changes_detected_networks + when: + - MD_Extended.vxlan.overlay.networks is defined + - MD_Extended.vxlan.overlay.networks + - vars_common_vxlan.changes_detected_networks diff --git a/roles/dtc/deploy/tasks/main.yml b/roles/dtc/deploy/tasks/main.yml index 76f46304..811d76d7 100644 --- a/roles/dtc/deploy/tasks/main.yml +++ b/roles/dtc/deploy/tasks/main.yml @@ -24,7 +24,21 @@ - name: Import Role Tasks ansible.builtin.import_tasks: sub_main.yml tags: "{{ nac_tags.deploy }}" # Tags defined in roles/common_global/vars/main.yml - when: changes_detected_fabric or changes_detected_inventory or changes_detected_vpc_peering or changes_detected_interfaces or changes_detected_link_vpc_peering or changes_detected_vrfs or changes_detected_networks or changes_detected_policy or changes_detected_fabric_links + when: > + (vars_common_vxlan.changes_detected_fabric) or + (vars_common_vxlan.changes_detected_inventory) or + (vars_common_vxlan.changes_detected_vpc_peering) or + (vars_common_vxlan.changes_detected_interfaces) or + (vars_common_vxlan.changes_detected_link_vpc_peering) or + (vars_common_vxlan.changes_detected_vrfs) or + (vars_common_vxlan.changes_detected_networks) or + (vars_common_vxlan.changes_detected_policy) or + (vars_common_vxlan.changes_detected_fabric_links) or + (vars_common_isn.changes_detected_fabric) or + (vars_common_isn.changes_detected_inventory) or + (vars_common_msd.changes_detected_fabric) or + (vars_common_msd.changes_detected_vrfs) or + (vars_common_msd.changes_detected_networks) - name: Mark Stage Role Deploy Completed cisco.nac_dc_vxlan.common.run_map: diff --git a/roles/dtc/remove/tasks/main.yml b/roles/dtc/remove/tasks/main.yml index c9f755aa..8764d30e 100644 --- a/roles/dtc/remove/tasks/main.yml +++ b/roles/dtc/remove/tasks/main.yml @@ -23,15 +23,24 @@ - name: Import VXLAN Role Tasks ansible.builtin.import_tasks: sub_main_vxlan.yml - when: - - MD_Extended.vxlan.fabric.type == 'VXLAN_EVPN' - - changes_detected_interfaces or changes_detected_networks or changes_detected_vrfs or changes_detected_vpc_peering or changes_detected_link_vpc_peering or changes_detected_inventory + # Check with Matt on changes_detected_policy here + # Was not there previously + when: > + (MD_Extended.vxlan.fabric.type == 'VXLAN_EVPN') and + (vars_common_vxlan.changes_detected_inventory) or + (vars_common_vxlan.changes_detected_vpc_peering) or + (vars_common_vxlan.changes_detected_interfaces) or + (vars_common_vxlan.changes_detected_link_vpc_peering) or + (vars_common_vxlan.changes_detected_vrfs) or + (vars_common_vxlan.changes_detected_networks) + + # (vars_common_vxlan.changes_detected_policy) - name: Import MSD Role Tasks ansible.builtin.import_tasks: sub_main_msd.yml when: - MD_Extended.vxlan.fabric.type == 'MSD' - # - changes_detected_interfaces or changes_detected_networks or changes_detected_vrfs + # - vars_common_msd.changes_detected_interfaces or vars_common_msd.changes_detected_networks or vars_common_msd.changes_detected_vrfs - name: Mark Stage Role Remove Completed cisco.nac_dc_vxlan.common.run_map: diff --git a/roles/dtc/remove/tasks/msd/networks.yml b/roles/dtc/remove/tasks/msd/networks.yml index 706fa9ef..98f57ae7 100644 --- a/roles/dtc/remove/tasks/msd/networks.yml +++ b/roles/dtc/remove/tasks/msd/networks.yml @@ -29,7 +29,7 @@ cisco.dcnm.dcnm_network: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: overridden - config: "{{ net_config }}" + config: "{{ vars_common_msd.net_config }}" vars: ansible_command_timeout: 3000 ansible_connect_timeout: 3000 diff --git a/roles/dtc/remove/tasks/msd/vrfs.yml b/roles/dtc/remove/tasks/msd/vrfs.yml index 68bce074..1de111af 100644 --- a/roles/dtc/remove/tasks/msd/vrfs.yml +++ b/roles/dtc/remove/tasks/msd/vrfs.yml @@ -29,7 +29,7 @@ cisco.dcnm.dcnm_vrf: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: overridden - config: "{{ vrf_config }}" + config: "{{ vars_common_msd.vrf_config }}" vars: ansible_command_timeout: 3000 ansible_connect_timeout: 3000 diff --git a/roles/dtc/remove/tasks/sub_main_msd.yml b/roles/dtc/remove/tasks/sub_main_msd.yml index 4efd9228..92f2cdfd 100644 --- a/roles/dtc/remove/tasks/sub_main_msd.yml +++ b/roles/dtc/remove/tasks/sub_main_msd.yml @@ -44,14 +44,14 @@ ansible.builtin.import_tasks: msd/networks.yml tags: "{{ nac_tags.remove_networks }}" when: - - changes_detected_networks + - vars_common_msd.changes_detected_networks # These are not working right... investigate - name: Remove Fabric VRFs ansible.builtin.import_tasks: msd/vrfs.yml tags: "{{ nac_tags.remove_vrfs }}" when: - - changes_detected_vrfs + - vars_common_msd.changes_detected_vrfs - name: Remove Child Fabrics ansible.builtin.import_tasks: msd/child_fabrics.yml diff --git a/roles/dtc/remove/tasks/sub_main_vxlan.yml b/roles/dtc/remove/tasks/sub_main_vxlan.yml index 397e124c..0842dce8 100644 --- a/roles/dtc/remove/tasks/sub_main_vxlan.yml +++ b/roles/dtc/remove/tasks/sub_main_vxlan.yml @@ -43,40 +43,40 @@ ansible.builtin.import_tasks: vxlan/policy.yml tags: "{{ nac_tags.remove_policy }}" when: - - changes_detected_policy + - vars_common_vxlan.changes_detected_policy - name: Remove Fabric Interfaces ansible.builtin.import_tasks: vxlan/interfaces.yml tags: "{{ nac_tags.remove_interfaces }}" when: - - changes_detected_interfaces + - vars_common_vxlan.changes_detected_interfaces - name: Remove Fabric Networks ansible.builtin.import_tasks: vxlan/networks.yml tags: "{{ nac_tags.remove_networks }}" when: - - changes_detected_networks + - vars_common_vxlan.changes_detected_networks - name: Remove Fabric VRFs ansible.builtin.import_tasks: vxlan/vrfs.yml tags: "{{ nac_tags.remove_vrfs }}" when: - - changes_detected_vrfs + - vars_common_vxlan.changes_detected_vrfs - name: Remove Fabric Links ansible.builtin.import_tasks: vxlan/links.yml tags: "{{ nac_tags.remove_links }}" when: - - changes_detected_link_vpc_peering + - vars_common_vxlan.changes_detected_link_vpc_peering - name: Remove Fabric vPC Peering ansible.builtin.import_tasks: vxlan/vpc_peers.yml tags: "{{ nac_tags.remove_vpc_peers }}" when: - - changes_detected_vpc_peering + - vars_common_vxlan.changes_detected_vpc_peering - name: Remove Fabric Switches ansible.builtin.import_tasks: vxlan/switches.yml tags: "{{ nac_tags.remove_switches }}" when: - - changes_detected_inventory + - vars_common_vxlan.changes_detected_inventory diff --git a/roles/dtc/remove/tasks/vxlan/interfaces.yml b/roles/dtc/remove/tasks/vxlan/interfaces.yml index 22039b2f..cf3611e7 100644 --- a/roles/dtc/remove/tasks/vxlan/interfaces.yml +++ b/roles/dtc/remove/tasks/vxlan/interfaces.yml @@ -29,7 +29,7 @@ cisco.dcnm.dcnm_interface: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: overridden - config: "{{ interface_all }}" + config: "{{ vars_common_vxlan.interface_all }}" # deploy: false vars: ansible_command_timeout: 3000 diff --git a/roles/dtc/remove/tasks/vxlan/links.yml b/roles/dtc/remove/tasks/vxlan/links.yml index 16dee9d6..a9667d85 100644 --- a/roles/dtc/remove/tasks/vxlan/links.yml +++ b/roles/dtc/remove/tasks/vxlan/links.yml @@ -29,7 +29,7 @@ cisco.dcnm.dcnm_links: state: replaced src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ link_vpc_peering }}" + config: "{{ vars_common_vxlan.link_vpc_peering }}" vars: ansible_command_timeout: 3000 ansible_connect_timeout: 3000 @@ -54,7 +54,7 @@ - name: Create a list of links that already exist cisco.nac_dc_vxlan.dtc.links_filter_and_remove: existing_links: "{{ result_links.response }}" - fabric_links: "{{ fabric_links }}" + fabric_links: "{{ vars_common_vxlan.fabric_links }}" register: links_to_be_removed when: result_links.response is defined diff --git a/roles/dtc/remove/tasks/vxlan/networks.yml b/roles/dtc/remove/tasks/vxlan/networks.yml index 706fa9ef..6709f07f 100644 --- a/roles/dtc/remove/tasks/vxlan/networks.yml +++ b/roles/dtc/remove/tasks/vxlan/networks.yml @@ -29,7 +29,7 @@ cisco.dcnm.dcnm_network: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: overridden - config: "{{ net_config }}" + config: "{{ vars_common_vxlan.net_config }}" vars: ansible_command_timeout: 3000 ansible_connect_timeout: 3000 diff --git a/roles/dtc/remove/tasks/vxlan/switches.yml b/roles/dtc/remove/tasks/vxlan/switches.yml index 1094f199..d1105d1c 100644 --- a/roles/dtc/remove/tasks/vxlan/switches.yml +++ b/roles/dtc/remove/tasks/vxlan/switches.yml @@ -27,7 +27,7 @@ - name: Remove Unmanaged NDFC Fabric Devices cisco.dcnm.dcnm_inventory: fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ updated_inv_config['updated_inv_list'] }}" + config: "{{ vars_common_vxlan.updated_inv_config['updated_inv_list'] }}" deploy: true save: true state: overridden diff --git a/roles/dtc/remove/tasks/vxlan/vpc_peers.yml b/roles/dtc/remove/tasks/vxlan/vpc_peers.yml index dc8e1dcb..298ac9e2 100644 --- a/roles/dtc/remove/tasks/vxlan/vpc_peers.yml +++ b/roles/dtc/remove/tasks/vxlan/vpc_peers.yml @@ -30,7 +30,7 @@ src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" deploy: true state: overridden - config: "{{ vpc_peering }}" + config: "{{ vars_common_vxlan.vpc_peering }}" vars: ansible_command_timeout: 1000 ansible_connect_timeout: 1000 diff --git a/roles/dtc/remove/tasks/vxlan/vrfs.yml b/roles/dtc/remove/tasks/vxlan/vrfs.yml index 68bce074..be99d449 100644 --- a/roles/dtc/remove/tasks/vxlan/vrfs.yml +++ b/roles/dtc/remove/tasks/vxlan/vrfs.yml @@ -29,7 +29,7 @@ cisco.dcnm.dcnm_vrf: fabric: "{{ MD_Extended.vxlan.fabric.name }}" state: overridden - config: "{{ vrf_config }}" + config: "{{ vars_common_vxlan.vrf_config }}" vars: ansible_command_timeout: 3000 ansible_connect_timeout: 3000 diff --git a/tests/integration/host_vars/examples/fabric_empty_example/networks.yaml b/tests/integration/host_vars/examples/fabric_empty_example/networks.yaml index 8b8384c6..f74926a7 100644 --- a/tests/integration/host_vars/examples/fabric_empty_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_empty_example/networks.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: networks: [] diff --git a/tests/integration/host_vars/examples/fabric_empty_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_empty_example/vrfs.yaml index 0025ac5b..d035334b 100644 --- a/tests/integration/host_vars/examples/fabric_empty_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_empty_example/vrfs.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: vrfs: [] vrf_attach_groups: [] \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_full_large_example/networks.yaml b/tests/integration/host_vars/examples/fabric_full_large_example/networks.yaml index 93139f70..f40e2f86 100644 --- a/tests/integration/host_vars/examples/fabric_full_large_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_full_large_example/networks.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: networks: - name: NetAsCodeNet1 vrf_name: NetAsCodeVrf1 diff --git a/tests/integration/host_vars/examples/fabric_full_large_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_full_large_example/vrfs.yaml index 76b91f90..deaa5fab 100644 --- a/tests/integration/host_vars/examples/fabric_full_large_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_full_large_example/vrfs.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: vrfs: - name: NetAsCodeVrf1 vrf_id: 150001 diff --git a/tests/integration/host_vars/examples/fabric_full_small_isis_ingress_example/networks.yaml b/tests/integration/host_vars/examples/fabric_full_small_isis_ingress_example/networks.yaml index c95a81b7..4da2cb1f 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_isis_ingress_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_isis_ingress_example/networks.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: networks: - name: NetAsCodeNet1 vrf_name: NetAsCodeVrf1 diff --git a/tests/integration/host_vars/examples/fabric_full_small_isis_ingress_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_full_small_isis_ingress_example/vrfs.yaml index 0afbcc7d..beb68996 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_isis_ingress_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_isis_ingress_example/vrfs.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: vrfs: - name: NetAsCodeVrf1 vrf_id: 150001 diff --git a/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_asm_example/networks.yaml b/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_asm_example/networks.yaml index 8cf44458..05dd9c3f 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_asm_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_asm_example/networks.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: networks: - name: NetAsCodeNet1 vrf_name: NetAsCodeVrf1 diff --git a/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_asm_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_asm_example/vrfs.yaml index 907cd699..b2790816 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_asm_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_asm_example/vrfs.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: vrfs: - name: NetAsCodeVrf1 vrf_id: 150001 diff --git a/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_bidir_example/networks.yaml b/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_bidir_example/networks.yaml index c95a81b7..4da2cb1f 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_bidir_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_bidir_example/networks.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: networks: - name: NetAsCodeNet1 vrf_name: NetAsCodeVrf1 diff --git a/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_bidir_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_bidir_example/vrfs.yaml index b04540ab..efe02fce 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_bidir_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_isis_multicast_bidir_example/vrfs.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: vrfs: - name: NetAsCodeVrf1 vrf_id: 150001 diff --git a/tests/integration/host_vars/examples/fabric_full_small_ospf_ingress_example/networks.yaml b/tests/integration/host_vars/examples/fabric_full_small_ospf_ingress_example/networks.yaml index c95a81b7..4da2cb1f 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_ospf_ingress_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_ospf_ingress_example/networks.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: networks: - name: NetAsCodeNet1 vrf_name: NetAsCodeVrf1 diff --git a/tests/integration/host_vars/examples/fabric_full_small_ospf_ingress_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_full_small_ospf_ingress_example/vrfs.yaml index b04540ab..efe02fce 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_ospf_ingress_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_ospf_ingress_example/vrfs.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: vrfs: - name: NetAsCodeVrf1 vrf_id: 150001 diff --git a/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_asm_example/networks.yaml b/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_asm_example/networks.yaml index 8cf44458..05dd9c3f 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_asm_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_asm_example/networks.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: networks: - name: NetAsCodeNet1 vrf_name: NetAsCodeVrf1 diff --git a/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_asm_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_asm_example/vrfs.yaml index 1b50bb6e..10c471af 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_asm_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_asm_example/vrfs.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: vrfs: - name: NetAsCodeVrf1 vrf_id: 150001 diff --git a/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_bidir_example/networks.yaml b/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_bidir_example/networks.yaml index c95a81b7..4da2cb1f 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_bidir_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_bidir_example/networks.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: networks: - name: NetAsCodeNet1 vrf_name: NetAsCodeVrf1 diff --git a/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_bidir_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_bidir_example/vrfs.yaml index b04540ab..efe02fce 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_bidir_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_ospf_multicast_bidir_example/vrfs.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: vrfs: - name: NetAsCodeVrf1 vrf_id: 150001 diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/networks.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/networks.yaml index 8cf44458..05dd9c3f 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_sha_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/networks.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: networks: - name: NetAsCodeNet1 vrf_name: NetAsCodeVrf1 diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/vrfs.yaml index 1b50bb6e..10c471af 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_sha_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/vrfs.yaml @@ -21,7 +21,7 @@ --- vxlan: - overlay_services: + overlay: vrfs: - name: NetAsCodeVrf1 vrf_id: 150001 From 7c314917d2d9d30cb213fdea2eb41dc733a40d46 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Sun, 22 Dec 2024 19:23:33 +0000 Subject: [PATCH 35/66] Initialize shared dict vars --- roles/dtc/common/tasks/main.yml | 32 +++++++++++++++++++++++ roles/dtc/common/tasks/sub_main_vxlan.yml | 1 + roles/dtc/create/tasks/main.yml | 14 +++++----- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index bbb3cdff..c837b2ff 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -21,6 +21,38 @@ --- +# -------------------------------------------------------------------- +# Initialize NameSpace Dicts For Variable Sharing +# -------------------------------------------------------------------- +- name: Initialize NameSpace Dict For Sharing Variables + ansible.builtin.set_fact: + vars_common_vxlan: + changes_detected_fabric: false + changes_detected_fabric_links: false + changes_detected_interface_access_po: false + changes_detected_interface_access: false + changes_detected_interfaces: false + changes_detected_interface_loopback: false + changes_detected_interface_po_routed: false + changes_detected_interface_routed: false + changes_detected_interface_trunk_po: false + changes_detected_interface_trunk: false + changes_detected_interface_vpc: false + changes_detected_inventory: false + changes_detected_link_vpc_peering: false + changes_detected_networks: false + changes_detected_policy: false + changes_detected_sub_interface_routed: false + changes_detected_vpc_peering: false + changes_detected_vrfs: false + vars_common_isn: + changes_detected_fabric: false + changes_detected_inventory: false + vars_common_msd: + changes_detected_fabric: false + changes_detected_vrfs: false + changes_detected_networks: false + - name: Import Role Tasks for VXLAN Fabric ansible.builtin.import_tasks: sub_main_vxlan.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index b82b5621..5f2921ae 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -176,6 +176,7 @@ changes_detected_interface_trunk_po: "{{ changes_detected_interface_trunk_po }}" changes_detected_interface_trunk: "{{ changes_detected_interface_trunk }}" changes_detected_interface_vpc: "{{ changes_detected_interface_vpc }}" + changes_detected_inventory: "{{ changes_detected_inventory }}" changes_detected_link_vpc_peering: "{{ changes_detected_link_vpc_peering }}" changes_detected_networks: "{{ changes_detected_networks }}" changes_detected_policy: "{{ changes_detected_policy }}" diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index 05f98ba1..c12191db 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -50,13 +50,13 @@ (vars_common_msd.changes_detected_networks) # Check with Matt and Pete on External Fabrics -- name: Import Role Tasks External Fabric - ansible.builtin.import_tasks: sub_main_external.yml - when: > - (MD_Extended.vxlan.global.fabric_type == 'External') and - (changes_detected_inventory) or - (changes_detected_interfaces) or - (changes_detected_policy) +# - name: Import Role Tasks External Fabric +# ansible.builtin.import_tasks: sub_main_external.yml +# when: > +# (MD_Extended.vxlan.global.fabric_type == 'External') and +# (changes_detected_inventory) or +# (changes_detected_interfaces) or +# (changes_detected_policy) - name: Mark Stage Role Create Completed cisco.nac_dc_vxlan.common.run_map: From 6293b98a6746a96dcfd441568b2e9a8dbd940d6f Mon Sep 17 00:00:00 2001 From: Matt Thurston Date: Wed, 8 Jan 2025 17:05:19 +0000 Subject: [PATCH 36/66] refactored external network into new format --- plugins/action/common/nac_dc_validate.py | 4 ++- .../dtc/update_switch_hostname_policy.py | 2 +- roles/dtc/common/tasks/main.yml | 22 ++++++++++++++-- roles/dtc/common/tasks/sub_main_vxlan.yml | 5 ---- roles/dtc/common/templates/ndfc_fabric.j2 | 2 +- .../advanced/dc_external_fabric_advanced.j2 | 10 +++---- .../bootstrap/dc_external_fabric_bootstrap.j2 | 26 +++++++++---------- .../dc_external_fabric_flow_monitor.j2 | 16 ++++++------ .../general/dc_external_fabric_general.j2 | 2 +- roles/dtc/common/templates/ndfc_inventory.j2 | 5 ++++ roles/dtc/create/tasks/main.yml | 23 +++++++++++----- roles/dtc/create/tasks/sub_main_external.yml | 14 +++++----- 12 files changed, 80 insertions(+), 51 deletions(-) diff --git a/plugins/action/common/nac_dc_validate.py b/plugins/action/common/nac_dc_validate.py index 5b4271a3..712aff51 100644 --- a/plugins/action/common/nac_dc_validate.py +++ b/plugins/action/common/nac_dc_validate.py @@ -95,7 +95,7 @@ def run(self, tmp=None, task_vars=None): rules_list.append(f'{rules}vxlan/') elif results['data']['vxlan']['fabric']['type'] in ('MSD', 'MCF'): rules_list.append(f'{rules}multisite/') - elif results['data']['vxlan']['fabric']['type'] in ('ISN'): + elif results['data']['vxlan']['fabric']['type'] in ('ISN', 'External'): rules_list.append(f'{rules}isn/') else: results['failed'] = True @@ -119,6 +119,8 @@ def run(self, tmp=None, task_vars=None): rules_list.append(f'{rules}vxlan/') elif results['data']['vxlan']['global']['fabric_type'] in ('MSD', 'MCF'): rules_list.append(f'{rules}multisite/') + elif results['data']['vxlan']['global']['fabric_type'] in ('ISN', 'External'): + rules_list.append(f'{rules}isn/') else: results['failed'] = True results['msg'] = f"vxlan.fabric.type {results['data']['vxlan']['global']['fabric_type']} is not a supported fabric type." diff --git a/plugins/action/dtc/update_switch_hostname_policy.py b/plugins/action/dtc/update_switch_hostname_policy.py index 2b841e3b..ec8f2d4b 100644 --- a/plugins/action/dtc/update_switch_hostname_policy.py +++ b/plugins/action/dtc/update_switch_hostname_policy.py @@ -50,7 +50,7 @@ def run(self, tmp=None, task_vars=None): ) dm_switches = [] - if model_data["vxlan"]["fabric"]["type"] in ('VXLAN_EVPN'): + if model_data["vxlan"]["fabric"]["type"] in ('VXLAN_EVPN','External'): dm_switches = model_data["vxlan"]["topology"]["switches"] elif model_data["vxlan"]["fabric"]["type"] in ('ISN'): dm_switches = model_data["vxlan"]["multisite"]["isn"]["topology"]["switches"] diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index c837b2ff..0a21bd04 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -37,7 +37,6 @@ changes_detected_interface_routed: false changes_detected_interface_trunk_po: false changes_detected_interface_trunk: false - changes_detected_interface_vpc: false changes_detected_inventory: false changes_detected_link_vpc_peering: false changes_detected_networks: false @@ -52,6 +51,20 @@ changes_detected_fabric: false changes_detected_vrfs: false changes_detected_networks: false + vars_common_external: + changes_detected_inventory: false + changes_detected_fabric: false + changes_detected_interface_access_po: false + changes_detected_interface_access: false + changes_detected_interfaces: false + changes_detected_interface_loopback: false + changes_detected_interface_po_routed: false + changes_detected_interface_routed: false + changes_detected_interface_trunk_po: false + changes_detected_interface_trunk: false + changes_detected_interface_vpc: false + changes_detected_sub_interface_routed: false + changes_detected_policy: false - name: Import Role Tasks for VXLAN Fabric ansible.builtin.import_tasks: sub_main_vxlan.yml @@ -66,4 +79,9 @@ - name: Import Role Tasks for MSD Fabric ansible.builtin.import_tasks: sub_main_msd.yml tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml - when: MD_Extended.vxlan.fabric.type == 'MSD' \ No newline at end of file + when: MD_Extended.vxlan.fabric.type == 'MSD' + +- name: Import Role Tasks for MSD Fabric + ansible.builtin.import_tasks: sub_main_external.yml + tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml + when: MD_Extended.vxlan.fabric.type == 'External' \ No newline at end of file diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index 5f2921ae..d636ad9b 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -215,7 +215,6 @@ - "+ vPC Link Peer Changes Detected - [ {{ vars_common_vxlan.changes_detected_link_vpc_peering }} ]" - "+ vPC Peer Changes Detected - [ {{ vars_common_vxlan.changes_detected_vpc_peering }} ]" - "+ ----- Interfaces -----" - - "+ Interface vPC Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_vpc }} ]" - "+ Interface Access Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_access }} ]" - "+ Interface Access PO Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_access_po }} ]" - "+ Interface Loopback Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_loopback }} ]" @@ -226,11 +225,7 @@ - "+ Sub Interface Routed Changes Detected - [ {{ vars_common_vxlan.changes_detected_sub_interface_routed }} ]" - "+ ----- All Interfaces -----" - "+ All Interfaces Changes Detected - [ {{ vars_common_vxlan.changes_detected_interfaces }} ]" - - "+ ----- All Interfaces -----" - - "+ VRFs Changes Detected - [ {{ vars_common_vxlan.changes_detected_vrfs }} ]" - - "+ Networks Changes Detected - [ {{ vars_common_vxlan.changes_detected_networks }} ]" - "+ Policy Changes Detected - [ {{ vars_common_vxlan.changes_detected_policy }} ]" - - "+ Fabric Links Changes Detected - [ {{ vars_common_vxlan.changes_detected_fabric_links }} ]" - "+ ----- Run Map -----" - "+ Run Map Diff Run - [ {{ run_map_read_result.diff_run }} ]" - "+ Force Run Flag - [ {{ force_run_all }} ]" diff --git a/roles/dtc/common/templates/ndfc_fabric.j2 b/roles/dtc/common/templates/ndfc_fabric.j2 index 9dafcbf2..ff547678 100644 --- a/roles/dtc/common/templates/ndfc_fabric.j2 +++ b/roles/dtc/common/templates/ndfc_fabric.j2 @@ -19,7 +19,7 @@ {# Include NDFC ISN Base Template #} {% include '/ndfc_fabric/isn_fabric/isn_fabric_base.j2' %} -{% elif vxlan.fabric_type == 'External' %} +{% elif vxlan.fabric.type == 'External' %} {# Include NDFC External Fabric Base Template #} {% include '/ndfc_fabric/dc_external_fabric/dc_external_fabric_base.j2' %} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/advanced/dc_external_fabric_advanced.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/advanced/dc_external_fabric_advanced.j2 index c565b063..ea85c02d 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/advanced/dc_external_fabric_advanced.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/advanced/dc_external_fabric_advanced.j2 @@ -1,7 +1,7 @@ {# Auto-generated NDFC DC VXLAN EVPN Advanced config data structure for fabric {{ vxlan.fabric.name }} #} POWER_REDUNDANCY_MODE: ps-redundant - FEATURE_PTP: {{ global.ptp.ptp_enable | default(defaults.vxlan.global.ptp.ptp_enable) }} - PTP_DOMAIN_ID: {{ global.ptp.ptp_domain_id | default(defaults.vxlan.global.ptp.ptp_domain_id) }} - PTP_LB_ID: {{ global.ptp.ptp_lb_id | default(defaults.vxlan.global.ptp.ptp_lb_id) }} - ENABLE_NXAPI: {{ global.enable_nxapi | default(defaults.vxlan.global.enable_nxapi) }} - ENABLE_NXAPI_HTTP: {{ global.enable_nxapi_http | default(defaults.vxlan.global.enable_nxapi_http ) }} \ No newline at end of file + FEATURE_PTP: {{ vxlan.global.ptp.ptp_enable | default(defaults.vxlan.global.ptp.ptp_enable) }} + PTP_DOMAIN_ID: {{ vxlan.global.ptp.ptp_domain_id | default(defaults.vxlan.global.ptp.ptp_domain_id) }} + PTP_LB_ID: {{ vxlan.global.ptp.ptp_lb_id | default(defaults.vxlan.global.ptp.ptp_lb_id) }} + ENABLE_NXAPI: {{ vxlan.global.enable_nxapi | default(defaults.vxlan.global.enable_nxapi) }} + ENABLE_NXAPI_HTTP: {{ vxlan.global.enable_nxapi_http | default(defaults.vxlan.global.enable_nxapi_http ) }} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/bootstrap/dc_external_fabric_bootstrap.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/bootstrap/dc_external_fabric_bootstrap.j2 index 8ff02c27..cde31538 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/bootstrap/dc_external_fabric_bootstrap.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/bootstrap/dc_external_fabric_bootstrap.j2 @@ -1,17 +1,17 @@ {# Auto-generated NDFC DC VXLAN EVPN Bootstrap config data structure for fabric {{ vxlan.fabric.name }} #} -{% if global.bootstrap is defined %} -{% if global.bootstrap.enable_bootstrap is defined and global.bootstrap.enable_bootstrap %} - BOOTSTRAP_ENABLE: {{ global.bootstrap.enable_bootstrap }} - DHCP_ENABLE: {{ global.bootstrap.enable_local_dhcp_server }} - DHCP_IPV6_ENABLE: {{ global.bootstrap.dhcp_version }} - DHCP_START: {{ global.bootstrap.dhcp_v4.scope_start_address }} - DHCP_END: {{ global.bootstrap.dhcp_v4.scope_end_address }} - MGMT_GW: {{ global.bootstrap.dhcp_v4.switch_mgmt_default_gw }} - MGMT_PREFIX: {{ global.bootstrap.dhcp_v4.mgmt_prefix }} - BOOTSTRAP_MULTISUBNET: "{{ global.bootstrap.dhcp_v4.multi_subnet_scope }}" - DOMAIN_NAME: "{{ global.bootstrap.dhcp_v4.domain_name }}" +{% if vxlan.global.bootstrap is defined %} +{% if vxlan.global.bootstrap.enable_bootstrap is defined and vxlan.global.bootstrap.enable_bootstrap %} + BOOTSTRAP_ENABLE: {{ vxlan.global.bootstrap.enable_bootstrap }} + DHCP_ENABLE: {{ vxlan.global.bootstrap.enable_local_dhcp_server }} + DHCP_IPV6_ENABLE: {{ vxlan.global.bootstrap.dhcp_version }} + DHCP_START: {{ vxlan.global.bootstrap.dhcp_v4.scope_start_address }} + DHCP_END: {{ vxlan.global.bootstrap.dhcp_v4.scope_end_address }} + MGMT_GW: {{ vxlan.global.bootstrap.dhcp_v4.switch_mgmt_default_gw }} + MGMT_PREFIX: {{ vxlan.global.bootstrap.dhcp_v4.mgmt_prefix }} + BOOTSTRAP_MULTISUBNET: "{{ vxlan.global.bootstrap.dhcp_v4.multi_subnet_scope }}" + DOMAIN_NAME: "{{ vxlan.global.bootstrap.dhcp_v4.domain_name }}" {% endif %} -{% if global.bootstrap.enable_bootstrap is defined and not global.bootstrap.enable_bootstrap %} - BOOTSTRAP_ENABLE: {{ global.bootstrap.enable_bootstrap }} +{% if vxlan.global.bootstrap.enable_bootstrap is defined and not vxlan.global.bootstrap.enable_bootstrap %} + BOOTSTRAP_ENABLE: {{ vxlan.global.bootstrap.enable_bootstrap }} {% endif %} {% endif %} diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/flow_monitor/dc_external_fabric_flow_monitor.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/flow_monitor/dc_external_fabric_flow_monitor.j2 index 29bac8dd..765a5dc9 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/flow_monitor/dc_external_fabric_flow_monitor.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/flow_monitor/dc_external_fabric_flow_monitor.j2 @@ -1,26 +1,26 @@ {# Auto-generated NDFC DC VXLAN EVPN Flow Monitor config data structure for fabric {{ vxlan.fabric.name }} #} - ENABLE_NETFLOW: {{ global.netflow.enable | default(defaults.vxlan.global.netflow.enable) }} -{% if global.netflow.enable is defined and global.netflow.enable | bool or defaults.vxlan.global.netflow.enable | bool %} -{% if global.netflow.exporter is defined %} + ENABLE_NETFLOW: {{ vxlan.global.netflow.enable | default(defaults.vxlan.global.netflow.enable) }} +{% if vxlan.global.netflow.enable is defined and vxlan.global.netflow.enable | bool or defaults.vxlan.global.netflow.enable | bool %} +{% if vxlan.global.netflow.exporter is defined %} {% set exporter_dict = dict() %} {% set _ = exporter_dict.update({ "NETFLOW_EXPORTER_LIST":[] }) %} -{% for e in global.netflow.exporter %} +{% for e in vxlan.global.netflow.exporter %} {% set _ = exporter_dict["NETFLOW_EXPORTER_LIST"].append(dict(EXPORTER_NAME=e.name,IP=e.ip_address,VRF=e.vrf | default(""), SRC_IF_NAME=e.source_interface,UDP_PORT=e.udp_port)) %} {% endfor %} NETFLOW_EXPORTER_LIST: "{{ exporter_dict | tojson | replace('"', '\\"') }}" {% endif %} -{% if global.netflow.record is defined %} +{% if vxlan.global.netflow.record is defined %} {% set record_dict = dict() %} {% set _ = record_dict.update({ "NETFLOW_RECORD_LIST":[] }) %} -{% for r in global.netflow.record %} +{% for r in vxlan.global.netflow.record %} {% set _ = record_dict["NETFLOW_RECORD_LIST"].append(dict(RECORD_NAME=r.name,RECORD_TEMPLATE =r.template,LAYER2_RECORD=r.layer2 | default(false) | string | lower)) %} {% endfor %} NETFLOW_RECORD_LIST: "{{ record_dict | tojson | replace('"', '\\"') }}" {% endif %} -{% if global.netflow.monitor is defined %} +{% if vxlan.global.netflow.monitor is defined %} {% set monitor_dict = dict() %} {% set _ = monitor_dict.update({ "NETFLOW_MONITOR_LIST":[] }) %} -{% for m in global.netflow.monitor %} +{% for m in vxlan.global.netflow.monitor %} {% set _ = monitor_dict["NETFLOW_MONITOR_LIST"].append(dict(MONITOR_NAME=m.name,RECORD_NAME=m.record,EXPORTER1=m.exporter1,EXPORTER2=m.exporter2 | default(""))) %} {% endfor %} NETFLOW_MONITOR_LIST: "{{ monitor_dict | tojson | replace('"', '\\"') }}" diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/general/dc_external_fabric_general.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/general/dc_external_fabric_general.j2 index 8838f10c..80017a6d 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/general/dc_external_fabric_general.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_external_fabric/general/dc_external_fabric_general.j2 @@ -1,4 +1,4 @@ {# Auto-generated NDFC DC VXLAN EVPN General config data structure for fabric {{ vxlan.fabric.name }} #} - BGP_AS: {{ global.bgp_asn }} + BGP_AS: {{ vxlan.global.bgp_asn }} {# #} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory.j2 index 9bae159b..209148ae 100644 --- a/roles/dtc/common/templates/ndfc_inventory.j2 +++ b/roles/dtc/common/templates/ndfc_inventory.j2 @@ -13,5 +13,10 @@ {# Include NDFC ISN Base Template #} {% include '/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2' %} +{% elif vxlan.fabric.type == 'External' %} + +{# Include NDFC DC External Template #} +{% include '/ndfc_inventory/dc_external_fabric/dc_external_fabric_inventory.j2' %} + {# Supported fabric types are: DC VXLAN EVPN and ISN #} {% endif %} \ No newline at end of file diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index c12191db..c3eb2feb 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -50,13 +50,22 @@ (vars_common_msd.changes_detected_networks) # Check with Matt and Pete on External Fabrics -# - name: Import Role Tasks External Fabric -# ansible.builtin.import_tasks: sub_main_external.yml -# when: > -# (MD_Extended.vxlan.global.fabric_type == 'External') and -# (changes_detected_inventory) or -# (changes_detected_interfaces) or -# (changes_detected_policy) +- name: Import Role Tasks External Fabric + ansible.builtin.import_tasks: sub_main_external.yml + when: > + (MD_Extended.vxlan.global.fabric_type == 'External') and + (vars_common_external.changes_detected_inventory) or + (vars_common_external.changes_detected_interfaces) or + (vars_common_external.changes_detected_fabric) or + (vars_common_external.changes_detected_interface_access_po) or + (vars_common_external.changes_detected_interface_access) or + (vars_common_external.changes_detected_interface_loopback) or + (vars_common_external.changes_detected_interface_po_routed) or + (vars_common_external.changes_detected_interface_routed) or + (vars_common_external.changes_detected_interface_trunk_po) or + (vars_common_external.changes_detected_interface_trunk) or + (vars_common_external.changes_detected_sub_interface_routed) or + (vars_common_external.changes_detected_policy) - name: Mark Stage Role Create Completed cisco.nac_dc_vxlan.common.run_map: diff --git a/roles/dtc/create/tasks/sub_main_external.yml b/roles/dtc/create/tasks/sub_main_external.yml index 2b9a771b..9257eeac 100644 --- a/roles/dtc/create/tasks/sub_main_external.yml +++ b/roles/dtc/create/tasks/sub_main_external.yml @@ -36,26 +36,26 @@ ansible.builtin.import_tasks: external/fabric.yml when: - MD_Extended.vxlan.global is defined - - changes_detected_fabric + - vars_common_external.changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" - name: Manage NDFC Fabric Switches - ansible.builtin.import_tasks: vxlan/devices.yml + ansible.builtin.import_tasks: external/devices.yml when: - MD_Extended.vxlan.topology.switches | length > 0 - - changes_detected_inventory + - vars_common_external.changes_detected_inventory tags: "{{ nac_tags.create_switches }}" - name: Manage NDFC Fabric Interfaces - ansible.builtin.import_tasks: vxlan/interfaces.yml + ansible.builtin.import_tasks: external/interfaces.yml when: - (MD_Extended.vxlan.topology.interfaces.modes.all.count >0) and (MD_Extended.vxlan.topology.switches | length > 0) - - changes_detected_interfaces + - vars_common_external.changes_detected_interfaces tags: "{{ nac_tags.create_interfaces }}" - name: Manage NDFC Fabric Policies - ansible.builtin.import_tasks: vxlan/policies.yml + ansible.builtin.import_tasks: external/policies.yml when: - (MD_Extended.vxlan.policy is defined) and (MD_Extended.vxlan.policy.policies | length > 0) - - changes_detected_policy + - vars_common_external.changes_detected_policy tags: "{{ nac_tags.create_policy }}" From cffab6611cfa7dff287bfbd4b69909b305830f8b Mon Sep 17 00:00:00 2001 From: Matt Thurston Date: Thu, 9 Jan 2025 08:31:49 +0000 Subject: [PATCH 37/66] more refactoring for external fabrics --- .../dtc/common/tasks/external/ndfc_fabric.yml | 77 ++++++++++ .../tasks/external/ndfc_interface_access.yml | 83 ++++++++++ .../external/ndfc_interface_access_po.yml | 83 ++++++++++ .../tasks/external/ndfc_interface_all.yml | 83 ++++++++++ .../external/ndfc_interface_loopback.yml | 83 ++++++++++ .../external/ndfc_interface_po_routed.yml | 83 ++++++++++ .../tasks/external/ndfc_interface_routed.yml | 83 ++++++++++ .../tasks/external/ndfc_interface_trunk.yml | 83 ++++++++++ .../external/ndfc_interface_trunk_po.yml | 83 ++++++++++ .../tasks/external/ndfc_interface_vpc.yml | 83 ++++++++++ .../common/tasks/external/ndfc_inventory.yml | 105 +++++++++++++ .../dtc/common/tasks/external/ndfc_policy.yml | 78 ++++++++++ .../external/ndfc_sub_interface_routed.yml | 83 ++++++++++ roles/dtc/common/tasks/sub_main_external.yml | 142 ++++++++++++++++++ roles/dtc/common/tasks/sub_main_vxlan.yml | 5 + .../dc_external_fabric_inventory.j2 | 40 +++++ roles/dtc/create/tasks/external/devices.yml | 36 +++++ .../tasks/external/devices_discovery.yml | 60 ++++++++ .../dtc/create/tasks/external/interfaces.yml | 133 ++++++++++++++++ roles/dtc/create/tasks/external/policies.yml | 41 +++++ 20 files changed, 1547 insertions(+) create mode 100644 roles/dtc/common/tasks/external/ndfc_fabric.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_interface_access.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_interface_access_po.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_interface_all.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_interface_loopback.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_interface_po_routed.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_interface_routed.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_interface_trunk.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_interface_trunk_po.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_interface_vpc.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_inventory.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_policy.yml create mode 100644 roles/dtc/common/tasks/external/ndfc_sub_interface_routed.yml create mode 100644 roles/dtc/common/tasks/sub_main_external.yml create mode 100644 roles/dtc/common/templates/ndfc_inventory/dc_external_fabric/dc_external_fabric_inventory.j2 create mode 100644 roles/dtc/create/tasks/external/devices.yml create mode 100644 roles/dtc/create/tasks/external/devices_discovery.yml create mode 100644 roles/dtc/create/tasks/external/interfaces.yml create mode 100644 roles/dtc/create/tasks/external/policies.yml diff --git a/roles/dtc/common/tasks/external/ndfc_fabric.yml b/roles/dtc/common/tasks/external/ndfc_fabric.yml new file mode 100644 index 00000000..a6ed2eea --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_fabric.yml @@ -0,0 +1,77 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_fabric: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_fabric.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + # TODO: Add capability to overridde path variable above for CI/CD pipeline + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Fabric Creation Parameters From Template + ansible.builtin.template: + src: ndfc_fabric.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- ansible.builtin.set_fact: + fabric_config: "{{ lookup('file', file_name) | from_yaml }}" + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_fabric: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/external/ndfc_interface_access.yml b/roles/dtc/common/tasks/external/ndfc_interface_access.yml new file mode 100644 index 00000000..ba50dea1 --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_interface_access.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_access: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_access.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interface_access.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set interface_access Var + ansible.builtin.set_fact: + interface_access: [] + delegate_to: localhost + +- name: Set interface_access Var + ansible.builtin.set_fact: + interface_access: "{{ lookup('file', file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_access: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_interface_access_po.yml b/roles/dtc/common/tasks/external/ndfc_interface_access_po.yml new file mode 100644 index 00000000..2e5b2b6f --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_interface_access_po.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_access_po: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_access_po.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interface_access_po.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set interface_access_po Var + ansible.builtin.set_fact: + interface_access_po: [] + delegate_to: localhost + +- name: Set interface_access_po Var + ansible.builtin.set_fact: + interface_access_po: "{{ lookup('file', file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_access_po: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_interface_all.yml b/roles/dtc/common/tasks/external/ndfc_interface_all.yml new file mode 100644 index 00000000..ff904775 --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_interface_all.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interfaces: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_all.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Set interface_all Var + ansible.builtin.set_fact: + interface_all: [] + delegate_to: localhost + +- name: Set interface_all Var + ansible.builtin.set_fact: + interface_all: "{{ interface_access + interface_access_po + interface_trunk + interface_trunk_po + interface_routed + interface_po_routed + sub_interface_routed + interface_vpc + int_loopback_config }}" + when: MD_Extended.vxlan.topology.interfaces.modes.all.count > 0 + delegate_to: localhost + +- name: Save interface_all + ansible.builtin.copy: + content: "{{ interface_all | to_nice_yaml }}" + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interfaces: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/external/ndfc_interface_loopback.yml b/roles/dtc/common/tasks/external/ndfc_interface_loopback.yml new file mode 100644 index 00000000..d720d5f6 --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_interface_loopback.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_loopback: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_loopback_interfaces.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Loopback Interfaces List From Template + ansible.builtin.template: + src: ndfc_loopback_interfaces.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set int_loopback_config Var + ansible.builtin.set_fact: + int_loopback_config: [] + delegate_to: localhost + +- name: Set int_loopback_config Var + ansible.builtin.set_fact: + int_loopback_config: "{{ lookup('file', file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_loopback: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_interface_po_routed.yml b/roles/dtc/common/tasks/external/ndfc_interface_po_routed.yml new file mode 100644 index 00000000..7fb2af33 --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_interface_po_routed.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_po_routed: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_po_routed.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface Po + ansible.builtin.template: + src: ndfc_interface_po_routed.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set interface_po_routed Var default + ansible.builtin.set_fact: + interface_po_routed: [] + delegate_to: localhost + +- name: Set interface_po_routed Var + ansible.builtin.set_fact: + interface_po_routed: "{{ lookup('file', file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_po_routed: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_interface_routed.yml b/roles/dtc/common/tasks/external/ndfc_interface_routed.yml new file mode 100644 index 00000000..4c2f9068 --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_interface_routed.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_routed: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_routed.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interface_routed.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set interface_routed Var default + ansible.builtin.set_fact: + interface_routed: [] + delegate_to: localhost + +- name: Set interface_routed Var + ansible.builtin.set_fact: + interface_routed: "{{ lookup('file', file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_routed: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_interface_trunk.yml b/roles/dtc/common/tasks/external/ndfc_interface_trunk.yml new file mode 100644 index 00000000..073f02ce --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_interface_trunk.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_trunk: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_trunk.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interface_trunk.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set interface_trunk Var + ansible.builtin.set_fact: + interface_trunk: [] + delegate_to: localhost + +- name: Set interface_trunk Var + ansible.builtin.set_fact: + interface_trunk: "{{ lookup('file', file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_trunk: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_interface_trunk_po.yml b/roles/dtc/common/tasks/external/ndfc_interface_trunk_po.yml new file mode 100644 index 00000000..b97086ac --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_interface_trunk_po.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_trunk_po: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_trunk_po.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interface_trunk_po.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set interface_trunk_po Var + ansible.builtin.set_fact: + interface_trunk_po: [] + delegate_to: localhost + +- name: Set interface_trunk_po Var + ansible.builtin.set_fact: + interface_trunk_po: "{{ lookup('file', file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_trunk_po: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_interface_vpc.yml b/roles/dtc/common/tasks/external/ndfc_interface_vpc.yml new file mode 100644 index 00000000..5554d65d --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_interface_vpc.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_vpc: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_vpc.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build VPC interface + ansible.builtin.template: + src: ndfc_interface_vpc.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set interface_vpc Var default + ansible.builtin.set_fact: + interface_vpc: [] + delegate_to: localhost + +- name: Set interface_vpc Var + ansible.builtin.set_fact: + interface_vpc: "{{ lookup('file', file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access_vpc.count > 0 or MD_Extended.vxlan.topology.interfaces.modes.trunk_vpc.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_vpc: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_inventory.yml b/roles/dtc/common/tasks/external/ndfc_inventory.yml new file mode 100644 index 00000000..db6667a4 --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_inventory.yml @@ -0,0 +1,105 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Get POAP Data From POAP Enabled Devices + cisco.nac_dc_vxlan.dtc.get_poap_data: + model_data: "{{ MD_Extended }}" + register: poap_data + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_inventory: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_inventory.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Set Path For Inventory File Lookup + ansible.builtin.set_fact: + inv_file_path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Build Fabric Switch Inventory List From Template + ansible.builtin.template: + src: ndfc_inventory.j2 + dest: "{{ inv_file_path }}" + delegate_to: localhost + +- name: Create Empty inv_config Var + ansible.builtin.set_fact: + inv_config: [] + delegate_to: localhost + +- name: Set inv_config Var + ansible.builtin.set_fact: + inv_config: "{{ lookup('file', file_name) | from_yaml }}" + when: (MD_Extended.vxlan.topology.switches | default([])) | length > 0 + delegate_to: localhost + +- name: Retrieve NDFC Device Username and Password from Group Vars and update inv_config + cisco.nac_dc_vxlan.common.get_credentials: + inv_list: "{{ inv_config }}" + register: updated_inv_config + no_log: true + +- name: Credential Retrieval Failed + ansible.builtin.fail: + msg: "{{ updated_inv_config }}" + when: updated_inv_config['retrieve_failed'] + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_inventory: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_policy.yml b/roles/dtc/common/tasks/external/ndfc_policy.yml new file mode 100644 index 00000000..1203bb7b --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_policy.yml @@ -0,0 +1,78 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_policy: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_policy.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + # TODO: Add capability to overridde path variable above for CI/CD pipeline + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Policy List From Template + ansible.builtin.template: + src: ndfc_policy.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- ansible.builtin.set_fact: + policy_config: "{{ lookup('file', file_name) | from_yaml }}" + when: (MD_Extended.vxlan.policy.policies | default([])) | length > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_policy: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_sub_interface_routed.yml b/roles/dtc/common/tasks/external/ndfc_sub_interface_routed.yml new file mode 100644 index 00000000..9677853e --- /dev/null +++ b/roles/dtc/common/tasks/external/ndfc_sub_interface_routed.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_sub_interface_routed: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_sub_interface_routed.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ role_path }}/files/{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ role_path }}/files/{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build sub_interface + ansible.builtin.template: + src: ndfc_sub_interface_routed.j2 + dest: "{{ role_path }}/files/{{ file_name }}" + delegate_to: localhost + +- name: Set sub_interface_routed Var default + ansible.builtin.set_fact: + sub_interface_routed: [] + delegate_to: localhost + +- name: Set sub_interface_routed Var + ansible.builtin.set_fact: + sub_interface_routed: "{{ lookup('file', file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" + file_name_current: "{{ role_path }}/files/{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_sub_interface_routed: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/sub_main_external.yml b/roles/dtc/common/tasks/sub_main_external.yml new file mode 100644 index 00000000..fa81ecc1 --- /dev/null +++ b/roles/dtc/common/tasks/sub_main_external.yml @@ -0,0 +1,142 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- ansible.builtin.fail: msg="Service Model Not Defined. Role cisco.nac_dc_vxlan.validate Must Be Called First" + when: MD is undefined + delegate_to: localhost + +# -------------------------------------------------------------------- +# Remove all files from the previous run if run_map requires it +# -------------------------------------------------------------------- +- name: Cleanup Files from Previous Run if run_map requires it + ansible.builtin.import_tasks: cleanup_files.yml + when: + - not run_map_read_result.diff_run or ((force_run_all is defined) and (force_run_all is true|bool)) + +# -------------------------------------------------------------------- +# Build Create Fabric Parameter List From Template +# -------------------------------------------------------------------- + +- name: Build Fabric Create Parameters + ansible.builtin.import_tasks: external/ndfc_fabric.yml + +# -------------------------------------------------------------------- +# Build NDFC Fabric Switch Inventory List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Switch Inventory List From Template + ansible.builtin.import_tasks: external/ndfc_inventory.yml + +- name: Build NDFC Interface Access Po List From Template + ansible.builtin.import_tasks: external/ndfc_interface_access_po.yml + +- name: Build NDFC Interface Access List From Template + ansible.builtin.import_tasks: external/ndfc_interface_access.yml + +- name: Build NDFC Interface Loopback List From Template + ansible.builtin.import_tasks: external/ndfc_interface_loopback.yml + +- name: Build NDFC Interface Po Routed List From Template + ansible.builtin.import_tasks: external/ndfc_interface_po_routed.yml + +- name: Build NDFC Interface Routed List From Template + ansible.builtin.import_tasks: external/ndfc_interface_routed.yml + +- name: Build NDFC Interface Trunk Po List From Template + ansible.builtin.import_tasks: external/ndfc_interface_trunk_po.yml + +- name: Build NDFC Interface Trunk List From Template + ansible.builtin.import_tasks: external/ndfc_interface_trunk.yml + +- name: Build NDFC Interface VPC List From Template + ansible.builtin.import_tasks: external/ndfc_interface_vpc.yml + +- name: Build NDFC Sub Interface Routed List From Template + ansible.builtin.import_tasks: external/ndfc_sub_interface_routed.yml + +- name: Build NDFC Interface all List From Template + ansible.builtin.import_tasks: external/ndfc_interface_all.yml + +- name: Build NDFC Policy List From Template + ansible.builtin.import_tasks: external/ndfc_policy.yml + + +# -------------------------------------------------------------------- +# Save Local Variables To NameSpace Dict For Use Elsewhere +# -------------------------------------------------------------------- +- name: Save Local Variables With Namespace Context + ansible.builtin.set_fact: + vars_common_external: + changes_detected_fabric: "{{ changes_detected_fabric }}" + changes_detected_inventory: "{{ changes_detected_inventory }}" + changes_detected_interface_access_po: "{{ changes_detected_interface_access_po }}" + changes_detected_interface_access: "{{ changes_detected_interface_access }}" + changes_detected_interface_loopback: "{{ changes_detected_interface_loopback }}" + changes_detected_interface_po_routed: "{{ changes_detected_interface_po_routed }}" + changes_detected_interface_routed: "{{ changes_detected_interface_routed }}" + changes_detected_interface_trunk_po: "{{ changes_detected_interface_trunk_po }}" + changes_detected_interface_trunk: "{{ changes_detected_interface_trunk }}" + changes_detected_sub_interface_routed: "{{ changes_detected_sub_interface_routed }}" + changes_detected_interfaces: "{{ changes_detected_interfaces }}" + changes_detected_policy: "{{ changes_detected_policy }}" + fabric_config: "{{ fabric_config }}" + interface_access_po: "{{ interface_access_po }}" + interface_access: "{{ interface_access }}" + interface_all: "{{ interface_all }}" + int_loopback_config: "{{ int_loopback_config }}" + interface_po_routed: "{{ interface_po_routed }}" + interface_routed: "{{ interface_routed }}" + interface_trunk_po: "{{ interface_trunk_po }}" + interface_trunk: "{{ interface_trunk }}" + inv_config: "{{ inv_config }}" + poap_data: "{{ poap_data }}" + policy_config: "{{ policy_config }}" + sub_interface_routed: "{{ sub_interface_routed }}" + updated_inv_config: "{{ updated_inv_config }}" + +- name: Run Diff Flags + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Fabric Changes Detected - [ {{ vars_common_external.changes_detected_fabric }} ]" + - "+ Inventory Changes Detected - [ {{ vars_common_external.changes_detected_inventory }} ]" + - "+ ----- Interfaces -----" + - "+ Interface Access Changes Detected - [ {{ vars_common_external.changes_detected_interface_access }} ]" + - "+ Interface Access PO Changes Detected - [ {{ vars_common_external.changes_detected_interface_access_po }} ]" + - "+ Interface Loopback Changes Detected - [ {{ vars_common_external.changes_detected_interface_loopback }} ]" + - "+ Interface PO Routed Changes Detected - [ {{ vars_common_external.changes_detected_interface_po_routed }} ]" + - "+ Interface Routed Changes Detected - [ {{ vars_common_external.changes_detected_interface_routed }} ]" + - "+ Interface Trunk Changes Detected - [ {{ vars_common_external.changes_detected_interface_trunk }} ]" + - "+ Interface Trunk PO Changes Detected - [ {{ vars_common_external.changes_detected_interface_trunk_po }} ]" + - "+ Sub Interface Routed Changes Detected - [ {{ vars_common_external.changes_detected_sub_interface_routed }} ]" + - "+ ----- All Interfaces -----" + - "+ All Interfaces Changes Detected - [ {{ vars_common_external.changes_detected_interfaces }} ]" + - "+ ----- All Interfaces -----" + - "+ VRFs Changes Detected - [ {{ vars_common_external.changes_detected_vrfs }} ]" + - "+ Networks Changes Detected - [ {{ vars_common_external.changes_detected_networks }} ]" + - "+ Policy Changes Detected - [ {{ vars_common_external.changes_detected_policy }} ]" + - "+ Fabric Links Changes Detected - [ {{ vars_common_external.changes_detected_fabric_links }} ]" + - "+ ----- Run Map -----" + - "+ Run Map Diff Run - [ {{ run_map_read_result.diff_run }} ]" + - "+ Force Run Flag - [ {{ force_run_all }} ]" + - "----------------------------------------------------------------" diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index d636ad9b..5f2921ae 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -215,6 +215,7 @@ - "+ vPC Link Peer Changes Detected - [ {{ vars_common_vxlan.changes_detected_link_vpc_peering }} ]" - "+ vPC Peer Changes Detected - [ {{ vars_common_vxlan.changes_detected_vpc_peering }} ]" - "+ ----- Interfaces -----" + - "+ Interface vPC Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_vpc }} ]" - "+ Interface Access Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_access }} ]" - "+ Interface Access PO Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_access_po }} ]" - "+ Interface Loopback Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_loopback }} ]" @@ -225,7 +226,11 @@ - "+ Sub Interface Routed Changes Detected - [ {{ vars_common_vxlan.changes_detected_sub_interface_routed }} ]" - "+ ----- All Interfaces -----" - "+ All Interfaces Changes Detected - [ {{ vars_common_vxlan.changes_detected_interfaces }} ]" + - "+ ----- All Interfaces -----" + - "+ VRFs Changes Detected - [ {{ vars_common_vxlan.changes_detected_vrfs }} ]" + - "+ Networks Changes Detected - [ {{ vars_common_vxlan.changes_detected_networks }} ]" - "+ Policy Changes Detected - [ {{ vars_common_vxlan.changes_detected_policy }} ]" + - "+ Fabric Links Changes Detected - [ {{ vars_common_vxlan.changes_detected_fabric_links }} ]" - "+ ----- Run Map -----" - "+ Run Map Diff Run - [ {{ run_map_read_result.diff_run }} ]" - "+ Force Run Flag - [ {{ force_run_all }} ]" diff --git a/roles/dtc/common/templates/ndfc_inventory/dc_external_fabric/dc_external_fabric_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory/dc_external_fabric/dc_external_fabric_inventory.j2 new file mode 100644 index 00000000..636e4534 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_inventory/dc_external_fabric/dc_external_fabric_inventory.j2 @@ -0,0 +1,40 @@ +{% set poap_data = poap_data['poap_data'] %} +{% for switch in MD_Extended.vxlan.topology.switches %} +{% if switch.management.management_ipv4_address is defined %} +- seed_ip: {{ switch['management']['management_ipv4_address'] }} +{% elif switch.management.management_ipv6_address is defined %} +- seed_ip: {{ switch['management']['management_ipv6_address'] }} +{% endif %} + auth_proto: {{ MD['vxlan']['global']['auth_proto'] | default(defaults.vxlan.global.auth_proto) }} + user_name: PLACE_HOLDER_USERNAME + password: PLACE_HOLDER_PASSWORD + max_hops: 0 # this is the default value as it is not defined into the data model + role: {{ switch['role'] }} + preserve_config: false +{% if MD_Extended.vxlan.global.bootstrap is defined %} +{% if MD_Extended.vxlan.global.bootstrap.enable_bootstrap is defined and MD_Extended.vxlan.global.bootstrap.enable_bootstrap %} +{% if switch.poap is defined and switch.poap.bootstrap %} +{% if poap_data[switch['serial_number']] is defined %} +{% set pdata = poap_data[switch['serial_number']] %} + poap: + - serial_number: {{ switch['serial_number'] }} + hostname: {{ switch['name'] }} + model: {{ pdata['model'] }} + version: {{ pdata['version'] }} + config_data: + modulesModel: {{ pdata['modulesModel'] }} + gateway: {{ pdata['gateway'] }} +{% elif switch['poap']['preprovision'] is defined %} + poap: + - preprovision_serial: {{ switch['poap']['preprovision']['serial_number'] }} + model: {{ switch['poap']['preprovision']['model'] }} + version: {{ switch['poap']['preprovision']['version'] }} + config_data: + modulesModel: {{ switch['poap']['preprovision']['modulesModel'] }} + gateway: {{ switch['management']['default_gateway_v4'] }} + hostname: {{ switch['name'] }} +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} diff --git a/roles/dtc/create/tasks/external/devices.yml b/roles/dtc/create/tasks/external/devices.yml new file mode 100644 index 00000000..352b2a88 --- /dev/null +++ b/roles/dtc/create/tasks/external/devices.yml @@ -0,0 +1,36 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Manage Devices Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Devices Fabric {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +- name: Manage Devices Discovery + ansible.builtin.import_tasks: devices_discovery.yml + +# TODO: Enable This Capability +# - name: Add Devices POAP +# ansible.builtin.import_tasks: devices_poap.yml diff --git a/roles/dtc/create/tasks/external/devices_discovery.yml b/roles/dtc/create/tasks/external/devices_discovery.yml new file mode 100644 index 00000000..e606c63f --- /dev/null +++ b/roles/dtc/create/tasks/external/devices_discovery.yml @@ -0,0 +1,60 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Add NDFC Fabric Devices {{ MD_Extended.vxlan.fabric.name }} + cisco.dcnm.dcnm_inventory: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: "{{ vars_common_external.updated_inv_config['updated_inv_list'] }}" + deploy: false + save: true + state: merged + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: MD_Extended.vxlan.topology.switches | length > 0 + +- name: Create List of Switch Serial Numbers from Data Model + ansible.builtin.set_fact: + md_serial_numbers: "{{ MD_Extended.vxlan.topology.switches | map(attribute='serial_number') | list }}" + delegate_to: localhost + +- name: Build Switch Hostname Policy Payload from Data Model Update + cisco.nac_dc_vxlan.dtc.update_switch_hostname_policy: + model_data: "{{ MD_Extended }}" + switch_serial_numbers: "{{ md_serial_numbers }}" + template_name: host_11_1 + register: results +# do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest + +- name: Join List of Switch Hostname Policy IDs from NDFC + ansible.builtin.set_fact: + policy_ids: "{{ results.policy_update.values() | map(attribute='policyId') | list | join('%2C') }}" + when: results.policy_update | length > 0 + delegate_to: localhost + +- name: Update Switch Hostname Policy in NDFC + cisco.dcnm.dcnm_rest: + method: PUT + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/policies/{{ policy_ids }}/bulk" + json_data: "{{ results.policy_update.values() | list | to_json }}" + when: results.policy_update | length > 0 \ No newline at end of file diff --git a/roles/dtc/create/tasks/external/interfaces.yml b/roles/dtc/create/tasks/external/interfaces.yml new file mode 100644 index 00000000..9867e283 --- /dev/null +++ b/roles/dtc/create/tasks/external/interfaces.yml @@ -0,0 +1,133 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Manage Fabric Interfaces Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Fabric Interfaces {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +# -------------------------------------------------------------------- +# Manage Interface Access Portchannel Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Access Portchannel Interface + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_external.interface_access_po }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 + +# -------------------------------------------------------------------- +# Manage Interface Trunk Portchannel Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Trunk Portchannel Interface + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_external.interface_trunk_po }}" + when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 + +# -------------------------------------------------------------------- +# Manage Interface Routed Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Interface Routed + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_external.interface_routed }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 + +# -------------------------------------------------------------------- +# Manage Sub-interface Routed Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Sub-interface Routed + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_external.sub_interface_routed }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 + +# -------------------------------------------------------------------- +# Manage interface Port-Channel Routed Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Interface Port-Channel Routed + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_external.interface_po_routed }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 + +# -------------------------------------------------------------------- +# Manage interface Loopback Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage NDFC Fabric Loopback + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_external.int_loopback_config }}" + when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 + + # -------------------------------------------------------------------- +# Manage Interface Trunk Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Interface Trunk + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_external.interface_trunk }}" + when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 + +# -------------------------------------------------------------------- +# Manage Interface Access Routed Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Interface Access + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_external.interface_access }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 + +## Will discuss with team and switchover to the below code and remove the above code +# # -------------------------------------------------------------------- +# # Manage Interface All Configuration on NDFC +# # -------------------------------------------------------------------- + +# - name: Manage Interface All +# cisco.dcnm.dcnm_interface: +# fabric: "{{ MD_Extended.vxlan.fabric.name }}" +# state: replaced +# config: "{{ vars_common_vxlan.interface_all }}" +# vars: +# ansible_command_timeout: 3000 +# ansible_connect_timeout: 3000 +# when: MD_Extended.vxlan.topology.interfaces.modes.all.count > 0 +# delegate_to: localhost diff --git a/roles/dtc/create/tasks/external/policies.yml b/roles/dtc/create/tasks/external/policies.yml new file mode 100644 index 00000000..a2214d83 --- /dev/null +++ b/roles/dtc/create/tasks/external/policies.yml @@ -0,0 +1,41 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Manage Policies Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Policies Fabric {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +# -------------------------------------------------------------------- +# Manage VRF Configuration on NDFC +# -------------------------------------------------------------------- +- name: Manage NDFC Fabric Policies + cisco.dcnm.dcnm_policy: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + use_desc_as_key: true + config: "{{ vars_common_external.policy_config }}" + deploy: false + state: merged + register: manage_policies_result From e019b7490b3ce1b3c36bb63271dd0aa36fdc61f1 Mon Sep 17 00:00:00 2001 From: Matt Thurston Date: Thu, 9 Jan 2025 08:42:34 +0000 Subject: [PATCH 38/66] bug fix in sub_main_external in common --- roles/dtc/common/tasks/sub_main_external.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/roles/dtc/common/tasks/sub_main_external.yml b/roles/dtc/common/tasks/sub_main_external.yml index fa81ecc1..0e00ca53 100644 --- a/roles/dtc/common/tasks/sub_main_external.yml +++ b/roles/dtc/common/tasks/sub_main_external.yml @@ -132,10 +132,7 @@ - "+ ----- All Interfaces -----" - "+ All Interfaces Changes Detected - [ {{ vars_common_external.changes_detected_interfaces }} ]" - "+ ----- All Interfaces -----" - - "+ VRFs Changes Detected - [ {{ vars_common_external.changes_detected_vrfs }} ]" - - "+ Networks Changes Detected - [ {{ vars_common_external.changes_detected_networks }} ]" - "+ Policy Changes Detected - [ {{ vars_common_external.changes_detected_policy }} ]" - - "+ Fabric Links Changes Detected - [ {{ vars_common_external.changes_detected_fabric_links }} ]" - "+ ----- Run Map -----" - "+ Run Map Diff Run - [ {{ run_map_read_result.diff_run }} ]" - "+ Force Run Flag - [ {{ force_run_all }} ]" From c2a0c482656a846009fe7af44d780fa8f7e5f48d Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Fri, 10 Jan 2025 20:49:16 +0000 Subject: [PATCH 39/66] External plus refactoring --- .../common/prepare_plugins/prep_001_fabric.py | 6 + .../prepare_plugins/prep_002_list_defaults.py | 273 ++++++++++-------- .../prep_103_topology_switches.py | 5 + .../prep_104_fabric_overlay.py | 18 +- .../prep_105_topology_interfaces.py | 5 + .../prep_106_topology_vpc_interfaces.py | 4 + .../prepare_plugins/prep_107_vrf_lites.py | 6 +- .../common/prepare_plugins/prep_999_verify.py | 28 +- plugins/action/dtc/get_poap_data.py | 4 + plugins/action/dtc/map_msd_inventory.py | 32 +- plugins/plugin_utils/data_model_keys.py | 80 ++--- roles/dtc/common/tasks/cleanup_files.yml | 12 +- .../dtc/common/tasks/external/ndfc_fabric.yml | 18 +- .../tasks/external/ndfc_interface_access.yml | 18 +- .../external/ndfc_interface_access_po.yml | 18 +- .../tasks/external/ndfc_interface_all.yml | 16 +- .../external/ndfc_interface_loopback.yml | 18 +- .../external/ndfc_interface_po_routed.yml | 18 +- .../tasks/external/ndfc_interface_routed.yml | 18 +- .../tasks/external/ndfc_interface_trunk.yml | 18 +- .../external/ndfc_interface_trunk_po.yml | 18 +- .../tasks/external/ndfc_interface_vpc.yml | 18 +- .../common/tasks/external/ndfc_inventory.yml | 18 +- .../dtc/common/tasks/external/ndfc_policy.yml | 18 +- .../external/ndfc_sub_interface_routed.yml | 18 +- roles/dtc/common/tasks/isn/ndfc_fabric.yml | 18 +- roles/dtc/common/tasks/isn/ndfc_inventory.yml | 18 +- roles/dtc/common/tasks/main.yml | 2 + roles/dtc/common/tasks/msd/ndfc_fabric.yml | 18 +- roles/dtc/common/tasks/msd/ndfc_networks.yml | 18 +- roles/dtc/common/tasks/msd/ndfc_vrfs.yml | 49 ++-- roles/dtc/common/tasks/sub_main_external.yml | 5 + roles/dtc/common/tasks/sub_main_isn.yml | 5 + roles/dtc/common/tasks/sub_main_msd.yml | 11 +- roles/dtc/common/tasks/sub_main_vxlan.yml | 5 + roles/dtc/common/tasks/vxlan/ndfc_fabric.yml | 18 +- .../common/tasks/vxlan/ndfc_fabric_links.yml | 18 +- .../tasks/vxlan/ndfc_interface_access.yml | 18 +- .../tasks/vxlan/ndfc_interface_access_po.yml | 18 +- .../common/tasks/vxlan/ndfc_interface_all.yml | 16 +- .../tasks/vxlan/ndfc_interface_loopback.yml | 18 +- .../tasks/vxlan/ndfc_interface_po_routed.yml | 18 +- .../tasks/vxlan/ndfc_interface_routed.yml | 18 +- .../tasks/vxlan/ndfc_interface_trunk.yml | 18 +- .../tasks/vxlan/ndfc_interface_trunk_po.yml | 18 +- .../common/tasks/vxlan/ndfc_interface_vpc.yml | 18 +- .../dtc/common/tasks/vxlan/ndfc_inventory.yml | 18 +- .../tasks/vxlan/ndfc_link_vpc_peering.yml | 18 +- .../dtc/common/tasks/vxlan/ndfc_networks.yml | 18 +- roles/dtc/common/tasks/vxlan/ndfc_policy.yml | 23 +- .../tasks/vxlan/ndfc_sub_interface_routed.yml | 18 +- .../common/tasks/vxlan/ndfc_vpc_peering.yml | 18 +- roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml | 24 +- roles/dtc/create/tasks/msd/vrfs_networks.yml | 20 +- 54 files changed, 669 insertions(+), 538 deletions(-) diff --git a/plugins/action/common/prepare_plugins/prep_001_fabric.py b/plugins/action/common/prepare_plugins/prep_001_fabric.py index 2e9742c1..847706fd 100644 --- a/plugins/action/common/prepare_plugins/prep_001_fabric.py +++ b/plugins/action/common/prepare_plugins/prep_001_fabric.py @@ -123,6 +123,7 @@ def prepare(self): # For backwards compatibility, replace 'overlay_services' key with 'overlay' # NOTE: No prepare plugin, jinja2 template or ansible task should reference 'overlay_services' after this replacement. # NOTE: Rules are different since rules run BEFORE prepare plugins + # import epdb ; epdb.set_trace() parent_keys = ['vxlan', 'overlay_services'] dm_check = data_model_key_check(model_data, parent_keys) if 'overlay_services' in dm_check['keys_found']: @@ -134,6 +135,11 @@ def prepare(self): model_data['vxlan']['overlay'] = model_data['vxlan']['overlay_services'] del model_data['vxlan']['overlay_services'] + parent_keys = ['vxlan', 'multisite', 'overlay'] + dm_check = data_model_key_check(model_data, parent_keys) + if 'multisite' in dm_check['keys_found'] and 'overlay' in dm_check['keys_found']: + model_data['vxlan']['overlay'] = model_data['vxlan']['multisite']['overlay'] + self.kwargs['results']['model_extended'] = model_data return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py index 6d8280ad..6a2d2d38 100644 --- a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py @@ -22,11 +22,48 @@ from ansible.utils.display import Display from ....plugin_utils.helper_functions import data_model_key_check from ....plugin_utils.data_model_keys import model_keys +from functools import reduce +import operator display = Display() +def getFromDict(dataDict, mapList): + """ + # Summary + + Get subset of a nested Dict from a list of keys + + """ + return reduce(operator.getitem, mapList, dataDict) def update_nested_dict(nested_dict, keys, new_value): + """ + # Summary + + Update nested dictionary element value + + ## Raises + + None + + ## Parameters + + - nested_dict: Dictionary to be updated + - keys: A list of keys to access the value + - value: Update the key with this value + + ## Updates + + Updates nested_dict + + ## Usage + + ```python + + update_nested_dict(self.model_data, keys, []) + + ``` + """ if len(keys) == 1: nested_dict[keys[0]] = new_value else: @@ -41,12 +78,92 @@ def __init__(self, **kwargs): self.keys = [] def set_list_default(self, parent_keys, target_key): + """ + # Summary + + Defaults a target_key to be an empty list [] if the + target_key does not exist or does exist but there is no + data associated with the target_key. + + ## Raises + + None + + ## Parameters + + - parent_keys: A list of parent keys + - target_key: The key under the parent keys to access the list + + ## Updates + + Updates self.model_data + + ## Usage + + ```python + parent_keys = ['vxlan', 'global', 'dns_servers'] + target_key = 'dns_servers' + + self.set_list_default(parent_keys, target_key) + + ``` + """ keys = parent_keys + [target_key] dm_check = data_model_key_check(self.model_data, keys) if target_key in dm_check['keys_not_found'] or \ target_key in dm_check['keys_no_data']: update_nested_dict(self.model_data, keys, []) + def set_nested_list_default(self, model_data_subset, target_key): + """ + # Summary + + Update part of a model_data dictionary that has an arbitrary + list of items that needs to be set to empty list [] + + ## Raises + + None + + ## Parameters + + - model_data_subset: Model data subset entry point + - target_key: The target key for each list item under the entry point + + ## Updates + + Updates self.model_data + + ## Usage + + ```python + + model_data_subset = self.model_data['vxlan']['topology']['switches'] + target_key = 'freeforms' + + self.set_nested_list_default(model_data_subset, target_key) + + ``` + """ + list_index = 0 + for item in model_data_subset: + dm_check = data_model_key_check(item, [target_key]) + if target_key in dm_check['keys_not_found'] or \ + target_key in dm_check['keys_no_data']: + model_data_subset[list_index][target_key] = [] + + list_index += 1 + + # The code in this set_nested_list_default function effectively replaces this pattern: + # + # for switch in self.model_data['vxlan']['topology']['switches']: + # dm_check = data_model_key_check(switch, ['freeforms']) + # if 'freeforms' in dm_check['keys_not_found'] or \ + # 'freeforms' in dm_check['keys_no_data']: + # self.model_data['vxlan']['topology']['switches'][list_index]['freeforms'] = [] + + # list_index += 1 + # The prepare method is used to default each list or nested list # in the model data to an empty list if the key for the list does # not exist or data under they key does not exist. @@ -61,139 +178,43 @@ def prepare(self): # -------------------------------------------------------------------- from pprint import pprint - paths = [ - 'global.dns_servers', - 'global.ntp_servers', - 'global.syslog_servers', - 'global.spanning_tree', - 'global.spanning_tree.vlan_range', - 'global.spanning_tree.mst_instance_range', - 'global.netflow', - 'global.netflow.exporter', - 'global.netflow.record', - 'global.netflow.monitor', - 'underlay', - 'topology', - 'topology.edge_connections', - 'topology.fabric_links', - 'topology.switches', - 'topology.vpc_peers', - 'overlay', - 'overlay.vrfs', - 'overlay.vrf_attach_groups', - 'overlay.networks', - 'overlay.network_attach_groups', - 'multisite', - 'multisite.overlay', - 'multisite.overlay.vrfs', - 'multisite.overlay.vrf_attach_groups', - 'multisite.overlay.networks', - 'multisite.overlay.network_attach_groups', - 'policy', - 'policy.policies', - 'policy.groups', - 'policy.switches' - ] - for path in paths: + # type: enum('VXLAN_EVPN', 'MSD', 'MCF', 'ISN') + fabric_type = self.model_data['vxlan']['fabric']['type'] + + # for path in paths: + for path in model_keys[fabric_type]: # Get all but the last 2 elements of model_keys[path] - path_type = model_keys[path][-1] - parent_keys = model_keys[path][:-2] - target_key = model_keys[path][-2] + path_type = model_keys[fabric_type][path][-1] + parent_keys = model_keys[fabric_type][path][:-2] + target_key = model_keys[fabric_type][path][-2] if path_type == 'KEY': dm_check = data_model_key_check(self.model_data, parent_keys + [target_key]) if target_key in dm_check['keys_not_found'] or target_key in dm_check['keys_no_data']: update_nested_dict(self.model_data, parent_keys + [target_key], {}) if path_type == 'LIST': self.set_list_default(parent_keys, target_key) - - # -------------------------------------------------------------------- - # The following sections deal with more difficult nexted list - # structures where there is a list_index in the middle of the dict. - # There may be a way to reduce the amount of code but for now leaving - # it as is. - # -------------------------------------------------------------------- - - # -------------------------------------------------------------------- - # Fabric Topology Switches Freeforms List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.topology.switches[index].freeforms list elements - list_index = 0 - for switch in self.model_data['vxlan']['topology']['switches']: - dm_check = data_model_key_check(switch, ['freeforms']) - if 'freeforms' in dm_check['keys_not_found'] or \ - 'freeforms' in dm_check['keys_no_data']: - self.model_data['vxlan']['topology']['switches'][list_index]['freeforms'] = [] - - list_index += 1 - - # -------------------------------------------------------------------- - # Fabric Topology Switches Interfaces List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.topology.switches[index].interfaces list elements - list_index = 0 - for switch in self.model_data['vxlan']['topology']['switches']: - dm_check = data_model_key_check(switch, ['interfaces']) - if 'interfaces' in dm_check['keys_not_found'] or 'interfaces' in dm_check['keys_no_data']: - self.model_data['vxlan']['topology']['switches'][list_index]['interfaces'] = [] - - list_index += 1 - - # -------------------------------------------------------------------- - # Fabric Overlay vrf and network attach group List Defaults - # -------------------------------------------------------------------- - - # Check vxlan.overlay.vrf_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['overlay']['vrf_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay']['vrf_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # Check vxlan.overlay.network_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['overlay']['network_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['overlay']['network_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # Check vxlan.multisite.overlay.vrf_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['multisite']['overlay']['vrf_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # Check vxlan.multisite.overlay.network_attach_groups[index].switches list elements - list_index = 0 - for group in self.model_data['vxlan']['multisite']['overlay']['network_attach_groups']: - dm_check = data_model_key_check(group, ['switches']) - if 'switches' in dm_check['keys_not_found'] or \ - 'switches' in dm_check['keys_no_data']: - self.model_data['vxlan']['multisite']['overlay']['network_attach_groups'][list_index]['switches'] = [] - - list_index += 1 - - # Before returning check to see if global or underlay data is present and - # generate a warning if they are empty. There might actualy be data but - # one of the other model files might have a bug or everything except the - # top level vxlan key is commented out. - if not bool(self.model_data['vxlan']['underlay']): - msg = '((vxlan.underlay)) data is empty! Check your host_vars model data.' - display.warning(msg=msg, formatted=True) - if not bool(self.model_data['vxlan']['global']): - msg = '((vxlan.global)) data is empty! Check your host_vars model data.' - display.warning(msg=msg, formatted=True) + if path_type == 'LIST_INDEX': + # model_keys['VXLAN_EVPN']['topology.switches.freeform'] = [root_key, 'topology', 'switches', 'freeform', 'LIST_INDEX'] + model_data_subset = getFromDict(self.model_data, parent_keys) + target_key = target_key + self.set_nested_list_default(model_data_subset, target_key) + + + # Quick Sanity Check: + # + # For Fabric Type: VXLAN_EVPN or External + # * Check for existence of global or underlay data + # + # There might actualy be data but one of the other model files might + # have a bug or everything except the top level vxlan key is commented out. + if fabric_type in ['VXLAN_EVPN', 'External']: + fn = self.model_data['vxlan']['fabric']['name'] + if not bool(self.model_data['vxlan'].get('underlay')): + msg = "((vxlan.underlay)) data is empty! Check your host_vars model data for fabric {fn}." + display.warning(msg=msg, formatted=True) + if not bool(self.model_data['vxlan'].get('global')): + msg = "((vxlan.global)) data is empty! Check your host_vars model data for fabric {fn}." + display.warning(msg=msg, formatted=True) self.kwargs['results']['model_extended'] = self.model_data return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_103_topology_switches.py b/plugins/action/common/prepare_plugins/prep_103_topology_switches.py index 7f89b670..7b9cb176 100644 --- a/plugins/action/common/prepare_plugins/prep_103_topology_switches.py +++ b/plugins/action/common/prepare_plugins/prep_103_topology_switches.py @@ -29,6 +29,11 @@ def __init__(self, **kwargs): def prepare(self): model_data = self.kwargs['results']['model_extended'] + + # This plugin does not apply to the follwing fabric types + if model_data['vxlan']['fabric']['type'] in ['ISN', 'MSD', 'MCF']: + return self.kwargs['results'] + # Loop over all the roles in vxlan.topology.switches.role model_data['vxlan']['topology']['spine'] = {} model_data['vxlan']['topology']['leaf'] = {} diff --git a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py index 4e9f2697..412a8611 100644 --- a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py +++ b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py @@ -29,7 +29,12 @@ def __init__(self, **kwargs): def prepare(self): model_data = self.kwargs['results']['model_extended'] - switches = model_data['vxlan']['topology']['switches'] + + # We don't have switches for Multisite fabrics so need special handling + if model_data['vxlan']['fabric']['type'] in ('MSD', 'MCF', 'ISN'): + switches = [] + else: + switches = model_data['vxlan']['topology']['switches'] if model_data['vxlan']['fabric']['type'] in ('VXLAN_EVPN'): # Rebuild sm_data['vxlan']['overlay']['vrf_attach_groups'] into @@ -85,6 +90,7 @@ def prepare(self): # a structure that is easier to use. vrf_grp_name_list = [] model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'] = {} + model_data['vxlan']['multisite']['overlay']['vrf_attach_switches_list'] = [] for grp in model_data['vxlan']['multisite']['overlay']['vrf_attach_groups']: model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'][grp['name']] = [] vrf_grp_name_list.append(grp['name']) @@ -99,6 +105,11 @@ def prepare(self): elif found_switch.get('management').get('management_ipv6_address'): switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] + # Append switch to a flat list of switches for cross comparison later when we query the + # MSD fabric information. We need to stop execution if the list returned by the MSD query + # does not include one of these switches. + model_data['vxlan']['multisite']['overlay']['vrf_attach_switches_list'].append(switch['hostname']) + # Remove vrf_attach_group from vrf if the group_name is not defined for vrf in model_data['vxlan']['multisite']['overlay']['vrfs']: if 'vrf_attach_group' in vrf: @@ -109,6 +120,7 @@ def prepare(self): # a structure that is easier to use. net_grp_name_list = [] model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'] = {} + model_data['vxlan']['multisite']['overlay']['network_attach_switches_list'] = [] for grp in model_data['vxlan']['multisite']['overlay']['network_attach_groups']: model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'][grp['name']] = [] net_grp_name_list.append(grp['name']) @@ -122,6 +134,10 @@ def prepare(self): switch['mgmt_ip_address'] = found_switch['management']['management_ipv4_address'] elif found_switch.get('management').get('management_ipv6_address'): switch['mgmt_ip_address'] = found_switch['management']['management_ipv6_address'] + # Append switch to a flat list of switches for cross comparison later when we query the + # MSD fabric information. We need to stop execution if the list returned by the MSD query + # does not include one of these switches. + model_data['vxlan']['multisite']['overlay']['network_attach_switches_list'].append(switch['hostname']) # Remove network_attach_group from net if the group_name is not defined for net in model_data['vxlan']['multisite']['overlay']['networks']: diff --git a/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py b/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py index d4cffc4a..e391161c 100644 --- a/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py +++ b/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py @@ -34,6 +34,11 @@ def __init__(self, **kwargs): def prepare(self): model_data = self.kwargs['results']['model_extended'] + # This plugin does not apply to the follwing fabric types + if model_data['vxlan']['fabric']['type'] in ['ISN', 'MSD', 'MCF']: + return self.kwargs['results'] + + model_data['vxlan']['topology']['interfaces'] = {} model_data['vxlan']['topology']['interfaces']['modes'] = {} diff --git a/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py b/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py index ecd7b360..531bdf98 100644 --- a/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py +++ b/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py @@ -30,6 +30,10 @@ def __init__(self, **kwargs): def prepare(self): model_data = self.kwargs['results']['model_extended'] + + if model_data['vxlan']['fabric']['type'] == 'ISN': + return self.kwargs['results'] + # Check if vxlan.topology is defined if model_data.get('vxlan').get('topology') is not None: model_data['vxlan']['topology'] = model_data.get('vxlan').get('topology', {}) diff --git a/plugins/action/common/prepare_plugins/prep_107_vrf_lites.py b/plugins/action/common/prepare_plugins/prep_107_vrf_lites.py index bafb2ac9..5bd4e492 100644 --- a/plugins/action/common/prepare_plugins/prep_107_vrf_lites.py +++ b/plugins/action/common/prepare_plugins/prep_107_vrf_lites.py @@ -33,8 +33,12 @@ def __init__(self, **kwargs): self.keys = [] def prepare(self): - templates_path = self.kwargs['templates_path'] model_data = self.kwargs['results']['model_extended'] + + if model_data['vxlan']['fabric']['type'] == 'ISN': + return self.kwargs['results'] + + templates_path = self.kwargs['templates_path'] default_values = self.kwargs['default_values'] # Remove lines 41-43 after route control that includes route-maps, prefix-lists, etc is merged diff --git a/plugins/action/common/prepare_plugins/prep_999_verify.py b/plugins/action/common/prepare_plugins/prep_999_verify.py index 97e62a33..03724319 100644 --- a/plugins/action/common/prepare_plugins/prep_999_verify.py +++ b/plugins/action/common/prepare_plugins/prep_999_verify.py @@ -41,6 +41,10 @@ def prepare(self): fail_msg += " the data was not included in the data model." fail_msg += " Data Model Section: ({})" + # from pprint import pprint + # md = model_data + # pprint(md) + # This prepare plugin serves as a final sanity check after all of the # previous prepare plugins have been called to transform the model data. @@ -48,21 +52,19 @@ def prepare(self): # This plugin ensures the following: # * All keys required for this collection to function are present (not accidentally overwritten) # * List items that were present before the prepare plugins ran are still present - for key in model_keys.keys(): - dm_check = data_model_key_check(model_data, model_keys[key]) - # model_keys['policy.policies'] = [root_key, 'policy', 'policies', 'LIST'] - # Get 2nd to last item from the python list above - # model_keys[key][-2] - Gets 'policies' - if model_keys[key][-2] in dm_check['keys_not_found']: + fabric_type = model_data['vxlan']['fabric']['type'] + for key in model_keys[fabric_type].keys(): + # Remove the meta_data item from model_keys entry (KEY, LIST, LIST_INDEX) + model_keys[fabric_type][key].pop() + dm_check = data_model_key_check(model_data, model_keys[fabric_type][key]) + # Example: + # model_keys['VXLAN_EVPN']['policy.policies'] = [root_key, 'policy', 'policies', 'LIST'] + # * Get 2nd to last item from the python list above + # * model_keys[key][-2] - Gets 'policies' + if model_keys[fabric_type][key][-2] in dm_check['keys_not_found']: self.kwargs['results']['failed'] = True - self.kwargs['results']['msg'] = fail_msg.format(key, model_keys[key]) + self.kwargs['results']['msg'] = fail_msg.format(key, model_keys[fabric_type][key]) return self.kwargs['results'] - - - # from pprint import pprint - # md = model_data - # import epdb ; epdb.set_trace() - # pprint(md) # We don't need to pass any data back in this plugin because we don't modify any data. return self.kwargs['results'] diff --git a/plugins/action/dtc/get_poap_data.py b/plugins/action/dtc/get_poap_data.py index 4600b871..9042247d 100644 --- a/plugins/action/dtc/get_poap_data.py +++ b/plugins/action/dtc/get_poap_data.py @@ -173,6 +173,10 @@ def run(self, tmp=None, task_vars=None): # Get data from Ansible task parameters params = {} params['model_data'] = self._task.args["model_data"] + + if params['model_data']['vxlan']['fabric']['type'] == 'ISN': + return results + params['action_plugin'] = self._execute_module params['task_vars'] = task_vars params['tmp'] = tmp diff --git a/plugins/action/dtc/map_msd_inventory.py b/plugins/action/dtc/map_msd_inventory.py index 0b421194..fa6da96e 100644 --- a/plugins/action/dtc/map_msd_inventory.py +++ b/plugins/action/dtc/map_msd_inventory.py @@ -37,6 +37,7 @@ def run(self, tmp=None, task_vars=None): results['failed'] = False parent_fabric_name = self._task.args['parent_fabric_name'] + model_data_overlay = self._task.args['model_data_overlay'] msd_inventory = self._execute_module( module_name="cisco.dcnm.dcnm_inventory", @@ -48,11 +49,36 @@ def run(self, tmp=None, task_vars=None): tmp=tmp ) + response = msd_inventory.get('response', []) msd_switches = {} - for switch in msd_inventory.get('response', []): + + if isinstance(response, str): + if response == 'The queried switch is not part of the fabric configured': + results['msd_switches'] = msd_switches + return results + + for switch in response: msd_switches.update({switch['hostName']: switch['ipAddress']}) msd_switches.update({switch['ipAddress']: switch['ipAddress']}) - results['msd_switches'] = msd_switches + # Cross reference msd_switches with the switches defined in + # VRF and Network attach list. + # + # Only makes sense to check this if msd_switches actually has switches. + if bool(msd_switches): + results['msg'] = [] + for switch in model_data_overlay['vrf_attach_switches_list']: + if switch not in msd_switches.keys(): + results['failed'] = True + msg = f"Switch ({switch}) defined under vxlan.multisite.overlay.vrf_attach_groups" + msg += f" does not exist under this MSD fabric ({parent_fabric_name})" + results['msg'].append(msg) + for switch in model_data_overlay['network_attach_switches_list']: + if switch not in msd_switches.keys(): + results['failed'] = True + msg = f"Switch ({switch}) defined under vxlan.multisite.overlay.network_attach_groups" + msg += f" does not exist under this MSD fabric ({parent_fabric_name})" + results['msg'].append(msg) - return results + results['msd_switches'] = msd_switches + return results \ No newline at end of file diff --git a/plugins/plugin_utils/data_model_keys.py b/plugins/plugin_utils/data_model_keys.py index d10b6a41..04b53945 100644 --- a/plugins/plugin_utils/data_model_keys.py +++ b/plugins/plugin_utils/data_model_keys.py @@ -26,45 +26,55 @@ # from ..helper_functions import do_something root_key = 'vxlan' +# Keys here match data model schema +# type: enum('VXLAN_EVPN', 'MSD', 'MCF', 'ISN') +model_keys = {'VXLAN_EVPN': {}, 'MSD': {}, 'MCF': {}, 'ISN': {}} -model_keys = {} -model_keys['fabric.name'] = [root_key, 'fabric', 'name', 'KEY'] -model_keys['fabric.type'] = [root_key, 'fabric', 'type', 'KEY'] +# VXLAN_EVPN KEYS -model_keys['global'] = [root_key, 'global', 'KEY'] -model_keys['global.dns_servers'] = [root_key, 'global', 'dns_servers', 'LIST'] -model_keys['global.ntp_servers'] = [root_key, 'global', 'ntp_servers', 'LIST'] -model_keys['global.syslog_servers'] = [root_key, 'global', 'syslog_servers', 'LIST'] -model_keys['global.netflow'] = [root_key, 'global', 'netflow', 'KEY'] -model_keys['global.netflow.exporter'] = [root_key, 'global', 'netflow', 'exporter', 'LIST'] -model_keys['global.netflow.record'] = [root_key, 'global', 'netflow', 'record', 'LIST'] -model_keys['global.netflow.monitor'] = [root_key, 'global', 'netflow', 'monitor', 'LIST'] -model_keys['global.spanning_tree'] = [root_key, 'global', 'spanning_tree', 'KEY'] -model_keys['global.spanning_tree.vlan_range'] = [root_key, 'global', 'spanning_tree', 'vlan_range', 'LIST'] -model_keys['global.spanning_tree.mst_instance_range'] = [root_key, 'global', 'spanning_tree', 'mst_instance_range', 'LIST'] +model_keys['VXLAN_EVPN']['global'] = [root_key, 'global', 'KEY'] +model_keys['VXLAN_EVPN']['global.dns_servers'] = [root_key, 'global', 'dns_servers', 'LIST'] +model_keys['VXLAN_EVPN']['global.ntp_servers'] = [root_key, 'global', 'ntp_servers', 'LIST'] +model_keys['VXLAN_EVPN']['global.syslog_servers'] = [root_key, 'global', 'syslog_servers', 'LIST'] +model_keys['VXLAN_EVPN']['global.netflow'] = [root_key, 'global', 'netflow', 'KEY'] +model_keys['VXLAN_EVPN']['global.netflow.exporter'] = [root_key, 'global', 'netflow', 'exporter', 'LIST'] +model_keys['VXLAN_EVPN']['global.netflow.record'] = [root_key, 'global', 'netflow', 'record', 'LIST'] +model_keys['VXLAN_EVPN']['global.netflow.monitor'] = [root_key, 'global', 'netflow', 'monitor', 'LIST'] +model_keys['VXLAN_EVPN']['global.spanning_tree'] = [root_key, 'global', 'spanning_tree', 'KEY'] +model_keys['VXLAN_EVPN']['global.spanning_tree.vlan_range'] = [root_key, 'global', 'spanning_tree', 'vlan_range', 'LIST'] +model_keys['VXLAN_EVPN']['global.spanning_tree.mst_instance_range'] = [root_key, 'global', 'spanning_tree', 'mst_instance_range', 'LIST'] # --- -model_keys['underlay'] = [root_key, 'underlay', 'KEY'] +model_keys['VXLAN_EVPN']['underlay'] = [root_key, 'underlay', 'KEY'] # --- -model_keys['topology'] = [root_key, 'topology', 'KEY'] -model_keys['topology.edge_connections'] = [root_key, 'topology', 'edge_connections', 'LIST'] -model_keys['topology.fabric_links'] = [root_key, 'topology', 'fabric_links', 'LIST'] -model_keys['topology.switches'] = [root_key, 'topology', 'switches', 'LIST'] -model_keys['topology.vpc_peers'] = [root_key, 'topology', 'vpc_peers', 'LIST'] +model_keys['VXLAN_EVPN']['topology'] = [root_key, 'topology', 'KEY'] +model_keys['VXLAN_EVPN']['topology.edge_connections'] = [root_key, 'topology', 'edge_connections', 'LIST'] +model_keys['VXLAN_EVPN']['topology.fabric_links'] = [root_key, 'topology', 'fabric_links', 'LIST'] +model_keys['VXLAN_EVPN']['topology.switches'] = [root_key, 'topology', 'switches', 'LIST'] +model_keys['VXLAN_EVPN']['topology.switches.freeform'] = [root_key, 'topology', 'switches', 'freeform', 'LIST_INDEX'] +model_keys['VXLAN_EVPN']['topology.switches.interfaces'] = [root_key, 'topology', 'switches', 'interfaces', 'LIST_INDEX'] +model_keys['VXLAN_EVPN']['topology.vpc_peers'] = [root_key, 'topology', 'vpc_peers', 'LIST'] # --- -model_keys['overlay'] = [root_key, 'overlay', 'KEY'] -model_keys['overlay.vrfs'] = [root_key, 'overlay', 'vrfs', 'LIST'] -model_keys['overlay.vrf_attach_groups'] = [root_key, 'overlay', 'vrf_attach_groups', 'LIST'] -model_keys['overlay.networks'] = [root_key, 'overlay', 'networks', 'LIST'] -model_keys['overlay.network_attach_groups'] = [root_key, 'overlay', 'network_attach_groups', 'LIST'] +model_keys['VXLAN_EVPN']['overlay'] = [root_key, 'overlay', 'KEY'] +model_keys['VXLAN_EVPN']['overlay.vrfs'] = [root_key, 'overlay', 'vrfs', 'LIST'] +model_keys['VXLAN_EVPN']['overlay.vrf_attach_groups'] = [root_key, 'overlay', 'vrf_attach_groups', 'LIST'] +model_keys['VXLAN_EVPN']['overlay.vrf_attach_groups.switches'] = [root_key, 'overlay', 'vrf_attach_groups', 'switches', 'LIST_INDEX'] +model_keys['VXLAN_EVPN']['overlay.networks'] = [root_key, 'overlay', 'networks', 'LIST'] +model_keys['VXLAN_EVPN']['overlay.network_attach_groups'] = [root_key, 'overlay', 'network_attach_groups', 'LIST'] +model_keys['VXLAN_EVPN']['overlay.network_attach_groups.switches'] = [root_key, 'overlay', 'network_attach_groups', 'switches', 'LIST_INDEX'] # --- -model_keys['multisite'] = [root_key, 'multisite', 'KEY'] -model_keys['multisite.overlay'] = [root_key, 'multisite', 'overlay', 'KEY'] -model_keys['multisite.overlay.vrfs'] = [root_key, 'multisite', 'overlay', 'vrfs', 'LIST'] -model_keys['multisite.overlay.vrf_attach_groups'] = [root_key, 'multisite', 'overlay', 'vrf_attach_groups', 'LIST'] -model_keys['multisite.overlay.networks'] = [root_key, 'multisite', 'overlay', 'networks', 'LIST'] -model_keys['multisite.overlay.network_attach_groups'] = [root_key, 'multisite', 'overlay', 'network_attach_groups', 'LIST'] +model_keys['VXLAN_EVPN']['policy'] = [root_key, 'policy', 'KEY'] +model_keys['VXLAN_EVPN']['policy.policies'] = [root_key, 'policy', 'policies', 'LIST'] +model_keys['VXLAN_EVPN']['policy.groups'] = [root_key, 'policy', 'groups', 'LIST'] +model_keys['VXLAN_EVPN']['policy.switches'] = [root_key, 'policy', 'switches', 'LIST'] + +# MSD KEYS + # --- -model_keys['policy'] = [root_key, 'policy', 'KEY'] -model_keys['policy.policies'] = [root_key, 'policy', 'policies', 'LIST'] -model_keys['policy.groups'] = [root_key, 'policy', 'groups', 'LIST'] -model_keys['policy.switches'] = [root_key, 'policy', 'switches', 'LIST'] +model_keys['MSD']['multisite'] = [root_key, 'multisite', 'KEY'] +model_keys['MSD']['multisite.overlay'] = [root_key, 'multisite', 'overlay', 'KEY'] +model_keys['MSD']['multisite.overlay.vrfs'] = [root_key, 'multisite', 'overlay', 'vrfs', 'LIST'] +model_keys['MSD']['multisite.overlay.vrf_attach_groups'] = [root_key, 'multisite', 'overlay', 'vrf_attach_groups', 'LIST'] +model_keys['MSD']['multisite.overlay.vrf_attach_groups.switches'] = [root_key, 'multisite', 'overlay', 'vrf_attach_groups', 'switches', 'LIST_INDEX'] +model_keys['MSD']['multisite.overlay.networks'] = [root_key, 'multisite', 'overlay', 'networks', 'LIST'] +model_keys['MSD']['multisite.overlay.network_attach_groups'] = [root_key, 'multisite', 'overlay', 'network_attach_groups', 'LIST'] +model_keys['MSD']['multisite.overlay.network_attach_groups.switches'] = [root_key, 'multisite', 'overlay', 'network_attach_groups', 'switches', 'LIST_INDEX'] diff --git a/roles/dtc/common/tasks/cleanup_files.yml b/roles/dtc/common/tasks/cleanup_files.yml index 61356931..7c20ba89 100644 --- a/roles/dtc/common/tasks/cleanup_files.yml +++ b/roles/dtc/common/tasks/cleanup_files.yml @@ -3,18 +3,12 @@ - name: Delete content & directory ansible.builtin.file: state: absent - path: "{{ role_path }}/files/" + path: "{{ path_name }}" delegate_to: localhost - name: Recreate the directory ansible.builtin.file: - path: "{{ role_path }}/files/" + path: "{{ path_name }}" state: directory mode: '0755' - delegate_to: localhost - -- name: Add gitkeep file back to the directory - ansible.builtin.file: - path: "{{ role_path }}/files/.gitkeep" - state: touch - delegate_to: localhost + delegate_to: localhost \ No newline at end of file diff --git a/roles/dtc/common/tasks/external/ndfc_fabric.yml b/roles/dtc/common/tasks/external/ndfc_fabric.yml index a6ed2eea..02d383b8 100644 --- a/roles/dtc/common/tasks/external/ndfc_fabric.yml +++ b/roles/dtc/common/tasks/external/ndfc_fabric.yml @@ -28,43 +28,43 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_fabric.yml" + file_name: "ndfc_fabric.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost # TODO: Add capability to overridde path variable above for CI/CD pipeline - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Fabric Creation Parameters From Template ansible.builtin.template: src: ndfc_fabric.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - ansible.builtin.set_fact: - fabric_config: "{{ lookup('file', file_name) | from_yaml }}" + fabric_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_interface_access.yml b/roles/dtc/common/tasks/external/ndfc_interface_access.yml index ba50dea1..8b146321 100644 --- a/roles/dtc/common/tasks/external/ndfc_interface_access.yml +++ b/roles/dtc/common/tasks/external/ndfc_interface_access.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_access.yml" + file_name: "ndfc_interface_access.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_access.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_access Var @@ -63,14 +63,14 @@ - name: Set interface_access Var ansible.builtin.set_fact: - interface_access: "{{ lookup('file', file_name) | from_yaml }}" + interface_access: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_interface_access_po.yml b/roles/dtc/common/tasks/external/ndfc_interface_access_po.yml index 2e5b2b6f..702e4b44 100644 --- a/roles/dtc/common/tasks/external/ndfc_interface_access_po.yml +++ b/roles/dtc/common/tasks/external/ndfc_interface_access_po.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_access_po.yml" + file_name: "ndfc_interface_access_po.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_access_po.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_access_po Var @@ -63,14 +63,14 @@ - name: Set interface_access_po Var ansible.builtin.set_fact: - interface_access_po: "{{ lookup('file', file_name) | from_yaml }}" + interface_access_po: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_interface_all.yml b/roles/dtc/common/tasks/external/ndfc_interface_all.yml index ff904775..b4850efb 100644 --- a/roles/dtc/common/tasks/external/ndfc_interface_all.yml +++ b/roles/dtc/common/tasks/external/ndfc_interface_all.yml @@ -28,25 +28,25 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_all.yml" + file_name: "ndfc_interface_all.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists @@ -64,13 +64,13 @@ - name: Save interface_all ansible.builtin.copy: content: "{{ interface_all | to_nice_yaml }}" - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_interface_loopback.yml b/roles/dtc/common/tasks/external/ndfc_interface_loopback.yml index d720d5f6..0de48d66 100644 --- a/roles/dtc/common/tasks/external/ndfc_interface_loopback.yml +++ b/roles/dtc/common/tasks/external/ndfc_interface_loopback.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_loopback_interfaces.yml" + file_name: "ndfc_loopback_interfaces.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Loopback Interfaces List From Template ansible.builtin.template: src: ndfc_loopback_interfaces.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set int_loopback_config Var @@ -63,14 +63,14 @@ - name: Set int_loopback_config Var ansible.builtin.set_fact: - int_loopback_config: "{{ lookup('file', file_name) | from_yaml }}" + int_loopback_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_interface_po_routed.yml b/roles/dtc/common/tasks/external/ndfc_interface_po_routed.yml index 7fb2af33..5573b8c0 100644 --- a/roles/dtc/common/tasks/external/ndfc_interface_po_routed.yml +++ b/roles/dtc/common/tasks/external/ndfc_interface_po_routed.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_po_routed.yml" + file_name: "ndfc_interface_po_routed.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface Po ansible.builtin.template: src: ndfc_interface_po_routed.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_po_routed Var default @@ -63,14 +63,14 @@ - name: Set interface_po_routed Var ansible.builtin.set_fact: - interface_po_routed: "{{ lookup('file', file_name) | from_yaml }}" + interface_po_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_interface_routed.yml b/roles/dtc/common/tasks/external/ndfc_interface_routed.yml index 4c2f9068..14a6a992 100644 --- a/roles/dtc/common/tasks/external/ndfc_interface_routed.yml +++ b/roles/dtc/common/tasks/external/ndfc_interface_routed.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_routed.yml" + file_name: "ndfc_interface_routed.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_routed.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_routed Var default @@ -63,14 +63,14 @@ - name: Set interface_routed Var ansible.builtin.set_fact: - interface_routed: "{{ lookup('file', file_name) | from_yaml }}" + interface_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_interface_trunk.yml b/roles/dtc/common/tasks/external/ndfc_interface_trunk.yml index 073f02ce..5cb9a408 100644 --- a/roles/dtc/common/tasks/external/ndfc_interface_trunk.yml +++ b/roles/dtc/common/tasks/external/ndfc_interface_trunk.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_trunk.yml" + file_name: "ndfc_interface_trunk.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_trunk.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_trunk Var @@ -63,14 +63,14 @@ - name: Set interface_trunk Var ansible.builtin.set_fact: - interface_trunk: "{{ lookup('file', file_name) | from_yaml }}" + interface_trunk: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_interface_trunk_po.yml b/roles/dtc/common/tasks/external/ndfc_interface_trunk_po.yml index b97086ac..2e155dc7 100644 --- a/roles/dtc/common/tasks/external/ndfc_interface_trunk_po.yml +++ b/roles/dtc/common/tasks/external/ndfc_interface_trunk_po.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_trunk_po.yml" + file_name: "ndfc_interface_trunk_po.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_trunk_po.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_trunk_po Var @@ -63,14 +63,14 @@ - name: Set interface_trunk_po Var ansible.builtin.set_fact: - interface_trunk_po: "{{ lookup('file', file_name) | from_yaml }}" + interface_trunk_po: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_interface_vpc.yml b/roles/dtc/common/tasks/external/ndfc_interface_vpc.yml index 5554d65d..d8c264f1 100644 --- a/roles/dtc/common/tasks/external/ndfc_interface_vpc.yml +++ b/roles/dtc/common/tasks/external/ndfc_interface_vpc.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_vpc.yml" + file_name: "ndfc_interface_vpc.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build VPC interface ansible.builtin.template: src: ndfc_interface_vpc.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_vpc Var default @@ -63,14 +63,14 @@ - name: Set interface_vpc Var ansible.builtin.set_fact: - interface_vpc: "{{ lookup('file', file_name) | from_yaml }}" + interface_vpc: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.access_vpc.count > 0 or MD_Extended.vxlan.topology.interfaces.modes.trunk_vpc.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_inventory.yml b/roles/dtc/common/tasks/external/ndfc_inventory.yml index db6667a4..c530ce8b 100644 --- a/roles/dtc/common/tasks/external/ndfc_inventory.yml +++ b/roles/dtc/common/tasks/external/ndfc_inventory.yml @@ -33,31 +33,31 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_inventory.yml" + file_name: "ndfc_inventory.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Set Path For Inventory File Lookup ansible.builtin.set_fact: - inv_file_path: "{{ role_path }}/files/{{ file_name }}" + inv_file_path: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Build Fabric Switch Inventory List From Template @@ -73,7 +73,7 @@ - name: Set inv_config Var ansible.builtin.set_fact: - inv_config: "{{ lookup('file', file_name) | from_yaml }}" + inv_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: (MD_Extended.vxlan.topology.switches | default([])) | length > 0 delegate_to: localhost @@ -91,8 +91,8 @@ - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_policy.yml b/roles/dtc/common/tasks/external/ndfc_policy.yml index 1203bb7b..54fb0d5c 100644 --- a/roles/dtc/common/tasks/external/ndfc_policy.yml +++ b/roles/dtc/common/tasks/external/ndfc_policy.yml @@ -28,44 +28,44 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_policy.yml" + file_name: "ndfc_policy.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost # TODO: Add capability to overridde path variable above for CI/CD pipeline - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Policy List From Template ansible.builtin.template: src: ndfc_policy.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - ansible.builtin.set_fact: - policy_config: "{{ lookup('file', file_name) | from_yaml }}" + policy_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: (MD_Extended.vxlan.policy.policies | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/external/ndfc_sub_interface_routed.yml b/roles/dtc/common/tasks/external/ndfc_sub_interface_routed.yml index 9677853e..5446268d 100644 --- a/roles/dtc/common/tasks/external/ndfc_sub_interface_routed.yml +++ b/roles/dtc/common/tasks/external/ndfc_sub_interface_routed.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_sub_interface_routed.yml" + file_name: "ndfc_sub_interface_routed.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build sub_interface ansible.builtin.template: src: ndfc_sub_interface_routed.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set sub_interface_routed Var default @@ -63,14 +63,14 @@ - name: Set sub_interface_routed Var ansible.builtin.set_fact: - sub_interface_routed: "{{ lookup('file', file_name) | from_yaml }}" + sub_interface_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/isn/ndfc_fabric.yml b/roles/dtc/common/tasks/isn/ndfc_fabric.yml index a6ed2eea..02d383b8 100644 --- a/roles/dtc/common/tasks/isn/ndfc_fabric.yml +++ b/roles/dtc/common/tasks/isn/ndfc_fabric.yml @@ -28,43 +28,43 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_fabric.yml" + file_name: "ndfc_fabric.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost # TODO: Add capability to overridde path variable above for CI/CD pipeline - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Fabric Creation Parameters From Template ansible.builtin.template: src: ndfc_fabric.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - ansible.builtin.set_fact: - fabric_config: "{{ lookup('file', file_name) | from_yaml }}" + fabric_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/isn/ndfc_inventory.yml b/roles/dtc/common/tasks/isn/ndfc_inventory.yml index bcaae060..c4d37aa6 100644 --- a/roles/dtc/common/tasks/isn/ndfc_inventory.yml +++ b/roles/dtc/common/tasks/isn/ndfc_inventory.yml @@ -33,31 +33,31 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_inventory.yml" + file_name: "ndfc_inventory.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Set Path For Inventory File Lookup ansible.builtin.set_fact: - inv_file_path: "{{ role_path }}/files/{{ file_name }}" + inv_file_path: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Build Fabric Switch Inventory List From Template @@ -73,7 +73,7 @@ - name: Set inv_config Var ansible.builtin.set_fact: - inv_config: "{{ lookup('file', file_name) | from_yaml }}" + inv_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: (MD_Extended.vxlan.multisite.isn.topology.switches | default([])) | length > 0 delegate_to: localhost @@ -91,8 +91,8 @@ - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index 0a21bd04..185c9eb3 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -65,6 +65,8 @@ changes_detected_interface_vpc: false changes_detected_sub_interface_routed: false changes_detected_policy: false + tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml + - name: Import Role Tasks for VXLAN Fabric ansible.builtin.import_tasks: sub_main_vxlan.yml diff --git a/roles/dtc/common/tasks/msd/ndfc_fabric.yml b/roles/dtc/common/tasks/msd/ndfc_fabric.yml index a6ed2eea..02d383b8 100644 --- a/roles/dtc/common/tasks/msd/ndfc_fabric.yml +++ b/roles/dtc/common/tasks/msd/ndfc_fabric.yml @@ -28,43 +28,43 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_fabric.yml" + file_name: "ndfc_fabric.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost # TODO: Add capability to overridde path variable above for CI/CD pipeline - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Fabric Creation Parameters From Template ansible.builtin.template: src: ndfc_fabric.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - ansible.builtin.set_fact: - fabric_config: "{{ lookup('file', file_name) | from_yaml }}" + fabric_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/msd/ndfc_networks.yml b/roles/dtc/common/tasks/msd/ndfc_networks.yml index 0f024b8f..905c88a2 100644 --- a/roles/dtc/common/tasks/msd/ndfc_networks.yml +++ b/roles/dtc/common/tasks/msd/ndfc_networks.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_attach_networks.yml" + file_name: "ndfc_attach_networks.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Networks Attach List From Template ansible.builtin.template: src: ndfc_attach_networks.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set net_config Var @@ -63,14 +63,14 @@ - name: Set net_config Var ansible.builtin.set_fact: - net_config: "{{ lookup('file', file_name) | from_yaml }}" + net_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: (MD_Extended.vxlan.multisite.overlay.networks | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/msd/ndfc_vrfs.yml b/roles/dtc/common/tasks/msd/ndfc_vrfs.yml index 9923d716..b8b489d9 100644 --- a/roles/dtc/common/tasks/msd/ndfc_vrfs.yml +++ b/roles/dtc/common/tasks/msd/ndfc_vrfs.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_attach_vrfs.yml" + file_name: "ndfc_attach_vrfs.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build VRFs Attach List From Template ansible.builtin.template: src: ndfc_attach_vrfs.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Create Empty vrf_config Var @@ -63,14 +63,14 @@ - name: Set vrf_config Var ansible.builtin.set_fact: - vrf_config: "{{ lookup('file', file_name) | from_yaml }}" + vrf_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: (MD_Extended.vxlan.multisite.overlay.vrfs | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost @@ -87,20 +87,21 @@ file_name: "{{ MD_Extended.vxlan.fabric.name }}_attach_vrfs_loopbacks.yml" delegate_to: localhost -- name: Build VRFs Attach List From Template for loopback - ansible.builtin.template: - src: ndfc_attach_vrfs_loopbacks.j2 - dest: "{{ role_path }}/files/{{ file_name }}" - delegate_to: localhost +# Check with Matt and Pete on how we want to handle VRF loopbacks for MSD +# - name: Build VRFs Attach List From Template for loopback +# ansible.builtin.template: +# src: ndfc_attach_vrfs_loopbacks.j2 +# dest: "{{ path_name }}{{ file_name }}" +# delegate_to: localhost -- name: Create Empty vrf_config Var - ansible.builtin.set_fact: - vrf_attach_config: [] - delegate_to: localhost +# - name: Create Empty vrf_config Var +# ansible.builtin.set_fact: +# vrf_attach_config: [] +# delegate_to: localhost -- name: Set vrf_config Var - ansible.builtin.set_fact: - vrf_attach_config: "{{ lookup('file', file_name) | from_yaml }}" - when: > - (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 - delegate_to: localhost \ No newline at end of file +# - name: Set vrf_config Var +# ansible.builtin.set_fact: +# vrf_attach_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" +# when: > +# (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 +# delegate_to: localhost \ No newline at end of file diff --git a/roles/dtc/common/tasks/sub_main_external.yml b/roles/dtc/common/tasks/sub_main_external.yml index 0e00ca53..1be6a5e6 100644 --- a/roles/dtc/common/tasks/sub_main_external.yml +++ b/roles/dtc/common/tasks/sub_main_external.yml @@ -28,6 +28,11 @@ # -------------------------------------------------------------------- # Remove all files from the previous run if run_map requires it # -------------------------------------------------------------------- +- name: Set path_name Var + ansible.builtin.set_fact: + path_name: "{{ role_path }}/files/external/{{ MD_Extended.vxlan.fabric.name }}/" + delegate_to: localhost + - name: Cleanup Files from Previous Run if run_map requires it ansible.builtin.import_tasks: cleanup_files.yml when: diff --git a/roles/dtc/common/tasks/sub_main_isn.yml b/roles/dtc/common/tasks/sub_main_isn.yml index b9b47486..f7e2c820 100644 --- a/roles/dtc/common/tasks/sub_main_isn.yml +++ b/roles/dtc/common/tasks/sub_main_isn.yml @@ -28,6 +28,11 @@ # -------------------------------------------------------------------- # Remove all files from the previous run if run_map requires it # -------------------------------------------------------------------- +- name: Set path_name Var + ansible.builtin.set_fact: + path_name: "{{ role_path }}/files/isn/{{ MD_Extended.vxlan.fabric.name }}/" + delegate_to: localhost + - name: Cleanup Files from Previous Run if run_map requires it ansible.builtin.import_tasks: cleanup_files.yml when: diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 3507c8b3..1499db16 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -28,6 +28,11 @@ # -------------------------------------------------------------------- # Remove all files from the previous run if run_map requires it # -------------------------------------------------------------------- +- name: Set path_name Var + ansible.builtin.set_fact: + path_name: "{{ role_path }}/files/msd/{{ MD_Extended.vxlan.fabric.name }}/" + delegate_to: localhost + - name: Cleanup Files from Previous Run if run_map requires it ansible.builtin.import_tasks: cleanup_files.yml when: @@ -50,12 +55,15 @@ - name: Get Switch Inventory from MSD Fabric cisco.nac_dc_vxlan.dtc.map_msd_inventory: parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" + model_data_overlay: "{{ MD_Extended.vxlan.multisite.overlay }}" register: msd_inventory - name: Set MSD Switches List ansible.builtin.set_fact: msd_switches: "{{ msd_inventory.msd_switches }}" +- debug: msg="{{ msd_switches }}" + # -------------------------------------------------------------------- # Build NDFC Fabric VRFs Attach List From Template # -------------------------------------------------------------------- @@ -82,7 +90,8 @@ fabric_config: "{{ fabric_config }}" net_config: "{{ net_config }}" vrf_config: "{{ vrf_config }}" - vrf_attach_config: "{{ vrf_attach_config }}" + # Check with Matt and Pete on how to handle this for MSD + # vrf_attach_config: "{{ vrf_attach_config }}" - name: Run Diff Flags ansible.builtin.debug: diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index 5f2921ae..1bc3e4ba 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -28,6 +28,11 @@ # -------------------------------------------------------------------- # Remove all files from the previous run if run_map requires it # -------------------------------------------------------------------- +- name: Set path_name Var + ansible.builtin.set_fact: + path_name: "{{ role_path }}/files/vxlan/{{ MD_Extended.vxlan.fabric.name }}/" + delegate_to: localhost + - name: Cleanup Files from Previous Run if run_map requires it ansible.builtin.import_tasks: cleanup_files.yml when: diff --git a/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml b/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml index a6ed2eea..02d383b8 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml @@ -28,43 +28,43 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_fabric.yml" + file_name: "ndfc_fabric.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost # TODO: Add capability to overridde path variable above for CI/CD pipeline - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Fabric Creation Parameters From Template ansible.builtin.template: src: ndfc_fabric.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - ansible.builtin.set_fact: - fabric_config: "{{ lookup('file', file_name) | from_yaml }}" + fabric_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_fabric_links.yml b/roles/dtc/common/tasks/vxlan/ndfc_fabric_links.yml index dcfabf80..6f7a762f 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_fabric_links.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_fabric_links.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_fabric_links.yml" + file_name: "ndfc_fabric_links.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Fabric Links ansible.builtin.template: src: ndfc_fabric_links.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set fabric_links Var default @@ -63,14 +63,14 @@ - name: Set fabric_links Var ansible.builtin.set_fact: - fabric_links: "{{ lookup('file', file_name) | from_yaml }}" + fabric_links: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.fabric_links | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml index ba50dea1..8b146321 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_access.yml" + file_name: "ndfc_interface_access.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_access.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_access Var @@ -63,14 +63,14 @@ - name: Set interface_access Var ansible.builtin.set_fact: - interface_access: "{{ lookup('file', file_name) | from_yaml }}" + interface_access: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml index 2e5b2b6f..702e4b44 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_access_po.yml" + file_name: "ndfc_interface_access_po.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_access_po.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_access_po Var @@ -63,14 +63,14 @@ - name: Set interface_access_po Var ansible.builtin.set_fact: - interface_access_po: "{{ lookup('file', file_name) | from_yaml }}" + interface_access_po: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml index ff904775..b4850efb 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml @@ -28,25 +28,25 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_all.yml" + file_name: "ndfc_interface_all.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists @@ -64,13 +64,13 @@ - name: Save interface_all ansible.builtin.copy: content: "{{ interface_all | to_nice_yaml }}" - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml index d720d5f6..0de48d66 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_loopback_interfaces.yml" + file_name: "ndfc_loopback_interfaces.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Loopback Interfaces List From Template ansible.builtin.template: src: ndfc_loopback_interfaces.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set int_loopback_config Var @@ -63,14 +63,14 @@ - name: Set int_loopback_config Var ansible.builtin.set_fact: - int_loopback_config: "{{ lookup('file', file_name) | from_yaml }}" + int_loopback_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml index 7fb2af33..5573b8c0 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_po_routed.yml" + file_name: "ndfc_interface_po_routed.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface Po ansible.builtin.template: src: ndfc_interface_po_routed.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_po_routed Var default @@ -63,14 +63,14 @@ - name: Set interface_po_routed Var ansible.builtin.set_fact: - interface_po_routed: "{{ lookup('file', file_name) | from_yaml }}" + interface_po_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml index 4c2f9068..14a6a992 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_routed.yml" + file_name: "ndfc_interface_routed.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_routed.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_routed Var default @@ -63,14 +63,14 @@ - name: Set interface_routed Var ansible.builtin.set_fact: - interface_routed: "{{ lookup('file', file_name) | from_yaml }}" + interface_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml index 073f02ce..5cb9a408 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_trunk.yml" + file_name: "ndfc_interface_trunk.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_trunk.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_trunk Var @@ -63,14 +63,14 @@ - name: Set interface_trunk Var ansible.builtin.set_fact: - interface_trunk: "{{ lookup('file', file_name) | from_yaml }}" + interface_trunk: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml index b97086ac..2e155dc7 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_trunk_po.yml" + file_name: "ndfc_interface_trunk_po.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Interface ansible.builtin.template: src: ndfc_interface_trunk_po.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_trunk_po Var @@ -63,14 +63,14 @@ - name: Set interface_trunk_po Var ansible.builtin.set_fact: - interface_trunk_po: "{{ lookup('file', file_name) | from_yaml }}" + interface_trunk_po: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml index 5554d65d..d8c264f1 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_interface_vpc.yml" + file_name: "ndfc_interface_vpc.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build VPC interface ansible.builtin.template: src: ndfc_interface_vpc.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set interface_vpc Var default @@ -63,14 +63,14 @@ - name: Set interface_vpc Var ansible.builtin.set_fact: - interface_vpc: "{{ lookup('file', file_name) | from_yaml }}" + interface_vpc: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.access_vpc.count > 0 or MD_Extended.vxlan.topology.interfaces.modes.trunk_vpc.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml b/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml index db6667a4..c530ce8b 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml @@ -33,31 +33,31 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_inventory.yml" + file_name: "ndfc_inventory.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Set Path For Inventory File Lookup ansible.builtin.set_fact: - inv_file_path: "{{ role_path }}/files/{{ file_name }}" + inv_file_path: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Build Fabric Switch Inventory List From Template @@ -73,7 +73,7 @@ - name: Set inv_config Var ansible.builtin.set_fact: - inv_config: "{{ lookup('file', file_name) | from_yaml }}" + inv_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: (MD_Extended.vxlan.topology.switches | default([])) | length > 0 delegate_to: localhost @@ -91,8 +91,8 @@ - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml b/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml index 1102baf1..7a70e982 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_link_vpc_peering.yml" + file_name: "ndfc_link_vpc_peering.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Links for VPC Peering ansible.builtin.template: src: ndfc_links_vpc_peering.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set link_vpc_peering Var default @@ -63,14 +63,14 @@ - name: Set link_vpc_peering Var ansible.builtin.set_fact: - link_vpc_peering: "{{ lookup('file', file_name) | from_yaml }}" + link_vpc_peering: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.vpc_peers | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_networks.yml b/roles/dtc/common/tasks/vxlan/ndfc_networks.yml index 797d1149..cec0f780 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_networks.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_networks.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_attach_networks.yml" + file_name: "ndfc_attach_networks.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Networks Attach List From Template ansible.builtin.template: src: ndfc_attach_networks.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set net_config Var @@ -63,15 +63,15 @@ - name: Set net_config Var ansible.builtin.set_fact: - net_config: "{{ lookup('file', file_name) | from_yaml }}" + net_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: > (MD_Extended.vxlan.overlay.networks | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_policy.yml b/roles/dtc/common/tasks/vxlan/ndfc_policy.yml index 1203bb7b..9f965bbe 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_policy.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_policy.yml @@ -28,44 +28,49 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_policy.yml" + file_name: "ndfc_policy.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost # TODO: Add capability to overridde path variable above for CI/CD pipeline - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build Policy List From Template ansible.builtin.template: src: ndfc_policy.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set policy_config Var + ansible.builtin.set_fact: + policy_config: [] delegate_to: localhost - ansible.builtin.set_fact: - policy_config: "{{ lookup('file', file_name) | from_yaml }}" + policy_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: (MD_Extended.vxlan.policy.policies | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml index 9677853e..5446268d 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_sub_interface_routed.yml" + file_name: "ndfc_sub_interface_routed.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build sub_interface ansible.builtin.template: src: ndfc_sub_interface_routed.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set sub_interface_routed Var default @@ -63,14 +63,14 @@ - name: Set sub_interface_routed Var ansible.builtin.set_fact: - sub_interface_routed: "{{ lookup('file', file_name) | from_yaml }}" + sub_interface_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml b/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml index 261d4899..08fa07fc 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_vpc_peering.yml" + file_name: "ndfc_vpc_peering.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous Data File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build vPC Peering ansible.builtin.template: src: ndfc_vpc_peering.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Set vpc_peering Var default @@ -63,14 +63,14 @@ - name: Set vpc_peering Var ansible.builtin.set_fact: - vpc_peering: "{{ lookup('file', file_name) | from_yaml }}" + vpc_peering: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.vpc_peers | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml index 30c72ff5..a7e492c9 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml @@ -28,32 +28,32 @@ - name: Set file_name Var ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_ndfc_attach_vrfs.yml" + file_name: "ndfc_attach_vrfs.yml" delegate_to: localhost - name: Stat Previous File If It Exists ansible.builtin.stat: - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" register: data_file_previous delegate_to: localhost - name: Backup Previous Data File If It Exists ansible.builtin.copy: - src: "{{ role_path }}/files/{{ file_name }}" - dest: "{{ role_path }}/files/{{ file_name }}.old" + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" when: data_file_previous.stat.exists - name: Delete Previous File If It Exists ansible.builtin.file: state: absent - path: "{{ role_path }}/files/{{ file_name }}" + path: "{{ path_name }}{{ file_name }}" delegate_to: localhost when: data_file_previous.stat.exists - name: Build VRFs Attach List From Template ansible.builtin.template: src: ndfc_attach_vrfs.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Create Empty vrf_config Var @@ -63,15 +63,15 @@ - name: Set vrf_config Var ansible.builtin.set_fact: - vrf_config: "{{ lookup('file', file_name) | from_yaml }}" + vrf_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: > (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 delegate_to: localhost - name: Diff Previous and Current Data Files cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ role_path }}/files/{{ file_name }}.old" - file_name_current: "{{ role_path }}/files/{{ file_name }}" + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" register: file_diff_result delegate_to: localhost @@ -85,13 +85,13 @@ - name: Set file_name Var for loopback attachments ansible.builtin.set_fact: - file_name: "{{ MD_Extended.vxlan.fabric.name }}_attach_vrfs_loopbacks.yml" + file_name: "attach_vrfs_loopbacks.yml" delegate_to: localhost - name: Build VRFs Attach List From Template for loopback ansible.builtin.template: src: ndfc_attach_vrfs_loopbacks.j2 - dest: "{{ role_path }}/files/{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost - name: Create Empty vrf_config Var @@ -101,7 +101,7 @@ - name: Set vrf_config Var ansible.builtin.set_fact: - vrf_attach_config: "{{ lookup('file', file_name) | from_yaml }}" + vrf_attach_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" when: > (MD_Extended.vxlan.overlay.vrfs | default([])) | length > 0 delegate_to: localhost \ 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 f67605ef..114c7c6c 100644 --- a/roles/dtc/create/tasks/msd/vrfs_networks.yml +++ b/roles/dtc/create/tasks/msd/vrfs_networks.yml @@ -45,15 +45,17 @@ # -------------------------------------------------------------------- # Manage Loopback VRF attachments on NDFC # -------------------------------------------------------------------- -- name: Attach VRF Loopbacks per VRF - cisco.dcnm.dcnm_rest: - path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/top-down/v2/fabrics/{{ MD_Extended.vxlan.fabric.name }}/vrfs/attachments" - method: "POST" - json_data: "{{ vars_common_msd.vrf_attach_config | to_json}}" - when: - - MD_Extended.vxlan.overlay.vrfs is defined - - MD_Extended.vxlan.overlay.vrfs - - vars_common_msd.changes_detected_vrfs + +# Check with Matt and Pete on how we want to handle this for MSD +# - name: Attach VRF Loopbacks per VRF +# cisco.dcnm.dcnm_rest: +# path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/top-down/v2/fabrics/{{ MD_Extended.vxlan.fabric.name }}/vrfs/attachments" +# method: "POST" +# json_data: "{{ vars_common_msd.vrf_attach_config | to_json}}" +# when: +# - MD_Extended.vxlan.overlay.vrfs is defined +# - MD_Extended.vxlan.overlay.vrfs +# - vars_common_msd.changes_detected_vrfs # -------------------------------------------------------------------- # Manage Network Configuration on NDFC From 4ab1f1648cf9c0b929a13cc0ccaba59cbcec1e63 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Mon, 13 Jan 2025 18:11:27 +0000 Subject: [PATCH 40/66] ISN remove devices and bug fixes --- plugins/plugin_utils/data_model_keys.py | 8 +++ roles/dtc/create/tasks/main.yml | 2 +- roles/dtc/create/tasks/sub_main_external.yml | 2 + roles/dtc/remove/tasks/isn/switches.yml | 45 ++++++++++++++++ roles/dtc/remove/tasks/main.yml | 13 +++-- roles/dtc/remove/tasks/msd/child_fabrics.yml | 1 - roles/dtc/remove/tasks/sub_main_isn.yml | 54 ++++++++++++++++++++ 7 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 roles/dtc/remove/tasks/isn/switches.yml create mode 100644 roles/dtc/remove/tasks/sub_main_isn.yml diff --git a/plugins/plugin_utils/data_model_keys.py b/plugins/plugin_utils/data_model_keys.py index 04b53945..b5a5711f 100644 --- a/plugins/plugin_utils/data_model_keys.py +++ b/plugins/plugin_utils/data_model_keys.py @@ -71,6 +71,7 @@ # --- model_keys['MSD']['multisite'] = [root_key, 'multisite', 'KEY'] +model_keys['MSD']['multisite.child_fabrics'] = [root_key, 'multisite', 'child_fabrics', 'KEY'] model_keys['MSD']['multisite.overlay'] = [root_key, 'multisite', 'overlay', 'KEY'] model_keys['MSD']['multisite.overlay.vrfs'] = [root_key, 'multisite', 'overlay', 'vrfs', 'LIST'] model_keys['MSD']['multisite.overlay.vrf_attach_groups'] = [root_key, 'multisite', 'overlay', 'vrf_attach_groups', 'LIST'] @@ -78,3 +79,10 @@ model_keys['MSD']['multisite.overlay.networks'] = [root_key, 'multisite', 'overlay', 'networks', 'LIST'] model_keys['MSD']['multisite.overlay.network_attach_groups'] = [root_key, 'multisite', 'overlay', 'network_attach_groups', 'LIST'] model_keys['MSD']['multisite.overlay.network_attach_groups.switches'] = [root_key, 'multisite', 'overlay', 'network_attach_groups', 'switches', 'LIST_INDEX'] + +# ISN KEYS + +# --- +model_keys['ISN']['multisite.isn'] = [root_key, 'multisite', 'isn', 'KEY'] +model_keys['ISN']['multisite.isn.topology'] = [root_key, 'multisite', 'isn', 'topology', 'KEY'] +model_keys['ISN']['multisite.isn.topology.switches'] = [root_key, 'multisite', 'isn', 'topology', 'switches', 'LIST'] \ No newline at end of file diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index c3eb2feb..20b72ddc 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -53,7 +53,7 @@ - name: Import Role Tasks External Fabric ansible.builtin.import_tasks: sub_main_external.yml when: > - (MD_Extended.vxlan.global.fabric_type == 'External') and + (MD_Extended.vxlan.fabric.type == 'External') and (vars_common_external.changes_detected_inventory) or (vars_common_external.changes_detected_interfaces) or (vars_common_external.changes_detected_fabric) or diff --git a/roles/dtc/create/tasks/sub_main_external.yml b/roles/dtc/create/tasks/sub_main_external.yml index 9257eeac..78ba9baa 100644 --- a/roles/dtc/create/tasks/sub_main_external.yml +++ b/roles/dtc/create/tasks/sub_main_external.yml @@ -35,6 +35,8 @@ - name: Create NDFC External Fabric ansible.builtin.import_tasks: external/fabric.yml when: + - MD_Extended.vxlan.fabric.name is defined + - MD_Extended.vxlan.fabric.type == "External" - MD_Extended.vxlan.global is defined - vars_common_external.changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" diff --git a/roles/dtc/remove/tasks/isn/switches.yml b/roles/dtc/remove/tasks/isn/switches.yml new file mode 100644 index 00000000..8d147f65 --- /dev/null +++ b/roles/dtc/remove/tasks/isn/switches.yml @@ -0,0 +1,45 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT +--- + +- ansible.builtin.debug: msg="Removing Unmanaged Fabric Switches. This could take several minutes..." + when: + - (inventory_delete_mode is defined) and (inventory_delete_mode is true|bool) + +- name: Remove Unmanaged NDFC Fabric Devices + cisco.dcnm.dcnm_inventory: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: "{{ vars_common_isn.updated_inv_config['updated_inv_list'] }}" + deploy: true + save: true + state: overridden + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: + - (inventory_delete_mode is defined) and (inventory_delete_mode is true|bool) + +- ansible.builtin.debug: + msg: + - "----------------------------------------------------------------------------------------------------------" + - "+ SKIPPING Remove NDFC Fabric Devices task because inventory_delete_mode flag is set to False +" + - "----------------------------------------------------------------------------------------------------------" + when: not ((inventory_delete_mode is defined) and (inventory_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/main.yml b/roles/dtc/remove/tasks/main.yml index 8764d30e..3c17da86 100644 --- a/roles/dtc/remove/tasks/main.yml +++ b/roles/dtc/remove/tasks/main.yml @@ -38,9 +38,16 @@ - name: Import MSD Role Tasks ansible.builtin.import_tasks: sub_main_msd.yml - when: - - MD_Extended.vxlan.fabric.type == 'MSD' - # - vars_common_msd.changes_detected_interfaces or vars_common_msd.changes_detected_networks or vars_common_msd.changes_detected_vrfs + when: > + (MD_Extended.vxlan.fabric.type == 'MSD') and + (vars_common_msd.changes_detected_vrfs) or + (vars_common_msd.changes_detected_networks) + +- name: Import ISN Role Tasks + ansible.builtin.import_tasks: sub_main_isn.yml + when: > + (MD_Extended.vxlan.fabric.type == 'ISN') and + (vars_common_isn.changes_detected_inventory) - name: Mark Stage Role Remove Completed cisco.nac_dc_vxlan.common.run_map: diff --git a/roles/dtc/remove/tasks/msd/child_fabrics.yml b/roles/dtc/remove/tasks/msd/child_fabrics.yml index 2dea537f..6383c438 100644 --- a/roles/dtc/remove/tasks/msd/child_fabrics.yml +++ b/roles/dtc/remove/tasks/msd/child_fabrics.yml @@ -24,7 +24,6 @@ - ansible.builtin.debug: msg="Removing Unmanaged Child Fabrics. This could take several minutes..." when: - MD_Extended.vxlan.multisite.child_fabrics is defined - - MD_Extended.vxlan.multisite.child_fabrics | length > 0 - (child_fabric_delete_mode is defined) and (child_fabric_delete_mode is true|bool) - name: Get Fabric Association Data from NDFC diff --git a/roles/dtc/remove/tasks/sub_main_isn.yml b/roles/dtc/remove/tasks/sub_main_isn.yml new file mode 100644 index 00000000..960c1351 --- /dev/null +++ b/roles/dtc/remove/tasks/sub_main_isn.yml @@ -0,0 +1,54 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.remove] + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Calling Role - [cisco.nac_dc_vxlan.dtc.remove] +" + - "----------------------------------------------------------------" + tags: "{{ nac_tags.remove }}" # Tags defined in roles/common_global/vars/main.yml + +- ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" + tags: "{{ nac_tags.remove }}" + +# TODO: May need this to remove Policy in the future for ISN +# lines 36 - 48 +# - name: Get List of Fabric Switches from NDFC +# cisco.dcnm.dcnm_rest: +# method: GET +# path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/inventory/switchesByFabric" +# register: switch_list +# tags: "{{ nac_tags.remove }}" + +# - name: Remove Fabric Policy +# ansible.builtin.import_tasks: vxlan/policy.yml +# tags: "{{ nac_tags.remove_policy }}" +# when: +# - vars_common_vxlan.changes_detected_policy + +- name: Remove Fabric Switches + ansible.builtin.import_tasks: isn/switches.yml + tags: "{{ nac_tags.remove_switches }}" + when: + - vars_common_isn.changes_detected_inventory From fdaa9d05decb22d7b07e51a9161832fcdfcfe447 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Tue, 14 Jan 2025 18:37:35 +0000 Subject: [PATCH 41/66] Enable child fabric delete mode flag --- README.md | 2 ++ plugins/action/dtc/manage_child_fabrics.py | 9 +++++++++ roles/common_global/defaults/main.yml | 1 + roles/dtc/common/tasks/msd/ndfc_children.yml | 20 +++++++++++++++++++- roles/dtc/create/tasks/msd/child_fabrics.yml | 1 + roles/dtc/remove/tasks/msd/child_fabrics.yml | 15 ++++++++++++++- 6 files changed, 46 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a74e1a8..0ebfd59e 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Inside the [example repository](https://github.com/netascode/ansible-dc-vxlan-ex ```yaml # Control Parameters for 'Remove' role tasks +child_fabric_delete_mode: false interface_delete_mode: false inventory_delete_mode: false link_fabric_delete_mode: false @@ -85,6 +86,7 @@ The following control variables are available in this collection. | `link_vpc_delete_mode` | Remove vpc link state as part of the remove role | `false` | | `vpc_delete_mode` | Remove vpc pair state as part of the remove role | `false` | | `policy_delete_mode` | Remove policy state as part of the remove role | `false` | +| `child_fabric_delete_mode` | Remove child fabric from MSD|MCF fabric as part of the remove role | `false` | These variables are described in more detail in different sections of this document. diff --git a/plugins/action/dtc/manage_child_fabrics.py b/plugins/action/dtc/manage_child_fabrics.py index b69e4744..11f59bde 100644 --- a/plugins/action/dtc/manage_child_fabrics.py +++ b/plugins/action/dtc/manage_child_fabrics.py @@ -35,6 +35,7 @@ class ActionModule(ActionBase): def run(self, tmp=None, task_vars=None): results = super(ActionModule, self).run(tmp, task_vars) results['failed'] = False + results['child_fabrics_moved'] = False fabric_associations = self._task.args['fabric_associations'].get('response').get('DATA') parent_fabric_name = self._task.args['parent_fabric_name'] @@ -67,6 +68,14 @@ def run(self, tmp=None, task_vars=None): results['msg'] = f"{add_fabric_result['msg']['MESSAGE']}: {add_fabric_result['msg']['DATA']}" break + # If a child fabric is successfully added under an MSD fabric set a flag + # indicating this so that it can be used later to prevent managing VRFs + # and Networks. If we dont prevent this then the VRFs and Networks could + # be removed as part of moving the child fabric. + # + # TBD: This flag is not actually being used currently. Discuss with team. + results['child_fabrics_moved'] = True + results['changed'] = True if operation == 'remove': diff --git a/roles/common_global/defaults/main.yml b/roles/common_global/defaults/main.yml index d6b5a954..d4bcfe4e 100644 --- a/roles/common_global/defaults/main.yml +++ b/roles/common_global/defaults/main.yml @@ -33,6 +33,7 @@ force_run_all: false # Parameters to enable/disable remove role tasks +child_fabric_delete_mode: false interface_delete_mode: false inventory_delete_mode: false link_fabric_delete_mode: false diff --git a/roles/dtc/common/tasks/msd/ndfc_children.yml b/roles/dtc/common/tasks/msd/ndfc_children.yml index 6def6b2e..5ffba9e3 100644 --- a/roles/dtc/common/tasks/msd/ndfc_children.yml +++ b/roles/dtc/common/tasks/msd/ndfc_children.yml @@ -1,3 +1,21 @@ --- -- debug: msg="Building NDFC MSD Child Fabric Data" \ No newline at end of file +- debug: msg="Building NDFC MSD Child Fabric Data" + +# Notes on items that still need support for MSD +# +# - Fabric Settings for MSD (Need Customer Requirements Here) +# - Fabric Settings for ISN (Need Customer Requirements Here) +# - Enable Interface Management under ISN workflow +# - Enable Policy Management under ISN/MSD worflows +# - Verify addition of multiple ISN Fabrics/Devies +# (Test Two ISN Fabrics with two ISN devices - Full Mesh) +# (Configure interfaces between the ISN devices) +# (What policy should be applied between the ISN devices) +# - Verify support of VRF / Network properties at MSD level +# - Enable support of VRF / Netowrk properties at Child level under MSD fabric +# - Verify Order of Operations +# - Create VXLAN / ISN Fabrics then MSD Fabric + Association +# - Create MSD Fabric then VXLAN / ISN Fabrics + Association +# - VRF / Network problem when child fabrics moved under MSD but MSD level VRF/Net model data is empty +# (Result is all VRF/Networks are removed after they get moved under MSD - can be controlled with flag) \ No newline at end of file diff --git a/roles/dtc/create/tasks/msd/child_fabrics.yml b/roles/dtc/create/tasks/msd/child_fabrics.yml index 61afd99a..a3129cf5 100644 --- a/roles/dtc/create/tasks/msd/child_fabrics.yml +++ b/roles/dtc/create/tasks/msd/child_fabrics.yml @@ -44,3 +44,4 @@ child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" operation: add when: fabric_associations is defined and fabric_associations + register: fabric_move_result diff --git a/roles/dtc/remove/tasks/msd/child_fabrics.yml b/roles/dtc/remove/tasks/msd/child_fabrics.yml index 6383c438..0a14762a 100644 --- a/roles/dtc/remove/tasks/msd/child_fabrics.yml +++ b/roles/dtc/remove/tasks/msd/child_fabrics.yml @@ -31,6 +31,9 @@ method: GET path: /appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations register: fabric_associations + when: + - MD_Extended.vxlan.multisite.child_fabrics is defined + - (child_fabric_delete_mode is defined) and (child_fabric_delete_mode is true|bool) - name: Remove Unmanaged Child Fabrics from NDFC cisco.nac_dc_vxlan.dtc.manage_child_fabrics: @@ -38,4 +41,14 @@ parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" operation: remove - when: fabric_associations is defined and fabric_associations + when: + - fabric_associations is defined and fabric_associations + - (child_fabric_delete_mode is defined) and (child_fabric_delete_mode is true|bool) + + +- ansible.builtin.debug: + msg: + - "---------------------------------------------------------------------------------------------------------------" + - "+ SKIPPING Remove Unmanaged Child Fabrics task because child_fabric_delete_mode flag is set to False +" + - "---------------------------------------------------------------------------------------------------------------" + when: not ((child_fabric_delete_mode is defined) and (child_fabric_delete_mode is true|bool)) From e765809ec88ff2d901379f9517bf0e00524aa496 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Tue, 14 Jan 2025 18:55:06 +0000 Subject: [PATCH 42/66] Github actions fixes --- plugins/action/common/nac_dc_validate.py | 4 ++-- .../action/common/prepare_plugins/prep_001_fabric.py | 10 ++++------ .../common/prepare_plugins/prep_002_list_defaults.py | 1 - plugins/action/dtc/map_msd_inventory.py | 2 +- plugins/plugin_utils/data_model_keys.py | 2 -- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/plugins/action/common/nac_dc_validate.py b/plugins/action/common/nac_dc_validate.py index 712aff51..bea761d9 100644 --- a/plugins/action/common/nac_dc_validate.py +++ b/plugins/action/common/nac_dc_validate.py @@ -113,14 +113,14 @@ def run(self, tmp=None, task_vars=None): "Attempting to use vxlan.global.fabric_type due to vxlan.fabric.type not being found. " "vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric.type." ) - display.deprecated(msg=deprecated_msg, version='1.0.0') + display.deprecated(msg=deprecated_msg, version='1.0.0', collection_name='cisco.nac_dc_vxlan') if results['data']['vxlan']['global']['fabric_type'] in ('VXLAN_EVPN'): rules_list.append(f'{rules}vxlan/') elif results['data']['vxlan']['global']['fabric_type'] in ('MSD', 'MCF'): rules_list.append(f'{rules}multisite/') elif results['data']['vxlan']['global']['fabric_type'] in ('ISN', 'External'): - rules_list.append(f'{rules}isn/') + rules_list.append(f'{rules}isn/') else: results['failed'] = True results['msg'] = f"vxlan.fabric.type {results['data']['vxlan']['global']['fabric_type']} is not a supported fabric type." diff --git a/plugins/action/common/prepare_plugins/prep_001_fabric.py b/plugins/action/common/prepare_plugins/prep_001_fabric.py index 847706fd..8dfd709b 100644 --- a/plugins/action/common/prepare_plugins/prep_001_fabric.py +++ b/plugins/action/common/prepare_plugins/prep_001_fabric.py @@ -59,7 +59,7 @@ def prepare(self): "vxlan.fabric.name and vxlan.fabric.type not being defined. " "vxlan.global.name and vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric." ) - display.deprecated(msg=deprecated_msg, version="1.0.0") + display.deprecated(msg=deprecated_msg, version="1.0.0", collection_name='cisco.nac_dc_vxlan') parent_keys = ['vxlan', 'global'] dm_check = data_model_key_check(model_data, parent_keys) @@ -93,7 +93,7 @@ def prepare(self): "Attempting to use vxlan.global.name due to vxlan.fabric.name not being defined. " "vxlan.global.name is being deprecated. Please use vxlan.fabric." ) - display.deprecated(msg=deprecated_msg, version="1.0.0") + display.deprecated(msg=deprecated_msg, version="1.0.0", collection_name='cisco.nac_dc_vxlan') parent_keys = ['vxlan', 'global', 'name'] dm_check = data_model_key_check(model_data, parent_keys) if 'name' in dm_check['keys_data']: @@ -110,7 +110,7 @@ def prepare(self): "Attempting to use vxlan.global.type due to vxlan.fabric.type not being defined. " "vxlan.global.type is being deprecated. Please use vxlan.fabric." ) - display.deprecated(msg=deprecated_msg, version="1.0.0") + display.deprecated(msg=deprecated_msg, version="1.0.0", collection_name='cisco.nac_dc_vxlan') parent_keys = ['vxlan', 'global', 'fabric_type'] dm_check = data_model_key_check(model_data, parent_keys) if 'fabric_type' in dm_check['keys_data']: @@ -119,7 +119,6 @@ def prepare(self): self.kwargs['results']['failed'] = True self.kwargs['results']['msg'] = "vxlan.fabric.type is not defined in the data model." - # For backwards compatibility, replace 'overlay_services' key with 'overlay' # NOTE: No prepare plugin, jinja2 template or ansible task should reference 'overlay_services' after this replacement. # NOTE: Rules are different since rules run BEFORE prepare plugins @@ -131,7 +130,7 @@ def prepare(self): "vxlan.overlay_services is being deprecated. " "Please use vxlan.overlay instead" ) - display.deprecated(msg=deprecated_msg, version="1.0.0") + display.deprecated(msg=deprecated_msg, version="1.0.0", collection_name='cisco.nac_dc_vxlan') model_data['vxlan']['overlay'] = model_data['vxlan']['overlay_services'] del model_data['vxlan']['overlay_services'] @@ -140,6 +139,5 @@ def prepare(self): if 'multisite' in dm_check['keys_found'] and 'overlay' in dm_check['keys_found']: model_data['vxlan']['overlay'] = model_data['vxlan']['multisite']['overlay'] - self.kwargs['results']['model_extended'] = model_data return self.kwargs['results'] diff --git a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py index 6a2d2d38..0cb7fc23 100644 --- a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py @@ -178,7 +178,6 @@ def prepare(self): # -------------------------------------------------------------------- from pprint import pprint - # type: enum('VXLAN_EVPN', 'MSD', 'MCF', 'ISN') fabric_type = self.model_data['vxlan']['fabric']['type'] # for path in paths: diff --git a/plugins/action/dtc/map_msd_inventory.py b/plugins/action/dtc/map_msd_inventory.py index fa6da96e..e317ad24 100644 --- a/plugins/action/dtc/map_msd_inventory.py +++ b/plugins/action/dtc/map_msd_inventory.py @@ -81,4 +81,4 @@ def run(self, tmp=None, task_vars=None): results['msg'].append(msg) results['msd_switches'] = msd_switches - return results \ No newline at end of file + return results diff --git a/plugins/plugin_utils/data_model_keys.py b/plugins/plugin_utils/data_model_keys.py index b5a5711f..69f9a972 100644 --- a/plugins/plugin_utils/data_model_keys.py +++ b/plugins/plugin_utils/data_model_keys.py @@ -26,8 +26,6 @@ # from ..helper_functions import do_something root_key = 'vxlan' -# Keys here match data model schema -# type: enum('VXLAN_EVPN', 'MSD', 'MCF', 'ISN') model_keys = {'VXLAN_EVPN': {}, 'MSD': {}, 'MCF': {}, 'ISN': {}} # VXLAN_EVPN KEYS From cde1ce4b520d70a03598bebe4b60998b99693175 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Tue, 14 Jan 2025 19:04:21 +0000 Subject: [PATCH 43/66] GitHub Actions Issues --- tests/sanity/ignore-2.14.txt | 7 +++---- tests/sanity/ignore-2.15.txt | 7 +++---- tests/sanity/ignore-2.16.txt | 7 +++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 811563c5..5be6c9c9 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -1,14 +1,13 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name -plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name +plugins/action/common/prepare_plugins/prep_001_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_002_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_107_vrf_lites.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_999_verify.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_service_model.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/get_credentials.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/run_map.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 811563c5..5be6c9c9 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -1,14 +1,13 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name -plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name +plugins/action/common/prepare_plugins/prep_001_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_002_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_107_vrf_lites.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_999_verify.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_service_model.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/get_credentials.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/run_map.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.16.txt b/tests/sanity/ignore-2.16.txt index 811563c5..5be6c9c9 100644 --- a/tests/sanity/ignore-2.16.txt +++ b/tests/sanity/ignore-2.16.txt @@ -1,14 +1,13 @@ plugins/action/common/check_roles.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/nac_dc_validate.py ansible-deprecated-no-collection-name -plugins/action/common/prepare_plugins/prep_001_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation -plugins/action/common/prepare_plugins/prep_101_fabric.py ansible-deprecated-no-collection-name +plugins/action/common/prepare_plugins/prep_001_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_002_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_103_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_107_vrf_lites.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_999_verify.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_service_model.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/get_credentials.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/run_map.py action-plugin-docs # action plugin has no matching module to provide documentation From c6e6d3ba4125309e42c53037966ff0b4a094f29b Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Tue, 14 Jan 2025 21:08:44 +0000 Subject: [PATCH 44/66] More GitHub Actions Fixes --- .../common/prepare_plugins/prep_002_list_defaults.py | 7 +++---- .../common/prepare_plugins/prep_104_fabric_overlay.py | 2 +- .../common/prepare_plugins/prep_105_topology_interfaces.py | 1 - plugins/action/common/prepare_plugins/prep_999_verify.py | 6 ------ plugins/action/dtc/update_switch_hostname_policy.py | 2 +- plugins/plugin_utils/data_model_keys.py | 2 +- .../files/rules/vxlan/402_overlay_services_vrfs.py | 1 - .../files/rules/vxlan/403_overlay_services_networks.py | 1 - 8 files changed, 6 insertions(+), 16 deletions(-) diff --git a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py index 0cb7fc23..60a2ca5d 100644 --- a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py @@ -27,6 +27,7 @@ display = Display() + def getFromDict(dataDict, mapList): """ # Summary @@ -36,6 +37,7 @@ def getFromDict(dataDict, mapList): """ return reduce(operator.getitem, mapList, dataDict) + def update_nested_dict(nested_dict, keys, new_value): """ # Summary @@ -148,8 +150,7 @@ def set_nested_list_default(self, model_data_subset, target_key): list_index = 0 for item in model_data_subset: dm_check = data_model_key_check(item, [target_key]) - if target_key in dm_check['keys_not_found'] or \ - target_key in dm_check['keys_no_data']: + if target_key in dm_check['keys_not_found'] or target_key in dm_check['keys_no_data']: model_data_subset[list_index][target_key] = [] list_index += 1 @@ -195,10 +196,8 @@ def prepare(self): if path_type == 'LIST_INDEX': # model_keys['VXLAN_EVPN']['topology.switches.freeform'] = [root_key, 'topology', 'switches', 'freeform', 'LIST_INDEX'] model_data_subset = getFromDict(self.model_data, parent_keys) - target_key = target_key self.set_nested_list_default(model_data_subset, target_key) - # Quick Sanity Check: # # For Fabric Type: VXLAN_EVPN or External diff --git a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py index 412a8611..b7080ecd 100644 --- a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py +++ b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py @@ -19,7 +19,7 @@ # # SPDX-License-Identifier: MIT -from ....plugin_utils.helper_functions import data_model_key_check +# from ....plugin_utils.helper_functions import data_model_key_check class PreparePlugin: diff --git a/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py b/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py index e391161c..eb677916 100644 --- a/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py +++ b/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py @@ -38,7 +38,6 @@ def prepare(self): if model_data['vxlan']['fabric']['type'] in ['ISN', 'MSD', 'MCF']: return self.kwargs['results'] - model_data['vxlan']['topology']['interfaces'] = {} model_data['vxlan']['topology']['interfaces']['modes'] = {} diff --git a/plugins/action/common/prepare_plugins/prep_999_verify.py b/plugins/action/common/prepare_plugins/prep_999_verify.py index 03724319..ce6b7894 100644 --- a/plugins/action/common/prepare_plugins/prep_999_verify.py +++ b/plugins/action/common/prepare_plugins/prep_999_verify.py @@ -31,7 +31,6 @@ def __init__(self, **kwargs): self.kwargs = kwargs self.keys = [] - def prepare(self): model_data = self.kwargs['results']['model_extended'] self.kwargs['results']['failed'] = False @@ -41,11 +40,6 @@ def prepare(self): fail_msg += " the data was not included in the data model." fail_msg += " Data Model Section: ({})" - # from pprint import pprint - # md = model_data - # pprint(md) - - # This prepare plugin serves as a final sanity check after all of the # previous prepare plugins have been called to transform the model data. # diff --git a/plugins/action/dtc/update_switch_hostname_policy.py b/plugins/action/dtc/update_switch_hostname_policy.py index ec8f2d4b..6b96bec0 100644 --- a/plugins/action/dtc/update_switch_hostname_policy.py +++ b/plugins/action/dtc/update_switch_hostname_policy.py @@ -50,7 +50,7 @@ def run(self, tmp=None, task_vars=None): ) dm_switches = [] - if model_data["vxlan"]["fabric"]["type"] in ('VXLAN_EVPN','External'): + if model_data["vxlan"]["fabric"]["type"] in ('VXLAN_EVPN', 'External'): dm_switches = model_data["vxlan"]["topology"]["switches"] elif model_data["vxlan"]["fabric"]["type"] in ('ISN'): dm_switches = model_data["vxlan"]["multisite"]["isn"]["topology"]["switches"] diff --git a/plugins/plugin_utils/data_model_keys.py b/plugins/plugin_utils/data_model_keys.py index 69f9a972..83dfc79f 100644 --- a/plugins/plugin_utils/data_model_keys.py +++ b/plugins/plugin_utils/data_model_keys.py @@ -83,4 +83,4 @@ # --- model_keys['ISN']['multisite.isn'] = [root_key, 'multisite', 'isn', 'KEY'] model_keys['ISN']['multisite.isn.topology'] = [root_key, 'multisite', 'isn', 'topology', 'KEY'] -model_keys['ISN']['multisite.isn.topology.switches'] = [root_key, 'multisite', 'isn', 'topology', 'switches', 'LIST'] \ No newline at end of file +model_keys['ISN']['multisite.isn.topology.switches'] = [root_key, 'multisite', 'isn', 'topology', 'switches', 'LIST'] diff --git a/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py b/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py index ec2fcf1d..8a28aadc 100644 --- a/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py +++ b/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py @@ -110,7 +110,6 @@ def match(cls, inventory): return results - @classmethod def data_model_key_check(cls, tested_object, keys): dm_key_dict = {'keys_found': [], 'keys_not_found': [], 'keys_data': [], 'keys_no_data': []} diff --git a/roles/validate/files/rules/vxlan/403_overlay_services_networks.py b/roles/validate/files/rules/vxlan/403_overlay_services_networks.py index daf4c7ac..f164b771 100644 --- a/roles/validate/files/rules/vxlan/403_overlay_services_networks.py +++ b/roles/validate/files/rules/vxlan/403_overlay_services_networks.py @@ -21,7 +21,6 @@ def match(cls, inventory): # if 'enable' in check['keys_data']: # fabric_netflow_status = cls.safeget(inventory, netflow_keys) - if inventory.get("vxlan", None): if inventory["vxlan"].get("underlay", None): if inventory["vxlan"].get("underlay").get("multicast", None): From 5382ce2c52624427d3d4ef170cbbcf75ce4321a4 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Wed, 15 Jan 2025 00:14:44 +0000 Subject: [PATCH 45/66] Deploy False for Fabrics --- .../ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 | 2 +- .../common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 | 2 +- .../common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 index 145e840c..af39712d 100644 --- a/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/dc_vxlan_fabric/dc_vxlan_fabric_base.j2 @@ -2,7 +2,7 @@ {% import 'ndfc_utils.j2' as ndfc_utils with context %} - FABRIC_NAME: {{ vxlan.fabric.name }} FABRIC_TYPE: {{ vxlan.fabric.type }} - DEPLOY: True + DEPLOY: False {# Include NDFC DC VXLAN EVPN General Template #} {% include '/ndfc_fabric/dc_vxlan_fabric/general/dc_vxlan_fabric_general.j2' %} diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 index b7ad1e74..c3d190aa 100644 --- a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 @@ -1,7 +1,7 @@ {# Auto-generated NDFC ISN Base config data structure for fabric {{ vxlan.fabric.name }} #} - FABRIC_NAME: {{ vxlan.fabric.name }} FABRIC_TYPE: ISN - DEPLOY: True + DEPLOY: False {# Include NDFC ISN General Template #} {% include '/ndfc_fabric/isn_fabric/general/isn_fabric_general.j2' %} diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 index ba997f3d..7d4af48e 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/msd_fabric_base.j2 @@ -1,7 +1,7 @@ {# Auto-generated NDFC MultiSite Domain (MSD) Base config data structure for fabric {{ vxlan.fabric.name }} #} - FABRIC_NAME: {{ vxlan.fabric.name }} FABRIC_TYPE: VXLAN_EVPN_MSD - DEPLOY: True + DEPLOY: False {# Include NDFC DC VXLAN EVPN General Template #} {% include '/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2' %} From 57b7636b01352a8d0eaf67ed5ae91fab758ced09 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Thu, 16 Jan 2025 03:42:41 +0000 Subject: [PATCH 46/66] Refactor for sharing code and simplification --- .../prep_103_topology_switches.py | 2 +- .../prep_104_fabric_overlay.py | 2 +- .../prep_105_topology_interfaces.py | 2 +- .../prep_106_topology_vpc_interfaces.py | 4 +- plugins/action/dtc/get_poap_data.py | 4 +- .../dtc/update_switch_hostname_policy.py | 6 +- plugins/plugin_utils/data_model_keys.py | 22 ++- roles/dtc/common/tasks/common/ndfc_fabric.yml | 77 +++++++++ .../common/tasks/common/ndfc_fabric_links.yml | 83 +++++++++ .../tasks/common/ndfc_interface_access.yml | 83 +++++++++ .../tasks/common/ndfc_interface_access_po.yml | 83 +++++++++ .../tasks/common/ndfc_interface_all.yml | 83 +++++++++ .../tasks/common/ndfc_interface_loopback.yml | 83 +++++++++ .../tasks/common/ndfc_interface_po_routed.yml | 83 +++++++++ .../tasks/common/ndfc_interface_routed.yml | 83 +++++++++ .../tasks/common/ndfc_interface_trunk.yml | 83 +++++++++ .../tasks/common/ndfc_interface_trunk_po.yml | 83 +++++++++ .../tasks/common/ndfc_interface_vpc.yml | 83 +++++++++ .../common/tasks/common/ndfc_inventory.yml | 105 ++++++++++++ .../tasks/common/ndfc_link_vpc_peering.yml | 83 +++++++++ roles/dtc/common/tasks/common/ndfc_policy.yml | 83 +++++++++ .../common/ndfc_sub_interface_routed.yml | 83 +++++++++ .../common/tasks/common/ndfc_vpc_peering.yml | 83 +++++++++ roles/dtc/common/tasks/main.yml | 15 ++ roles/dtc/common/tasks/sub_main_external.yml | 26 +-- roles/dtc/common/tasks/sub_main_isn.yml | 131 ++++++++++++++- roles/dtc/common/tasks/sub_main_msd.yml | 2 +- roles/dtc/common/tasks/sub_main_vxlan.yml | 32 ++-- .../ndfc_interface_access.j2 | 0 .../ndfc_interface_access_po.j2 | 0 .../ndfc_interface_po_routed.j2 | 0 .../ndfc_interface_routed.j2 | 0 .../ndfc_interface_trunk.j2 | 0 .../ndfc_interface_trunk_po.j2 | 0 .../ndfc_interface_vpc.j2 | 0 .../ndfc_loopback_interfaces.j2 | 0 .../ndfc_sub_interface_routed.j2 | 0 roles/dtc/common/templates/ndfc_inventory.j2 | 4 +- .../ndfc_inventory/common/fabric_inventory.j2 | 41 +++++ .../isn_fabric/isn_fabric_inventory.j2 | 6 +- roles/dtc/create/tasks/common/devices.yml | 32 ++++ .../create/tasks/common/devices_discovery.yml | 74 ++++++++ .../tasks/common/devices_preprovision.yml | 79 +++++++++ roles/dtc/create/tasks/common/fabric.yml | 48 ++++++ roles/dtc/create/tasks/common/interfaces.yml | 158 ++++++++++++++++++ roles/dtc/create/tasks/common/links.yml | 82 +++++++++ roles/dtc/create/tasks/common/policies.yml | 55 ++++++ roles/dtc/create/tasks/common/vpc_peering.yml | 68 ++++++++ roles/dtc/create/tasks/external/devices.yml | 4 - roles/dtc/create/tasks/main.yml | 4 +- roles/dtc/create/tasks/sub_main_external.yml | 12 +- roles/dtc/create/tasks/sub_main_isn.yml | 27 ++- roles/dtc/create/tasks/sub_main_msd.yml | 4 +- roles/dtc/create/tasks/sub_main_vxlan.yml | 26 +-- roles/dtc/remove/tasks/common/interfaces.yml | 82 +++++++++ roles/dtc/remove/tasks/common/policy.yml | 72 ++++++++ roles/dtc/remove/tasks/common/switches.yml | 59 +++++++ roles/dtc/remove/tasks/isn/links.yml | 83 +++++++++ roles/dtc/remove/tasks/sub_main_isn.yml | 42 +++-- roles/dtc/remove/tasks/sub_main_vxlan.yml | 8 +- 60 files changed, 2557 insertions(+), 105 deletions(-) create mode 100644 roles/dtc/common/tasks/common/ndfc_fabric.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_fabric_links.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_interface_access.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_interface_access_po.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_interface_all.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_interface_loopback.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_interface_po_routed.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_interface_routed.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_interface_trunk.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_interface_trunk_po.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_interface_vpc.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_inventory.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_link_vpc_peering.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_policy.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_sub_interface_routed.yml create mode 100644 roles/dtc/common/tasks/common/ndfc_vpc_peering.yml rename roles/dtc/common/templates/{ => ndfc_interfaces}/ndfc_interface_access.j2 (100%) rename roles/dtc/common/templates/{ => ndfc_interfaces}/ndfc_interface_access_po.j2 (100%) rename roles/dtc/common/templates/{ => ndfc_interfaces}/ndfc_interface_po_routed.j2 (100%) rename roles/dtc/common/templates/{ => ndfc_interfaces}/ndfc_interface_routed.j2 (100%) rename roles/dtc/common/templates/{ => ndfc_interfaces}/ndfc_interface_trunk.j2 (100%) rename roles/dtc/common/templates/{ => ndfc_interfaces}/ndfc_interface_trunk_po.j2 (100%) rename roles/dtc/common/templates/{ => ndfc_interfaces}/ndfc_interface_vpc.j2 (100%) rename roles/dtc/common/templates/{ => ndfc_interfaces}/ndfc_loopback_interfaces.j2 (100%) rename roles/dtc/common/templates/{ => ndfc_interfaces}/ndfc_sub_interface_routed.j2 (100%) create mode 100644 roles/dtc/common/templates/ndfc_inventory/common/fabric_inventory.j2 create mode 100644 roles/dtc/create/tasks/common/devices.yml create mode 100644 roles/dtc/create/tasks/common/devices_discovery.yml create mode 100644 roles/dtc/create/tasks/common/devices_preprovision.yml create mode 100644 roles/dtc/create/tasks/common/fabric.yml create mode 100644 roles/dtc/create/tasks/common/interfaces.yml create mode 100644 roles/dtc/create/tasks/common/links.yml create mode 100644 roles/dtc/create/tasks/common/policies.yml create mode 100644 roles/dtc/create/tasks/common/vpc_peering.yml create mode 100644 roles/dtc/remove/tasks/common/interfaces.yml create mode 100644 roles/dtc/remove/tasks/common/policy.yml create mode 100644 roles/dtc/remove/tasks/common/switches.yml create mode 100644 roles/dtc/remove/tasks/isn/links.yml diff --git a/plugins/action/common/prepare_plugins/prep_103_topology_switches.py b/plugins/action/common/prepare_plugins/prep_103_topology_switches.py index 7b9cb176..5945b6f1 100644 --- a/plugins/action/common/prepare_plugins/prep_103_topology_switches.py +++ b/plugins/action/common/prepare_plugins/prep_103_topology_switches.py @@ -31,7 +31,7 @@ def prepare(self): model_data = self.kwargs['results']['model_extended'] # This plugin does not apply to the follwing fabric types - if model_data['vxlan']['fabric']['type'] in ['ISN', 'MSD', 'MCF']: + if model_data['vxlan']['fabric']['type'] in ['MSD', 'MCF']: return self.kwargs['results'] # Loop over all the roles in vxlan.topology.switches.role diff --git a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py index b7080ecd..409749c5 100644 --- a/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py +++ b/plugins/action/common/prepare_plugins/prep_104_fabric_overlay.py @@ -31,7 +31,7 @@ def prepare(self): model_data = self.kwargs['results']['model_extended'] # We don't have switches for Multisite fabrics so need special handling - if model_data['vxlan']['fabric']['type'] in ('MSD', 'MCF', 'ISN'): + if model_data['vxlan']['fabric']['type'] in ('MSD', 'MCF'): switches = [] else: switches = model_data['vxlan']['topology']['switches'] diff --git a/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py b/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py index eb677916..e5aab073 100644 --- a/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py +++ b/plugins/action/common/prepare_plugins/prep_105_topology_interfaces.py @@ -35,7 +35,7 @@ def prepare(self): model_data = self.kwargs['results']['model_extended'] # This plugin does not apply to the follwing fabric types - if model_data['vxlan']['fabric']['type'] in ['ISN', 'MSD', 'MCF']: + if model_data['vxlan']['fabric']['type'] in ['MSD', 'MCF']: return self.kwargs['results'] model_data['vxlan']['topology']['interfaces'] = {} diff --git a/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py b/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py index 531bdf98..a8c3c043 100644 --- a/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py +++ b/plugins/action/common/prepare_plugins/prep_106_topology_vpc_interfaces.py @@ -31,8 +31,8 @@ def __init__(self, **kwargs): def prepare(self): model_data = self.kwargs['results']['model_extended'] - if model_data['vxlan']['fabric']['type'] == 'ISN': - return self.kwargs['results'] + # if model_data['vxlan']['fabric']['type'] == 'ISN': + # return self.kwargs['results'] # Check if vxlan.topology is defined if model_data.get('vxlan').get('topology') is not None: diff --git a/plugins/action/dtc/get_poap_data.py b/plugins/action/dtc/get_poap_data.py index 9042247d..b771cfb2 100644 --- a/plugins/action/dtc/get_poap_data.py +++ b/plugins/action/dtc/get_poap_data.py @@ -174,8 +174,8 @@ def run(self, tmp=None, task_vars=None): params = {} params['model_data'] = self._task.args["model_data"] - if params['model_data']['vxlan']['fabric']['type'] == 'ISN': - return results + # if params['model_data']['vxlan']['fabric']['type'] == 'ISN': + # return results params['action_plugin'] = self._execute_module params['task_vars'] = task_vars diff --git a/plugins/action/dtc/update_switch_hostname_policy.py b/plugins/action/dtc/update_switch_hostname_policy.py index 6b96bec0..e85c88cd 100644 --- a/plugins/action/dtc/update_switch_hostname_policy.py +++ b/plugins/action/dtc/update_switch_hostname_policy.py @@ -50,10 +50,10 @@ def run(self, tmp=None, task_vars=None): ) dm_switches = [] - if model_data["vxlan"]["fabric"]["type"] in ('VXLAN_EVPN', 'External'): + if model_data["vxlan"]["fabric"]["type"] in ('VXLAN_EVPN', 'ISN', 'External'): dm_switches = model_data["vxlan"]["topology"]["switches"] - elif model_data["vxlan"]["fabric"]["type"] in ('ISN'): - dm_switches = model_data["vxlan"]["multisite"]["isn"]["topology"]["switches"] + # elif model_data["vxlan"]["fabric"]["type"] in ('ISN'): + # dm_switches = model_data["vxlan"]["multisite"]["isn"]["topology"]["switches"] switch_match = next((item for item in dm_switches if item["serial_number"] == switch_serial_number)) diff --git a/plugins/plugin_utils/data_model_keys.py b/plugins/plugin_utils/data_model_keys.py index 83dfc79f..161beaf5 100644 --- a/plugins/plugin_utils/data_model_keys.py +++ b/plugins/plugin_utils/data_model_keys.py @@ -65,6 +65,21 @@ model_keys['VXLAN_EVPN']['policy.groups'] = [root_key, 'policy', 'groups', 'LIST'] model_keys['VXLAN_EVPN']['policy.switches'] = [root_key, 'policy', 'switches', 'LIST'] +# ISN KEYS + +model_keys['ISN']['topology'] = [root_key, 'topology', 'KEY'] +model_keys['ISN']['topology.edge_connections'] = [root_key, 'topology', 'edge_connections', 'LIST'] +model_keys['ISN']['topology.fabric_links'] = [root_key, 'topology', 'fabric_links', 'LIST'] +model_keys['ISN']['topology.switches'] = [root_key, 'topology', 'switches', 'LIST'] +model_keys['ISN']['topology.switches.freeform'] = [root_key, 'topology', 'switches', 'freeform', 'LIST_INDEX'] +model_keys['ISN']['topology.switches.interfaces'] = [root_key, 'topology', 'switches', 'interfaces', 'LIST_INDEX'] +model_keys['ISN']['topology.vpc_peers'] = [root_key, 'topology', 'vpc_peers', 'LIST'] +# --- +model_keys['ISN']['policy'] = [root_key, 'policy', 'KEY'] +model_keys['ISN']['policy.policies'] = [root_key, 'policy', 'policies', 'LIST'] +model_keys['ISN']['policy.groups'] = [root_key, 'policy', 'groups', 'LIST'] +model_keys['ISN']['policy.switches'] = [root_key, 'policy', 'switches', 'LIST'] + # MSD KEYS # --- @@ -77,10 +92,3 @@ model_keys['MSD']['multisite.overlay.networks'] = [root_key, 'multisite', 'overlay', 'networks', 'LIST'] model_keys['MSD']['multisite.overlay.network_attach_groups'] = [root_key, 'multisite', 'overlay', 'network_attach_groups', 'LIST'] model_keys['MSD']['multisite.overlay.network_attach_groups.switches'] = [root_key, 'multisite', 'overlay', 'network_attach_groups', 'switches', 'LIST_INDEX'] - -# ISN KEYS - -# --- -model_keys['ISN']['multisite.isn'] = [root_key, 'multisite', 'isn', 'KEY'] -model_keys['ISN']['multisite.isn.topology'] = [root_key, 'multisite', 'isn', 'topology', 'KEY'] -model_keys['ISN']['multisite.isn.topology.switches'] = [root_key, 'multisite', 'isn', 'topology', 'switches', 'LIST'] diff --git a/roles/dtc/common/tasks/common/ndfc_fabric.yml b/roles/dtc/common/tasks/common/ndfc_fabric.yml new file mode 100644 index 00000000..02d383b8 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_fabric.yml @@ -0,0 +1,77 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_fabric: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_fabric.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + # TODO: Add capability to overridde path variable above for CI/CD pipeline + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Fabric Creation Parameters From Template + ansible.builtin.template: + src: ndfc_fabric.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- ansible.builtin.set_fact: + fabric_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_fabric: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/common/ndfc_fabric_links.yml b/roles/dtc/common/tasks/common/ndfc_fabric_links.yml new file mode 100644 index 00000000..6f7a762f --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_fabric_links.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_fabric_links: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_fabric_links.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Fabric Links + ansible.builtin.template: + src: ndfc_fabric_links.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set fabric_links Var default + ansible.builtin.set_fact: + fabric_links: [] + delegate_to: localhost + +- name: Set fabric_links Var + ansible.builtin.set_fact: + fabric_links: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.fabric_links | length > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_fabric_links: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/common/ndfc_interface_access.yml b/roles/dtc/common/tasks/common/ndfc_interface_access.yml new file mode 100644 index 00000000..8e92dfa7 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_interface_access.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_access: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_interface_access.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interfaces/ndfc_interface_access.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set interface_access Var + ansible.builtin.set_fact: + interface_access: [] + delegate_to: localhost + +- name: Set interface_access Var + ansible.builtin.set_fact: + interface_access: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_access: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_interface_access_po.yml b/roles/dtc/common/tasks/common/ndfc_interface_access_po.yml new file mode 100644 index 00000000..c0283359 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_interface_access_po.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_access_po: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_interface_access_po.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interfaces/ndfc_interface_access_po.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set interface_access_po Var + ansible.builtin.set_fact: + interface_access_po: [] + delegate_to: localhost + +- name: Set interface_access_po Var + ansible.builtin.set_fact: + interface_access_po: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_access_po: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_interface_all.yml b/roles/dtc/common/tasks/common/ndfc_interface_all.yml new file mode 100644 index 00000000..b4850efb --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_interface_all.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interfaces: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_interface_all.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Set interface_all Var + ansible.builtin.set_fact: + interface_all: [] + delegate_to: localhost + +- name: Set interface_all Var + ansible.builtin.set_fact: + interface_all: "{{ interface_access + interface_access_po + interface_trunk + interface_trunk_po + interface_routed + interface_po_routed + sub_interface_routed + interface_vpc + int_loopback_config }}" + when: MD_Extended.vxlan.topology.interfaces.modes.all.count > 0 + delegate_to: localhost + +- name: Save interface_all + ansible.builtin.copy: + content: "{{ interface_all | to_nice_yaml }}" + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interfaces: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/common/ndfc_interface_loopback.yml b/roles/dtc/common/tasks/common/ndfc_interface_loopback.yml new file mode 100644 index 00000000..205aea48 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_interface_loopback.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_loopback: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_loopback_interfaces.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Loopback Interfaces List From Template + ansible.builtin.template: + src: ndfc_interfaces/ndfc_loopback_interfaces.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set int_loopback_config Var + ansible.builtin.set_fact: + int_loopback_config: [] + delegate_to: localhost + +- name: Set int_loopback_config Var + ansible.builtin.set_fact: + int_loopback_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_loopback: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_interface_po_routed.yml b/roles/dtc/common/tasks/common/ndfc_interface_po_routed.yml new file mode 100644 index 00000000..65cdc6d3 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_interface_po_routed.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_po_routed: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_interface_po_routed.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface Po + ansible.builtin.template: + src: ndfc_interfaces/ndfc_interface_po_routed.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set interface_po_routed Var default + ansible.builtin.set_fact: + interface_po_routed: [] + delegate_to: localhost + +- name: Set interface_po_routed Var + ansible.builtin.set_fact: + interface_po_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_po_routed: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_interface_routed.yml b/roles/dtc/common/tasks/common/ndfc_interface_routed.yml new file mode 100644 index 00000000..3b0a6c48 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_interface_routed.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_routed: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_interface_routed.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interfaces/ndfc_interface_routed.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set interface_routed Var default + ansible.builtin.set_fact: + interface_routed: [] + delegate_to: localhost + +- name: Set interface_routed Var + ansible.builtin.set_fact: + interface_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_routed: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_interface_trunk.yml b/roles/dtc/common/tasks/common/ndfc_interface_trunk.yml new file mode 100644 index 00000000..d174d1aa --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_interface_trunk.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_trunk: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_interface_trunk.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interfaces/ndfc_interface_trunk.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set interface_trunk Var + ansible.builtin.set_fact: + interface_trunk: [] + delegate_to: localhost + +- name: Set interface_trunk Var + ansible.builtin.set_fact: + interface_trunk: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_trunk: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_interface_trunk_po.yml b/roles/dtc/common/tasks/common/ndfc_interface_trunk_po.yml new file mode 100644 index 00000000..c5c86764 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_interface_trunk_po.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_trunk_po: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_interface_trunk_po.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Interface + ansible.builtin.template: + src: ndfc_interfaces/ndfc_interface_trunk_po.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set interface_trunk_po Var + ansible.builtin.set_fact: + interface_trunk_po: [] + delegate_to: localhost + +- name: Set interface_trunk_po Var + ansible.builtin.set_fact: + interface_trunk_po: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_trunk_po: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_interface_vpc.yml b/roles/dtc/common/tasks/common/ndfc_interface_vpc.yml new file mode 100644 index 00000000..3249fdc3 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_interface_vpc.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_interface_vpc: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_interface_vpc.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build VPC interface + ansible.builtin.template: + src: ndfc_interfaces/ndfc_interface_vpc.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set interface_vpc Var default + ansible.builtin.set_fact: + interface_vpc: [] + delegate_to: localhost + +- name: Set interface_vpc Var + ansible.builtin.set_fact: + interface_vpc: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access_vpc.count > 0 or MD_Extended.vxlan.topology.interfaces.modes.trunk_vpc.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_interface_vpc: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_inventory.yml b/roles/dtc/common/tasks/common/ndfc_inventory.yml new file mode 100644 index 00000000..c530ce8b --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_inventory.yml @@ -0,0 +1,105 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Get POAP Data From POAP Enabled Devices + cisco.nac_dc_vxlan.dtc.get_poap_data: + model_data: "{{ MD_Extended }}" + register: poap_data + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_inventory: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_inventory.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Set Path For Inventory File Lookup + ansible.builtin.set_fact: + inv_file_path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Build Fabric Switch Inventory List From Template + ansible.builtin.template: + src: ndfc_inventory.j2 + dest: "{{ inv_file_path }}" + delegate_to: localhost + +- name: Create Empty inv_config Var + ansible.builtin.set_fact: + inv_config: [] + delegate_to: localhost + +- name: Set inv_config Var + ansible.builtin.set_fact: + inv_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: (MD_Extended.vxlan.topology.switches | default([])) | length > 0 + delegate_to: localhost + +- name: Retrieve NDFC Device Username and Password from Group Vars and update inv_config + cisco.nac_dc_vxlan.common.get_credentials: + inv_list: "{{ inv_config }}" + register: updated_inv_config + no_log: true + +- name: Credential Retrieval Failed + ansible.builtin.fail: + msg: "{{ updated_inv_config }}" + when: updated_inv_config['retrieve_failed'] + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_inventory: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_link_vpc_peering.yml b/roles/dtc/common/tasks/common/ndfc_link_vpc_peering.yml new file mode 100644 index 00000000..7a70e982 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_link_vpc_peering.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_link_vpc_peering: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_link_vpc_peering.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Links for VPC Peering + ansible.builtin.template: + src: ndfc_links_vpc_peering.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set link_vpc_peering Var default + ansible.builtin.set_fact: + link_vpc_peering: [] + delegate_to: localhost + +- name: Set link_vpc_peering Var + ansible.builtin.set_fact: + link_vpc_peering: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.vpc_peers | length > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_link_vpc_peering: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_policy.yml b/roles/dtc/common/tasks/common/ndfc_policy.yml new file mode 100644 index 00000000..9f965bbe --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_policy.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_policy: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_policy.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + # TODO: Add capability to overridde path variable above for CI/CD pipeline + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build Policy List From Template + ansible.builtin.template: + src: ndfc_policy.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set policy_config Var + ansible.builtin.set_fact: + policy_config: [] + delegate_to: localhost + +- ansible.builtin.set_fact: + policy_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: (MD_Extended.vxlan.policy.policies | default([])) | length > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_policy: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_sub_interface_routed.yml b/roles/dtc/common/tasks/common/ndfc_sub_interface_routed.yml new file mode 100644 index 00000000..6f0fd1c6 --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_sub_interface_routed.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_sub_interface_routed: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_sub_interface_routed.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build sub_interface + ansible.builtin.template: + src: ndfc_interfaces/ndfc_sub_interface_routed.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set sub_interface_routed Var default + ansible.builtin.set_fact: + sub_interface_routed: [] + delegate_to: localhost + +- name: Set sub_interface_routed Var + ansible.builtin.set_fact: + sub_interface_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_sub_interface_routed: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/common/ndfc_vpc_peering.yml b/roles/dtc/common/tasks/common/ndfc_vpc_peering.yml new file mode 100644 index 00000000..08fa07fc --- /dev/null +++ b/roles/dtc/common/tasks/common/ndfc_vpc_peering.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Initialize changes_detected Var + ansible.builtin.set_fact: + changes_detected_vpc_peering: false + delegate_to: localhost + +- name: Set file_name Var + ansible.builtin.set_fact: + file_name: "ndfc_vpc_peering.yml" + delegate_to: localhost + +- name: Stat Previous File If It Exists + ansible.builtin.stat: + path: "{{ path_name }}{{ file_name }}" + register: data_file_previous + delegate_to: localhost + +- name: Backup Previous Data File If It Exists + ansible.builtin.copy: + src: "{{ path_name }}{{ file_name }}" + dest: "{{ path_name }}{{ file_name }}.old" + when: data_file_previous.stat.exists + +- name: Delete Previous Data File If It Exists + ansible.builtin.file: + state: absent + path: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + when: data_file_previous.stat.exists + +- name: Build vPC Peering + ansible.builtin.template: + src: ndfc_vpc_peering.j2 + dest: "{{ path_name }}{{ file_name }}" + delegate_to: localhost + +- name: Set vpc_peering Var default + ansible.builtin.set_fact: + vpc_peering: [] + delegate_to: localhost + +- name: Set vpc_peering Var + ansible.builtin.set_fact: + vpc_peering: "{{ lookup('file', path_name + file_name) | from_yaml }}" + when: MD_Extended.vxlan.topology.vpc_peers | length > 0 + delegate_to: localhost + +- name: Diff Previous and Current Data Files + cisco.nac_dc_vxlan.dtc.diff_model_changes: + file_name_previous: "{{ path_name }}{{ file_name }}.old" + file_name_current: "{{ path_name }}{{ file_name }}" + register: file_diff_result + delegate_to: localhost + +- name: Set File Change Flag Based on File Diff Result + ansible.builtin.set_fact: + changes_detected_vpc_peering: true + delegate_to: localhost + when: + - file_diff_result.file_data_changed + - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index 185c9eb3..d91eefba 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -37,6 +37,7 @@ changes_detected_interface_routed: false changes_detected_interface_trunk_po: false changes_detected_interface_trunk: false + changes_detected_interface_vpc: false changes_detected_inventory: false changes_detected_link_vpc_peering: false changes_detected_networks: false @@ -46,7 +47,21 @@ changes_detected_vrfs: false vars_common_isn: changes_detected_fabric: false + changes_detected_fabric_links: false + changes_detected_interface_access_po: false + changes_detected_interface_access: false + changes_detected_interfaces: false + changes_detected_interface_loopback: false + changes_detected_interface_po_routed: false + changes_detected_interface_routed: false + changes_detected_interface_trunk_po: false + changes_detected_interface_trunk: false + changes_detected_interface_vpc: false changes_detected_inventory: false + changes_detected_networks: false + changes_detected_policy: false + changes_detected_sub_interface_routed: false + changes_detected_vrfs: false vars_common_msd: changes_detected_fabric: false changes_detected_vrfs: false diff --git a/roles/dtc/common/tasks/sub_main_external.yml b/roles/dtc/common/tasks/sub_main_external.yml index 1be6a5e6..4790a2e6 100644 --- a/roles/dtc/common/tasks/sub_main_external.yml +++ b/roles/dtc/common/tasks/sub_main_external.yml @@ -43,47 +43,47 @@ # -------------------------------------------------------------------- - name: Build Fabric Create Parameters - ansible.builtin.import_tasks: external/ndfc_fabric.yml + ansible.builtin.import_tasks: common/ndfc_fabric.yml # -------------------------------------------------------------------- # Build NDFC Fabric Switch Inventory List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Switch Inventory List From Template - ansible.builtin.import_tasks: external/ndfc_inventory.yml + ansible.builtin.import_tasks: common/ndfc_inventory.yml - name: Build NDFC Interface Access Po List From Template - ansible.builtin.import_tasks: external/ndfc_interface_access_po.yml + ansible.builtin.import_tasks: common/ndfc_interface_access_po.yml - name: Build NDFC Interface Access List From Template - ansible.builtin.import_tasks: external/ndfc_interface_access.yml + ansible.builtin.import_tasks: common/ndfc_interface_access.yml - name: Build NDFC Interface Loopback List From Template - ansible.builtin.import_tasks: external/ndfc_interface_loopback.yml + ansible.builtin.import_tasks: common/ndfc_interface_loopback.yml - name: Build NDFC Interface Po Routed List From Template - ansible.builtin.import_tasks: external/ndfc_interface_po_routed.yml + ansible.builtin.import_tasks: common/ndfc_interface_po_routed.yml - name: Build NDFC Interface Routed List From Template - ansible.builtin.import_tasks: external/ndfc_interface_routed.yml + ansible.builtin.import_tasks: common/ndfc_interface_routed.yml - name: Build NDFC Interface Trunk Po List From Template - ansible.builtin.import_tasks: external/ndfc_interface_trunk_po.yml + ansible.builtin.import_tasks: common/ndfc_interface_trunk_po.yml - name: Build NDFC Interface Trunk List From Template - ansible.builtin.import_tasks: external/ndfc_interface_trunk.yml + ansible.builtin.import_tasks: common/ndfc_interface_trunk.yml - name: Build NDFC Interface VPC List From Template - ansible.builtin.import_tasks: external/ndfc_interface_vpc.yml + ansible.builtin.import_tasks: common/ndfc_interface_vpc.yml - name: Build NDFC Sub Interface Routed List From Template - ansible.builtin.import_tasks: external/ndfc_sub_interface_routed.yml + ansible.builtin.import_tasks: common/ndfc_sub_interface_routed.yml - name: Build NDFC Interface all List From Template - ansible.builtin.import_tasks: external/ndfc_interface_all.yml + ansible.builtin.import_tasks: common/ndfc_interface_all.yml - name: Build NDFC Policy List From Template - ansible.builtin.import_tasks: external/ndfc_policy.yml + ansible.builtin.import_tasks: common/ndfc_policy.yml # -------------------------------------------------------------------- diff --git a/roles/dtc/common/tasks/sub_main_isn.yml b/roles/dtc/common/tasks/sub_main_isn.yml index f7e2c820..70ae5a7d 100644 --- a/roles/dtc/common/tasks/sub_main_isn.yml +++ b/roles/dtc/common/tasks/sub_main_isn.yml @@ -43,14 +43,98 @@ # -------------------------------------------------------------------- - name: Build Fabric Create Parameters - ansible.builtin.import_tasks: isn/ndfc_fabric.yml + ansible.builtin.import_tasks: common/ndfc_fabric.yml # -------------------------------------------------------------------- # Build NDFC Fabric Switch Inventory List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Switch Inventory List From Template - ansible.builtin.import_tasks: isn/ndfc_inventory.yml + ansible.builtin.import_tasks: common/ndfc_inventory.yml + +# -------------------------------------------------------------------- +# Build NDFC Fabric Loopback Interfaces List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Loopback Interfaces List From Template + ansible.builtin.import_tasks: common/ndfc_interface_loopback.yml + +# -------------------------------------------------------------------- +# Build NDFC Fabric Access Port-Channel Interfaces List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Access Port-Channel Interfaces List From Template + ansible.builtin.import_tasks: common/ndfc_interface_access_po.yml + +# -------------------------------------------------------------------- +# Build NDFC Fabric Trunk Port-Channel Interfaces List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Trunk Port-Channel Interfaces List From Template + ansible.builtin.import_tasks: common/ndfc_interface_trunk_po.yml + +# -------------------------------------------------------------------- +# Build NDFC Fabric Interface Routed List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Interface Routed List From Template + ansible.builtin.import_tasks: common/ndfc_interface_routed.yml + +# -------------------------------------------------------------------- +# Build NDFC Fabric Sub-Interface Routed List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Sub-Interface Routed List From Template + ansible.builtin.import_tasks: common/ndfc_sub_interface_routed.yml + +# -------------------------------------------------------------------- +# Build NDFC Fabric Routed Port-Channel Interface List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Routed Port-Channel Interface List From Template + ansible.builtin.import_tasks: common/ndfc_interface_po_routed.yml + +# -------------------------------------------------------------------- +# Build Trunk Interfaces List From Template +# -------------------------------------------------------------------- + +- name: Build Trunk Interfaces List From Template + ansible.builtin.import_tasks: common/ndfc_interface_trunk.yml + +# -------------------------------------------------------------------- +# Build Access Interfaces List From Template +# -------------------------------------------------------------------- + +- name: Build Access Interfaces List From Template + ansible.builtin.import_tasks: common/ndfc_interface_access.yml + +# -------------------------------------------------------------------- +# Build Fabric interface VPC List From Template +# -------------------------------------------------------------------- + +- name: Build Fabric interface VPC List From Template + ansible.builtin.import_tasks: common/ndfc_interface_vpc.yml + +# -------------------------------------------------------------------- +# Build Fabric interface all List From Template +# -------------------------------------------------------------------- + +- name: Build Fabric interface All List From Template + ansible.builtin.import_tasks: common/ndfc_interface_all.yml + +# -------------------------------------------------------------------- +# Build Fabric Policy List From Template +# -------------------------------------------------------------------- + +- name: Build Fabric Policy List From Template + ansible.builtin.import_tasks: common/ndfc_policy.yml + +# -------------------------------------------------------------------- +# Build Fabric Links List From Template +# -------------------------------------------------------------------- + +- name: Build Fabric Links List From Template + ansible.builtin.import_tasks: common/ndfc_fabric_links.yml # -------------------------------------------------------------------- # Save Local Variables To NameSpace Dict For Use Elsewhere @@ -59,18 +143,57 @@ ansible.builtin.set_fact: vars_common_isn: changes_detected_fabric: "{{ changes_detected_fabric }}" + changes_detected_fabric_links: "{{ changes_detected_fabric_links }}" + changes_detected_interface_access_po: "{{ changes_detected_interface_access_po }}" + changes_detected_interface_access: "{{ changes_detected_interface_access }}" + changes_detected_interfaces: "{{ changes_detected_interfaces }}" + changes_detected_interface_loopback: "{{ changes_detected_interface_loopback }}" + changes_detected_interface_po_routed: "{{ changes_detected_interface_po_routed }}" + changes_detected_interface_routed: "{{ changes_detected_interface_routed }}" + changes_detected_interface_trunk_po: "{{ changes_detected_interface_trunk_po }}" + changes_detected_interface_trunk: "{{ changes_detected_interface_trunk }}" + changes_detected_interface_vpc: "{{ changes_detected_interface_vpc }}" changes_detected_inventory: "{{ changes_detected_inventory }}" + changes_detected_policy: "{{ changes_detected_policy }}" + changes_detected_sub_interface_routed: "{{ changes_detected_sub_interface_routed }}" fabric_config: "{{ fabric_config }}" + fabric_links: "{{ fabric_links }}" + interface_access_po: "{{ interface_access_po }}" + interface_access: "{{ interface_access }}" + interface_all: "{{ interface_all }}" + int_loopback_config: "{{ int_loopback_config }}" + interface_po_routed: "{{ interface_po_routed }}" + interface_routed: "{{ interface_routed }}" + interface_trunk_po: "{{ interface_trunk_po }}" + interface_trunk: "{{ interface_trunk }}" + interface_vpc: "{{ interface_vpc }}" inv_config: "{{ inv_config }}" poap_data: "{{ poap_data }}" + policy_config: "{{ policy_config }}" + sub_interface_routed: "{{ sub_interface_routed }}" updated_inv_config: "{{ updated_inv_config }}" - name: Run Diff Flags ansible.builtin.debug: msg: - "----------------------------------------------------------------" - - "+ Fabric Changes Detected - [ {{ vars_common_isn.changes_detected_fabric }} ]" - - "+ Inventory Changes Detected - [ {{ vars_common_isn.changes_detected_inventory }} ]" + - "+ Fabric Changes Detected - [ {{ vars_common_vxlan.changes_detected_fabric }} ]" + - "+ Inventory Changes Detected - [ {{ vars_common_vxlan.changes_detected_inventory }} ]" + - "+ ----- Interfaces -----" + - "+ Interface vPC Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_vpc }} ]" + - "+ Interface Access Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_access }} ]" + - "+ Interface Access PO Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_access_po }} ]" + - "+ Interface Loopback Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_loopback }} ]" + - "+ Interface PO Routed Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_po_routed }} ]" + - "+ Interface Routed Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_routed }} ]" + - "+ Interface Trunk Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_trunk }} ]" + - "+ Interface Trunk PO Changes Detected - [ {{ vars_common_vxlan.changes_detected_interface_trunk_po }} ]" + - "+ Sub Interface Routed Changes Detected - [ {{ vars_common_vxlan.changes_detected_sub_interface_routed }} ]" + - "+ ----- All Interfaces -----" + - "+ All Interfaces Changes Detected - [ {{ vars_common_vxlan.changes_detected_interfaces }} ]" + - "+ ----- All Interfaces -----" + - "+ Policy Changes Detected - [ {{ vars_common_vxlan.changes_detected_policy }} ]" + - "+ Fabric Links Changes Detected - [ {{ vars_common_vxlan.changes_detected_fabric_links }} ]" - "+ ----- Run Map -----" - "+ Run Map Diff Run - [ {{ run_map_read_result.diff_run }} ]" - "+ Force Run Flag - [ {{ force_run_all }} ]" diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 1499db16..5ea45ee7 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -43,7 +43,7 @@ # -------------------------------------------------------------------- - name: Build Fabric Create Parameters - ansible.builtin.import_tasks: msd/ndfc_fabric.yml + ansible.builtin.import_tasks: common/ndfc_fabric.yml # -------------------------------------------------------------------- # Build NDFC Child Fabric Inventory List From Template diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index 1bc3e4ba..c12a059c 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -43,28 +43,28 @@ # -------------------------------------------------------------------- - name: Build Fabric Create Parameters - ansible.builtin.import_tasks: vxlan/ndfc_fabric.yml + ansible.builtin.import_tasks: common/ndfc_fabric.yml # -------------------------------------------------------------------- # Build NDFC Fabric Switch Inventory List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Switch Inventory List From Template - ansible.builtin.import_tasks: vxlan/ndfc_inventory.yml + ansible.builtin.import_tasks: common/ndfc_inventory.yml # -------------------------------------------------------------------- # Build Fabric intra links for vpc peering From Template # -------------------------------------------------------------------- - name: Build Intra Fabric Links From Template - ansible.builtin.import_tasks: vxlan/ndfc_link_vpc_peering.yml + ansible.builtin.import_tasks: common/ndfc_link_vpc_peering.yml # -------------------------------------------------------------------- # Build vPC Peering parameter List From Template # -------------------------------------------------------------------- - name: Build vPC Peering Parameters - ansible.builtin.import_tasks: vxlan/ndfc_vpc_peering.yml + ansible.builtin.import_tasks: common/ndfc_vpc_peering.yml # -------------------------------------------------------------------- # Build NDFC Fabric VRFs Attach List From Template @@ -85,84 +85,84 @@ # -------------------------------------------------------------------- - name: Build NDFC Fabric Loopback Interfaces List From Template - ansible.builtin.import_tasks: vxlan/ndfc_interface_loopback.yml + ansible.builtin.import_tasks: common/ndfc_interface_loopback.yml # -------------------------------------------------------------------- # Build NDFC Fabric Access Port-Channel Interfaces List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Access Port-Channel Interfaces List From Template - ansible.builtin.import_tasks: vxlan/ndfc_interface_access_po.yml + ansible.builtin.import_tasks: common/ndfc_interface_access_po.yml # -------------------------------------------------------------------- # Build NDFC Fabric Trunk Port-Channel Interfaces List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Trunk Port-Channel Interfaces List From Template - ansible.builtin.import_tasks: vxlan/ndfc_interface_trunk_po.yml + ansible.builtin.import_tasks: common/ndfc_interface_trunk_po.yml # -------------------------------------------------------------------- # Build NDFC Fabric Interface Routed List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Interface Routed List From Template - ansible.builtin.import_tasks: vxlan/ndfc_interface_routed.yml + ansible.builtin.import_tasks: common/ndfc_interface_routed.yml # -------------------------------------------------------------------- # Build NDFC Fabric Sub-Interface Routed List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Sub-Interface Routed List From Template - ansible.builtin.import_tasks: vxlan/ndfc_sub_interface_routed.yml + ansible.builtin.import_tasks: common/ndfc_sub_interface_routed.yml # -------------------------------------------------------------------- # Build NDFC Fabric Routed Port-Channel Interface List From Template # -------------------------------------------------------------------- - name: Build NDFC Fabric Routed Port-Channel Interface List From Template - ansible.builtin.import_tasks: vxlan/ndfc_interface_po_routed.yml + ansible.builtin.import_tasks: common/ndfc_interface_po_routed.yml # -------------------------------------------------------------------- # Build Trunk Interfaces List From Template # -------------------------------------------------------------------- - name: Build Trunk Interfaces List From Template - ansible.builtin.import_tasks: vxlan/ndfc_interface_trunk.yml + ansible.builtin.import_tasks: common/ndfc_interface_trunk.yml # -------------------------------------------------------------------- # Build Access Interfaces List From Template # -------------------------------------------------------------------- - name: Build Access Interfaces List From Template - ansible.builtin.import_tasks: vxlan/ndfc_interface_access.yml + ansible.builtin.import_tasks: common/ndfc_interface_access.yml # -------------------------------------------------------------------- # Build Fabric interface VPC List From Template # -------------------------------------------------------------------- - name: Build Fabric interface VPC List From Template - ansible.builtin.import_tasks: vxlan/ndfc_interface_vpc.yml + ansible.builtin.import_tasks: common/ndfc_interface_vpc.yml # -------------------------------------------------------------------- # Build Fabric interface all List From Template # -------------------------------------------------------------------- - name: Build Fabric interface All List From Template - ansible.builtin.import_tasks: vxlan/ndfc_interface_all.yml + ansible.builtin.import_tasks: common/ndfc_interface_all.yml # -------------------------------------------------------------------- # Build Fabric Policy List From Template # -------------------------------------------------------------------- - name: Build Fabric Policy List From Template - ansible.builtin.import_tasks: vxlan/ndfc_policy.yml + ansible.builtin.import_tasks: common/ndfc_policy.yml # -------------------------------------------------------------------- # Build Fabric Links List From Template # -------------------------------------------------------------------- - name: Build Fabric Links List From Template - ansible.builtin.import_tasks: vxlan/ndfc_fabric_links.yml + ansible.builtin.import_tasks: common/ndfc_fabric_links.yml # -------------------------------------------------------------------- # Save Local Variables To NameSpace Dict For Use Elsewhere diff --git a/roles/dtc/common/templates/ndfc_interface_access.j2 b/roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_access.j2 similarity index 100% rename from roles/dtc/common/templates/ndfc_interface_access.j2 rename to roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_access.j2 diff --git a/roles/dtc/common/templates/ndfc_interface_access_po.j2 b/roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_access_po.j2 similarity index 100% rename from roles/dtc/common/templates/ndfc_interface_access_po.j2 rename to roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_access_po.j2 diff --git a/roles/dtc/common/templates/ndfc_interface_po_routed.j2 b/roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_po_routed.j2 similarity index 100% rename from roles/dtc/common/templates/ndfc_interface_po_routed.j2 rename to roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_po_routed.j2 diff --git a/roles/dtc/common/templates/ndfc_interface_routed.j2 b/roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_routed.j2 similarity index 100% rename from roles/dtc/common/templates/ndfc_interface_routed.j2 rename to roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_routed.j2 diff --git a/roles/dtc/common/templates/ndfc_interface_trunk.j2 b/roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_trunk.j2 similarity index 100% rename from roles/dtc/common/templates/ndfc_interface_trunk.j2 rename to roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_trunk.j2 diff --git a/roles/dtc/common/templates/ndfc_interface_trunk_po.j2 b/roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_trunk_po.j2 similarity index 100% rename from roles/dtc/common/templates/ndfc_interface_trunk_po.j2 rename to roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_trunk_po.j2 diff --git a/roles/dtc/common/templates/ndfc_interface_vpc.j2 b/roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_vpc.j2 similarity index 100% rename from roles/dtc/common/templates/ndfc_interface_vpc.j2 rename to roles/dtc/common/templates/ndfc_interfaces/ndfc_interface_vpc.j2 diff --git a/roles/dtc/common/templates/ndfc_loopback_interfaces.j2 b/roles/dtc/common/templates/ndfc_interfaces/ndfc_loopback_interfaces.j2 similarity index 100% rename from roles/dtc/common/templates/ndfc_loopback_interfaces.j2 rename to roles/dtc/common/templates/ndfc_interfaces/ndfc_loopback_interfaces.j2 diff --git a/roles/dtc/common/templates/ndfc_sub_interface_routed.j2 b/roles/dtc/common/templates/ndfc_interfaces/ndfc_sub_interface_routed.j2 similarity index 100% rename from roles/dtc/common/templates/ndfc_sub_interface_routed.j2 rename to roles/dtc/common/templates/ndfc_interfaces/ndfc_sub_interface_routed.j2 diff --git a/roles/dtc/common/templates/ndfc_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory.j2 index 209148ae..1c11ea39 100644 --- a/roles/dtc/common/templates/ndfc_inventory.j2 +++ b/roles/dtc/common/templates/ndfc_inventory.j2 @@ -6,7 +6,7 @@ {% if vxlan.fabric.type == 'VXLAN_EVPN' %} {# Include NDFC DC VXLAN EVPN Base Template #} -{% include '/ndfc_inventory/dc_vxlan_fabric/dc_vxlan_fabric_inventory.j2' %} +{% include '/ndfc_inventory/common/fabric_inventory.j2' %} {% elif vxlan.fabric.type == 'ISN'%} @@ -16,7 +16,7 @@ {% elif vxlan.fabric.type == 'External' %} {# Include NDFC DC External Template #} -{% include '/ndfc_inventory/dc_external_fabric/dc_external_fabric_inventory.j2' %} +{% include '/ndfc_inventory/common/fabric_inventory.j2' %} {# Supported fabric types are: DC VXLAN EVPN and ISN #} {% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_inventory/common/fabric_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory/common/fabric_inventory.j2 new file mode 100644 index 00000000..6e300cc7 --- /dev/null +++ b/roles/dtc/common/templates/ndfc_inventory/common/fabric_inventory.j2 @@ -0,0 +1,41 @@ +{# Auto-generated NDFC DC VXLAN EVPN Inventory config data structure for fabric {{ vxlan.fabric.name }} #} +{% set poap_data = poap_data['poap_data'] %} +{% for switch in MD_Extended.vxlan.topology.switches %} +{% if switch.management.management_ipv4_address is defined %} +- seed_ip: {{ switch['management']['management_ipv4_address'] }} +{% elif switch.management.management_ipv6_address is defined %} +- seed_ip: {{ switch['management']['management_ipv6_address'] }} +{% endif %} + auth_proto: {{ MD['vxlan']['global']['auth_proto'] | default(defaults.vxlan.global.auth_proto) }} + user_name: PLACE_HOLDER_USERNAME + password: PLACE_HOLDER_PASSWORD + max_hops: 0 # this is the default value as it is not defined into the data model + role: {{ switch['role'] }} + preserve_config: false +{% if MD_Extended.vxlan.global.bootstrap is defined %} +{% if MD_Extended.vxlan.global.bootstrap.enable_bootstrap is defined and MD_Extended.vxlan.global.bootstrap.enable_bootstrap %} +{% if switch.poap is defined and switch.poap.bootstrap %} +{% if poap_data[switch['serial_number']] is defined %} +{% set pdata = poap_data[switch['serial_number']] %} + poap: + - serial_number: {{ switch['serial_number'] }} + hostname: {{ switch['name'] }} + model: {{ pdata['model'] }} + version: {{ pdata['version'] }} + config_data: + modulesModel: {{ pdata['modulesModel'] }} + gateway: {{ pdata['gateway'] }} +{% elif switch['poap']['preprovision'] is defined %} + poap: + - preprovision_serial: {{ switch['poap']['preprovision']['serial_number'] }} + model: {{ switch['poap']['preprovision']['model'] }} + version: {{ switch['poap']['preprovision']['version'] }} + config_data: + modulesModel: {{ switch['poap']['preprovision']['modulesModel'] }} + gateway: {{ switch['management']['default_gateway_v4'] }} + hostname: {{ switch['name'] }} +{% endif %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2 index dbe6eb18..6f3c0c18 100644 --- a/roles/dtc/common/templates/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2 +++ b/roles/dtc/common/templates/ndfc_inventory/isn_fabric/isn_fabric_inventory.j2 @@ -1,6 +1,6 @@ {# Auto-generated NDFC ISN Inventory config data structure for fabric {{ vxlan.fabric.name }} #} {% set poap_data = poap_data['poap_data'] %} -{% for switch in MD_Extended.vxlan.multisite.isn.topology.switches %} +{% for switch in MD_Extended.vxlan.topology.switches %} {% if switch.management.management_ipv4_address is defined %} - seed_ip: {{ switch['management']['management_ipv4_address'] }} {% elif switch.management.management_ipv6_address is defined %} @@ -13,8 +13,8 @@ max_hops: 0 # this is the default value as it is not defined into the data model role: core_router preserve_config: true -{% if MD_Extended.vxlan.multisite.isn.bootstrap is defined %} -{% if MD_Extended.vxlan.multisite.isn.bootstrap.enable_bootstrap is defined and MD_Extended.vxlan.multisite.isn.bootstrap.enable_bootstrap %} +{% if MD_Extended.vxlan.topology.bootstrap is defined %} +{% if MD_Extended.vxlan.topology.bootstrap.enable_bootstrap is defined and MD_Extended.vxlan.topology.bootstrap.enable_bootstrap %} {% if switch.poap is defined and switch.poap.bootstrap %} {% if poap_data[switch['serial_number']] is defined %} {% set pdata = poap_data[switch['serial_number']] %} diff --git a/roles/dtc/create/tasks/common/devices.yml b/roles/dtc/create/tasks/common/devices.yml new file mode 100644 index 00000000..4700c863 --- /dev/null +++ b/roles/dtc/create/tasks/common/devices.yml @@ -0,0 +1,32 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Manage Devices Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Devices Fabric {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +- name: Manage Devices Discovery + ansible.builtin.import_tasks: devices_discovery.yml diff --git a/roles/dtc/create/tasks/common/devices_discovery.yml b/roles/dtc/create/tasks/common/devices_discovery.yml new file mode 100644 index 00000000..a745277e --- /dev/null +++ b/roles/dtc/create/tasks/common/devices_discovery.yml @@ -0,0 +1,74 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Choose vars_common Based On Fabric Type + ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_vxlan }}" + when: MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_msd }}" + when: MD_Extended.vxlan.fabric.type == "MSD" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_isn }}" + when: MD_Extended.vxlan.fabric.type == "ISN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_external }}" + when: MD_Extended.vxlan.fabric.type == "External" + +- name: Add NDFC Fabric Devices {{ MD_Extended.vxlan.fabric.name }} + cisco.dcnm.dcnm_inventory: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: "{{ vars_common_local.updated_inv_config['updated_inv_list'] }}" + deploy: false + save: true + state: merged + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: MD_Extended.vxlan.topology.switches | length > 0 + +- name: Create List of Switch Serial Numbers from Data Model + ansible.builtin.set_fact: + md_serial_numbers: "{{ MD_Extended.vxlan.topology.switches | map(attribute='serial_number') | list }}" + delegate_to: localhost + +- name: Build Switch Hostname Policy Payload from Data Model Update + cisco.nac_dc_vxlan.dtc.update_switch_hostname_policy: + model_data: "{{ MD_Extended }}" + switch_serial_numbers: "{{ md_serial_numbers }}" + template_name: host_11_1 + register: results +# do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest + +- name: Join List of Switch Hostname Policy IDs from NDFC + ansible.builtin.set_fact: + policy_ids: "{{ results.policy_update.values() | map(attribute='policyId') | list | join('%2C') }}" + when: results.policy_update | length > 0 + delegate_to: localhost + +- name: Update Switch Hostname Policy in NDFC + cisco.dcnm.dcnm_rest: + method: PUT + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/policies/{{ policy_ids }}/bulk" + json_data: "{{ results.policy_update.values() | list | to_json }}" + when: results.policy_update | length > 0 \ No newline at end of file diff --git a/roles/dtc/create/tasks/common/devices_preprovision.yml b/roles/dtc/create/tasks/common/devices_preprovision.yml new file mode 100644 index 00000000..add6d8a8 --- /dev/null +++ b/roles/dtc/create/tasks/common/devices_preprovision.yml @@ -0,0 +1,79 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +# This is just a placeholder example and is not currently enabled as part of +# the solution workflow. The module calls below represent a pre-provision +# workflow and how the dcnm_inventory module can be used to pre-provision +# a switch. + + tasks: + - name: Pre-provision switch Configuration + cisco.dcnm.dcnm_inventory: + fabric: nac-ndfc1 + state: merged # Only 2 options supported merged/query for poap config + config: + # All the values below are mandatory if poap configuration is being done - state is merged + - seed_ip: 192.168.9.14 + user_name: admin + password: cisco.123 + role: border + poap: + - preprovision_serial: 9Y0K4YPFFFF + model: N9K-C9300v + version: 9.3(7) + hostname: netascode-leaf3 + # image_policy: "prepro_image_policy" + config_data: + modulesModel: [N9K-X9364v, N9K-vSUP] + gateway: 192.168.9.1/24 + vars: + ansible_command_timeout: 1000 + ansible_connect_timeout: 1000 + + # Note: Calling the module in this way will switch out the fake + # serial number with the actual switch serial number and also + # poap the switch if it's in poap mode and appears in the NDFC + # poap list. + - name: Pre-provision switch Configuration + cisco.dcnm.dcnm_inventory: + fabric: nac-ndfc1 + state: merged # Only 2 options supported merged/query for poap config + config: + # All the values below are mandatory if poap configuration is being done - state is merged + - seed_ip: 192.168.9.14 + user_name: admin + password: cisco.123 + role: border + poap: + - preprovision_serial: 9Y0K4YPFFFF + serial_number: 9Y0K4YPFV64 + vars: + ansible_command_timeout: 1000 + ansible_connect_timeout: 1000 + + # preprovision: + # serial: 9Y0K4YPFFFF + # model: N9K-C9300v + # version: 9.4(8) + # modulesModel: [N9K-X9364v, N9K-vSUP] + # gateway: 10.15.9.1/24 # Add netmask to management key diff --git a/roles/dtc/create/tasks/common/fabric.yml b/roles/dtc/create/tasks/common/fabric.yml new file mode 100644 index 00000000..384c22e1 --- /dev/null +++ b/roles/dtc/create/tasks/common/fabric.yml @@ -0,0 +1,48 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Choose vars_common Based On Fabric Type + ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_vxlan }}" + when: MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_msd }}" + when: MD_Extended.vxlan.fabric.type == "MSD" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_isn }}" + when: MD_Extended.vxlan.fabric.type == "ISN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_external }}" + when: MD_Extended.vxlan.fabric.type == "External" + +- name: Manage Fabric Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Fabric {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +- name: Manage fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC + cisco.dcnm.dcnm_fabric: + state: merged + config: "{{ vars_common_local.fabric_config }}" diff --git a/roles/dtc/create/tasks/common/interfaces.yml b/roles/dtc/create/tasks/common/interfaces.yml new file mode 100644 index 00000000..1d378d15 --- /dev/null +++ b/roles/dtc/create/tasks/common/interfaces.yml @@ -0,0 +1,158 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Choose vars_common Based On Fabric Type + ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_vxlan }}" + when: MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_msd }}" + when: MD_Extended.vxlan.fabric.type == "MSD" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_isn }}" + when: MD_Extended.vxlan.fabric.type == "ISN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_external }}" + when: MD_Extended.vxlan.fabric.type == "External" + +- name: Manage Fabric Interfaces Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Fabric Interfaces {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +# -------------------------------------------------------------------- +# Manage Interface Access Portchannel Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Access Portchannel Interface + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_local.interface_access_po }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 + +# -------------------------------------------------------------------- +# Manage Interface Trunk Portchannel Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Trunk Portchannel Interface + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_local.interface_trunk_po }}" + when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 + +# -------------------------------------------------------------------- +# Manage Interface Routed Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Interface Routed + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_local.interface_routed }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 + +# -------------------------------------------------------------------- +# Manage Sub-interface Routed Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Sub-interface Routed + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_local.sub_interface_routed }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 + +# -------------------------------------------------------------------- +# Manage interface Port-Channel Routed Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Interface Port-Channel Routed + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_local.interface_po_routed }}" + when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 + +# -------------------------------------------------------------------- +# Manage interface Loopback Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage NDFC Fabric Loopback + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_local.int_loopback_config }}" + when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 + + # -------------------------------------------------------------------- +# Manage Interface Trunk Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Interface Trunk + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_local.interface_trunk }}" + when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 + +# -------------------------------------------------------------------- +# Manage Interface Access Routed Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage Interface Access + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_local.interface_access }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 + +# -------------------------------------------------------------------- +# Manage interface vPC Configuration on NDFC +# -------------------------------------------------------------------- + +- name: Manage NDFC Fabric vPCs + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: replaced + config: "{{ vars_common_local.interface_vpc }}" + when: MD_Extended.vxlan.topology.interfaces.modes.access_vpc.count > 0 or MD_Extended.vxlan.topology.interfaces.modes.trunk_vpc.count > 0 + +## Will discuss with team and switchover to the below code and remove the above code +# # -------------------------------------------------------------------- +# # Manage Interface All Configuration on NDFC +# # -------------------------------------------------------------------- + +# - name: Manage Interface All +# cisco.dcnm.dcnm_interface: +# fabric: "{{ MD_Extended.vxlan.fabric.name }}" +# state: replaced +# config: "{{ vars_common_local.interface_all }}" +# vars: +# ansible_command_timeout: 3000 +# ansible_connect_timeout: 3000 +# when: MD_Extended.vxlan.topology.interfaces.modes.all.count > 0 +# delegate_to: localhost diff --git a/roles/dtc/create/tasks/common/links.yml b/roles/dtc/create/tasks/common/links.yml new file mode 100644 index 00000000..e5000014 --- /dev/null +++ b/roles/dtc/create/tasks/common/links.yml @@ -0,0 +1,82 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Choose vars_common Based On Fabric Type + ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_vxlan }}" + when: MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_msd }}" + when: MD_Extended.vxlan.fabric.type == "MSD" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_isn }}" + when: MD_Extended.vxlan.fabric.type == "ISN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_external }}" + when: MD_Extended.vxlan.fabric.type == "External" + +- name: Manage Fabric Intra Fabric Links Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Fabric Links {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +- name: Query Links - with Src & Dst Fabric + cisco.dcnm.dcnm_links: + state: query # choose from [merged, replaced, deleted, query] + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: + - dst_fabric: "{{ MD_Extended.vxlan.fabric.name }}" # Destination fabric + register: result_links + +- name: Create empty result List + ansible.builtin.set_fact: + required_links: [] + +- name: Create a list of links that already exist + cisco.nac_dc_vxlan.dtc.existing_links_check: + existing_links: "{{ result_links.response }}" + fabric_links: "{{ vars_common_local.fabric_links }}" + register: not_required_links + when: result_links.response is defined + +# do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest +- name: Set not_required_links if result_links.response is not defined + ansible.builtin.set_fact: + not_required_links: [] + when: result_links.response is not defined + +- name: remove unwanted links from required links input + ansible.builtin.set_fact: + required_links: "{{ vars_common_local.fabric_links | difference(not_required_links['not_required_links']) }}" +# -------------------------------------------------------------------- +# Manage VRF Configuration on NDFC +# -------------------------------------------------------------------- +- name: Manage NDFC Fabric Links + cisco.dcnm.dcnm_links: + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: "{{ required_links }}" + deploy: false + state: merged + register: manage_fabric_links_result diff --git a/roles/dtc/create/tasks/common/policies.yml b/roles/dtc/create/tasks/common/policies.yml new file mode 100644 index 00000000..d41f057c --- /dev/null +++ b/roles/dtc/create/tasks/common/policies.yml @@ -0,0 +1,55 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Choose vars_common Based On Fabric Type + ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_vxlan }}" + when: MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_msd }}" + when: MD_Extended.vxlan.fabric.type == "MSD" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_isn }}" + when: MD_Extended.vxlan.fabric.type == "ISN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_external }}" + when: MD_Extended.vxlan.fabric.type == "External" + +- name: Manage Policies Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Policies Fabric {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +# -------------------------------------------------------------------- +# Manage VRF Configuration on NDFC +# -------------------------------------------------------------------- +- name: Manage NDFC Fabric Policies + cisco.dcnm.dcnm_policy: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + use_desc_as_key: true + config: "{{ vars_common_local.policy_config }}" + deploy: false + state: merged + register: manage_policies_result diff --git a/roles/dtc/create/tasks/common/vpc_peering.yml b/roles/dtc/create/tasks/common/vpc_peering.yml new file mode 100644 index 00000000..93c80bba --- /dev/null +++ b/roles/dtc/create/tasks/common/vpc_peering.yml @@ -0,0 +1,68 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +--- + +- name: Choose vars_common Based On Fabric Type + ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_vxlan }}" + when: MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_msd }}" + when: MD_Extended.vxlan.fabric.type == "MSD" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_isn }}" + when: MD_Extended.vxlan.fabric.type == "ISN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_external }}" + when: MD_Extended.vxlan.fabric.type == "External" + +- name: Manage Fabric vPC Peers Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Fabric vPC Peers {{ MD_Extended.vxlan.fabric.name }}" + - "----------------------------------------------------------------" + +# -------------------------------------------------------------------- +# Manage Intra Fabric Links Configuration on NDFC (prepare links for vpc peering) +# -------------------------------------------------------------------- + +- name: Manage Intra Fabric Links for vpc peering + cisco.dcnm.dcnm_links: + state: replaced + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: "{{ vars_common_local.link_vpc_peering }}" + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: link_vpc_peering|length != 0 + +# -------------------------------------------------------------------- +# Manage vPC Peering +# -------------------------------------------------------------------- + +- name: Manage vPC Peering + cisco.dcnm.dcnm_vpc_pair: + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" + deploy: false + state: replaced + config: "{{ vars_common_local.vpc_peering }}" diff --git a/roles/dtc/create/tasks/external/devices.yml b/roles/dtc/create/tasks/external/devices.yml index 352b2a88..4700c863 100644 --- a/roles/dtc/create/tasks/external/devices.yml +++ b/roles/dtc/create/tasks/external/devices.yml @@ -30,7 +30,3 @@ - name: Manage Devices Discovery ansible.builtin.import_tasks: devices_discovery.yml - -# TODO: Enable This Capability -# - name: Add Devices POAP -# ansible.builtin.import_tasks: devices_poap.yml diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index 20b72ddc..b75ad0da 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -39,7 +39,9 @@ when: > (MD_Extended.vxlan.fabric.type == 'ISN') and (vars_common_isn.changes_detected_fabric) or - (vars_common_isn.changes_detected_inventory) + (vars_common_isn.changes_detected_inventory) or + (vars_common_isn.changes_detected_interfaces) or + (vars_common_isn.changes_detected_policy) - name: Import MSD Role Tasks ansible.builtin.import_tasks: sub_main_msd.yml diff --git a/roles/dtc/create/tasks/sub_main_external.yml b/roles/dtc/create/tasks/sub_main_external.yml index 78ba9baa..f4f499f6 100644 --- a/roles/dtc/create/tasks/sub_main_external.yml +++ b/roles/dtc/create/tasks/sub_main_external.yml @@ -41,22 +41,22 @@ - vars_common_external.changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" -- name: Manage NDFC Fabric Switches - ansible.builtin.import_tasks: external/devices.yml +- name: Manage NDFC External Fabric Switches + ansible.builtin.import_tasks: common/devices.yml when: - MD_Extended.vxlan.topology.switches | length > 0 - vars_common_external.changes_detected_inventory tags: "{{ nac_tags.create_switches }}" -- name: Manage NDFC Fabric Interfaces - ansible.builtin.import_tasks: external/interfaces.yml +- name: Manage NDFC External Fabric Interfaces + ansible.builtin.import_tasks: common/interfaces.yml when: - (MD_Extended.vxlan.topology.interfaces.modes.all.count >0) and (MD_Extended.vxlan.topology.switches | length > 0) - vars_common_external.changes_detected_interfaces tags: "{{ nac_tags.create_interfaces }}" -- name: Manage NDFC Fabric Policies - ansible.builtin.import_tasks: external/policies.yml +- name: Manage NDFC External Fabric Policies + ansible.builtin.import_tasks: common/policies.yml when: - (MD_Extended.vxlan.policy is defined) and (MD_Extended.vxlan.policy.policies | length > 0) - vars_common_external.changes_detected_policy diff --git a/roles/dtc/create/tasks/sub_main_isn.yml b/roles/dtc/create/tasks/sub_main_isn.yml index b67d04de..8b55e671 100644 --- a/roles/dtc/create/tasks/sub_main_isn.yml +++ b/roles/dtc/create/tasks/sub_main_isn.yml @@ -33,7 +33,7 @@ tags: "{{ nac_tags.create }}" - name: Create NDFC ISN Fabric - ansible.builtin.import_tasks: isn/fabric.yml + ansible.builtin.import_tasks: common/fabric.yml when: - MD_Extended.vxlan.fabric.name is defined - MD_Extended.vxlan.fabric.type == "ISN" @@ -41,8 +41,29 @@ tags: "{{ nac_tags.create_fabric }}" - name: Manage NDFC ISN Fabric Switches - ansible.builtin.import_tasks: isn/devices.yml + ansible.builtin.import_tasks: common/devices.yml when: - - MD_Extended.vxlan.multisite.isn.topology.switches | length > 0 + - MD_Extended.vxlan.topology.switches | length > 0 - vars_common_isn.changes_detected_inventory tags: "{{ nac_tags.create_switches }}" + +- name: Manage NDFC ISN Fabric Interfaces + ansible.builtin.import_tasks: common/interfaces.yml + when: + - (MD_Extended.vxlan.topology.interfaces.modes.all.count >0) and (MD_Extended.vxlan.topology.switches | length > 0) + - vars_common_isn.changes_detected_interfaces + tags: "{{ nac_tags.create_interfaces }}" + +- name: Manage NDFC ISN Fabric Intra Links + ansible.builtin.import_tasks: common/links.yml + when: + - MD_Extended.vxlan.topology.fabric_links | length > 0 + - vars_common_isn.changes_detected_fabric_links + tags: "{{ nac_tags.create_links }}" + +- name: Manage NDFC ISN Fabric Policies + ansible.builtin.import_tasks: common/policies.yml + when: + - (MD_Extended.vxlan.policy is defined) and (MD_Extended.vxlan.policy.policies | length > 0) + - vars_common_isn.changes_detected_policy + tags: "{{ nac_tags.create_policy }}" diff --git a/roles/dtc/create/tasks/sub_main_msd.yml b/roles/dtc/create/tasks/sub_main_msd.yml index 4111180d..6f7f2957 100644 --- a/roles/dtc/create/tasks/sub_main_msd.yml +++ b/roles/dtc/create/tasks/sub_main_msd.yml @@ -33,7 +33,7 @@ tags: "{{ nac_tags.create }}" - name: Create NDFC MSD Fabric - ansible.builtin.import_tasks: msd/fabric.yml + ansible.builtin.import_tasks: common/fabric.yml when: - MD_Extended.vxlan.fabric.name is defined - MD_Extended.vxlan.fabric.type == "MSD" @@ -45,7 +45,7 @@ when: - MD_Extended.vxlan.multisite.child_fabrics is defined and MD_Extended.vxlan.multisite.child_fabrics | length > 0 -- name: Manage NDFC Fabric VRFs and Networks +- name: Manage NDFC MSD Fabric VRFs and Networks ansible.builtin.import_tasks: msd/vrfs_networks.yml when: - MD_Extended.vxlan.multisite.overlay is defined diff --git a/roles/dtc/create/tasks/sub_main_vxlan.yml b/roles/dtc/create/tasks/sub_main_vxlan.yml index aa4bc319..35f4992b 100644 --- a/roles/dtc/create/tasks/sub_main_vxlan.yml +++ b/roles/dtc/create/tasks/sub_main_vxlan.yml @@ -32,8 +32,8 @@ - ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" tags: "{{ nac_tags.create }}" -- name: Create NDFC Fabric - ansible.builtin.import_tasks: vxlan/fabric.yml +- name: Create NDFC VXLAN Fabric + ansible.builtin.import_tasks: common/fabric.yml when: - MD_Extended.vxlan.fabric.name is defined - MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" @@ -41,28 +41,28 @@ - vars_common_vxlan.changes_detected_fabric tags: "{{ nac_tags.create_fabric }}" -- name: Manage NDFC Fabric Switches - ansible.builtin.import_tasks: vxlan/devices.yml +- name: Manage NDFC VXLAN Fabric Switches + ansible.builtin.import_tasks: common/devices.yml when: - MD_Extended.vxlan.topology.switches | length > 0 - vars_common_vxlan.changes_detected_inventory tags: "{{ nac_tags.create_switches }}" -- name: Manage VPC Peering - ansible.builtin.import_tasks: vxlan/vpc_peering.yml +- name: Manage NDFC VXLAN VPC Peering + ansible.builtin.import_tasks: common/vpc_peering.yml when: - MD_Extended.vxlan.topology.vpc_peers | length > 0 - vars_common_vxlan.changes_detected_vpc_peering tags: "{{ nac_tags.create_vpc_peers }}" -- name: Manage NDFC Fabric Interfaces - ansible.builtin.import_tasks: vxlan/interfaces.yml +- name: Manage NDFC VXLAN Fabric Interfaces + ansible.builtin.import_tasks: common/interfaces.yml when: - (MD_Extended.vxlan.topology.interfaces.modes.all.count >0) and (MD_Extended.vxlan.topology.switches | length > 0) - vars_common_vxlan.changes_detected_interfaces tags: "{{ nac_tags.create_interfaces }}" -- name: Manage NDFC Fabric VRFs and Networks +- name: Manage NDFC VXLAN Fabric VRFs and Networks ansible.builtin.import_tasks: vxlan/vrfs_networks.yml when: - MD_Extended.vxlan.overlay is defined @@ -70,15 +70,15 @@ - vars_common_vxlan.changes_detected_vrfs or vars_common_vxlan.changes_detected_networks tags: "{{ nac_tags.create_vrfs_networks }}" -- name: Manage NDFC Fabric Intra Links - ansible.builtin.import_tasks: vxlan/links.yml +- name: Manage NDFC VXLAN Fabric Intra Links + ansible.builtin.import_tasks: common/links.yml when: - MD_Extended.vxlan.topology.fabric_links | length > 0 - vars_common_vxlan.changes_detected_fabric_links tags: "{{ nac_tags.create_links }}" -- name: Manage NDFC Fabric Policies - ansible.builtin.import_tasks: vxlan/policies.yml +- name: Manage NDFC VXLAN Fabric Policies + ansible.builtin.import_tasks: common/policies.yml when: - (MD_Extended.vxlan.policy is defined) and (MD_Extended.vxlan.policy.policies | length > 0) - vars_common_vxlan.changes_detected_policy diff --git a/roles/dtc/remove/tasks/common/interfaces.yml b/roles/dtc/remove/tasks/common/interfaces.yml new file mode 100644 index 00000000..3f375ce6 --- /dev/null +++ b/roles/dtc/remove/tasks/common/interfaces.yml @@ -0,0 +1,82 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT +--- + +- name: Choose vars_common Based On Fabric Type + ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_vxlan }}" + when: MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_msd }}" + when: MD_Extended.vxlan.fabric.type == "MSD" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_isn }}" + when: MD_Extended.vxlan.fabric.type == "ISN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_external }}" + when: MD_Extended.vxlan.fabric.type == "External" + +- ansible.builtin.debug: msg="Removing Unmanaged Fabric Interfaces. This could take several minutes..." + when: + - switch_list.response.DATA | length > 0 + - (interface_delete_mode is defined) and (interface_delete_mode is true|bool) + +- name: Remove Unmanaged Fabric Interfaces + cisco.dcnm.dcnm_interface: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + state: overridden + config: "{{ vars_common_local.interface_all }}" + # deploy: false + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + register: int_data + when: + - switch_list.response.DATA | length > 0 + - (interface_delete_mode is defined) and (interface_delete_mode is true|bool) + +# - name: Config-Save for Fabric {{ MD_Extended.vxlan.fabric.name }} after removing or defaulting interfaces +# cisco.dcnm.dcnm_rest: +# method: POST +# path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/config-save" +# when: +# - int_data.changed is true +# - switch_list.response.DATA | length > 0 +# - (interface_delete_mode is defined) and (interface_delete_mode is true|bool) + +# - name: Deploy for Fabric {{ MD_Extended.vxlan.fabric.name }} after removing or defaulting interfaces +# cisco.dcnm.dcnm_rest: +# path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/config-deploy?forceShowRun=false" +# method: POST +# vars: +# ansible_command_timeout: 3000 +# ansible_connect_timeout: 3000 +# when: +# - int_data.changed is true +# - switch_list.response.DATA | length > 0 +# - (interface_delete_mode is defined) and (interface_delete_mode is true|bool) + +- ansible.builtin.debug: + msg: + - "-------------------------------------------------------------------------------------------------------------------" + - "+ SKIPPING Remove Unmanaged Fabric Interfaces task because interface_delete_mode flag is set to False +" + - "-------------------------------------------------------------------------------------------------------------------" + when: not ((interface_delete_mode is defined) and (interface_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/common/policy.yml b/roles/dtc/remove/tasks/common/policy.yml new file mode 100644 index 00000000..09dbc73b --- /dev/null +++ b/roles/dtc/remove/tasks/common/policy.yml @@ -0,0 +1,72 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT +--- + +- name: Choose vars_common Based On Fabric Type + ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_vxlan }}" + when: MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_msd }}" + when: MD_Extended.vxlan.fabric.type == "MSD" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_isn }}" + when: MD_Extended.vxlan.fabric.type == "ISN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_external }}" + when: MD_Extended.vxlan.fabric.type == "External" + +- block: + - ansible.builtin.debug: msg="Removing Unmanaged Fabric Policy From Switches. This could take several minutes..." + + - name: Create List of Switch Serial Numbers from NDFC Switch List + ansible.builtin.set_fact: + switch_serial_numbers: "{{ switch_list.response.DATA | map(attribute='serialNumber') | list }}" + delegate_to: localhost + + - name: Build Unmanaged Fabric Policy Payload + cisco.nac_dc_vxlan.dtc.unmanaged_policy: + switch_serial_numbers: "{{ switch_serial_numbers }}" + model_data: "{{ MD_Extended }}" + register: unmanaged_policy_config + # do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest + + - name: Remove Unmanaged NDFC Fabric Policy + cisco.dcnm.dcnm_policy: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + use_desc_as_key: true + config: "{{ unmanaged_policy_config.unmanaged_policies }}" + deploy: true + state: deleted + when: unmanaged_policy_config.unmanaged_policies | length > 0 + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: + - switch_list.response.DATA | length > 0 + - (policy_delete_mode is defined) and (policy_delete_mode is true|bool) + +- ansible.builtin.debug: + msg: + - "--------------------------------------------------------------------------------------------------------" + - "+ SKIPPING Remove Unmanaged Policy from Switches task because policy_delete_mode flag is set to False +" + - "--------------------------------------------------------------------------------------------------------" + when: not ((policy_delete_mode is defined) and (policy_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/common/switches.yml b/roles/dtc/remove/tasks/common/switches.yml new file mode 100644 index 00000000..1ed8f50a --- /dev/null +++ b/roles/dtc/remove/tasks/common/switches.yml @@ -0,0 +1,59 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT +--- + +- name: Choose vars_common Based On Fabric Type + ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_vxlan }}" + when: MD_Extended.vxlan.fabric.type == "VXLAN_EVPN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_msd }}" + when: MD_Extended.vxlan.fabric.type == "MSD" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_isn }}" + when: MD_Extended.vxlan.fabric.type == "ISN" +- ansible.builtin.set_fact: + vars_common_local: "{{ vars_common_external }}" + when: MD_Extended.vxlan.fabric.type == "External" + +- ansible.builtin.debug: msg="Removing Unmanaged Fabric Switches. This could take several minutes..." + when: + - (inventory_delete_mode is defined) and (inventory_delete_mode is true|bool) + +- name: Remove Unmanaged NDFC Fabric Devices + cisco.dcnm.dcnm_inventory: + fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: "{{ vars_common_local.updated_inv_config['updated_inv_list'] }}" + deploy: true + save: true + state: overridden + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: + - (inventory_delete_mode is defined) and (inventory_delete_mode is true|bool) + +- ansible.builtin.debug: + msg: + - "----------------------------------------------------------------------------------------------------------" + - "+ SKIPPING Remove NDFC Fabric Devices task because inventory_delete_mode flag is set to False +" + - "----------------------------------------------------------------------------------------------------------" + when: not ((inventory_delete_mode is defined) and (inventory_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/isn/links.yml b/roles/dtc/remove/tasks/isn/links.yml new file mode 100644 index 00000000..9a396cc6 --- /dev/null +++ b/roles/dtc/remove/tasks/isn/links.yml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT +--- + +- ansible.builtin.debug: msg="Removing Unmanaged vpc peer Links. This could take several minutes..." + when: + - switch_list.response.DATA | length > 0 + - (link_vpc_delete_mode is defined) and (link_vpc_delete_mode is true|bool) + +# TBD: Determine if this is needed for ISN +# +# - name: Remove Intra Fabric Links for vPC Peering +# cisco.dcnm.dcnm_links: +# state: replaced +# src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" +# config: "{{ vars_common_vxlan.link_vpc_peering }}" +# vars: +# ansible_command_timeout: 3000 +# ansible_connect_timeout: 3000 +# when: +# - switch_list.response.DATA | length > 0 +# - (link_vpc_delete_mode is defined) and (link_vpc_delete_mode is true|bool) + + +- block: + - ansible.builtin.debug: msg="Removing Unmanaged Fabric Links. This could take several minutes..." + + - name: Query Links - with Src & Dst Fabric + cisco.dcnm.dcnm_links: + state: query # choose from [merged, replaced, deleted, query] + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: + - dst_fabric: "{{ MD_Extended.vxlan.fabric.name }}" # Destination fabric + register: result_links + + - name: Create empty result List + ansible.builtin.set_fact: + required_links: [] + + - name: Create a list of links that already exist + cisco.nac_dc_vxlan.dtc.links_filter_and_remove: + existing_links: "{{ result_links.response }}" + fabric_links: "{{ vars_common_vxlan.fabric_links }}" + register: links_to_be_removed + when: result_links.response is defined + + # do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest + - name: Set not_required_links if result_links.response is not defined + ansible.builtin.set_fact: + links_to_be_removed: [] + when: result_links.response is not defined + # -------------------------------------------------------------------- + # Manage VRF Configuration on NDFC + # -------------------------------------------------------------------- + - name: Manage NDFC Fabric Links + cisco.dcnm.dcnm_links: + src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" + config: "{{ links_to_be_removed['links_to_be_removed'] }}" + deploy: false + state: deleted + register: delete_fabric_links_result + + when: + - switch_list.response.DATA | length > 0 + - (link_fabric_delete_mode is defined) and (link_fabric_delete_mode is true|bool) diff --git a/roles/dtc/remove/tasks/sub_main_isn.yml b/roles/dtc/remove/tasks/sub_main_isn.yml index 960c1351..90e71ea6 100644 --- a/roles/dtc/remove/tasks/sub_main_isn.yml +++ b/roles/dtc/remove/tasks/sub_main_isn.yml @@ -32,23 +32,33 @@ - ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" tags: "{{ nac_tags.remove }}" -# TODO: May need this to remove Policy in the future for ISN -# lines 36 - 48 -# - name: Get List of Fabric Switches from NDFC -# cisco.dcnm.dcnm_rest: -# method: GET -# path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/inventory/switchesByFabric" -# register: switch_list -# tags: "{{ nac_tags.remove }}" - -# - name: Remove Fabric Policy -# ansible.builtin.import_tasks: vxlan/policy.yml -# tags: "{{ nac_tags.remove_policy }}" -# when: -# - vars_common_vxlan.changes_detected_policy +- name: Get List of Fabric Switches from NDFC + cisco.dcnm.dcnm_rest: + method: GET + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/inventory/switchesByFabric" + register: switch_list + tags: "{{ nac_tags.remove }}" + +- name: Remove Fabric Policy + ansible.builtin.import_tasks: common/policy.yml + tags: "{{ nac_tags.remove_policy }}" + when: + - vars_common_isn.changes_detected_policy + +- name: Remove Fabric Interfaces + ansible.builtin.import_tasks: common/interfaces.yml + tags: "{{ nac_tags.remove_interfaces }}" + when: + - vars_common_isn.changes_detected_interfaces + +- name: Remove Fabric Links + ansible.builtin.import_tasks: isn/links.yml + tags: "{{ nac_tags.remove_links }}" + when: + - vars_common_isn.changes_detected_fabric_links - name: Remove Fabric Switches - ansible.builtin.import_tasks: isn/switches.yml + ansible.builtin.import_tasks: common/switches.yml tags: "{{ nac_tags.remove_switches }}" when: - - vars_common_isn.changes_detected_inventory + - vars_common_isn.changes_detected_inventory \ No newline at end of file diff --git a/roles/dtc/remove/tasks/sub_main_vxlan.yml b/roles/dtc/remove/tasks/sub_main_vxlan.yml index 0842dce8..cee3be03 100644 --- a/roles/dtc/remove/tasks/sub_main_vxlan.yml +++ b/roles/dtc/remove/tasks/sub_main_vxlan.yml @@ -40,13 +40,13 @@ tags: "{{ nac_tags.remove }}" - name: Remove Fabric Policy - ansible.builtin.import_tasks: vxlan/policy.yml + ansible.builtin.import_tasks: common/policy.yml tags: "{{ nac_tags.remove_policy }}" when: - vars_common_vxlan.changes_detected_policy - name: Remove Fabric Interfaces - ansible.builtin.import_tasks: vxlan/interfaces.yml + ansible.builtin.import_tasks: common/interfaces.yml tags: "{{ nac_tags.remove_interfaces }}" when: - vars_common_vxlan.changes_detected_interfaces @@ -67,7 +67,7 @@ ansible.builtin.import_tasks: vxlan/links.yml tags: "{{ nac_tags.remove_links }}" when: - - vars_common_vxlan.changes_detected_link_vpc_peering + - vars_common_vxlan.changes_detected_fabric_links - name: Remove Fabric vPC Peering ansible.builtin.import_tasks: vxlan/vpc_peers.yml @@ -76,7 +76,7 @@ - vars_common_vxlan.changes_detected_vpc_peering - name: Remove Fabric Switches - ansible.builtin.import_tasks: vxlan/switches.yml + ansible.builtin.import_tasks: common/switches.yml tags: "{{ nac_tags.remove_switches }}" when: - vars_common_vxlan.changes_detected_inventory From 7d7a39fb8a51fcd0c2f8a3ebaa7a1e88dc268664 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Thu, 16 Jan 2025 16:41:16 +0000 Subject: [PATCH 47/66] Refactoring and Multisite VRF and Network Removal Flag --- README.md | 12 +- roles/common_global/defaults/main.yml | 2 + roles/dtc/common/tasks/isn/ndfc_fabric.yml | 77 ---------- roles/dtc/common/tasks/isn/ndfc_inventory.yml | 105 ------------- .../tasks/isn/task_file_placeholder.yaml} | 15 +- roles/dtc/common/tasks/vxlan/ndfc_fabric.yml | 77 ---------- .../common/tasks/vxlan/ndfc_fabric_links.yml | 83 ---------- .../tasks/vxlan/ndfc_interface_access.yml | 83 ---------- .../tasks/vxlan/ndfc_interface_access_po.yml | 83 ---------- .../common/tasks/vxlan/ndfc_interface_all.yml | 83 ---------- .../tasks/vxlan/ndfc_interface_loopback.yml | 83 ---------- .../tasks/vxlan/ndfc_interface_po_routed.yml | 83 ---------- .../tasks/vxlan/ndfc_interface_routed.yml | 83 ---------- .../tasks/vxlan/ndfc_interface_trunk.yml | 83 ---------- .../tasks/vxlan/ndfc_interface_trunk_po.yml | 83 ---------- .../common/tasks/vxlan/ndfc_interface_vpc.yml | 83 ---------- .../dtc/common/tasks/vxlan/ndfc_inventory.yml | 105 ------------- .../tasks/vxlan/ndfc_link_vpc_peering.yml | 83 ---------- roles/dtc/common/tasks/vxlan/ndfc_policy.yml | 83 ---------- .../tasks/vxlan/ndfc_sub_interface_routed.yml | 83 ---------- .../common/tasks/vxlan/ndfc_vpc_peering.yml | 83 ---------- .../create/tasks/isn/devices_discovery.yml | 60 -------- ...{fabric.yml => task_file_placeholder.yaml} | 17 +-- roles/dtc/create/tasks/msd/fabric.yml | 34 ----- roles/dtc/create/tasks/vxlan/devices.yml | 36 ----- .../create/tasks/vxlan/devices_discovery.yml | 60 -------- .../tasks/vxlan/devices_preprovision.yml | 79 ---------- roles/dtc/create/tasks/vxlan/fabric.yml | 34 ----- roles/dtc/create/tasks/vxlan/interfaces.yml | 144 ------------------ roles/dtc/create/tasks/vxlan/links.yml | 68 --------- roles/dtc/create/tasks/vxlan/policies.yml | 41 ----- roles/dtc/create/tasks/vxlan/vpc_peering.yml | 54 ------- roles/dtc/remove/tasks/isn/switches.yml | 45 ------ roles/dtc/remove/tasks/msd/networks.yml | 8 +- roles/dtc/remove/tasks/msd/vrfs.yml | 12 +- roles/dtc/remove/tasks/vxlan/interfaces.yml | 68 --------- roles/dtc/remove/tasks/vxlan/policy.yml | 58 ------- roles/dtc/remove/tasks/vxlan/switches.yml | 45 ------ 38 files changed, 28 insertions(+), 2390 deletions(-) delete mode 100644 roles/dtc/common/tasks/isn/ndfc_fabric.yml delete mode 100644 roles/dtc/common/tasks/isn/ndfc_inventory.yml rename roles/dtc/{create/tasks/isn/devices.yml => common/tasks/isn/task_file_placeholder.yaml} (74%) delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_fabric.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_fabric_links.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_inventory.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_policy.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml delete mode 100644 roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml delete mode 100644 roles/dtc/create/tasks/isn/devices_discovery.yml rename roles/dtc/create/tasks/isn/{fabric.yml => task_file_placeholder.yaml} (71%) delete mode 100644 roles/dtc/create/tasks/msd/fabric.yml delete mode 100644 roles/dtc/create/tasks/vxlan/devices.yml delete mode 100644 roles/dtc/create/tasks/vxlan/devices_discovery.yml delete mode 100644 roles/dtc/create/tasks/vxlan/devices_preprovision.yml delete mode 100644 roles/dtc/create/tasks/vxlan/fabric.yml delete mode 100644 roles/dtc/create/tasks/vxlan/interfaces.yml delete mode 100644 roles/dtc/create/tasks/vxlan/links.yml delete mode 100644 roles/dtc/create/tasks/vxlan/policies.yml delete mode 100644 roles/dtc/create/tasks/vxlan/vpc_peering.yml delete mode 100644 roles/dtc/remove/tasks/isn/switches.yml delete mode 100644 roles/dtc/remove/tasks/vxlan/interfaces.yml delete mode 100644 roles/dtc/remove/tasks/vxlan/policy.yml delete mode 100644 roles/dtc/remove/tasks/vxlan/switches.yml diff --git a/README.md b/README.md index 0ebfd59e..7a64c63c 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ interface_delete_mode: false inventory_delete_mode: false link_fabric_delete_mode: false link_vpc_delete_mode: false +multisite_network_delete_mode: false +multisite_vrf_delete_mode: false network_delete_mode: false policy_delete_mode: false vpc_delete_mode: false @@ -78,15 +80,17 @@ The following control variables are available in this collection. | Variable | Description | Default Value | | -------- | ------- | ------- | +| `child_fabric_delete_mode` | Remove child fabric from MSD|MCF fabric as part of the remove role | `false` | | `force_run_all` | Force all roles in the collection to run | `false` | | `interface_delete_mode` | Remove interface state as part of the remove role | `false` | -| `network_delete_mode` | Remove network state as part of the remove role | `false` | -| `vrf_delete_mode` | Remove vrf state as part of the remove role | `false` | | `inventory_delete_mode` | Remove inventory state as part of the remove role | `false` | | `link_vpc_delete_mode` | Remove vpc link state as part of the remove role | `false` | -| `vpc_delete_mode` | Remove vpc pair state as part of the remove role | `false` | +| `multisite_network_delete_mode` | Remove network state as part of the remove role for multisite (MSD and MCF) fabrics | `false` | +| `multisite_vrf_delete_mode` | Remove vrf state as part of the remove role for multisite (MSD and MCF) fabrics | `false` | +| `network_delete_mode` | Remove network state as part of the remove role | `false` | | `policy_delete_mode` | Remove policy state as part of the remove role | `false` | -| `child_fabric_delete_mode` | Remove child fabric from MSD|MCF fabric as part of the remove role | `false` | +| `vrf_delete_mode` | Remove vrf state as part of the remove role | `false` | +| `vpc_delete_mode` | Remove vpc pair state as part of the remove role | `false` | These variables are described in more detail in different sections of this document. diff --git a/roles/common_global/defaults/main.yml b/roles/common_global/defaults/main.yml index d4bcfe4e..9a3e4ebc 100644 --- a/roles/common_global/defaults/main.yml +++ b/roles/common_global/defaults/main.yml @@ -38,6 +38,8 @@ interface_delete_mode: false inventory_delete_mode: false link_fabric_delete_mode: false link_vpc_delete_mode: false +multisite_network_delete_mode: false +multisite_vrf_delete_mode: false network_delete_mode: false policy_delete_mode: false vpc_delete_mode: false diff --git a/roles/dtc/common/tasks/isn/ndfc_fabric.yml b/roles/dtc/common/tasks/isn/ndfc_fabric.yml deleted file mode 100644 index 02d383b8..00000000 --- a/roles/dtc/common/tasks/isn/ndfc_fabric.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_fabric: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_fabric.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - # TODO: Add capability to overridde path variable above for CI/CD pipeline - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Fabric Creation Parameters From Template - ansible.builtin.template: - src: ndfc_fabric.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- ansible.builtin.set_fact: - fabric_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_fabric: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/isn/ndfc_inventory.yml b/roles/dtc/common/tasks/isn/ndfc_inventory.yml deleted file mode 100644 index c4d37aa6..00000000 --- a/roles/dtc/common/tasks/isn/ndfc_inventory.yml +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Get POAP Data From POAP Enabled Devices - cisco.nac_dc_vxlan.dtc.get_poap_data: - model_data: "{{ MD_Extended }}" - register: poap_data - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_inventory: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_inventory.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Set Path For Inventory File Lookup - ansible.builtin.set_fact: - inv_file_path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Build Fabric Switch Inventory List From Template - ansible.builtin.template: - src: ndfc_inventory.j2 - dest: "{{ inv_file_path }}" - delegate_to: localhost - -- name: Create Empty inv_config Var - ansible.builtin.set_fact: - inv_config: [] - delegate_to: localhost - -- name: Set inv_config Var - ansible.builtin.set_fact: - inv_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: (MD_Extended.vxlan.multisite.isn.topology.switches | default([])) | length > 0 - delegate_to: localhost - -- name: Retrieve NDFC Device Username and Password from Group Vars and update inv_config - cisco.nac_dc_vxlan.common.get_credentials: - inv_list: "{{ inv_config }}" - register: updated_inv_config - no_log: true - -- name: Credential Retrieval Failed - ansible.builtin.fail: - msg: "{{ updated_inv_config }}" - when: updated_inv_config['retrieve_failed'] - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_inventory: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/create/tasks/isn/devices.yml b/roles/dtc/common/tasks/isn/task_file_placeholder.yaml similarity index 74% rename from roles/dtc/create/tasks/isn/devices.yml rename to roles/dtc/common/tasks/isn/task_file_placeholder.yaml index 4700c863..2d2c07a7 100644 --- a/roles/dtc/create/tasks/isn/devices.yml +++ b/roles/dtc/common/tasks/isn/task_file_placeholder.yaml @@ -19,14 +19,7 @@ # # SPDX-License-Identifier: MIT ---- - -- name: Manage Devices Entry Point - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Manage Devices Fabric {{ MD_Extended.vxlan.fabric.name }}" - - "----------------------------------------------------------------" - -- name: Manage Devices Discovery - ansible.builtin.import_tasks: devices_discovery.yml +# This is a placeholder file for future expansion of ISN fabric type +# capabilities if needed. +# +# Tasks in this file are intended to override tasks under common \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml b/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml deleted file mode 100644 index 02d383b8..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_fabric.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_fabric: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_fabric.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - # TODO: Add capability to overridde path variable above for CI/CD pipeline - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Fabric Creation Parameters From Template - ansible.builtin.template: - src: ndfc_fabric.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- ansible.builtin.set_fact: - fabric_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_fabric: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/vxlan/ndfc_fabric_links.yml b/roles/dtc/common/tasks/vxlan/ndfc_fabric_links.yml deleted file mode 100644 index 6f7a762f..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_fabric_links.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_fabric_links: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_fabric_links.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Fabric Links - ansible.builtin.template: - src: ndfc_fabric_links.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set fabric_links Var default - ansible.builtin.set_fact: - fabric_links: [] - delegate_to: localhost - -- name: Set fabric_links Var - ansible.builtin.set_fact: - fabric_links: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.fabric_links | length > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_fabric_links: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml deleted file mode 100644 index 8b146321..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_access.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_interface_access: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_interface_access.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Interface - ansible.builtin.template: - src: ndfc_interface_access.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set interface_access Var - ansible.builtin.set_fact: - interface_access: [] - delegate_to: localhost - -- name: Set interface_access Var - ansible.builtin.set_fact: - interface_access: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_interface_access: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml deleted file mode 100644 index 702e4b44..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_access_po.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_interface_access_po: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_interface_access_po.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Interface - ansible.builtin.template: - src: ndfc_interface_access_po.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set interface_access_po Var - ansible.builtin.set_fact: - interface_access_po: [] - delegate_to: localhost - -- name: Set interface_access_po Var - ansible.builtin.set_fact: - interface_access_po: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_interface_access_po: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml deleted file mode 100644 index b4850efb..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_all.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_interfaces: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_interface_all.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Set interface_all Var - ansible.builtin.set_fact: - interface_all: [] - delegate_to: localhost - -- name: Set interface_all Var - ansible.builtin.set_fact: - interface_all: "{{ interface_access + interface_access_po + interface_trunk + interface_trunk_po + interface_routed + interface_po_routed + sub_interface_routed + interface_vpc + int_loopback_config }}" - when: MD_Extended.vxlan.topology.interfaces.modes.all.count > 0 - delegate_to: localhost - -- name: Save interface_all - ansible.builtin.copy: - content: "{{ interface_all | to_nice_yaml }}" - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_interfaces: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml deleted file mode 100644 index 0de48d66..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_loopback.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_interface_loopback: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_loopback_interfaces.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Loopback Interfaces List From Template - ansible.builtin.template: - src: ndfc_loopback_interfaces.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set int_loopback_config Var - ansible.builtin.set_fact: - int_loopback_config: [] - delegate_to: localhost - -- name: Set int_loopback_config Var - ansible.builtin.set_fact: - int_loopback_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_interface_loopback: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml deleted file mode 100644 index 5573b8c0..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_po_routed.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_interface_po_routed: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_interface_po_routed.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Interface Po - ansible.builtin.template: - src: ndfc_interface_po_routed.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set interface_po_routed Var default - ansible.builtin.set_fact: - interface_po_routed: [] - delegate_to: localhost - -- name: Set interface_po_routed Var - ansible.builtin.set_fact: - interface_po_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_interface_po_routed: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml deleted file mode 100644 index 14a6a992..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_routed.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_interface_routed: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_interface_routed.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Interface - ansible.builtin.template: - src: ndfc_interface_routed.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set interface_routed Var default - ansible.builtin.set_fact: - interface_routed: [] - delegate_to: localhost - -- name: Set interface_routed Var - ansible.builtin.set_fact: - interface_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_interface_routed: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml deleted file mode 100644 index 5cb9a408..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_interface_trunk: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_interface_trunk.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Interface - ansible.builtin.template: - src: ndfc_interface_trunk.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set interface_trunk Var - ansible.builtin.set_fact: - interface_trunk: [] - delegate_to: localhost - -- name: Set interface_trunk Var - ansible.builtin.set_fact: - interface_trunk: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_interface_trunk: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml deleted file mode 100644 index 2e155dc7..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_trunk_po.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_interface_trunk_po: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_interface_trunk_po.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Interface - ansible.builtin.template: - src: ndfc_interface_trunk_po.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set interface_trunk_po Var - ansible.builtin.set_fact: - interface_trunk_po: [] - delegate_to: localhost - -- name: Set interface_trunk_po Var - ansible.builtin.set_fact: - interface_trunk_po: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_interface_trunk_po: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml b/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml deleted file mode 100644 index d8c264f1..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_interface_vpc.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_interface_vpc: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_interface_vpc.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build VPC interface - ansible.builtin.template: - src: ndfc_interface_vpc.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set interface_vpc Var default - ansible.builtin.set_fact: - interface_vpc: [] - delegate_to: localhost - -- name: Set interface_vpc Var - ansible.builtin.set_fact: - interface_vpc: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access_vpc.count > 0 or MD_Extended.vxlan.topology.interfaces.modes.trunk_vpc.count > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_interface_vpc: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml b/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml deleted file mode 100644 index c530ce8b..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_inventory.yml +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Get POAP Data From POAP Enabled Devices - cisco.nac_dc_vxlan.dtc.get_poap_data: - model_data: "{{ MD_Extended }}" - register: poap_data - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_inventory: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_inventory.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Set Path For Inventory File Lookup - ansible.builtin.set_fact: - inv_file_path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Build Fabric Switch Inventory List From Template - ansible.builtin.template: - src: ndfc_inventory.j2 - dest: "{{ inv_file_path }}" - delegate_to: localhost - -- name: Create Empty inv_config Var - ansible.builtin.set_fact: - inv_config: [] - delegate_to: localhost - -- name: Set inv_config Var - ansible.builtin.set_fact: - inv_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: (MD_Extended.vxlan.topology.switches | default([])) | length > 0 - delegate_to: localhost - -- name: Retrieve NDFC Device Username and Password from Group Vars and update inv_config - cisco.nac_dc_vxlan.common.get_credentials: - inv_list: "{{ inv_config }}" - register: updated_inv_config - no_log: true - -- name: Credential Retrieval Failed - ansible.builtin.fail: - msg: "{{ updated_inv_config }}" - when: updated_inv_config['retrieve_failed'] - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_inventory: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml b/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml deleted file mode 100644 index 7a70e982..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_link_vpc_peering.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_link_vpc_peering: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_link_vpc_peering.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Links for VPC Peering - ansible.builtin.template: - src: ndfc_links_vpc_peering.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set link_vpc_peering Var default - ansible.builtin.set_fact: - link_vpc_peering: [] - delegate_to: localhost - -- name: Set link_vpc_peering Var - ansible.builtin.set_fact: - link_vpc_peering: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.vpc_peers | length > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_link_vpc_peering: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_policy.yml b/roles/dtc/common/tasks/vxlan/ndfc_policy.yml deleted file mode 100644 index 9f965bbe..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_policy.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_policy: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_policy.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - # TODO: Add capability to overridde path variable above for CI/CD pipeline - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build Policy List From Template - ansible.builtin.template: - src: ndfc_policy.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set policy_config Var - ansible.builtin.set_fact: - policy_config: [] - delegate_to: localhost - -- ansible.builtin.set_fact: - policy_config: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: (MD_Extended.vxlan.policy.policies | default([])) | length > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_policy: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml b/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml deleted file mode 100644 index 5446268d..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_sub_interface_routed.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_sub_interface_routed: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_sub_interface_routed.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build sub_interface - ansible.builtin.template: - src: ndfc_sub_interface_routed.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set sub_interface_routed Var default - ansible.builtin.set_fact: - sub_interface_routed: [] - delegate_to: localhost - -- name: Set sub_interface_routed Var - ansible.builtin.set_fact: - sub_interface_routed: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_sub_interface_routed: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml b/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml deleted file mode 100644 index 08fa07fc..00000000 --- a/roles/dtc/common/tasks/vxlan/ndfc_vpc_peering.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Initialize changes_detected Var - ansible.builtin.set_fact: - changes_detected_vpc_peering: false - delegate_to: localhost - -- name: Set file_name Var - ansible.builtin.set_fact: - file_name: "ndfc_vpc_peering.yml" - delegate_to: localhost - -- name: Stat Previous File If It Exists - ansible.builtin.stat: - path: "{{ path_name }}{{ file_name }}" - register: data_file_previous - delegate_to: localhost - -- name: Backup Previous Data File If It Exists - ansible.builtin.copy: - src: "{{ path_name }}{{ file_name }}" - dest: "{{ path_name }}{{ file_name }}.old" - when: data_file_previous.stat.exists - -- name: Delete Previous Data File If It Exists - ansible.builtin.file: - state: absent - path: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - when: data_file_previous.stat.exists - -- name: Build vPC Peering - ansible.builtin.template: - src: ndfc_vpc_peering.j2 - dest: "{{ path_name }}{{ file_name }}" - delegate_to: localhost - -- name: Set vpc_peering Var default - ansible.builtin.set_fact: - vpc_peering: [] - delegate_to: localhost - -- name: Set vpc_peering Var - ansible.builtin.set_fact: - vpc_peering: "{{ lookup('file', path_name + file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.vpc_peers | length > 0 - delegate_to: localhost - -- name: Diff Previous and Current Data Files - cisco.nac_dc_vxlan.dtc.diff_model_changes: - file_name_previous: "{{ path_name }}{{ file_name }}.old" - file_name_current: "{{ path_name }}{{ file_name }}" - register: file_diff_result - delegate_to: localhost - -- name: Set File Change Flag Based on File Diff Result - ansible.builtin.set_fact: - changes_detected_vpc_peering: true - delegate_to: localhost - when: - - file_diff_result.file_data_changed - - check_roles['save_previous'] \ No newline at end of file diff --git a/roles/dtc/create/tasks/isn/devices_discovery.yml b/roles/dtc/create/tasks/isn/devices_discovery.yml deleted file mode 100644 index 7374085b..00000000 --- a/roles/dtc/create/tasks/isn/devices_discovery.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Add NDFC Fabric Devices {{ MD_Extended.vxlan.fabric.name }} - cisco.dcnm.dcnm_inventory: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ vars_common_isn.updated_inv_config['updated_inv_list'] }}" - deploy: false - save: true - state: merged - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - when: MD_Extended.vxlan.multisite.isn.topology.switches | length > 0 - -- name: Create List of Switch Serial Numbers from Data Model - ansible.builtin.set_fact: - md_serial_numbers: "{{ MD_Extended.vxlan.multisite.isn.topology.switches | map(attribute='serial_number') | list }}" - delegate_to: localhost - -- name: Build Switch Hostname Policy Payload from Data Model Update - cisco.nac_dc_vxlan.dtc.update_switch_hostname_policy: - model_data: "{{ MD_Extended }}" - switch_serial_numbers: "{{ md_serial_numbers }}" - template_name: host_11_1 - register: results -# do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest - -- name: Join List of Switch Hostname Policy IDs from NDFC - ansible.builtin.set_fact: - policy_ids: "{{ results.policy_update.values() | map(attribute='policyId') | list | join('%2C') }}" - when: results.policy_update | length > 0 - delegate_to: localhost - -- name: Update Switch Hostname Policy in NDFC - cisco.dcnm.dcnm_rest: - method: PUT - path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/policies/{{ policy_ids }}/bulk" - json_data: "{{ results.policy_update.values() | list | to_json }}" - when: results.policy_update | length > 0 diff --git a/roles/dtc/create/tasks/isn/fabric.yml b/roles/dtc/create/tasks/isn/task_file_placeholder.yaml similarity index 71% rename from roles/dtc/create/tasks/isn/fabric.yml rename to roles/dtc/create/tasks/isn/task_file_placeholder.yaml index 0b17956e..2d2c07a7 100644 --- a/roles/dtc/create/tasks/isn/fabric.yml +++ b/roles/dtc/create/tasks/isn/task_file_placeholder.yaml @@ -19,16 +19,7 @@ # # SPDX-License-Identifier: MIT ---- - -- name: Manage Fabric Entry Point - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Manage Fabric {{ MD_Extended.vxlan.fabric.name }}" - - "----------------------------------------------------------------" - -- name: Manage Fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC - cisco.dcnm.dcnm_fabric: - state: merged - config: "{{ vars_common_isn.fabric_config }}" +# This is a placeholder file for future expansion of ISN fabric type +# capabilities if needed. +# +# Tasks in this file are intended to override tasks under common \ No newline at end of file diff --git a/roles/dtc/create/tasks/msd/fabric.yml b/roles/dtc/create/tasks/msd/fabric.yml deleted file mode 100644 index 7141b379..00000000 --- a/roles/dtc/create/tasks/msd/fabric.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Manage Fabric Entry Point - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Manage Fabric {{ MD_Extended.vxlan.fabric.name }}" - - "----------------------------------------------------------------" - -- name: Manage Fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC - cisco.dcnm.dcnm_fabric: - state: merged - config: "{{ vars_common_msd.fabric_config }}" diff --git a/roles/dtc/create/tasks/vxlan/devices.yml b/roles/dtc/create/tasks/vxlan/devices.yml deleted file mode 100644 index 352b2a88..00000000 --- a/roles/dtc/create/tasks/vxlan/devices.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Manage Devices Entry Point - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Manage Devices Fabric {{ MD_Extended.vxlan.fabric.name }}" - - "----------------------------------------------------------------" - -- name: Manage Devices Discovery - ansible.builtin.import_tasks: devices_discovery.yml - -# TODO: Enable This Capability -# - name: Add Devices POAP -# ansible.builtin.import_tasks: devices_poap.yml diff --git a/roles/dtc/create/tasks/vxlan/devices_discovery.yml b/roles/dtc/create/tasks/vxlan/devices_discovery.yml deleted file mode 100644 index dde9eaff..00000000 --- a/roles/dtc/create/tasks/vxlan/devices_discovery.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Add NDFC Fabric Devices {{ MD_Extended.vxlan.fabric.name }} - cisco.dcnm.dcnm_inventory: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ vars_common_vxlan.updated_inv_config['updated_inv_list'] }}" - deploy: false - save: true - state: merged - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - when: MD_Extended.vxlan.topology.switches | length > 0 - -- name: Create List of Switch Serial Numbers from Data Model - ansible.builtin.set_fact: - md_serial_numbers: "{{ MD_Extended.vxlan.topology.switches | map(attribute='serial_number') | list }}" - delegate_to: localhost - -- name: Build Switch Hostname Policy Payload from Data Model Update - cisco.nac_dc_vxlan.dtc.update_switch_hostname_policy: - model_data: "{{ MD_Extended }}" - switch_serial_numbers: "{{ md_serial_numbers }}" - template_name: host_11_1 - register: results -# do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest - -- name: Join List of Switch Hostname Policy IDs from NDFC - ansible.builtin.set_fact: - policy_ids: "{{ results.policy_update.values() | map(attribute='policyId') | list | join('%2C') }}" - when: results.policy_update | length > 0 - delegate_to: localhost - -- name: Update Switch Hostname Policy in NDFC - cisco.dcnm.dcnm_rest: - method: PUT - path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/policies/{{ policy_ids }}/bulk" - json_data: "{{ results.policy_update.values() | list | to_json }}" - when: results.policy_update | length > 0 \ No newline at end of file diff --git a/roles/dtc/create/tasks/vxlan/devices_preprovision.yml b/roles/dtc/create/tasks/vxlan/devices_preprovision.yml deleted file mode 100644 index add6d8a8..00000000 --- a/roles/dtc/create/tasks/vxlan/devices_preprovision.yml +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -# This is just a placeholder example and is not currently enabled as part of -# the solution workflow. The module calls below represent a pre-provision -# workflow and how the dcnm_inventory module can be used to pre-provision -# a switch. - - tasks: - - name: Pre-provision switch Configuration - cisco.dcnm.dcnm_inventory: - fabric: nac-ndfc1 - state: merged # Only 2 options supported merged/query for poap config - config: - # All the values below are mandatory if poap configuration is being done - state is merged - - seed_ip: 192.168.9.14 - user_name: admin - password: cisco.123 - role: border - poap: - - preprovision_serial: 9Y0K4YPFFFF - model: N9K-C9300v - version: 9.3(7) - hostname: netascode-leaf3 - # image_policy: "prepro_image_policy" - config_data: - modulesModel: [N9K-X9364v, N9K-vSUP] - gateway: 192.168.9.1/24 - vars: - ansible_command_timeout: 1000 - ansible_connect_timeout: 1000 - - # Note: Calling the module in this way will switch out the fake - # serial number with the actual switch serial number and also - # poap the switch if it's in poap mode and appears in the NDFC - # poap list. - - name: Pre-provision switch Configuration - cisco.dcnm.dcnm_inventory: - fabric: nac-ndfc1 - state: merged # Only 2 options supported merged/query for poap config - config: - # All the values below are mandatory if poap configuration is being done - state is merged - - seed_ip: 192.168.9.14 - user_name: admin - password: cisco.123 - role: border - poap: - - preprovision_serial: 9Y0K4YPFFFF - serial_number: 9Y0K4YPFV64 - vars: - ansible_command_timeout: 1000 - ansible_connect_timeout: 1000 - - # preprovision: - # serial: 9Y0K4YPFFFF - # model: N9K-C9300v - # version: 9.4(8) - # modulesModel: [N9K-X9364v, N9K-vSUP] - # gateway: 10.15.9.1/24 # Add netmask to management key diff --git a/roles/dtc/create/tasks/vxlan/fabric.yml b/roles/dtc/create/tasks/vxlan/fabric.yml deleted file mode 100644 index dfb042c9..00000000 --- a/roles/dtc/create/tasks/vxlan/fabric.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Manage Fabric Entry Point - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Manage Fabric {{ MD_Extended.vxlan.fabric.name }}" - - "----------------------------------------------------------------" - -- name: Manage fabric {{ MD_Extended.vxlan.fabric.name }} in NDFC - cisco.dcnm.dcnm_fabric: - state: merged - config: "{{ vars_common_vxlan.fabric_config }}" diff --git a/roles/dtc/create/tasks/vxlan/interfaces.yml b/roles/dtc/create/tasks/vxlan/interfaces.yml deleted file mode 100644 index 8b2a7c21..00000000 --- a/roles/dtc/create/tasks/vxlan/interfaces.yml +++ /dev/null @@ -1,144 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Manage Fabric Interfaces Entry Point - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Manage Fabric Interfaces {{ MD_Extended.vxlan.fabric.name }}" - - "----------------------------------------------------------------" - -# -------------------------------------------------------------------- -# Manage Interface Access Portchannel Configuration on NDFC -# -------------------------------------------------------------------- - -- name: Manage Access Portchannel Interface - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: replaced - config: "{{ vars_common_vxlan.interface_access_po }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 - -# -------------------------------------------------------------------- -# Manage Interface Trunk Portchannel Configuration on NDFC -# -------------------------------------------------------------------- - -- name: Manage Trunk Portchannel Interface - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: replaced - config: "{{ vars_common_vxlan.interface_trunk_po }}" - when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 - -# -------------------------------------------------------------------- -# Manage Interface Routed Configuration on NDFC -# -------------------------------------------------------------------- - -- name: Manage Interface Routed - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: replaced - config: "{{ vars_common_vxlan.interface_routed }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 - -# -------------------------------------------------------------------- -# Manage Sub-interface Routed Configuration on NDFC -# -------------------------------------------------------------------- - -- name: Manage Sub-interface Routed - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: replaced - config: "{{ vars_common_vxlan.sub_interface_routed }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 - -# -------------------------------------------------------------------- -# Manage interface Port-Channel Routed Configuration on NDFC -# -------------------------------------------------------------------- - -- name: Manage Interface Port-Channel Routed - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: replaced - config: "{{ vars_common_vxlan.interface_po_routed }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 - -# -------------------------------------------------------------------- -# Manage interface Loopback Configuration on NDFC -# -------------------------------------------------------------------- - -- name: Manage NDFC Fabric Loopback - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: replaced - config: "{{ vars_common_vxlan.int_loopback_config }}" - when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 - - # -------------------------------------------------------------------- -# Manage Interface Trunk Configuration on NDFC -# -------------------------------------------------------------------- - -- name: Manage Interface Trunk - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: replaced - config: "{{ vars_common_vxlan.interface_trunk }}" - when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 - -# -------------------------------------------------------------------- -# Manage Interface Access Routed Configuration on NDFC -# -------------------------------------------------------------------- - -- name: Manage Interface Access - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: replaced - config: "{{ vars_common_vxlan.interface_access }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 - -# -------------------------------------------------------------------- -# Manage interface vPC Configuration on NDFC -# -------------------------------------------------------------------- - -- name: Manage NDFC Fabric vPCs - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: replaced - config: "{{ vars_common_vxlan.interface_vpc }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access_vpc.count > 0 or MD_Extended.vxlan.topology.interfaces.modes.trunk_vpc.count > 0 - -## Will discuss with team and switchover to the below code and remove the above code -# # -------------------------------------------------------------------- -# # Manage Interface All Configuration on NDFC -# # -------------------------------------------------------------------- - -# - name: Manage Interface All -# cisco.dcnm.dcnm_interface: -# fabric: "{{ MD_Extended.vxlan.fabric.name }}" -# state: replaced -# config: "{{ vars_common_vxlan.interface_all }}" -# vars: -# ansible_command_timeout: 3000 -# ansible_connect_timeout: 3000 -# when: MD_Extended.vxlan.topology.interfaces.modes.all.count > 0 -# delegate_to: localhost diff --git a/roles/dtc/create/tasks/vxlan/links.yml b/roles/dtc/create/tasks/vxlan/links.yml deleted file mode 100644 index e292c721..00000000 --- a/roles/dtc/create/tasks/vxlan/links.yml +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Manage Fabric Intra Fabric Links Entry Point - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Manage Fabric Links {{ MD_Extended.vxlan.fabric.name }}" - - "----------------------------------------------------------------" - -- name: Query Links - with Src & Dst Fabric - cisco.dcnm.dcnm_links: - state: query # choose from [merged, replaced, deleted, query] - src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: - - dst_fabric: "{{ MD_Extended.vxlan.fabric.name }}" # Destination fabric - register: result_links - -- name: Create empty result List - ansible.builtin.set_fact: - required_links: [] - -- name: Create a list of links that already exist - cisco.nac_dc_vxlan.dtc.existing_links_check: - existing_links: "{{ result_links.response }}" - fabric_links: "{{ vars_common_vxlan.fabric_links }}" - register: not_required_links - when: result_links.response is defined - -# do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest -- name: Set not_required_links if result_links.response is not defined - ansible.builtin.set_fact: - not_required_links: [] - when: result_links.response is not defined - -- name: remove unwanted links from required links input - ansible.builtin.set_fact: - required_links: "{{ vars_common_vxlan.fabric_links | difference(not_required_links['not_required_links']) }}" -# -------------------------------------------------------------------- -# Manage VRF Configuration on NDFC -# -------------------------------------------------------------------- -- name: Manage NDFC Fabric Links - cisco.dcnm.dcnm_links: - src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ required_links }}" - deploy: false - state: merged - register: manage_fabric_links_result diff --git a/roles/dtc/create/tasks/vxlan/policies.yml b/roles/dtc/create/tasks/vxlan/policies.yml deleted file mode 100644 index d0e660c6..00000000 --- a/roles/dtc/create/tasks/vxlan/policies.yml +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Manage Policies Entry Point - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Manage Policies Fabric {{ MD_Extended.vxlan.fabric.name }}" - - "----------------------------------------------------------------" - -# -------------------------------------------------------------------- -# Manage VRF Configuration on NDFC -# -------------------------------------------------------------------- -- name: Manage NDFC Fabric Policies - cisco.dcnm.dcnm_policy: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - use_desc_as_key: true - config: "{{ vars_common_vxlan.policy_config }}" - deploy: false - state: merged - register: manage_policies_result diff --git a/roles/dtc/create/tasks/vxlan/vpc_peering.yml b/roles/dtc/create/tasks/vxlan/vpc_peering.yml deleted file mode 100644 index 02448332..00000000 --- a/roles/dtc/create/tasks/vxlan/vpc_peering.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT - ---- - -- name: Manage Fabric vPC Peers Entry Point - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Manage Fabric vPC Peers {{ MD_Extended.vxlan.fabric.name }}" - - "----------------------------------------------------------------" - -# -------------------------------------------------------------------- -# Manage Intra Fabric Links Configuration on NDFC (prepare links for vpc peering) -# -------------------------------------------------------------------- - -- name: Manage Intra Fabric Links for vpc peering - cisco.dcnm.dcnm_links: - state: replaced - src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ vars_common_vxlan.link_vpc_peering }}" - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - when: link_vpc_peering|length != 0 - -# -------------------------------------------------------------------- -# Manage vPC Peering -# -------------------------------------------------------------------- - -- name: Manage vPC Peering - cisco.dcnm.dcnm_vpc_pair: - src_fabric: "{{ MD_Extended.vxlan.fabric.name }}" - deploy: false - state: replaced - config: "{{ vars_common_vxlan.vpc_peering }}" diff --git a/roles/dtc/remove/tasks/isn/switches.yml b/roles/dtc/remove/tasks/isn/switches.yml deleted file mode 100644 index 8d147f65..00000000 --- a/roles/dtc/remove/tasks/isn/switches.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT ---- - -- ansible.builtin.debug: msg="Removing Unmanaged Fabric Switches. This could take several minutes..." - when: - - (inventory_delete_mode is defined) and (inventory_delete_mode is true|bool) - -- name: Remove Unmanaged NDFC Fabric Devices - cisco.dcnm.dcnm_inventory: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ vars_common_isn.updated_inv_config['updated_inv_list'] }}" - deploy: true - save: true - state: overridden - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - when: - - (inventory_delete_mode is defined) and (inventory_delete_mode is true|bool) - -- ansible.builtin.debug: - msg: - - "----------------------------------------------------------------------------------------------------------" - - "+ SKIPPING Remove NDFC Fabric Devices task because inventory_delete_mode flag is set to False +" - - "----------------------------------------------------------------------------------------------------------" - when: not ((inventory_delete_mode is defined) and (inventory_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/msd/networks.yml b/roles/dtc/remove/tasks/msd/networks.yml index 98f57ae7..aba6f853 100644 --- a/roles/dtc/remove/tasks/msd/networks.yml +++ b/roles/dtc/remove/tasks/msd/networks.yml @@ -23,7 +23,7 @@ - ansible.builtin.debug: msg="Removing Unmanaged Fabric Networks. This could take several minutes..." when: - switch_list.response.DATA | length > 0 - - (network_delete_mode is defined) and (network_delete_mode is true|bool) + - (multisite_network_delete_mode is defined) and (multisite_network_delete_mode is true|bool) - name: Remove Unmanaged Fabric Networks cisco.dcnm.dcnm_network: @@ -35,11 +35,11 @@ ansible_connect_timeout: 3000 when: - switch_list.response.DATA | length > 0 - - (network_delete_mode is defined) and (network_delete_mode is true|bool) + - (multisite_network_delete_mode is defined) and (multisite_network_delete_mode is true|bool) - ansible.builtin.debug: msg: - "---------------------------------------------------------------------------------------------------------------" - - "+ SKIPPING Remove Unmanaged Fabric Networks task because network_delete_mode flag is set to False +" + - "+ SKIPPING Remove Unmanaged Fabric Networks task because multisite_network_delete_mode flag is set to False +" - "---------------------------------------------------------------------------------------------------------------" - when: not ((network_delete_mode is defined) and (network_delete_mode is true|bool)) + when: not ((multisite_network_delete_mode is defined) and (multisite_network_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/msd/vrfs.yml b/roles/dtc/remove/tasks/msd/vrfs.yml index 1de111af..678303f0 100644 --- a/roles/dtc/remove/tasks/msd/vrfs.yml +++ b/roles/dtc/remove/tasks/msd/vrfs.yml @@ -23,7 +23,7 @@ - ansible.builtin.debug: msg="Removing Unmanaged Fabric VRFs. This could take several minutes..." when: - switch_list.response.DATA | length > 0 - - (vrf_delete_mode is defined) and (vrf_delete_mode is true|bool) + - (multisite_vrf_delete_mode is defined) and (multisite_vrf_delete_mode is true|bool) - name: Remove Unmanaged Fabric VRFs cisco.dcnm.dcnm_vrf: @@ -35,11 +35,11 @@ ansible_connect_timeout: 3000 when: - switch_list.response.DATA | length > 0 - - (vrf_delete_mode is defined) and (vrf_delete_mode is true|bool) + - (multisite_vrf_delete_mode is defined) and (multisite_vrf_delete_mode is true|bool) - ansible.builtin.debug: msg: - - "--------------------------------------------------------------------------------------------------------" - - "+ SKIPPING Remove Unmanaged Fabric VRFs task because vrf_delete_mode flag is set to False +" - - "--------------------------------------------------------------------------------------------------------" - when: not ((vrf_delete_mode is defined) and (vrf_delete_mode is true|bool)) + - "------------------------------------------------------------------------------------------------------------------" + - "+ SKIPPING Remove Unmanaged MultiSite Fabric VRFs task because multisite_vrf_delete_mode flag is set to False +" + - "------------------------------------------------------------------------------------------------------------------" + when: not ((multisite_vrf_delete_mode is defined) and (multisite_vrf_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/vxlan/interfaces.yml b/roles/dtc/remove/tasks/vxlan/interfaces.yml deleted file mode 100644 index cf3611e7..00000000 --- a/roles/dtc/remove/tasks/vxlan/interfaces.yml +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT ---- - -- ansible.builtin.debug: msg="Removing Unmanaged Fabric Interfaces. This could take several minutes..." - when: - - switch_list.response.DATA | length > 0 - - (interface_delete_mode is defined) and (interface_delete_mode is true|bool) - -- name: Remove Unmanaged Fabric Interfaces - cisco.dcnm.dcnm_interface: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - state: overridden - config: "{{ vars_common_vxlan.interface_all }}" - # deploy: false - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - register: int_data - when: - - switch_list.response.DATA | length > 0 - - (interface_delete_mode is defined) and (interface_delete_mode is true|bool) - -# - name: Config-Save for Fabric {{ MD_Extended.vxlan.fabric.name }} after removing or defaulting interfaces -# cisco.dcnm.dcnm_rest: -# method: POST -# path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/config-save" -# when: -# - int_data.changed is true -# - switch_list.response.DATA | length > 0 -# - (interface_delete_mode is defined) and (interface_delete_mode is true|bool) - -# - name: Deploy for Fabric {{ MD_Extended.vxlan.fabric.name }} after removing or defaulting interfaces -# cisco.dcnm.dcnm_rest: -# path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD_Extended.vxlan.fabric.name }}/config-deploy?forceShowRun=false" -# method: POST -# vars: -# ansible_command_timeout: 3000 -# ansible_connect_timeout: 3000 -# when: -# - int_data.changed is true -# - switch_list.response.DATA | length > 0 -# - (interface_delete_mode is defined) and (interface_delete_mode is true|bool) - -- ansible.builtin.debug: - msg: - - "-------------------------------------------------------------------------------------------------------------------" - - "+ SKIPPING Remove Unmanaged Fabric Interfaces task because interface_delete_mode flag is set to False +" - - "-------------------------------------------------------------------------------------------------------------------" - when: not ((interface_delete_mode is defined) and (interface_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/vxlan/policy.yml b/roles/dtc/remove/tasks/vxlan/policy.yml deleted file mode 100644 index 26cf28f8..00000000 --- a/roles/dtc/remove/tasks/vxlan/policy.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT ---- - -- block: - - ansible.builtin.debug: msg="Removing Unmanaged Fabric Policy From Switches. This could take several minutes..." - - - name: Create List of Switch Serial Numbers from NDFC Switch List - ansible.builtin.set_fact: - switch_serial_numbers: "{{ switch_list.response.DATA | map(attribute='serialNumber') | list }}" - delegate_to: localhost - - - name: Build Unmanaged Fabric Policy Payload - cisco.nac_dc_vxlan.dtc.unmanaged_policy: - switch_serial_numbers: "{{ switch_serial_numbers }}" - model_data: "{{ MD_Extended }}" - register: unmanaged_policy_config - # do not delegate_to: localhost as this action plugin uses Python to execute cisco.dcnm.dcnm_rest - - - name: Remove Unmanaged NDFC Fabric Policy - cisco.dcnm.dcnm_policy: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - use_desc_as_key: true - config: "{{ unmanaged_policy_config.unmanaged_policies }}" - deploy: true - state: deleted - when: unmanaged_policy_config.unmanaged_policies | length > 0 - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - when: - - switch_list.response.DATA | length > 0 - - (policy_delete_mode is defined) and (policy_delete_mode is true|bool) - -- ansible.builtin.debug: - msg: - - "--------------------------------------------------------------------------------------------------------" - - "+ SKIPPING Remove Unmanaged Policy from Switches task because policy_delete_mode flag is set to False +" - - "--------------------------------------------------------------------------------------------------------" - when: not ((policy_delete_mode is defined) and (policy_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/vxlan/switches.yml b/roles/dtc/remove/tasks/vxlan/switches.yml deleted file mode 100644 index d1105d1c..00000000 --- a/roles/dtc/remove/tasks/vxlan/switches.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (c) 2024 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 -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# SPDX-License-Identifier: MIT ---- - -- ansible.builtin.debug: msg="Removing Unmanaged Fabric Switches. This could take several minutes..." - when: - - (inventory_delete_mode is defined) and (inventory_delete_mode is true|bool) - -- name: Remove Unmanaged NDFC Fabric Devices - cisco.dcnm.dcnm_inventory: - fabric: "{{ MD_Extended.vxlan.fabric.name }}" - config: "{{ vars_common_vxlan.updated_inv_config['updated_inv_list'] }}" - deploy: true - save: true - state: overridden - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - when: - - (inventory_delete_mode is defined) and (inventory_delete_mode is true|bool) - -- ansible.builtin.debug: - msg: - - "----------------------------------------------------------------------------------------------------------" - - "+ SKIPPING Remove NDFC Fabric Devices task because inventory_delete_mode flag is set to False +" - - "----------------------------------------------------------------------------------------------------------" - when: not ((inventory_delete_mode is defined) and (inventory_delete_mode is true|bool)) From 459d30553b2d922f3676dd0ec2e5f5601bf8cb60 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Sat, 25 Jan 2025 02:57:24 +0000 Subject: [PATCH 48/66] Fix route control no data --- plugins/plugin_utils/data_model_keys.py | 4 +++ .../505_policy_route_control_route_map.py | 35 +++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/plugins/plugin_utils/data_model_keys.py b/plugins/plugin_utils/data_model_keys.py index 161beaf5..0c3eeb85 100644 --- a/plugins/plugin_utils/data_model_keys.py +++ b/plugins/plugin_utils/data_model_keys.py @@ -60,6 +60,10 @@ model_keys['VXLAN_EVPN']['overlay.network_attach_groups'] = [root_key, 'overlay', 'network_attach_groups', 'LIST'] model_keys['VXLAN_EVPN']['overlay.network_attach_groups.switches'] = [root_key, 'overlay', 'network_attach_groups', 'switches', 'LIST_INDEX'] # --- +model_keys['VXLAN_EVPN']['overlay_extensions'] = [root_key, 'overlay_extensions', 'KEY'] +model_keys['VXLAN_EVPN']['overlay_extensions.route_control'] = [root_key, 'overlay_extensions', 'route_control', 'KEY'] +model_keys['VXLAN_EVPN']['overlay_extensions.route_control.route_maps'] = [root_key, 'overlay_extensions', 'route_control', 'route_maps', 'LIST'] +# --- model_keys['VXLAN_EVPN']['policy'] = [root_key, 'policy', 'KEY'] model_keys['VXLAN_EVPN']['policy.policies'] = [root_key, 'policy', 'policies', 'LIST'] model_keys['VXLAN_EVPN']['policy.groups'] = [root_key, 'policy', 'groups', 'LIST'] diff --git a/roles/validate/files/rules/vxlan/505_policy_route_control_route_map.py b/roles/validate/files/rules/vxlan/505_policy_route_control_route_map.py index 937aee03..2ce7e6da 100644 --- a/roles/validate/files/rules/vxlan/505_policy_route_control_route_map.py +++ b/roles/validate/files/rules/vxlan/505_policy_route_control_route_map.py @@ -49,7 +49,7 @@ def match(cls, data): """ function used by iac-validate """ - route_control = [] + route_control = {} topology_switches = [] switch_policy = [] route_maps = [] @@ -94,7 +94,9 @@ def match(cls, data): ) # Check route maps integrity - if data["vxlan"].get("overlay_extensions").get("route_control").get("route_maps", None): + rm_keys = ['overlay_extensions', 'route_control', 'route_maps'] + check = cls.data_model_key_check(data["vxlan"], rm_keys) + if 'route_maps' in check['keys_data']: route_maps = data["vxlan"]["overlay_extensions"]["route_control"]["route_maps"] cls.check_route_maps( route_maps @@ -321,3 +323,32 @@ def check_set_metric_integrity( cls.results.append( "For vxlan.overlay_extensions.route_control.route_maps.entries.set.metric to be enabled, " + metric + " should be set in the metric.") + + + @classmethod + def data_model_key_check(cls, tested_object, keys): + dm_key_dict = {'keys_found': [], 'keys_not_found': [], 'keys_data': [], 'keys_no_data': []} + for key in keys: + if tested_object and key in tested_object: + dm_key_dict['keys_found'].append(key) + tested_object = tested_object[key] + if tested_object: + dm_key_dict['keys_data'].append(key) + else: + dm_key_dict['keys_no_data'].append(key) + else: + dm_key_dict['keys_not_found'].append(key) + return dm_key_dict + + @classmethod + def safeget(cls, dict, keys): + # Utility function to safely get nested dictionary values + for key in keys: + if dict is None: + return None + if key in dict: + dict = dict[key] + else: + return None + + return dict From 553df9e1ddde91aa29d9e7aa8265c15e0de81f81 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Sat, 25 Jan 2025 03:25:10 +0000 Subject: [PATCH 49/66] Fix github actions issue --- .../files/rules/vxlan/505_policy_route_control_route_map.py | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/validate/files/rules/vxlan/505_policy_route_control_route_map.py b/roles/validate/files/rules/vxlan/505_policy_route_control_route_map.py index 2ce7e6da..00894585 100644 --- a/roles/validate/files/rules/vxlan/505_policy_route_control_route_map.py +++ b/roles/validate/files/rules/vxlan/505_policy_route_control_route_map.py @@ -324,7 +324,6 @@ def check_set_metric_integrity( "For vxlan.overlay_extensions.route_control.route_maps.entries.set.metric to be enabled, " + metric + " should be set in the metric.") - @classmethod def data_model_key_check(cls, tested_object, keys): dm_key_dict = {'keys_found': [], 'keys_not_found': [], 'keys_data': [], 'keys_no_data': []} From d948485ab8a998d44a79fbf43865ba4751429e29 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Sat, 25 Jan 2025 19:26:03 +0000 Subject: [PATCH 50/66] Fix rule 401 --- .../rules/vxlan/401_overlay_services_cross_reference.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py index 01068590..d651e224 100644 --- a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py +++ b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py @@ -18,9 +18,13 @@ def match(cls, inventory): # Remove the check for overlay_services after deprecation # Remove lines 21 - 23 overlay_key = 'overlay' - check = cls.data_model_key_check(inventory, ['vxlan']) - if 'overlay_services' in check['keys_found'] and 'overlay_services' in check['keys_data']: + check = cls.data_model_key_check(inventory, ['vxlan', overlay_key]) + if overlay_key in check['keys_not_found'] or overlay_key in check['keys_no_data']: overlay_key = 'overlay_services' + check = cls.data_model_key_check(inventory, ['vxlan', overlay_key]) + if overlay_key in check['keys_not_found'] or overlay_key in check['keys_no_data']: + results.append('Overlay data not found!') + return results network_keys = ['vxlan', overlay_key, 'networks'] vrf_keys = ['vxlan', overlay_key, 'vrfs'] From 573184e72a5667523373eb6aea596e8e5e506482 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Mon, 27 Jan 2025 21:34:40 -0500 Subject: [PATCH 51/66] update defaults for msite --- roles/validate/files/defaults.yml | 544 +++++++++++++++--------------- 1 file changed, 274 insertions(+), 270 deletions(-) diff --git a/roles/validate/files/defaults.yml b/roles/validate/files/defaults.yml index 452e5a8a..fe812803 100644 --- a/roles/validate/files/defaults.yml +++ b/roles/validate/files/defaults.yml @@ -21,282 +21,286 @@ --- factory_defaults: - vxlan: - global: - route_reflectors: 2 - anycast_gateway_mac: 20:20:00:00:00:aa - auth_proto: MD5 - vpc: - peer_link_vlan: 3600 - peer_keep_alive: management - auto_recovery_time: 360 - delay_restore_time: 150 - peer_link_port_channel_id: 500 - advertise_pip: false - advertise_pip_border_only: true - domain_id_range: 1-1000 - spanning_tree: - root_bridge_protocol: unmanaged - vlan_range: - - from: 1 - to: 3967 - mst_instance_range: - - from: 0 - to: 0 - bridge_priority: 0 - netflow: - enable: false - topology: - switches: - routing_loopback_id: 0 - vtep_loopback_id: 1 - interfaces: - topology_switch_access_interface: - description: "NetAsCode Access Interface" - mtu: jumbo - speed: auto - enabled: true - access_vlan: 1 - spanning_tree_portfast: true - enable_bpdu_guard: true - topology_switch_trunk_interface: - description: "NetAsCode Trunk Interface" - mtu: jumbo - speed: auto - enabled: true - trunk_allowed_vlans: none - spanning_tree_portfast: true - enable_bpdu_guard: true - topology_switch_access_po_interface: - description: "NetAsCode Access PO Interface" - mtu: jumbo - speed: auto - enabled: true - access_vlan: 1 - pc_mode: active - spanning_tree_portfast: true - enable_bpdu_guard: true - topology_switch_trunk_po_interface: - description: "NetAsCode Trunk PO Interface" - mtu: jumbo - speed: auto - enabled: true - trunk_allowed_vlans: none - pc_mode: active - spanning_tree_portfast: true - enable_bpdu_guard: true - topology_switch_routed_interface: - description: "NetAsCode Routed Interface" - mtu: 9216 - speed: auto - enabled: true - topology_switch_routed_sub_interface: - description: "NetAsCode Routed Sub Interface" - mtu: 9216 - speed: auto - enabled: true - topology_switch_routed_po_interface: - description: "NetAsCode Routed PO Interface" - mtu: 9216 - speed: auto - enabled: true - pc_mode: active - topology_switch_loopback_interface: - description: "NetAsCode Loopback Interface" - enabled: true - vpc_peers: - domain_id: 1 - fabric_links: - edge_connections: - underlay: - general: - routing_protocol: ospf - enable_ipv6_underlay: false - replication_mode: multicast - fabric_interface_numbering: p2p - subnet_mask: 30 - manual_underlay_allocation: false - underlay_routing_loopback_id: 0 - underlay_vtep_loopback_id: 1 - underlay_routing_protocol_tag: UNDERLAY - underlay_rp_loopback_id: 254 - intra_fabric_interface_mtu: 9216 - layer2_host_interfacde_mtu: 9216 - unshut_host_interfaces: true - ipv4: - underlay_routing_loopback_ip_range: 10.2.0.0/22 - underlay_vtep_loopback_ip_range: 10.3.0.0/22 - underlay_rp_loopback_ip_range: 10.254.254.0/24 - underlay_subnet_ip_range: 10.4.0.0/16 - ipv6: - enable_ipv6_link_local_address: true - underlay_subnet_mask: 126 - ospf: - area_id: 0.0.0.0 - authentication_enable: false - authentication_key_id: 127 - isis: - level: level-2 - network_point_to_point: true - authentication_enable: false - authentication_key_id: 127 - overload_bit: true - overload_bit_elapsed_time: 60 - bgp: - authentication_enable: false - authentication_key_type: 3 - multicast: - group_subnet: 239.1.1.0/25 - rendezvous_points: 2 - rp_mode: asm - underlay_rp_loopback_id: 254 - trm_enable: false - trm_default_group: 239.1.1.0 - underlay_primary_rp_loopback_id: 2 - underlay_backup_rp_loopback_id: 3 - underlay_second_backup_rp_loopback_id: 4 - underlay_third_backup_rp_loopback_id: 5 - bfd: - enable: false - ibgp: false - ospf: false - pim: false - isis: false - authentication_enable: false - authentication_key_id: 100 - 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 - vrf_attach_groups: - switches: [] - network_attach_groups: - switches: [] - policy: - template_name: switch_freeform - priority: 500 - overlay_extensions: - vrf_lites: - ospf: - areas: - area_type: standard - default_area: 0 - distance: 110 - bfd: - enabled: false - bgp: - best_path_as_path_relax: false - graceful_restart: true - graceful_restart_helper: false - address_family_ipv4_unicast: - additional_paths_receive: false - additional_paths_send: false - default_originate: false - ebgp_distance: 20 - ibgp_distance: 200 - local_distance: 220 - address_family_ipv6_unicast: - additional_paths_receive: false - additional_paths_send: false - default_originate: false - ebgp_distance: 20 - ibgp_distance: 200 - local_distance: 220 + defaults: + vxlan: + global: + route_reflectors: 2 + anycast_gateway_mac: 20:20:00:00:00:aa + auth_proto: MD5 + vpc: + peer_link_vlan: 3600 + peer_keep_alive: management + auto_recovery_time: 360 + delay_restore_time: 150 + peer_link_port_channel_id: 500 + advertise_pip: false + advertise_pip_border_only: true + domain_id_range: 1-1000 + spanning_tree: + root_bridge_protocol: unmanaged + vlan_range: + - from: 1 + to: 3967 + mst_instance_range: + - from: 0 + to: 0 + bridge_priority: 0 + netflow: + enable: false + topology: switches: + routing_loopback_id: 0 + vtep_loopback_id: 1 interfaces: - ospf: - auth_type: none - auth_key_id: 0 - cost: 1 - passive_interface: false - mtu_ignore: false - advertise_subnet: false - bfd: - enabled: false - hello_interval: 10 - dead_interval: 40 - network_type: broadcast - priority: 1 - lsa_retransmit_interval: 5 - lsa_transmit_delay: 1 - bgp_peers: - next_hop_self: false + topology_switch_access_interface: + description: "NetAsCode Access Interface" + mtu: jumbo + speed: auto + enabled: true + access_vlan: 1 + spanning_tree_portfast: true + enable_bpdu_guard: true + topology_switch_trunk_interface: + description: "NetAsCode Trunk Interface" + mtu: jumbo + speed: auto + enabled: true + trunk_allowed_vlans: none + spanning_tree_portfast: true + enable_bpdu_guard: true + topology_switch_access_po_interface: + description: "NetAsCode Access PO Interface" + mtu: jumbo + speed: auto + enabled: true + access_vlan: 1 + pc_mode: active + spanning_tree_portfast: true + enable_bpdu_guard: true + topology_switch_trunk_po_interface: + description: "NetAsCode Trunk PO Interface" + mtu: jumbo + speed: auto + enabled: true + trunk_allowed_vlans: none + pc_mode: active + spanning_tree_portfast: true + enable_bpdu_guard: true + topology_switch_routed_interface: + description: "NetAsCode Routed Interface" + mtu: 9216 + speed: auto + enabled: true + topology_switch_routed_sub_interface: + description: "NetAsCode Routed Sub Interface" + mtu: 9216 + speed: auto + enabled: true + topology_switch_routed_po_interface: + description: "NetAsCode Routed PO Interface" + mtu: 9216 + speed: auto + enabled: true + pc_mode: active + topology_switch_loopback_interface: + description: "NetAsCode Loopback Interface" + enabled: true + vpc_peers: + domain_id: 1 + fabric_links: + edge_connections: + underlay: + general: + routing_protocol: ospf + enable_ipv6_underlay: false + replication_mode: multicast + fabric_interface_numbering: p2p + subnet_mask: 30 + manual_underlay_allocation: false + underlay_routing_loopback_id: 0 + underlay_vtep_loopback_id: 1 + underlay_routing_protocol_tag: UNDERLAY + underlay_rp_loopback_id: 254 + intra_fabric_interface_mtu: 9216 + layer2_host_interfacde_mtu: 9216 + unshut_host_interfaces: true + ipv4: + underlay_routing_loopback_ip_range: 10.2.0.0/22 + underlay_vtep_loopback_ip_range: 10.3.0.0/22 + underlay_rp_loopback_ip_range: 10.254.254.0/24 + underlay_subnet_ip_range: 10.4.0.0/16 + ipv6: + enable_ipv6_link_local_address: true + underlay_subnet_mask: 126 + ospf: + area_id: 0.0.0.0 + authentication_enable: false + authentication_key_id: 127 + isis: + level: level-2 + network_point_to_point: true + authentication_enable: false + authentication_key_id: 127 + overload_bit: true + overload_bit_elapsed_time: 60 + bgp: + authentication_enable: false + authentication_key_type: 3 + multicast: + group_subnet: 239.1.1.0/25 + rendezvous_points: 2 + rp_mode: asm + underlay_rp_loopback_id: 254 + trm_enable: false + trm_default_group: 239.1.1.0 + underlay_primary_rp_loopback_id: 2 + underlay_backup_rp_loopback_id: 3 + underlay_second_backup_rp_loopback_id: 4 + underlay_third_backup_rp_loopback_id: 5 + bfd: + enable: false + ibgp: false + ospf: false + pim: false + isis: false + authentication_enable: false + authentication_key_id: 100 + 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 + vrf_attach_groups: + switches: [] + network_attach_groups: + switches: [] + policy: + template_name: switch_freeform + priority: 500 + overlay_extensions: + vrf_lites: + ospf: + areas: + area_type: standard + default_area: 0 + distance: 110 bfd: enabled: false - disable_connected_check: false - remove_private_as: false - remove_private_as_all: false - ebgp_multihop: 2 + default_information_originate: + always: false + nssa: + default_information_originate: false + no_redistribution: false + no_summary: false + translate: + always: false + supress_fa: false + never: false + bgp: + best_path_as_path_relax: false + graceful_restart: true + graceful_restart_helper: false address_family_ipv4_unicast: - send_community: false - send_ext_community: false - allow_as_in: false - allow_as_in_number: 3 - as_override: false - route_reflector_client: false + additional_paths_receive: false + additional_paths_send: false default_originate: false - next_hop_self: false + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 220 address_family_ipv6_unicast: - send_community: false - send_ext_community: false - allow_as_in: false - allow_as_in_number: 3 - as_override: false - route_reflector_client: false + additional_paths_receive: false + additional_paths_send: false default_originate: false + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 220 + switches: + interfaces: + ospf: + auth_type: none + auth_key_id: 0 + cost: 1 + passive_interface: false + mtu_ignore: false + advertise_subnet: false + bfd: + enabled: false + hello_interval: 10 + dead_interval: 40 + network_type: broadcast + priority: 1 + lsa_retransmit_interval: 5 + lsa_transmit_delay: 1 + bgp_peers: next_hop_self: false - multisite: - enable_ipv6_underlay: false - anycast_gateway_mac: 20:20:00:00:00:aa - vtep_loopback_id: 100 - ipv4_vtep_loopback_range: 10.10.0.0/24 - ipv4_dci_subnet_range: 10.10.1.0/24 - ipv4_dci_subnet_mask: 30 - ipv6_vtep_loopback_range: fd00::a10:0/120 - ipv6_dci_subnet_range: fd00::a11:0/120 - ipv6_dci_subnet_mask: 126 - bgw_ip_tag: 54321 - overlay_ifc: Direct_To_BGWS - underlay_autoconfig: true - enable_bgp_send_community: false - enable_bgp_log_neighbor_change: false - enable_bgp_bfd: false - delay_restore: 300 - enable_ebgp_password: false - enable_trm: false - isn: - sub_int_range: 2-511 - bootstrap: - enable_bootstrap: false - enable_inband: false - enable_local_dhcp_server: false - dhcp_version: DHCPv4 - enable_aaa: false - netflow: - enable: false + bfd: + enabled: false + disable_connected_check: false + remove_private_as: false + remove_private_as_all: false + ebgp_multihop: 2 + address_family_ipv4_unicast: + send_community: false + send_ext_community: false + allow_as_in: false + allow_as_in_number: 3 + as_override: false + route_reflector_client: false + default_originate: false + next_hop_self: false + address_family_ipv6_unicast: + send_community: false + send_ext_community: false + allow_as_in: false + allow_as_in_number: 3 + as_override: false + route_reflector_client: false + default_originate: false + next_hop_self: false + multisite: + enable_ipv6_underlay: false + anycast_gateway_mac: 20:20:00:00:00:aa + vtep_loopback_id: 100 + bgw_ip_tag: 54321 + ipv4_vtep_loopback_range: 10.10.0.0/24 + ipv6_vtep_loopback_range: fd00::a10:0/120 + overlay_dci: + deployment_method: Direct_To_BGWS + ipv4_dci_subnet_range: 10.10.1.0/24 + ipv4_dci_subnet_mask: 30 + ipv6_dci_subnet_range: fd00::a11:0/120 + ipv6_dci_subnet_mask: 126 + underlay_autoconfig: true + enable_bgp_send_community: false + enable_bgp_log_neighbor_change: false + enable_bgp_bfd: false + delay_restore: 300 + enable_ebgp_password: false + enable_trm: false + isn: + sub_int_range: 2-511 From b7c3f2881e8c21320f6626f30d24e542136f0518 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 28 Jan 2025 07:09:22 -0500 Subject: [PATCH 52/66] fix typo --- plugins/action/common/prepare_service_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/action/common/prepare_service_model.py b/plugins/action/common/prepare_service_model.py index c61764d3..2211b207 100644 --- a/plugins/action/common/prepare_service_model.py +++ b/plugins/action/common/prepare_service_model.py @@ -86,7 +86,7 @@ def run(self, tmp=None, task_vars=None): results=results).prepare() if results.get('failed'): - # Check each plugin for failureds and break out of the loop early + # Check each plugin for failures and break out of the loop early # if a failure is encounterd. break From 3b0a95826abd40b3da417d1120153a1573baf535 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 28 Jan 2025 07:33:40 -0500 Subject: [PATCH 53/66] fix defaults --- roles/validate/files/defaults.yml | 547 +++++++++++++++--------------- 1 file changed, 273 insertions(+), 274 deletions(-) diff --git a/roles/validate/files/defaults.yml b/roles/validate/files/defaults.yml index fe812803..41e02f66 100644 --- a/roles/validate/files/defaults.yml +++ b/roles/validate/files/defaults.yml @@ -21,286 +21,285 @@ --- factory_defaults: - defaults: - vxlan: - global: - route_reflectors: 2 - anycast_gateway_mac: 20:20:00:00:00:aa - auth_proto: MD5 - vpc: - peer_link_vlan: 3600 - peer_keep_alive: management - auto_recovery_time: 360 - delay_restore_time: 150 - peer_link_port_channel_id: 500 - advertise_pip: false - advertise_pip_border_only: true - domain_id_range: 1-1000 - spanning_tree: - root_bridge_protocol: unmanaged - vlan_range: - - from: 1 - to: 3967 - mst_instance_range: - - from: 0 - to: 0 - bridge_priority: 0 - netflow: - enable: false - topology: - switches: - routing_loopback_id: 0 - vtep_loopback_id: 1 - interfaces: - topology_switch_access_interface: - description: "NetAsCode Access Interface" - mtu: jumbo - speed: auto - enabled: true - access_vlan: 1 - spanning_tree_portfast: true - enable_bpdu_guard: true - topology_switch_trunk_interface: - description: "NetAsCode Trunk Interface" - mtu: jumbo - speed: auto - enabled: true - trunk_allowed_vlans: none - spanning_tree_portfast: true - enable_bpdu_guard: true - topology_switch_access_po_interface: - description: "NetAsCode Access PO Interface" - mtu: jumbo - speed: auto - enabled: true - access_vlan: 1 - pc_mode: active - spanning_tree_portfast: true - enable_bpdu_guard: true - topology_switch_trunk_po_interface: - description: "NetAsCode Trunk PO Interface" - mtu: jumbo - speed: auto - enabled: true - trunk_allowed_vlans: none - pc_mode: active - spanning_tree_portfast: true - enable_bpdu_guard: true - topology_switch_routed_interface: - description: "NetAsCode Routed Interface" - mtu: 9216 - speed: auto - enabled: true - topology_switch_routed_sub_interface: - description: "NetAsCode Routed Sub Interface" - mtu: 9216 - speed: auto - enabled: true - topology_switch_routed_po_interface: - description: "NetAsCode Routed PO Interface" - mtu: 9216 - speed: auto - enabled: true - pc_mode: active - topology_switch_loopback_interface: - description: "NetAsCode Loopback Interface" - enabled: true - vpc_peers: - domain_id: 1 - fabric_links: - edge_connections: - underlay: - general: - routing_protocol: ospf - enable_ipv6_underlay: false - replication_mode: multicast - fabric_interface_numbering: p2p - subnet_mask: 30 - manual_underlay_allocation: false - underlay_routing_loopback_id: 0 - underlay_vtep_loopback_id: 1 - underlay_routing_protocol_tag: UNDERLAY - underlay_rp_loopback_id: 254 - intra_fabric_interface_mtu: 9216 - layer2_host_interfacde_mtu: 9216 - unshut_host_interfaces: true - ipv4: - underlay_routing_loopback_ip_range: 10.2.0.0/22 - underlay_vtep_loopback_ip_range: 10.3.0.0/22 - underlay_rp_loopback_ip_range: 10.254.254.0/24 - underlay_subnet_ip_range: 10.4.0.0/16 - ipv6: - enable_ipv6_link_local_address: true - underlay_subnet_mask: 126 + vxlan: + global: + route_reflectors: 2 + anycast_gateway_mac: 20:20:00:00:00:aa + auth_proto: MD5 + vpc: + peer_link_vlan: 3600 + peer_keep_alive: management + auto_recovery_time: 360 + delay_restore_time: 150 + peer_link_port_channel_id: 500 + advertise_pip: false + advertise_pip_border_only: true + domain_id_range: 1-1000 + spanning_tree: + root_bridge_protocol: unmanaged + vlan_range: + - from: 1 + to: 3967 + mst_instance_range: + - from: 0 + to: 0 + bridge_priority: 0 + netflow: + enable: false + topology: + switches: + routing_loopback_id: 0 + vtep_loopback_id: 1 + interfaces: + topology_switch_access_interface: + description: "NetAsCode Access Interface" + mtu: jumbo + speed: auto + enabled: true + access_vlan: 1 + spanning_tree_portfast: true + enable_bpdu_guard: true + topology_switch_trunk_interface: + description: "NetAsCode Trunk Interface" + mtu: jumbo + speed: auto + enabled: true + trunk_allowed_vlans: none + spanning_tree_portfast: true + enable_bpdu_guard: true + topology_switch_access_po_interface: + description: "NetAsCode Access PO Interface" + mtu: jumbo + speed: auto + enabled: true + access_vlan: 1 + pc_mode: active + spanning_tree_portfast: true + enable_bpdu_guard: true + topology_switch_trunk_po_interface: + description: "NetAsCode Trunk PO Interface" + mtu: jumbo + speed: auto + enabled: true + trunk_allowed_vlans: none + pc_mode: active + spanning_tree_portfast: true + enable_bpdu_guard: true + topology_switch_routed_interface: + description: "NetAsCode Routed Interface" + mtu: 9216 + speed: auto + enabled: true + topology_switch_routed_sub_interface: + description: "NetAsCode Routed Sub Interface" + mtu: 9216 + speed: auto + enabled: true + topology_switch_routed_po_interface: + description: "NetAsCode Routed PO Interface" + mtu: 9216 + speed: auto + enabled: true + pc_mode: active + topology_switch_loopback_interface: + description: "NetAsCode Loopback Interface" + enabled: true + vpc_peers: + domain_id: 1 + fabric_links: + edge_connections: + underlay: + general: + routing_protocol: ospf + enable_ipv6_underlay: false + replication_mode: multicast + fabric_interface_numbering: p2p + subnet_mask: 30 + manual_underlay_allocation: false + underlay_routing_loopback_id: 0 + underlay_vtep_loopback_id: 1 + underlay_routing_protocol_tag: UNDERLAY + underlay_rp_loopback_id: 254 + intra_fabric_interface_mtu: 9216 + layer2_host_interfacde_mtu: 9216 + unshut_host_interfaces: true + ipv4: + underlay_routing_loopback_ip_range: 10.2.0.0/22 + underlay_vtep_loopback_ip_range: 10.3.0.0/22 + underlay_rp_loopback_ip_range: 10.254.254.0/24 + underlay_subnet_ip_range: 10.4.0.0/16 + ipv6: + enable_ipv6_link_local_address: true + underlay_subnet_mask: 126 + ospf: + area_id: 0.0.0.0 + authentication_enable: false + authentication_key_id: 127 + isis: + level: level-2 + network_point_to_point: true + authentication_enable: false + authentication_key_id: 127 + overload_bit: true + overload_bit_elapsed_time: 60 + bgp: + authentication_enable: false + authentication_key_type: 3 + multicast: + group_subnet: 239.1.1.0/25 + rendezvous_points: 2 + rp_mode: asm + underlay_rp_loopback_id: 254 + trm_enable: false + trm_default_group: 239.1.1.0 + underlay_primary_rp_loopback_id: 2 + underlay_backup_rp_loopback_id: 3 + underlay_second_backup_rp_loopback_id: 4 + underlay_third_backup_rp_loopback_id: 5 + bfd: + enable: false + ibgp: false + ospf: false + pim: false + isis: false + authentication_enable: false + authentication_key_id: 100 + 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 + vrf_attach_groups: + switches: [] + network_attach_groups: + switches: [] + policy: + template_name: switch_freeform + priority: 500 + overlay_extensions: + vrf_lites: ospf: - area_id: 0.0.0.0 - authentication_enable: false - authentication_key_id: 127 - isis: - level: level-2 - network_point_to_point: true - authentication_enable: false - authentication_key_id: 127 - overload_bit: true - overload_bit_elapsed_time: 60 + areas: + area_type: standard + default_area: 0 + distance: 110 + bfd: + enabled: false + default_information_originate: + always: false + nssa: + default_information_originate: false + no_redistribution: false + no_summary: false + translate: + always: false + supress_fa: false + never: false bgp: - authentication_enable: false - authentication_key_type: 3 - multicast: - group_subnet: 239.1.1.0/25 - rendezvous_points: 2 - rp_mode: asm - underlay_rp_loopback_id: 254 - trm_enable: false - trm_default_group: 239.1.1.0 - underlay_primary_rp_loopback_id: 2 - underlay_backup_rp_loopback_id: 3 - underlay_second_backup_rp_loopback_id: 4 - underlay_third_backup_rp_loopback_id: 5 - bfd: - enable: false - ibgp: false - ospf: false - pim: false - isis: false - authentication_enable: false - authentication_key_id: 100 - 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 - vrf_attach_groups: - switches: [] - network_attach_groups: - switches: [] - policy: - template_name: switch_freeform - priority: 500 - overlay_extensions: - vrf_lites: - ospf: - areas: - area_type: standard - default_area: 0 - distance: 110 + best_path_as_path_relax: false + graceful_restart: true + graceful_restart_helper: false + address_family_ipv4_unicast: + additional_paths_receive: false + additional_paths_send: false + default_originate: false + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 220 + address_family_ipv6_unicast: + additional_paths_receive: false + additional_paths_send: false + default_originate: false + ebgp_distance: 20 + ibgp_distance: 200 + local_distance: 220 + switches: + interfaces: + ospf: + auth_type: none + auth_key_id: 0 + cost: 1 + passive_interface: false + mtu_ignore: false + advertise_subnet: false + bfd: + enabled: false + hello_interval: 10 + dead_interval: 40 + network_type: broadcast + priority: 1 + lsa_retransmit_interval: 5 + lsa_transmit_delay: 1 + bgp_peers: + next_hop_self: false bfd: enabled: false - default_information_originate: - always: false - nssa: - default_information_originate: false - no_redistribution: false - no_summary: false - translate: - always: false - supress_fa: false - never: false - bgp: - best_path_as_path_relax: false - graceful_restart: true - graceful_restart_helper: false + disable_connected_check: false + remove_private_as: false + remove_private_as_all: false + ebgp_multihop: 2 address_family_ipv4_unicast: - additional_paths_receive: false - additional_paths_send: false + send_community: false + send_ext_community: false + allow_as_in: false + allow_as_in_number: 3 + as_override: false + route_reflector_client: false default_originate: false - ebgp_distance: 20 - ibgp_distance: 200 - local_distance: 220 + next_hop_self: false address_family_ipv6_unicast: - additional_paths_receive: false - additional_paths_send: false + send_community: false + send_ext_community: false + allow_as_in: false + allow_as_in_number: 3 + as_override: false + route_reflector_client: false default_originate: false - ebgp_distance: 20 - ibgp_distance: 200 - local_distance: 220 - switches: - interfaces: - ospf: - auth_type: none - auth_key_id: 0 - cost: 1 - passive_interface: false - mtu_ignore: false - advertise_subnet: false - bfd: - enabled: false - hello_interval: 10 - dead_interval: 40 - network_type: broadcast - priority: 1 - lsa_retransmit_interval: 5 - lsa_transmit_delay: 1 - bgp_peers: next_hop_self: false - bfd: - enabled: false - disable_connected_check: false - remove_private_as: false - remove_private_as_all: false - ebgp_multihop: 2 - address_family_ipv4_unicast: - send_community: false - send_ext_community: false - allow_as_in: false - allow_as_in_number: 3 - as_override: false - route_reflector_client: false - default_originate: false - next_hop_self: false - address_family_ipv6_unicast: - send_community: false - send_ext_community: false - allow_as_in: false - allow_as_in_number: 3 - as_override: false - route_reflector_client: false - default_originate: false - next_hop_self: false - multisite: - enable_ipv6_underlay: false - anycast_gateway_mac: 20:20:00:00:00:aa - vtep_loopback_id: 100 - bgw_ip_tag: 54321 - ipv4_vtep_loopback_range: 10.10.0.0/24 - ipv6_vtep_loopback_range: fd00::a10:0/120 - overlay_dci: - deployment_method: Direct_To_BGWS - ipv4_dci_subnet_range: 10.10.1.0/24 - ipv4_dci_subnet_mask: 30 - ipv6_dci_subnet_range: fd00::a11:0/120 - ipv6_dci_subnet_mask: 126 - underlay_autoconfig: true - enable_bgp_send_community: false - enable_bgp_log_neighbor_change: false - enable_bgp_bfd: false - delay_restore: 300 - enable_ebgp_password: false - enable_trm: false - isn: - sub_int_range: 2-511 + multisite: + enable_ipv6_underlay: false + anycast_gateway_mac: 20:20:00:00:00:aa + vtep_loopback_id: 100 + bgw_ip_tag: 54321 + ipv4_vtep_loopback_range: 10.10.0.0/24 + ipv6_vtep_loopback_range: fd00::a10:0/120 + overlay_dci: + deployment_method: Direct_To_BGWS + ipv4_dci_subnet_range: 10.10.1.0/24 + ipv4_dci_subnet_mask: 30 + ipv6_dci_subnet_range: fd00::a11:0/120 + ipv6_dci_subnet_mask: 126 + underlay_autoconfig: true + enable_bgp_send_community: false + enable_bgp_log_neighbor_change: false + enable_bgp_bfd: false + delay_restore: 300 + enable_ebgp_password: false + enable_trm: false + isn: + sub_int_range: 2-511 From a0d2a08cf0e0810a4408ec5970a60ffa0b3b7ede Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 28 Jan 2025 08:28:14 -0500 Subject: [PATCH 54/66] refactor template groupings for vpc and vrf loopback --- ....yml => ndfc_vpc_fabric_peering_links.yml} | 2 +- ...peering.yml => ndfc_vpc_peering_pairs.yml} | 2 +- roles/dtc/common/tasks/sub_main_vxlan.yml | 4 +- roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml | 2 +- .../common/templates/ndfc_attach_networks.j2 | 6 +- .../dtc/common/templates/ndfc_attach_vrfs.j2 | 6 +- .../common/templates/ndfc_create_fabric.j2 | 347 ------------------ roles/dtc/common/templates/ndfc_fabric.j2 | 6 +- .../dtc/common/templates/ndfc_fabric_links.j2 | 3 +- roles/dtc/common/templates/ndfc_inventory.j2 | 6 +- .../ndfc_vpc_fabric_peering_links.j2} | 3 +- .../ndfc_vpc_peering_pairs.j2} | 3 +- .../ndfc_attach_vrfs_loopbacks.j2 | 3 + 13 files changed, 23 insertions(+), 370 deletions(-) rename roles/dtc/common/tasks/common/{ndfc_link_vpc_peering.yml => ndfc_vpc_fabric_peering_links.yml} (98%) rename roles/dtc/common/tasks/common/{ndfc_vpc_peering.yml => ndfc_vpc_peering_pairs.yml} (98%) delete mode 100644 roles/dtc/common/templates/ndfc_create_fabric.j2 rename roles/dtc/common/templates/{ndfc_links_vpc_peering.j2 => ndfc_vpc/ndfc_vpc_fabric_peering_links.j2} (92%) rename roles/dtc/common/templates/{ndfc_vpc_peering.j2 => ndfc_vpc/ndfc_vpc_peering_pairs.j2} (93%) rename roles/dtc/common/templates/{ => ndfc_vrfs}/ndfc_attach_vrfs_loopbacks.j2 (92%) diff --git a/roles/dtc/common/tasks/common/ndfc_link_vpc_peering.yml b/roles/dtc/common/tasks/common/ndfc_vpc_fabric_peering_links.yml similarity index 98% rename from roles/dtc/common/tasks/common/ndfc_link_vpc_peering.yml rename to roles/dtc/common/tasks/common/ndfc_vpc_fabric_peering_links.yml index 7a70e982..30ea4ef8 100644 --- a/roles/dtc/common/tasks/common/ndfc_link_vpc_peering.yml +++ b/roles/dtc/common/tasks/common/ndfc_vpc_fabric_peering_links.yml @@ -52,7 +52,7 @@ - name: Build Links for VPC Peering ansible.builtin.template: - src: ndfc_links_vpc_peering.j2 + src: ndfc_vpc/ndfc_vpc_fabric_peering_links.j2 dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost diff --git a/roles/dtc/common/tasks/common/ndfc_vpc_peering.yml b/roles/dtc/common/tasks/common/ndfc_vpc_peering_pairs.yml similarity index 98% rename from roles/dtc/common/tasks/common/ndfc_vpc_peering.yml rename to roles/dtc/common/tasks/common/ndfc_vpc_peering_pairs.yml index 08fa07fc..82b2fba9 100644 --- a/roles/dtc/common/tasks/common/ndfc_vpc_peering.yml +++ b/roles/dtc/common/tasks/common/ndfc_vpc_peering_pairs.yml @@ -52,7 +52,7 @@ - name: Build vPC Peering ansible.builtin.template: - src: ndfc_vpc_peering.j2 + src: ndfc_vpc/ndfc_vpc_peering_pairs.j2 dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost diff --git a/roles/dtc/common/tasks/sub_main_vxlan.yml b/roles/dtc/common/tasks/sub_main_vxlan.yml index c12a059c..b2e5b806 100644 --- a/roles/dtc/common/tasks/sub_main_vxlan.yml +++ b/roles/dtc/common/tasks/sub_main_vxlan.yml @@ -57,14 +57,14 @@ # -------------------------------------------------------------------- - name: Build Intra Fabric Links From Template - ansible.builtin.import_tasks: common/ndfc_link_vpc_peering.yml + ansible.builtin.import_tasks: common/ndfc_vpc_fabric_peering_links.yml # -------------------------------------------------------------------- # Build vPC Peering parameter List From Template # -------------------------------------------------------------------- - name: Build vPC Peering Parameters - ansible.builtin.import_tasks: common/ndfc_vpc_peering.yml + ansible.builtin.import_tasks: common/ndfc_vpc_peering_pairs.yml # -------------------------------------------------------------------- # Build NDFC Fabric VRFs Attach List From Template diff --git a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml index a7e492c9..b4ac10d1 100644 --- a/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml +++ b/roles/dtc/common/tasks/vxlan/ndfc_vrfs.yml @@ -90,7 +90,7 @@ - name: Build VRFs Attach List From Template for loopback ansible.builtin.template: - src: ndfc_attach_vrfs_loopbacks.j2 + src: ndfc_vrfs/ndfc_attach_vrfs_loopbacks.j2 dest: "{{ path_name }}{{ file_name }}" delegate_to: localhost diff --git a/roles/dtc/common/templates/ndfc_attach_networks.j2 b/roles/dtc/common/templates/ndfc_attach_networks.j2 index 03088f88..3d057020 100644 --- a/roles/dtc/common/templates/ndfc_attach_networks.j2 +++ b/roles/dtc/common/templates/ndfc_attach_networks.j2 @@ -1,7 +1,7 @@ --- -{#- This NDFC fabric networks data structure is auto-generated #} -{#- DO NOT EDIT MANUALLY #} - +# This NDFC fabric networks config data structure is auto-generated +# DO NOT EDIT MANUALLY +# {% set vxlan = MD_Extended.vxlan %} {% if vxlan.fabric.type == 'VXLAN_EVPN' %} diff --git a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 index d7edcaf8..3c4d3367 100644 --- a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 @@ -1,7 +1,7 @@ --- -{#- This NDFC fabric vrfs config data structure is auto-generated #} -{#- DO NOT EDIT MANUALLY #} - +# This NDFC fabric VRFs config data structure is auto-generated +# DO NOT EDIT MANUALLY +# {% set vxlan = MD_Extended.vxlan %} {% if vxlan.fabric.type == 'VXLAN_EVPN' %} diff --git a/roles/dtc/common/templates/ndfc_create_fabric.j2 b/roles/dtc/common/templates/ndfc_create_fabric.j2 deleted file mode 100644 index 86daf61a..00000000 --- a/roles/dtc/common/templates/ndfc_create_fabric.j2 +++ /dev/null @@ -1,347 +0,0 @@ -{% import 'ndfc_utils.j2' as ndfc_utils with context %} ---- -# This NDFC fabric config data structure is auto-generated -# DO NOT EDIT MANUALLY -# -{% set vxlan = MD_Extended.vxlan %} -{% set global = vxlan.global %} -{% set underlay = vxlan.underlay | default({}) %} -{# ------------------------------------------------------ #} -{# Global Parameters #} -{# ------------------------------------------------------ #} -- FABRIC_NAME: {{ global.name }} - BGP_AS: {{ global.bgp_asn }} - FABRIC_TYPE: VXLAN_EVPN - OVERLAY_MODE: cli - DEPLOY: True - GRFIELD_DEBUG_FLAG: Enable - AAA_REMOTE_IP_ENABLED: False - ENABLE_FABRIC_VPC_DOMAIN_ID: False - RR_COUNT: {{ global.route_reflectors | default(defaults.vxlan.global.route_reflectors) }} - ANYCAST_GW_MAC: {{ global.anycast_gateway_mac | default(defaults.vxlan.global.anycast_gateway_mac) }} -{# ------------------------------------------------------ #} -{# Manageability Parameters #} -{# ------------------------------------------------------ #} -{% if global.dns_servers is defined and global.dns_servers %} -{% set dns_server_ips = [] %} -{% set dns_server_vrfs = [] %} -{% for dns in global.dns_servers %} -{% if dns.ip_address | string is defined and dns.ip_address %} -{% set dns_ip = dns.ip_address | string %} -{% set dns_server_ips = dns_server_ips.append(dns_ip) %} -{% endif %} -{% if dns.vrf | string is defined and dns.vrf %} -{% set dns_vrf = dns.vrf | string %} -{% set dns_server_vrfs = dns_server_vrfs.append(dns_vrf) %} -{% endif %} -{% endfor %} - DNS_SERVER_IP_LIST: {{ dns_server_ips | join(',') | default(omit) }} - DNS_SERVER_VRF: {{ dns_server_vrfs | join(',') | default(omit) }} -{% endif %} -{% if global.ntp_servers is defined and global.ntp_servers %} -{% set ntp_server_ips = [] %} -{% set ntp_server_vrfs = [] %} -{% for ntp in global.ntp_servers %} -{% if ntp.ip_address is defined and ntp.ip_address %} -{% set ntp_ip = ntp.ip_address | string %} -{% set ntp_server_ips = ntp_server_ips.append(ntp_ip) %} -{% endif %} -{% if ntp.vrf is defined and ntp.vrf %} -{% set ntp_vrf = ntp.vrf|string %} -{% set ntp_server_vrfs = ntp_server_vrfs.append(ntp_vrf) %} -{% endif %} -{% endfor %} - NTP_SERVER_IP_LIST: {{ ntp_server_ips | join(',') | default(omit) }} - NTP_SERVER_VRF: {{ ntp_server_vrfs | join(',') | default(omit) }} -{% endif %} -{% if global.syslog_servers is defined and global.syslog_servers %} -{% set syslog_server_ips = [] %} -{% set syslog_server_vrfs = [] %} -{% set syslog_server_sevs = [] %} -{% for syslog_server in global.syslog_servers %} -{% if syslog_server.ip_address is defined and syslog_server.ip_address %} -{% set syslog_server_ip = syslog_server.ip_address | string %} -{% set syslog_server_ips = syslog_server_ips.append(syslog_server_ip) %} -{% endif %} -{% if syslog_server.vrf is defined and syslog_server.vrf %} -{% set syslog_server_vrf = syslog_server.vrf | string %} -{% set syslog_server_vrfs = syslog_server_vrfs.append(syslog_server_vrf) %} -{% endif %} -{% if syslog_server.severity is defined and syslog_server.severity %} -{% set syslog_server_sev = syslog_server.severity %} -{% set syslog_server_sevs = syslog_server_sevs.append(syslog_server_sev) %} -{% endif %} -{% endfor %} - SYSLOG_SERVER_IP_LIST: {{ syslog_server_ips | join(',') | default(omit) }} -{% if syslog_server_ips is defined and syslog_server_ips %} - SYSLOG_SERVER_VRF: {{ syslog_server_vrfs | join(',') | default(omit) }} - SYSLOG_SEV: {{ syslog_server_sevs | join(',') | default(omit) }} -{% endif %} -{% endif %} -{# ------------------------------------------------------ #} -{# Bootstrap Parameters #} -{# ------------------------------------------------------ #} -{% if global.bootstrap is defined %} -{% if global.bootstrap.enable_bootstrap is defined and global.bootstrap.enable_bootstrap %} - BOOTSTRAP_ENABLE: {{ global.bootstrap.enable_bootstrap }} - DHCP_ENABLE: {{ global.bootstrap.enable_local_dhcp_server }} - DHCP_IPV6_ENABLE: {{ global.bootstrap.dhcp_version }} - DHCP_START: {{ global.bootstrap.dhcp_v4.scope_start_address }} - DHCP_END: {{ global.bootstrap.dhcp_v4.scope_end_address }} - MGMT_GW: {{ global.bootstrap.dhcp_v4.switch_mgmt_default_gw }} - MGMT_PREFIX: {{ global.bootstrap.dhcp_v4.mgmt_prefix }} - BOOTSTRAP_MULTISUBNET: {{ global.bootstrap.dhcp_v4.multi_subnet_scope }} -{% endif %} -{% if global.bootstrap.enable_bootstrap is defined and not global.bootstrap.enable_bootstrap %} - BOOTSTRAP_ENABLE: {{ global.bootstrap.enable_bootstrap }} -{% endif %} -{% endif %} -{# ------------------------------------------------------ #} -{# vPC Parameters #} -{# ------------------------------------------------------ #} - VPC_PEER_LINK_VLAN: {{ vxlan.global.vpc.peer_link_vlan | default(defaults.vxlan.global.vpc.peer_link_vlan) }} - VPC_PEER_KEEP_ALIVE_OPTION: {{ vxlan.global.vpc.peer_keep_alive | default(defaults.vxlan.global.vpc.peer_keep_alive) }} - VPC_AUTO_RECOVERY_TIME: {{ vxlan.global.vpc.auto_recovery_time | default(defaults.vxlan.global.vpc.auto_recovery_time) }} - VPC_DELAY_RESTORE_TIME: {{ vxlan.global.vpc.delay_restore_time | default(defaults.vxlan.global.vpc.delay_restore_time) }} - VPC_PEER_LINK_PO: {{ vxlan.global.vpc.peer_link_port_channel_id | default(defaults.vxlan.global.vpc.peer_link_port_channel_id) }} - VPC_DOMAIN_ID_RANGE: {{ vxlan.global.vpc.domain_id_range | default(defaults.vxlan.global.vpc.domain_id_range) }} - VPC_DELAY_RESTORE: {{ vxlan.global.vpc.delay_restore_time | default(defaults.vxlan.global.vpc.delay_restore_time) }} - ADVERTISE_PIP_BGP: {{ (vxlan.global.vpc.advertise_pip | default(defaults.vxlan.global.vpc.advertise_pip) | title) }} -{% if (vxlan.global.vpc.advertise_pip | default(defaults.vxlan.global.vpc.advertise_pip) | title) == 'False' %} - ADVERTISE_PIP_ON_BORDER: {{ vxlan.global.vpc.advertise_pip_border_only | default(defaults.vxlan.global.vpc.advertise_pip_border_only) }} -{% endif %} -{# ------------------------------------------------------ #} -{# Underlay General Parameters #} -{# ------------------------------------------------------ #} - ENABLE_SGT: false - ENABLE_PVLAN: false - BGP_LB_ID: {{ underlay.general.underlay_routing_loopback_id | default(defaults.vxlan.underlay.general.underlay_routing_loopback_id) }} - NVE_LB_ID: {{ underlay.general.underlay_vtep_loopback_id | default(defaults.vxlan.underlay.general.underlay_vtep_loopback_id) }} - FABRIC_MTU: {{ underlay.general.intra_fabric_interface_mtu | default(defaults.vxlan.underlay.general.intra_fabric_interface_mtu) }} - L2_HOST_INTF_MTU: {{ underlay.general.layer2_host_interfacde_mtu | default(defaults.vxlan.underlay.general.layer2_host_interfacde_mtu) }} - HOST_INTF_ADMIN_STATE: {{ underlay.general.unshut_host_interfaces | default(defaults.vxlan.underlay.general.unshut_host_interfaces) }} -{% if (underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) == 'False' %} - FABRIC_INTERFACE_TYPE: {{ underlay.general.fabric_interface_numbering | default(defaults.vxlan.underlay.general.fabric_interface_numbering) }} - SUBNET_TARGET_MASK: {{ underlay.general.subnet_mask | default(defaults.vxlan.underlay.general.subnet_mask) }} - REPLICATION_MODE: {{ underlay.general.replication_mode | default(defaults.vxlan.underlay.general.replication_mode) | title }} -{% endif %} - LINK_STATE_ROUTING: {{ underlay.general.routing_protocol | default(defaults.vxlan.underlay.general.routing_protocol) }} - LINK_STATE_ROUTING_TAG: {{ underlay.general.underlay_routing_protocol_tag | default(defaults.vxlan.underlay.general.underlay_routing_protocol_tag) }} - UNDERLAY_IS_V6: {{ (underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) }} - STATIC_UNDERLAY_IP_ALLOC: {{ (underlay.general.manual_underlay_allocation | default(defaults.vxlan.underlay.general.manual_underlay_allocation) | title)}} -{# ------------------------------------------------------ #} -{# Underlay Multicast Parameters #} -{# ------------------------------------------------------ #} -{% if (underlay.general.replication_mode | default(defaults.vxlan.underlay.general.replication_mode) | title) == 'Multicast' %} - MULTICAST_GROUP_SUBNET: {{ underlay.multicast.group_subnet | default(defaults.vxlan.underlay.multicast.group_subnet) }} - RP_COUNT: {{ underlay.multicast.rendezvous_points | default(defaults.vxlan.underlay.multicast.rendezvous_points) }} - RP_MODE: {{ underlay.multicast.rp_mode | default(defaults.vxlan.underlay.multicast.rp_mode) }} - RP_LB_ID: {{ underlay.multicast.underlay_rp_loopback_id | default(defaults.vxlan.underlay.multicast.underlay_rp_loopback_id) }} - ENABLE_TRM: {{(underlay.multicast.trm_enable | default(defaults.vxlan.underlay.multicast.trm_enable) | title) }} -{% if (underlay.multicast.trm_enable | default(defaults.vxlan.underlay.multicast.trm_enable) | title) == 'True' %} - L3VNI_MCAST_GROUP: {{ underlay.multicast.trm_default_group | default(defaults.vxlan.underlay.multicast.trm_default_group) }} -{% endif %} -{% if underlay.multicast.rp_mode | default(defaults.vxlan.underlay.multicast.rp_mode) == 'bidir' %} - PHANTOM_RP_LB_ID1: {{ underlay.multicast.underlay_primary_rp_loopback_id | default(defaults.vxlan.underlay.multicast.underlay_primary_rp_loopback_id) }} - PHANTOM_RP_LB_ID2: {{ underlay.multicast.underlay_backup_rp_loopback_id | default(defaults.vxlan.underlay.multicast.underlay_backup_rp_loopback_id) }} -{% if underlay.multicast.rendezvous_points | default(defaults.vxlan.underlay.multicast.rendezvous_points) == 4 %} - PHANTOM_RP_LB_ID3: {{ underlay.multicast.underlay_second_backup_rp_loopback_id | default(defaults.vxlan.underlay.multicast.underlay_second_backup_rp_loopback_id) }} - PHANTOM_RP_LB_ID4: {{ underlay.multicast.underlay_third_backup_rp_loopback_id | default(defaults.vxlan.underlay.multicast.underlay_third_backup_rp_loopback_id) }} -{% endif %} -{% endif %} -{% endif %} -{# ------------------------------------------------------ #} -{# Underlay ISIS Parameters #} -{# ------------------------------------------------------ #} -{% if (underlay.general.routing_protocol | default(defaults.vxlan.underlay.general.routing_protocol)) == 'is-is' %} - ISIS_LEVEL: {{ underlay.isis.level | default(defaults.vxlan.underlay.isis.level) }} - ISIS_AUTH_ENABLE: {{ (underlay.isis.authentication_enable | default(defaults.vxlan.underlay.isis.authentication_enable) | title) }} -{% if (underlay.isis.authentication_enable | default(defaults.vxlan.underlay.isis.authentication_enable) | title) == 'True' %} - ISIS_AUTH_KEYCHAIN_NAME: {{ underlay.isis.authentication_keychain_name | default(omit) }} - ISIS_AUTH_KEYCHAIN_KEY_ID: {{ underlay.isis.authentication_key_id | default(defaults.vxlan.underlay.isis.authentication_key_id) }} - ISIS_AUTH_KEY: {{ underlay.isis.authentication_key }} -{% endif %} - ISIS_OVERLOAD_ENABLE: {{ underlay.isis.overload_bit | default(defaults.vxlan.underlay.isis.overload_bit) }} -{% if (underlay.isis.overload_bit | default(defaults.vxlan.underlay.isis.overload_bit) | title) == 'True' %} - ISIS_OVERLOAD_ELAPSE_TIME: {{ underlay.isis.overload_bit_elapsed_time | default(defaults.vxlan.underlay.isis.overload_bit_elapsed_time) }} -{% endif %} - ISIS_P2P_ENABLE: {{ underlay.isis.network_point_to_point | default(defaults.vxlan.underlay.isis.network_point_to_point) }} -{% if (underlay.bfd.enable | default(defaults.vxlan.underlay.bfd.enable) | title) == 'True' %} - BFD_ISIS_ENABLE: {{ underlay.bfd.isis | default(defaults.vxlan.underlay.bfd.isis) }} -{% endif %} -{# ------------------------------------------------------ #} -{# Underlay OSPF Parameters #} -{# ------------------------------------------------------ #} -{% elif (underlay.general.routing_protocol | default(defaults.vxlan.underlay.general.routing_protocol)) == 'ospf' %} - OSPF_AREA_ID: {{ underlay.ospf.area_id | default(defaults.vxlan.underlay.ospf.area_id) }} -{% if (underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) == 'False' %} - OSPF_AUTH_ENABLE: {{ (underlay.ospf.authentication_enable | default(defaults.vxlan.underlay.ospf.authentication_enable) | title) }} -{% endif %} -{% if (underlay.ospf.authentication_enable | default(defaults.vxlan.underlay.ospf.authentication_enable) | title) == 'True' %} - OSPF_AUTH_KEY_ID: {{ underlay.ospf.authentication_key_id | default(defaults.vxlan.underlay.ospf.authentication_key_id) }} - OSPF_AUTH_KEY: {{ underlay.ospf.authentication_key | default(omit) }} -{% endif %} -{% if (underlay.bfd.enable | default(defaults.vxlan.underlay.bfd.enable) | title) == 'True' %} - BFD_OSPF_ENABLE: {{ underlay.bfd.ospf | default(defaults.vxlan.underlay.bfd.ospf) }} -{% endif %} -{% endif %} -{# ------------------------------------------------------ #} -{# Underlay IPv4 Parameters #} -{# ------------------------------------------------------ #} -{% if (underlay.general.manual_underlay_allocation | default(defaults.vxlan.underlay.general.manual_underlay_allocation) | title) == 'False' %} -{% if (underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) == 'False' %} - LOOPBACK0_IP_RANGE: {{ underlay.ipv4.underlay_routing_loopback_ip_range | default(defaults.vxlan.underlay.ipv4.underlay_routing_loopback_ip_range) }} - LOOPBACK1_IP_RANGE: {{ underlay.ipv4.underlay_vtep_loopback_ip_range | default(defaults.vxlan.underlay.ipv4.underlay_vtep_loopback_ip_range) }} - SUBNET_RANGE: {{ underlay.ipv4.underlay_subnet_ip_range | default(defaults.vxlan.underlay.ipv4.underlay_subnet_ip_range) }} -{% endif %} - ANYCAST_RP_IP_RANGE: {{ underlay.ipv4.underlay_rp_loopback_ip_range | default(defaults.vxlan.underlay.ipv4.underlay_rp_loopback_ip_range) }} -{% endif %} -{# ------------------------------------------------------ #} -{# Underlay IPv6 Parameters #} -{# ------------------------------------------------------ #} -{% if (underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) == 'True' %} - USE_LINK_LOCAL: {{ underlay.ipv6.enable_ipv6_link_local_address | default(defaults.vxlan.underlay.ipv6.enable_ipv6_link_local_address | title) }} -{% if (underlay.ipv6.enable_ipv6_link_local_address | default(defaults.vxlan.underlay.ipv6.enable_ipv6_link_local_address) | title) == 'False' %} - V6_SUBNET_TARGET_MASK: {{ underlay.ipv6.underlay_subnet_mask | default(defaults.vxlan.underlay.ipv6.underlay_subnet_mask) }} -{% endif %} -{% endif %} -{# ------------------------------------------------------ #} -{# Underlay BGP Parameters #} -{# ------------------------------------------------------ #} -{% if (underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) == 'False' %} - BGP_AUTH_ENABLE: {{ (underlay.bgp.authentication_enable | default(defaults.vxlan.underlay.bgp.authentication_enable) | title)}} -{% endif %} -{% if (underlay.bgp.authentication_enable | default(defaults.vxlan.underlay.bgp.authentication_enable) | title) == 'True' %} - BGP_AUTH_KEY_TYPE: {{ underlay.bgp.authentication_key_type | default(defaults.vxlan.underlay.bgp.authentication_key_type) }} - BGP_AUTH_KEY: {{ underlay.bgp.authentication_key | default(omit) }} -{% endif %} -{# ------------------------------------------------------ #} -{# Underlay BFD Parameters #} -{# ------------------------------------------------------ #} -{% if (underlay.general.enable_ipv6_underlay | default(defaults.vxlan.underlay.general.enable_ipv6_underlay) | title) == 'False' %} - BFD_ENABLE: {{ underlay.bfd.enable | default(defaults.vxlan.underlay.bfd.enable) }} -{% endif %} -{% if (underlay.bfd.enable | default(defaults.vxlan.underlay.bfd.enable) | title) == 'True' %} - BFD_IBGP_ENABLE: {{ underlay.bfd.ibgp | default(defaults.vxlan.underlay.bfd.ibgp) }} - BFD_PIM_ENABLE: {{ underlay.bfd.pim | default(defaults.vxlan.underlay.bfd.pim) }} - BFD_AUTH_ENABLE: {{ (underlay.bfd.authentication_enable | default(defaults.vxlan.underlay.bfd.authentication_enable) | title)}} -{% if (underlay.bfd.authentication_enable | default(defaults.vxlan.underlay.bfd.authentication_enable) | title) == 'True' %} - BFD_AUTH_KEY: {{ underlay.bfd.authentication_key | default(omit) }} - BFD_AUTH_KEY_ID: {{ underlay.bfd.authentication_key_id | default(defaults.vxlan.underlay.bfd.authentication_key_id) }} -{% endif %} -{% endif %} -{# ------------------------------------------------------ #} -{# vPC Parameters #} -{# ------------------------------------------------------ #} - VPC_PEER_LINK_VLAN: {{ vpc.peer_link_vlan | default(defaults.vxlan.global.vpc.peer_link_vlan) }} - VPC_PEER_KEEP_ALIVE_OPTION: {{ vpc.peer_keep_alive | default(defaults.vxlan.global.vpc.peer_keep_alive) }} - VPC_AUTO_RECOVERY_TIME: {{ vpc.auto_recovery_time | default(defaults.vxlan.global.vpc.auto_recovery_time) }} - VPC_DELAY_RESTORE_TIME: {{ vpc.delay_restore_time | default(defaults.vxlan.global.vpc.delay_restore_time) }} - VPC_PEER_LINK_PO: {{ vpc.peer_link_port_channel_id | default(defaults.vxlan.global.vpc.peer_link_port_channel_id) }} - VPC_DOMAIN_ID_RANGE: {{ vpc.domain_id_range | default(defaults.vxlan.global.vpc.domain_id_range) }} - VPC_DELAY_RESTORE: {{ vpc.delay_restore_time | default(defaults.vxlan.global.vpc.delay_restore_time) }} - ADVERTISE_PIP_BGP: {{ (vpc.advertise_pip | default(defaults.vxlan.global.vpc.advertise_pip) | title) }} -{% if (vpc.advertise_pip | default(defaults.vxlan.global.vpc.advertise_pip) | title) == 'False' %} - ADVERTISE_PIP_ON_BORDER: {{ vpc.advertise_pip_border_only | default(defaults.vxlan.global.vpc.advertise_pip_border_only) }} -{% endif %} -{# ------------------------------------------------------ #} -{# STP Parameters #} -{# ------------------------------------------------------ #} -{# STP_ROOT_OPTION: {{ global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol) }} -{% if global.spanning_tree.root_bridge_protocol is defined and global.spanning_tree.root_bridge_protocol != 'unmanaged' %} -{% if (global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol)) == 'rpvst+' %} - STP_VLAN_RANGE: {{ ndfc_utils.convert_ranges(global.spanning_tree.vlan_range, defaults.vxlan.global.spanning_tree.vlan_range) }} -{% elif (global.spanning_tree.root_bridge_protocol | default(defaults.vxlan.global.spanning_tree.root_bridge_protocol)) == 'mst' %} - MST_INSTANCE_RANGE: {{ ndfc_utils.convert_ranges(global.spanning_tree.mst_instance_range, defaults.vxlan.global.spanning_tree.mst_instance_range) }} -{% endif %} - STP_BRIDGE_PRIORITY: {{ global.spanning_tree.bridge_priority | default(defaults.vxlan.global.spanning_tree.bridge_priority) }} -{% endif %}#} -{# ------------------------------------------------------ #} -{# Manageability Parameters #} -{# ------------------------------------------------------ #} -{% if global.dns_servers is defined and global.dns_servers %} -{% set dns_server_ips = [] %} -{% set dns_server_vrfs = [] %} -{% for dns in global.dns_servers %} -{% if dns.ip_address | string is defined and dns.ip_address %} -{% set dns_ip = dns.ip_address | string %} -{% set dns_server_ips = dns_server_ips.append(dns_ip) %} -{% endif %} -{% if dns.vrf | string is defined and dns.vrf %} -{% set dns_vrf = dns.vrf | string %} -{% set dns_server_vrfs = dns_server_vrfs.append(dns_vrf) %} -{% endif %} -{% endfor %} - DNS_SERVER_IP_LIST: {{ dns_server_ips | join(',') | default(omit) }} - DNS_SERVER_VRF: {{ dns_server_vrfs | join(',') | default(omit) }} -{% endif %} -{% if global.ntp_servers is defined and global.ntp_servers %} -{% set ntp_server_ips = [] %} -{% set ntp_server_vrfs = [] %} -{% for ntp in global.ntp_servers %} -{% if ntp.ip_address is defined and ntp.ip_address %} -{% set ntp_ip = ntp.ip_address | string %} -{% set ntp_server_ips = ntp_server_ips.append(ntp_ip) %} -{% endif %} -{% if ntp.vrf is defined and ntp.vrf %} -{% set ntp_vrf = ntp.vrf|string %} -{% set ntp_server_vrfs = ntp_server_vrfs.append(ntp_vrf) %} -{% endif %} -{% endfor %} - NTP_SERVER_IP_LIST: {{ ntp_server_ips | join(',') | default(omit) }} - NTP_SERVER_VRF: {{ ntp_server_vrfs | join(',') | default(omit) }} -{% endif %} -{% if global.syslog_servers is defined and global.syslog_servers %} -{% set syslog_server_ips = [] %} -{% set syslog_server_vrfs = [] %} -{% set syslog_server_sevs = [] %} -{% for syslog_server in global.syslog_servers %} -{% if syslog_server.ip_address is defined and syslog_server.ip_address %} -{% set syslog_server_ip = syslog_server.ip_address | string %} -{% set syslog_server_ips = syslog_server_ips.append(syslog_server_ip) %} -{% endif %} -{% if syslog_server.vrf is defined and syslog_server.vrf %} -{% set syslog_server_vrf = syslog_server.vrf | string %} -{% set syslog_server_vrfs = syslog_server_vrfs.append(syslog_server_vrf) %} -{% endif %} -{% if syslog_server.severity is defined and syslog_server.severity %} -{% set syslog_server_sev = syslog_server.severity %} -{% set syslog_server_sevs = syslog_server_sevs.append(syslog_server_sev) %} -{% endif %} -{% endfor %} - SYSLOG_SERVER_IP_LIST: {{ syslog_server_ips | join(',') | default(omit) }} -{% if syslog_server_ips is defined and syslog_server_ips %} - SYSLOG_SERVER_VRF: {{ syslog_server_vrfs | join(',') | default(omit) }} - SYSLOG_SEV: {{ syslog_server_sevs | join(',') | default(omit) }} -{% endif %} -{% endif %} -{# ------------------------------------------------------ #} -{# Flow Monitor Parameters #} -{# ------------------------------------------------------ #} - ENABLE_NETFLOW: {{ global.netflow.enable | default(defaults.vxlan.global.netflow.enable) }} -{% if global.netflow.enable is defined and global.netflow.enable | bool or defaults.vxlan.global.netflow.enable | bool %} -{% if global.netflow.exporter is defined %} -{% set exporter_dict = dict() %} -{% set _ = exporter_dict.update({ "NETFLOW_EXPORTER_LIST":[] }) %} -{% for e in global.netflow.exporter %} -{% set _ = exporter_dict["NETFLOW_EXPORTER_LIST"].append(dict(EXPORTER_NAME=e.name,IP=e.ip_address,VRF=e.vrf | default(""), SRC_IF_NAME=e.source_interface,UDP_PORT=e.udp_port)) %} -{% endfor %} - NETFLOW_EXPORTER_LIST: "{{ exporter_dict | tojson | replace('"', '\\"') }}" -{% endif %} -{% if global.netflow.record is defined %} -{% set record_dict = dict() %} -{% set _ = record_dict.update({ "NETFLOW_RECORD_LIST":[] }) %} -{% for r in global.netflow.record %} -{% set _ = record_dict["NETFLOW_RECORD_LIST"].append(dict(RECORD_NAME=r.name,RECORD_TEMPLATE =r.template,LAYER2_RECORD=r.layer2 | default(false) | string | lower)) %} -{% endfor %} - NETFLOW_RECORD_LIST: "{{ record_dict | tojson | replace('"', '\\"') }}" -{% endif %} -{% if global.netflow.monitor is defined %} -{% set monitor_dict = dict() %} -{% set _ = monitor_dict.update({ "NETFLOW_MONITOR_LIST":[] }) %} -{% for m in global.netflow.monitor %} -{% set _ = monitor_dict["NETFLOW_MONITOR_LIST"].append(dict(MONITOR_NAME=m.name,RECORD_NAME=m.record,EXPORTER1=m.exporter1,EXPORTER2=m.exporter2 | default(""))) %} -{% endfor %} - NETFLOW_MONITOR_LIST: "{{ monitor_dict | tojson | replace('"', '\\"') }}" -{% endif %} -{% endif %} diff --git a/roles/dtc/common/templates/ndfc_fabric.j2 b/roles/dtc/common/templates/ndfc_fabric.j2 index ff547678..9cb0152d 100644 --- a/roles/dtc/common/templates/ndfc_fabric.j2 +++ b/roles/dtc/common/templates/ndfc_fabric.j2 @@ -1,7 +1,7 @@ --- -{#- This NDFC fabric config data structure is auto-generated #} -{#- DO NOT EDIT MANUALLY #} - +# This NDFC fabric config data structure is auto-generated +# DO NOT EDIT MANUALLY +# {% set vxlan = MD_Extended.vxlan %} {% if vxlan.fabric.type == 'VXLAN_EVPN' %} diff --git a/roles/dtc/common/templates/ndfc_fabric_links.j2 b/roles/dtc/common/templates/ndfc_fabric_links.j2 index 5fa06432..9c02086f 100644 --- a/roles/dtc/common/templates/ndfc_fabric_links.j2 +++ b/roles/dtc/common/templates/ndfc_fabric_links.j2 @@ -1,8 +1,7 @@ --- -# This NDFC links for vPC Peering is auto-generated +# This NDFC fabric links config data structure is auto-generated # DO NOT EDIT MANUALLY # -#jinja2: trim_blocks: True, lstrip_blocks: False {% for link in MD_Extended.vxlan.topology.fabric_links %} - dst_fabric: "{{ MD_Extended.vxlan.fabric.name }}" src_interface: "{{ link.source_interface }}" diff --git a/roles/dtc/common/templates/ndfc_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory.j2 index 1c11ea39..61a7cc58 100644 --- a/roles/dtc/common/templates/ndfc_inventory.j2 +++ b/roles/dtc/common/templates/ndfc_inventory.j2 @@ -1,7 +1,7 @@ --- -{#- This NDFC fabric inventory config data structure is auto-generated #} -{#- DO NOT EDIT MANUALLY #} - +# This NDFC fabric inventory config data structure is auto-generated +# DO NOT EDIT MANUALLY +# {% set vxlan = MD_Extended.vxlan %} {% if vxlan.fabric.type == 'VXLAN_EVPN' %} diff --git a/roles/dtc/common/templates/ndfc_links_vpc_peering.j2 b/roles/dtc/common/templates/ndfc_vpc/ndfc_vpc_fabric_peering_links.j2 similarity index 92% rename from roles/dtc/common/templates/ndfc_links_vpc_peering.j2 rename to roles/dtc/common/templates/ndfc_vpc/ndfc_vpc_fabric_peering_links.j2 index d707b8b4..2abebf65 100644 --- a/roles/dtc/common/templates/ndfc_links_vpc_peering.j2 +++ b/roles/dtc/common/templates/ndfc_vpc/ndfc_vpc_fabric_peering_links.j2 @@ -1,8 +1,7 @@ --- -# This NDFC links for vPC Peering is auto-generated +# This NDFC config data that updates links for vPC Fabric Peering is auto-generated # DO NOT EDIT MANUALLY # -#jinja2: trim_blocks: True, lstrip_blocks: False {% for peers in MD_Extended.vxlan.topology.vpc_peers %} {% if peers['peer1_peerlink_interfaces'] is defined %} {% for interface_index in range(peers['peer1_peerlink_interfaces']|length) %} diff --git a/roles/dtc/common/templates/ndfc_vpc_peering.j2 b/roles/dtc/common/templates/ndfc_vpc/ndfc_vpc_peering_pairs.j2 similarity index 93% rename from roles/dtc/common/templates/ndfc_vpc_peering.j2 rename to roles/dtc/common/templates/ndfc_vpc/ndfc_vpc_peering_pairs.j2 index 30418a7f..fbd51826 100644 --- a/roles/dtc/common/templates/ndfc_vpc_peering.j2 +++ b/roles/dtc/common/templates/ndfc_vpc/ndfc_vpc_peering_pairs.j2 @@ -1,8 +1,7 @@ --- -# This NDFC vPC Peering config data structure is auto-generated +# This NDFC vPC Peering config data structure for vPC pairs is auto-generated # DO NOT EDIT MANUALLY # - {% if MD_Extended.vxlan.topology.vpc_peers is defined and MD_Extended.vxlan.topology.vpc_peers is not none %} {% for vpc_peer in MD_Extended.vxlan.topology.vpc_peers %} {% if MD_Extended.vxlan.topology.leaf[vpc_peer.peer1].management_ipv4_address is not none %} diff --git a/roles/dtc/common/templates/ndfc_attach_vrfs_loopbacks.j2 b/roles/dtc/common/templates/ndfc_vrfs/ndfc_attach_vrfs_loopbacks.j2 similarity index 92% rename from roles/dtc/common/templates/ndfc_attach_vrfs_loopbacks.j2 rename to roles/dtc/common/templates/ndfc_vrfs/ndfc_attach_vrfs_loopbacks.j2 index 7b64ca08..e7d789b9 100644 --- a/roles/dtc/common/templates/ndfc_attach_vrfs_loopbacks.j2 +++ b/roles/dtc/common/templates/ndfc_vrfs/ndfc_attach_vrfs_loopbacks.j2 @@ -1,3 +1,6 @@ +# This NDFC VRF loopback config data structure is auto-generated +# DO NOT EDIT MANUALLY +# [ {% for vrf in MD_Extended.vxlan.overlay.vrfs %} {% if vrf['vrf_attach_group'] is defined %} From 650efef5968428a7c1d41455d356d9f90e1aaea3 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 28 Jan 2025 18:53:53 -0500 Subject: [PATCH 55/66] fix to isn fabric template --- .../prepare_plugins/prep_002_list_defaults.py | 2 -- .../bootstrap/isn_fabric_bootstrap.j2 | 24 +++++++++---------- .../flow_monitor/isn_fabric_flow_monitor.j2 | 16 ++++++------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py index 60a2ca5d..f8ea09de 100644 --- a/plugins/action/common/prepare_plugins/prep_002_list_defaults.py +++ b/plugins/action/common/prepare_plugins/prep_002_list_defaults.py @@ -177,8 +177,6 @@ def prepare(self): # -------------------------------------------------------------------- # Fabric Global List Defaults # -------------------------------------------------------------------- - from pprint import pprint - fabric_type = self.model_data['vxlan']['fabric']['type'] # for path in paths: diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2 index 73889b0b..162627c2 100644 --- a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2 @@ -1,18 +1,18 @@ {# Auto-generated NDFC ISN Bootstrap config data structure for fabric {{ vxlan.fabric.name }} #} {# Most of these features are supported only on Cisco NX-OS switches #} {# Some of these features are supported only on Cisco Catalyst 9000 switches #} -{% if vxlan.multisite.isn.bootstrap is defined %} -{% if (vxlan.multisite.isn.bootstrap.enable_bootstrap is defined and vxlan.multisite.isn.bootstrap.enable_bootstrap | bool) or defaults.vxlan.multisite.isn.bootstrap.enable_bootstrap | bool %} - BOOTSTRAP_ENABLE: {{ vxlan.multisite.isn.bootstrap.enable_bootstrap | default(defaults.vxlan.multisite.isn.bootstrap.enable_bootstrap) | bool }} - INBAND_ENABLE: {{ vxlan.multisite.isn.bootstrap.enable_inband | default(defaults.vxlan.multisite.isn.bootstrap.enable_inband) | bool }} - DHCP_ENABLE: {{ vxlan.multisite.isn.bootstrap.enable_local_dhcp_server | default(defaults.vxlan.multisite.isn.bootstrap.enable_local_dhcp_server) | bool }} - DHCP_IPV6_ENABLE: {{ vxlan.multisite.isn.bootstrap.dhcp_version | default(defaults.vxlan.multisite.isn.bootstrap.dhcp_version) }} - DHCP_START: {{ vxlan.multisite.isn.bootstrap.dhcp_v4.scope_start_address }} - DHCP_END: {{ vxlan.multisite.isn.bootstrap.dhcp_v4.scope_end_address }} - MGMT_GW: {{ vxlan.multisite.isn.bootstrap.dhcp_v4.switch_mgmt_default_gw }} - MGMT_PREFIX: {{ vxlan.multisite.isn.bootstrap.dhcp_v4.mgmt_prefix }} - BOOTSTRAP_MULTISUBNET: "{{ vxlan.multisite.isn.bootstrap.dhcp_v4.multi_subnet_scope }}" - ENABLE_AAA: {{ vxlan.multisite.isn.bootstrap.enable_aaa | default(defaults.vxlan.multisite.isn.bootstrap.enable_aaa) | bool }} +{% if vxlan.global.bootstrap is defined %} +{% if (vxlan.global.bootstrap.enable_bootstrap is defined and vxlan.global.bootstrap.enable_bootstrap | bool) or defaults.vxlan.global.bootstrap.enable_bootstrap | bool %} + BOOTSTRAP_ENABLE: {{ vxlan.global.bootstrap.enable_bootstrap | default(defaults.vxlan.global.bootstrap.enable_bootstrap) | bool }} + INBAND_ENABLE: {{ vxlan.global.bootstrap.enable_inband | default(defaults.vxlan.global.bootstrap.enable_inband) | bool }} + DHCP_ENABLE: {{ vxlan.global.bootstrap.enable_local_dhcp_server | default(defaults.vxlan.global.bootstrap.enable_local_dhcp_server) | bool }} + DHCP_IPV6_ENABLE: {{ vxlan.global.bootstrap.dhcp_version | default(defaults.vxlan.global.bootstrap.dhcp_version) }} + DHCP_START: {{ vxlan.global.bootstrap.dhcp_v4.scope_start_address }} + DHCP_END: {{ vxlan.global.bootstrap.dhcp_v4.scope_end_address }} + MGMT_GW: {{ vxlan.global.bootstrap.dhcp_v4.switch_mgmt_default_gw }} + MGMT_PREFIX: {{ vxlan.global.bootstrap.dhcp_v4.mgmt_prefix }} + BOOTSTRAP_MULTISUBNET: "{{ vxlan.global.bootstrap.dhcp_v4.multi_subnet_scope }}" + ENABLE_AAA: {{ vxlan.global.bootstrap.enable_aaa | default(defaults.vxlan.global.bootstrap.enable_aaa) | bool }} {% endif %} {% else %} BOOTSTRAP_ENABLE: false diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2 index 75e95771..3dbcb883 100644 --- a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2 @@ -1,26 +1,26 @@ {# Auto-generated NDFC ISN Flow Monitor config data structure for fabric {{ vxlan.fabric.name }} #} - ENABLE_NETFLOW: {{ vxlan.multisite.isn.netflow.enable | default(defaults.vxlan.multisite.isn.netflow.enable) }} -{% if vxlan.multisite.isn.netflow.enable is defined and vxlan.multisite.isn.netflow.enable | bool or defaults.vxlan.multisite.isn.netflow.enable | bool %} -{% if vxlan.multisite.isn.netflow.exporter is defined %} + ENABLE_NETFLOW: {{ vxlan.global.netflow.enable | default(defaults.vxlan.global.netflow.enable) }} +{% if vxlan.global.netflow.enable is defined and vxlan.global.netflow.enable | bool or defaults.vxlan.global.netflow.enable | bool %} +{% if vxlan.global.netflow.exporter is defined %} {% set exporter_dict = dict() %} {% set _ = exporter_dict.update({ "NETFLOW_EXPORTER_LIST":[] }) %} -{% for e in vxlan.multisite.isn.netflow.exporter %} +{% for e in vxlan.global.netflow.exporter %} {% set _ = exporter_dict["NETFLOW_EXPORTER_LIST"].append(dict(EXPORTER_NAME=e.name,IP=e.ip_address,VRF=e.vrf | default(""), SRC_IF_NAME=e.source_interface,UDP_PORT=e.udp_port)) %} {% endfor %} NETFLOW_EXPORTER_LIST: "{{ exporter_dict | tojson | replace('"', '\\"') }}" {% endif %} -{% if vxlan.multisite.isn.netflow.record is defined %} +{% if vxlan.global.netflow.record is defined %} {% set record_dict = dict() %} {% set _ = record_dict.update({ "NETFLOW_RECORD_LIST":[] }) %} -{% for r in vxlan.multisite.isn.netflow.record %} +{% for r in vxlan.global.netflow.record %} {% set _ = record_dict["NETFLOW_RECORD_LIST"].append(dict(RECORD_NAME=r.name,RECORD_TEMPLATE =r.template,LAYER2_RECORD=r.layer2 | default(false) | string | lower)) %} {% endfor %} NETFLOW_RECORD_LIST: "{{ record_dict | tojson | replace('"', '\\"') }}" {% endif %} -{% if vxlan.multisite.isn.netflow.monitor is defined %} +{% if vxlan.global.netflow.monitor is defined %} {% set monitor_dict = dict() %} {% set _ = monitor_dict.update({ "NETFLOW_MONITOR_LIST":[] }) %} -{% for m in vxlan.multisite.isn.netflow.monitor %} +{% for m in vxlan.global.netflow.monitor %} {% set _ = monitor_dict["NETFLOW_MONITOR_LIST"].append(dict(MONITOR_NAME=m.name,RECORD_NAME=m.record,EXPORTER1=m.exporter1,EXPORTER2=m.exporter2 | default(""))) %} {% endfor %} NETFLOW_MONITOR_LIST: "{{ monitor_dict | tojson | replace('"', '\\"') }}" From 3c9cc02add8c939d74a6ad2c6c0fca65418ae16d Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Tue, 28 Jan 2025 22:33:36 -0500 Subject: [PATCH 56/66] get fabric attributes, fix msd templates, & start work on mapping switch to fabric --- plugins/action/dtc/manage_child_fabrics.py | 8 +++++ plugins/action/dtc/map_msd_inventory.py | 3 ++ plugins/plugin_utils/helper_functions.py | 30 +++++++++++++++++++ .../msd_fabric/dci/msd_fabric_dci.j2 | 22 +++++++------- .../msd_fabric/general/msd_fabric_general.j2 | 2 +- .../resources/msd_fabric_resources.j2 | 10 +++---- 6 files changed, 58 insertions(+), 17 deletions(-) diff --git a/plugins/action/dtc/manage_child_fabrics.py b/plugins/action/dtc/manage_child_fabrics.py index 11f59bde..80e47d02 100644 --- a/plugins/action/dtc/manage_child_fabrics.py +++ b/plugins/action/dtc/manage_child_fabrics.py @@ -26,6 +26,7 @@ from ansible.utils.display import Display from ansible.plugins.action import ActionBase +from ...plugin_utils.helper_functions import ndfc_get_fabric_attributes display = Display() @@ -36,6 +37,7 @@ def run(self, tmp=None, task_vars=None): results = super(ActionModule, self).run(tmp, task_vars) results['failed'] = False results['child_fabrics_moved'] = False + results['child_fabric_attributes'] = {} fabric_associations = self._task.args['fabric_associations'].get('response').get('DATA') parent_fabric_name = self._task.args['parent_fabric_name'] @@ -48,6 +50,8 @@ def run(self, tmp=None, task_vars=None): if fabric.get('fabricParent') == parent_fabric_name: associated_child_fabrics.append(fabric.get('fabricName')) + results['child_fabric_attributes'][fabric['fabricName']] = ndfc_get_fabric_attributes(self, task_vars, tmp, fabric['fabricName']) + if operation == 'add': for fabric in child_fabrics: if fabric.get('name') not in associated_child_fabrics: @@ -78,6 +82,8 @@ def run(self, tmp=None, task_vars=None): results['changed'] = True + results['child_fabric_attributes'][fabric] = ndfc_get_fabric_attributes(self, task_vars, tmp, fabric) + if operation == 'remove': for associated_child_fabric in associated_child_fabrics: if not any(associated_child_fabric == child_fabric['name'] for child_fabric in child_fabrics): @@ -100,6 +106,8 @@ def run(self, tmp=None, task_vars=None): results['changed'] = True + results['child_fabric_attributes'].pop(associated_child_fabric) + return results diff --git a/plugins/action/dtc/map_msd_inventory.py b/plugins/action/dtc/map_msd_inventory.py index e317ad24..64cc973c 100644 --- a/plugins/action/dtc/map_msd_inventory.py +++ b/plugins/action/dtc/map_msd_inventory.py @@ -60,6 +60,9 @@ def run(self, tmp=None, task_vars=None): for switch in response: msd_switches.update({switch['hostName']: switch['ipAddress']}) msd_switches.update({switch['ipAddress']: switch['ipAddress']}) + msd_switches.update({switch['fabricName']: switch['fabricName']}) + + import epdb; epdb.st() # Cross reference msd_switches with the switches defined in # VRF and Network attach list. diff --git a/plugins/plugin_utils/helper_functions.py b/plugins/plugin_utils/helper_functions.py index bc632aae..3b123e9d 100644 --- a/plugins/plugin_utils/helper_functions.py +++ b/plugins/plugin_utils/helper_functions.py @@ -164,3 +164,33 @@ def ndfc_get_nac_switch_policy_using_desc(self, task_vars, tmp, switch_serial_nu ] return policy_match + +def ndfc_get_fabric_attributes(self, task_vars, tmp, fabric): + """ + Get NDFC fabric attributes. + + :Parameters: + :self: Ansible action plugin instance object. + :task_vars (dict): Ansible task vars. + :tmp (None, optional): Ansible tmp object. Defaults to None via Action Plugin. + :fabric (str): The fabric name to be retrieved. + + :Returns: + :fabric_attributes: The NDFC fabric attributes data for the given fabric. + + :Raises: + N/A + """ + fabric_response = self._execute_module( + module_name="cisco.dcnm.dcnm_rest", + module_args={ + "method": "GET", + "path": f"/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{fabric}", + }, + task_vars=task_vars, + tmp=tmp + ) + + fabric_attributes = fabric_response['response']['DATA']['nvPairs'] + + return fabric_attributes diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 index 8867c152..0811c773 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/dci/msd_fabric_dci.j2 @@ -1,14 +1,14 @@ {# Auto-generated NDFC MSD DCI config data structure for fabric {{ vxlan.fabric.name }} #} - BORDER_GWY_CONNECTIONS: {{ vxlan.multisite.overlay_ifc | default(defaults.vxlan.multisite.overlay_ifc) }} - MS_UNDERLAY_AUTOCONFIG: {{ vxlan.multisite.underlay_autoconfig | default(defaults.vxlan.multisite.underlay_autoconfig) }} -{% if vxlan.multisite.underlay_autoconfig | default(defaults.vxlan.multisite.underlay_autoconfig) %} - ENABLE_BGP_SEND_COMM: {{ vxlan.multisite.enable_bgp_send_community | default(defaults.vxlan.multisite.enable_bgp_send_community) }} - ENABLE_BGP_LOG_NEIGHBOR_CHANGE: {{ vxlan.multisite.enable_bgp_log_neighbor_change | default(defaults.vxlan.multisite.enable_bgp_log_neighbor_change) | lower }} - ENABLE_BGP_BFD: {{ vxlan.multisite.enable_bgp_bfd | default(defaults.vxlan.multisite.enable_bgp_bfd) }} + BORDER_GWY_CONNECTIONS: {{ vxlan.multisite.overlay_dci.deployment_method | default(defaults.vxlan.multisite.overlay_dci.deployment_method) }} + MS_UNDERLAY_AUTOCONFIG: {{ vxlan.multisite.overlay_dci.underlay_autoconfig | default(defaults.vxlan.multisite.overlay_dci.underlay_autoconfig) }} +{% if (vxlan.multisite.overlay_dci.underlay_autoconfig | default(defaults.vxlan.multisite.overlay_dci.underlay_autoconfig) | ansible.builtin.bool) is sameas false %} + ENABLE_BGP_SEND_COMM: {{ vxlan.multisite.overlay_dci.enable_bgp_send_community | default(defaults.vxlan.multisite.overlay_dci.enable_bgp_send_community) }} + ENABLE_BGP_LOG_NEIGHBOR_CHANGE: {{ vxlan.multisite.overlay_dci.enable_bgp_log_neighbor_change | default(defaults.vxlan.multisite.overlay_dci.enable_bgp_log_neighbor_change) | lower }} + ENABLE_BGP_BFD: {{ vxlan.multisite.overlay_dci.enable_bgp_bfd | default(defaults.vxlan.multisite.overlay_dci.enable_bgp_bfd) }} {% endif %} - DELAY_RESTORE: {{ vxlan.multisite.delay_restore | default(defaults.vxlan.multisite.delay_restore) }} - MS_IFC_BGP_PASSWORD_ENABLE: {{ vxlan.multisite.enable_ebgp_password | default(defaults.vxlan.multisite.enable_ebgp_password) }} -{% if vxlan.multisite.enable_ebgp_password | default(defaults.vxlan.multisite.enable_ebgp_password) %} - MS_IFC_BGP_PASSWORD: {{ vxlan.multisite.ebgp_password }} - MS_IFC_BGP_AUTH_KEY_TYPE: {{ vxlan.multisite.ebgp_password_encryption_type | default(defaults.vxlan.multisite.ebgp_password_encryption_type) }} + DELAY_RESTORE: {{ vxlan.multisite.overlay_dci.delay_restore | default(defaults.vxlan.multisite.overlay_dci.delay_restore) }} + MS_IFC_BGP_PASSWORD_ENABLE: {{ vxlan.multisite.overlay_dci.enable_ebgp_password | default(defaults.vxlan.multisite.overlay_dci.enable_ebgp_password) }} +{% if vxlan.multisite.overlay_dci.enable_ebgp_password | default(defaults.vxlan.multisite.overlay_dci.enable_ebgp_password) %} + MS_IFC_BGP_PASSWORD: {{ vxlan.multisite.overlay_dci.ebgp_password }} + MS_IFC_BGP_AUTH_KEY_TYPE: {{ vxlan.multisite.overlay_dci.ebgp_password_encryption_type }} {% endif %} \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 index a593cfa1..e9c31188 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/general/msd_fabric_general.j2 @@ -1,6 +1,6 @@ {# Auto-generated NDFC MSD General config data structure for fabric {{ vxlan.fabric.name }} #} VXLAN_UNDERLAY_IS_V6: {{ vxlan.multisite.enable_ipv6_underlay | default(defaults.vxlan.multisite.enable_ipv6_underlay) }} -{% if not vxlan.multisite.enable_ipv6_underlay | default(defaults.vxlan.multisite.enable_ipv6_underlay) %} +{% if (vxlan.multisite.enable_ipv6_underlay | default(defaults.vxlan.multisite.enable_ipv6_underlay) | ansible.builtin.bool) is sameas false %} ENABLE_PVLAN: false {% endif %} ANYCAST_GW_MAC: {{ vxlan.multisite.anycast_gateway_mac | default(defaults.vxlan.multisite.anycast_gateway_mac) }} diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 index dc5d0db3..d713b60b 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 @@ -1,10 +1,10 @@ {# Auto-generated NDFC MSD Resources config data structure for fabric {{ vxlan.fabric.name }} #} -{% if not defaults.vxlan.multisite.enable_ipv6_underlay %} +{% if (vxlan.multisite.enable_ipv6_underlay | default(defaults.vxlan.multisite.enable_ipv6_underlay) | ansible.builtin.bool) is sameas false %} LOOPBACK100_IP_RANGE: {{ vxlan.multisite.ipv4_vtep_loopback_range | default(defaults.vxlan.multisite.ipv4_vtep_loopback_range) }} - DCI_SUBNET_RANGE: {{ vxlan.multisite.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.ipv4_dci_subnet_range) }} - DCI_SUBNET_TARGET_MASK: {{ vxlan.multisite.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.ipv4_dci_subnet_mask) }} + DCI_SUBNET_RANGE: {{ vxlan.multisite.overlay_dci.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.overlay_dci.ipv4_dci_subnet_range) }} + DCI_SUBNET_TARGET_MASK: {{ vxlan.multisite.overlay_dci.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.overlay_dci.ipv4_dci_subnet_mask) }} {% else %} LOOPBACK100_IPV6_RANGE: {{ vxlan.multisite.ipv6_vtep_loopback_range | default(defaults.vxlan.multisite.ipv6_vtep_loopback_range) }} - V6_DCI_SUBNET_RANGE: {{ vxlan.multisite.ipv6_dci_subnet_range | default(defaults.vxlan.multisite.ipv6_dci_subnet_range) }} - V6_DCI_SUBNET_TARGET_MASK: {{ vxlan.multisite.ipv6_dci_subnet_mask | default(defaults.vxlan.multisite.ipv6_dci_subnet_mask) }} + V6_DCI_SUBNET_RANGE: {{ vxlan.multisite.overlay_dci.ipv6_dci_subnet_range | default(defaults.vxlan.multisite.overlay_dci.ipv6_dci_subnet_range) }} + V6_DCI_SUBNET_TARGET_MASK: {{ vxlan.multisite.overlay_dci.ipv6_dci_subnet_mask | default(defaults.vxlan.multisite.overlay_dci.ipv6_dci_subnet_mask) }} {% endif %} \ No newline at end of file From 0ef58cd09f2804dbfb10dd42d6681603dd8bc852 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Wed, 29 Jan 2025 06:21:44 -0500 Subject: [PATCH 57/66] fix errors --- plugins/action/dtc/map_msd_inventory.py | 2 -- plugins/plugin_utils/helper_functions.py | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/action/dtc/map_msd_inventory.py b/plugins/action/dtc/map_msd_inventory.py index 64cc973c..cdc46a26 100644 --- a/plugins/action/dtc/map_msd_inventory.py +++ b/plugins/action/dtc/map_msd_inventory.py @@ -62,8 +62,6 @@ def run(self, tmp=None, task_vars=None): msd_switches.update({switch['ipAddress']: switch['ipAddress']}) msd_switches.update({switch['fabricName']: switch['fabricName']}) - import epdb; epdb.st() - # Cross reference msd_switches with the switches defined in # VRF and Network attach list. # diff --git a/plugins/plugin_utils/helper_functions.py b/plugins/plugin_utils/helper_functions.py index 3b123e9d..233163be 100644 --- a/plugins/plugin_utils/helper_functions.py +++ b/plugins/plugin_utils/helper_functions.py @@ -165,6 +165,7 @@ def ndfc_get_nac_switch_policy_using_desc(self, task_vars, tmp, switch_serial_nu return policy_match + def ndfc_get_fabric_attributes(self, task_vars, tmp, fabric): """ Get NDFC fabric attributes. From 938458d42deb7a11d994013acc2d965f7654446f Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 30 Jan 2025 08:01:59 -0500 Subject: [PATCH 58/66] refactor msite build for preprocessing for vrfs/networks attachments --- .../common/prepare_plugins/prep_001_fabric.py | 1 - plugins/action/dtc/manage_child_fabrics.py | 129 +++++++------- plugins/action/dtc/prepare_msite.py | 157 ++++++++++++++++++ plugins/plugin_utils/helper_functions.py | 38 +++++ ...fc_children.yml => ndfc_child_fabrics.yml} | 12 +- roles/dtc/common/tasks/sub_main_msd.yml | 20 +-- .../resources/msd_fabric_resources.j2 | 2 +- .../ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2 | 13 +- roles/dtc/create/tasks/msd/child_fabrics.yml | 47 ++++-- roles/dtc/remove/tasks/msd/child_fabrics.yml | 10 +- 10 files changed, 326 insertions(+), 103 deletions(-) create mode 100644 plugins/action/dtc/prepare_msite.py rename roles/dtc/common/tasks/msd/{ndfc_children.yml => ndfc_child_fabrics.yml} (71%) diff --git a/plugins/action/common/prepare_plugins/prep_001_fabric.py b/plugins/action/common/prepare_plugins/prep_001_fabric.py index 8dfd709b..bdd5a71a 100644 --- a/plugins/action/common/prepare_plugins/prep_001_fabric.py +++ b/plugins/action/common/prepare_plugins/prep_001_fabric.py @@ -122,7 +122,6 @@ def prepare(self): # For backwards compatibility, replace 'overlay_services' key with 'overlay' # NOTE: No prepare plugin, jinja2 template or ansible task should reference 'overlay_services' after this replacement. # NOTE: Rules are different since rules run BEFORE prepare plugins - # import epdb ; epdb.set_trace() parent_keys = ['vxlan', 'overlay_services'] dm_check = data_model_key_check(model_data, parent_keys) if 'overlay_services' in dm_check['keys_found']: diff --git a/plugins/action/dtc/manage_child_fabrics.py b/plugins/action/dtc/manage_child_fabrics.py index 80e47d02..d3a81c50 100644 --- a/plugins/action/dtc/manage_child_fabrics.py +++ b/plugins/action/dtc/manage_child_fabrics.py @@ -27,6 +27,7 @@ from ansible.utils.display import Display from ansible.plugins.action import ActionBase from ...plugin_utils.helper_functions import ndfc_get_fabric_attributes +from ...plugin_utils.helper_functions import ndfc_get_fabric_switches display = Display() @@ -37,76 +38,76 @@ def run(self, tmp=None, task_vars=None): results = super(ActionModule, self).run(tmp, task_vars) results['failed'] = False results['child_fabrics_moved'] = False - results['child_fabric_attributes'] = {} + # results['associated_child_fabrics'] = [] - fabric_associations = self._task.args['fabric_associations'].get('response').get('DATA') - parent_fabric_name = self._task.args['parent_fabric_name'] + # fabric_associations = self._task.args['fabric_associations'].get('response').get('DATA') + parent_fabric = self._task.args['parent_fabric'] child_fabrics = self._task.args['child_fabrics'] - operation = self._task.args['operation'] + state = self._task.args['state'] # Build a list of child fabrics that are associated with the parent fabric - associated_child_fabrics = [] - for fabric in fabric_associations: - if fabric.get('fabricParent') == parent_fabric_name: - associated_child_fabrics.append(fabric.get('fabricName')) + # associated_child_fabrics = [] + # for fabric in fabric_associations: + # if fabric.get('fabricParent') == parent_fabric_name: + # associated_child_fabrics.append(fabric.get('fabricName')) - results['child_fabric_attributes'][fabric['fabricName']] = ndfc_get_fabric_attributes(self, task_vars, tmp, fabric['fabricName']) - - if operation == 'add': + if state == 'present': + for fabric in child_fabrics: + # if fabric.get('name') not in associated_child_fabrics: + json_data = '{"destFabric":"%s","sourceFabric":"%s"}' % (parent_fabric, fabric) + add_fabric_result = self._execute_module( + module_name="cisco.dcnm.dcnm_rest", + module_args={ + "method": "POST", + "path": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd", + "json_data": json_data + }, + task_vars=task_vars, + tmp=tmp + ) + + if add_fabric_result.get('failed'): + results['failed'] = True + results['msg'] = f"{add_fabric_result['msg']['MESSAGE']}: {add_fabric_result['msg']['DATA']}" + break + + # If a child fabric is successfully added under an MSD fabric set a flag + # indicating this so that it can be used later to prevent managing VRFs + # and Networks. If we dont prevent this then the VRFs and Networks could + # be removed as part of moving the child fabric. + # + # TBD: This flag is not actually being used currently. Discuss with team. + results['child_fabrics_moved'] = True + + results['changed'] = True + + # associated_child_fabrics.append(fabric['name']) + + if state == 'absent': for fabric in child_fabrics: - if fabric.get('name') not in associated_child_fabrics: - json_data = '{"destFabric":"%s","sourceFabric":"%s"}' % (parent_fabric_name, fabric.get('name')) - add_fabric_result = self._execute_module( - module_name="cisco.dcnm.dcnm_rest", - module_args={ - "method": "POST", - "path": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdAdd", - "json_data": json_data - }, - task_vars=task_vars, - tmp=tmp - ) - - if add_fabric_result.get('failed'): - results['failed'] = True - results['msg'] = f"{add_fabric_result['msg']['MESSAGE']}: {add_fabric_result['msg']['DATA']}" - break - - # If a child fabric is successfully added under an MSD fabric set a flag - # indicating this so that it can be used later to prevent managing VRFs - # and Networks. If we dont prevent this then the VRFs and Networks could - # be removed as part of moving the child fabric. - # - # TBD: This flag is not actually being used currently. Discuss with team. - results['child_fabrics_moved'] = True - - results['changed'] = True - - results['child_fabric_attributes'][fabric] = ndfc_get_fabric_attributes(self, task_vars, tmp, fabric) - - if operation == 'remove': - for associated_child_fabric in associated_child_fabrics: - if not any(associated_child_fabric == child_fabric['name'] for child_fabric in child_fabrics): - json_data = '{"destFabric":"%s","sourceFabric":"%s"}' % (parent_fabric_name, associated_child_fabric) - remove_fabric_result = self._execute_module( - module_name="cisco.dcnm.dcnm_rest", - module_args={ - "method": "POST", - "path": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdExit", - "json_data": json_data - }, - task_vars=task_vars, - tmp=tmp - ) - - if remove_fabric_result.get('failed'): - results['failed'] = True - results['msg'] = f"{remove_fabric_result['msg']['MESSAGE']}: {remove_fabric_result['msg']['DATA']}" - break - - results['changed'] = True - - results['child_fabric_attributes'].pop(associated_child_fabric) + # if not any(associated_child_fabric == child_fabric['name'] for child_fabric in child_fabrics): + json_data = '{"destFabric":"%s","sourceFabric":"%s"}' % (parent_fabric, fabric) + remove_fabric_result = self._execute_module( + module_name="cisco.dcnm.dcnm_rest", + module_args={ + "method": "POST", + "path": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msdExit", + "json_data": json_data + }, + task_vars=task_vars, + tmp=tmp + ) + + if remove_fabric_result.get('failed'): + results['failed'] = True + results['msg'] = f"{remove_fabric_result['msg']['MESSAGE']}: {remove_fabric_result['msg']['DATA']}" + break + + results['changed'] = True + + # results['associated_child_fabrics'].pop(associated_child_fabric) + + # results['associated_child_fabrics'] = associated_child_fabrics return results diff --git a/plugins/action/dtc/prepare_msite.py b/plugins/action/dtc/prepare_msite.py new file mode 100644 index 00000000..557486a4 --- /dev/null +++ b/plugins/action/dtc/prepare_msite.py @@ -0,0 +1,157 @@ +# Copyright (c) 2024 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 +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible.utils.display import Display +from ansible.plugins.action import ActionBase +from ...plugin_utils.helper_functions import ndfc_get_fabric_attributes +from ...plugin_utils.helper_functions import ndfc_get_fabric_switches + +display = Display() + + +class ActionModule(ActionBase): + + def run(self, tmp=None, task_vars=None): + results = super(ActionModule, self).run(tmp, task_vars) + results['failed'] = False + results['md_msite'] = {} + + model_data = self._task.args["model_data"] + parent_fabric = self._task.args["parent_fabric"] + child_fabrics = self._task.args["child_fabrics"] + + # This is actaully not an accurrate API endpoint as it returns all fabrics in NDFC, not just the fabrics associated with MSD + # Therefore, we need to get the fabric associations response and filter out the fabrics that are not associated with the parent fabric (MSD) + msd_fabric_associations = self._execute_module( + module_name="cisco.dcnm.dcnm_rest", + module_args={ + "method": "GET", + "path": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations", + }, + task_vars=task_vars, + tmp=tmp + ) + + # Build a list of child fabrics that are associated with the parent fabric (MSD) + associated_child_fabrics = [] + for fabric in msd_fabric_associations.get('response').get('DATA'): + if fabric.get('fabricParent') == parent_fabric: + associated_child_fabrics.append(fabric.get('fabricName')) + + # Can probably remove this as I don't think it will be used + results['current_associated_child_fabrics'] = associated_child_fabrics + + # Build a list of child fabrics that are to be removed from the parent fabric (MSD) + child_fabrics_list = [child_fabric['name'] for child_fabric in child_fabrics] + child_fabrics_to_be_removed = [] + child_fabric_to_be_removed = [fabric for fabric in associated_child_fabrics if fabric not in child_fabrics_list] + child_fabrics_to_be_removed = child_fabrics_to_be_removed + child_fabric_to_be_removed + + results['child_fabrics_to_be_removed'] = child_fabrics_to_be_removed + + # Build a list of desired child fabrics that are not associated with the parent fabric (MSD) + child_fabrics_to_be_associated = [] + for fabric in child_fabrics: + if fabric.get('name') not in associated_child_fabrics: + child_fabrics_to_be_associated.append(fabric.get('name')) + + results['child_fabrics_to_be_associated'] = child_fabrics_to_be_associated + + # Merge the lists of currently associated child fabrics and child fabrics to be associated + # The assumption here is that the child fabric(s) that will be associated with the parent fabric (MSD) + # in the create role will either be sucessful and we have the prepared data to work with or + # the association will fail, resulting in runtime execution stopping, thus it doens't matter what prepared data we have. + associated_child_fabrics = associated_child_fabrics + child_fabrics_to_be_associated + + # Can probably remove this as I don't think it will be used + results['end_state_associated_child_fabrics'] = associated_child_fabrics + + child_fabrics_data = {} + for fabric in associated_child_fabrics: + child_fabrics_data.update({fabric: {}}) + child_fabrics_data[fabric].update({'attributes': ndfc_get_fabric_attributes(self, task_vars, tmp, fabric)}) + child_fabrics_data[fabric].update({'switches': ndfc_get_fabric_switches(self, task_vars, tmp, fabric)}) + + results['child_fabrics_data'] = child_fabrics_data + + # Rebuild sm_data['vxlan']['multisite']['overlay']['vrf_attach_groups'] into + # a structure that is easier to use just like MD_Extended. + vrf_grp_name_list = [] + model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'] = {} + model_data['vxlan']['multisite']['overlay']['vrf_attach_switches_list'] = [] + for grp in model_data['vxlan']['multisite']['overlay']['vrf_attach_groups']: + model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'][grp['name']] = [] + vrf_grp_name_list.append(grp['name']) + for switch in grp['switches']: + model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'][grp['name']].append(switch) + # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP + for switch in model_data['vxlan']['multisite']['overlay']['vrf_attach_groups_dict'][grp['name']]: + for child_fabric in child_fabrics_data.keys(): + for sw in child_fabrics_data[child_fabric]['switches']: + if switch['hostname'] == sw['hostname']: + switch['mgmt_ip_address'] = sw['mgmt_ip_address'] + + # Append switch to a flat list of switches for cross comparison later when we query the + # MSD fabric information. We need to stop execution if the list returned by the MSD query + # does not include one of these switches. + model_data['vxlan']['multisite']['overlay']['vrf_attach_switches_list'].append(switch['hostname']) + + # Remove vrf_attach_group from vrf if the group_name is not defined + for vrf in model_data['vxlan']['multisite']['overlay']['vrfs']: + if 'vrf_attach_group' in vrf: + if vrf.get('vrf_attach_group') not in vrf_grp_name_list: + del vrf['vrf_attach_group'] + + # Rebuild sm_data['vxlan']['overlay']['network_attach_groups'] into + # a structure that is easier to use. + net_grp_name_list = [] + model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'] = {} + model_data['vxlan']['multisite']['overlay']['network_attach_switches_list'] = [] + for grp in model_data['vxlan']['multisite']['overlay']['network_attach_groups']: + model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'][grp['name']] = [] + net_grp_name_list.append(grp['name']) + for switch in grp['switches']: + model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'][grp['name']].append(switch) + # If the switch is in the switch list and a hostname is used, replace the hostname with the management IP + for switch in model_data['vxlan']['multisite']['overlay']['network_attach_groups_dict'][grp['name']]: + for child_fabric in child_fabrics_data.keys(): + for sw in child_fabrics_data[child_fabric]['switches']: + if switch['hostname'] == sw['hostname']: + switch['mgmt_ip_address'] = sw['mgmt_ip_address'] + # Append switch to a flat list of switches for cross comparison later when we query the + # MSD fabric information. We need to stop execution if the list returned by the MSD query + # does not include one of these switches. + model_data['vxlan']['multisite']['overlay']['network_attach_switches_list'].append(switch['hostname']) + + # Remove network_attach_group from net if the group_name is not defined + for net in model_data['vxlan']['multisite']['overlay']['networks']: + if 'network_attach_group' in net: + if net.get('network_attach_group') not in net_grp_name_list: + del net['network_attach_group'] + + results['overlay_attach_groups'] = model_data['vxlan']['multisite']['overlay'] + + return results diff --git a/plugins/plugin_utils/helper_functions.py b/plugins/plugin_utils/helper_functions.py index 233163be..7115e9d6 100644 --- a/plugins/plugin_utils/helper_functions.py +++ b/plugins/plugin_utils/helper_functions.py @@ -195,3 +195,41 @@ def ndfc_get_fabric_attributes(self, task_vars, tmp, fabric): fabric_attributes = fabric_response['response']['DATA']['nvPairs'] return fabric_attributes + + +def ndfc_get_fabric_switches(self, task_vars, tmp, fabric): + """ + Get NDFC fabric switches. + + :Parameters: + :self: Ansible action plugin instance object. + :task_vars (dict): Ansible task vars. + :tmp (None, optional): Ansible tmp object. Defaults to None via Action Plugin. + :fabric (str): The fabric name to be retrieved. + + :Returns: + :fabric_switches: The NDFC fabric switches data for the given fabric. + + :Raises: + N/A + """ + fabric_response = self._execute_module( + module_name="cisco.dcnm.dcnm_inventory", + module_args={ + "fabric": fabric, + "state": "query" + }, + task_vars=task_vars, + tmp=tmp + ) + + fabric_switches = [] + for fabric_switch in fabric_response['response']: + fabric_switches.append( + { + 'hostname': fabric_switch['hostName'], + 'mgmt_ip_address': fabric_switch['ipAddress'] + } + ) + + return fabric_switches diff --git a/roles/dtc/common/tasks/msd/ndfc_children.yml b/roles/dtc/common/tasks/msd/ndfc_child_fabrics.yml similarity index 71% rename from roles/dtc/common/tasks/msd/ndfc_children.yml rename to roles/dtc/common/tasks/msd/ndfc_child_fabrics.yml index 5ffba9e3..19eae49d 100644 --- a/roles/dtc/common/tasks/msd/ndfc_children.yml +++ b/roles/dtc/common/tasks/msd/ndfc_child_fabrics.yml @@ -18,4 +18,14 @@ # - Create VXLAN / ISN Fabrics then MSD Fabric + Association # - Create MSD Fabric then VXLAN / ISN Fabrics + Association # - VRF / Network problem when child fabrics moved under MSD but MSD level VRF/Net model data is empty -# (Result is all VRF/Networks are removed after they get moved under MSD - can be controlled with flag) \ No newline at end of file +# (Result is all VRF/Networks are removed after they get moved under MSD - can be controlled with flag) + +- name: Prepare Multisite Data + cisco.nac_dc_vxlan.dtc.prepare_msite: + model_data: "{{ MD_Extended }}" + parent_fabric: "{{ MD_Extended.vxlan.fabric.name }}" + child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" + when: + - MD_Extended.vxlan.multisite.child_fabrics is defined + - MD_Extended.vxlan.multisite.child_fabrics + register: MD_Msite diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 5ea45ee7..d0eebb26 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -50,19 +50,19 @@ # -------------------------------------------------------------------- - name: Build NDFC Child Fabric Inventory List From Template - ansible.builtin.import_tasks: msd/ndfc_children.yml + ansible.builtin.import_tasks: msd/ndfc_child_fabrics.yml -- name: Get Switch Inventory from MSD Fabric - cisco.nac_dc_vxlan.dtc.map_msd_inventory: - parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" - model_data_overlay: "{{ MD_Extended.vxlan.multisite.overlay }}" - register: msd_inventory +# - name: Get Switch Inventory from MSD Fabric +# cisco.nac_dc_vxlan.dtc.map_msd_inventory: +# parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" +# model_data_overlay: "{{ MD_Extended.vxlan.multisite.overlay }}" +# register: msd_inventory -- name: Set MSD Switches List - ansible.builtin.set_fact: - msd_switches: "{{ msd_inventory.msd_switches }}" +# - name: Set MSD Switches List +# ansible.builtin.set_fact: +# msd_switches: "{{ msd_inventory.msd_switches }}" -- debug: msg="{{ msd_switches }}" +# - debug: msg="{{ msd_switches }}" # -------------------------------------------------------------------- # Build NDFC Fabric VRFs Attach List From Template diff --git a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 index d713b60b..496f07d8 100644 --- a/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/msd_fabric/resources/msd_fabric_resources.j2 @@ -2,7 +2,7 @@ {% if (vxlan.multisite.enable_ipv6_underlay | default(defaults.vxlan.multisite.enable_ipv6_underlay) | ansible.builtin.bool) is sameas false %} LOOPBACK100_IP_RANGE: {{ vxlan.multisite.ipv4_vtep_loopback_range | default(defaults.vxlan.multisite.ipv4_vtep_loopback_range) }} DCI_SUBNET_RANGE: {{ vxlan.multisite.overlay_dci.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.overlay_dci.ipv4_dci_subnet_range) }} - DCI_SUBNET_TARGET_MASK: {{ vxlan.multisite.overlay_dci.ipv4_dci_subnet_range | default(defaults.vxlan.multisite.overlay_dci.ipv4_dci_subnet_mask) }} + DCI_SUBNET_TARGET_MASK: {{ vxlan.multisite.overlay_dci.ipv4_dci_subnet_mask | default(defaults.vxlan.multisite.overlay_dci.ipv4_dci_subnet_mask) }} {% else %} LOOPBACK100_IPV6_RANGE: {{ vxlan.multisite.ipv6_vtep_loopback_range | default(defaults.vxlan.multisite.ipv6_vtep_loopback_range) }} V6_DCI_SUBNET_RANGE: {{ vxlan.multisite.overlay_dci.ipv6_dci_subnet_range | default(defaults.vxlan.multisite.overlay_dci.ipv6_dci_subnet_range) }} 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 1eb61cbc..2531665f 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 @@ -1,6 +1,7 @@ {# 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 %} @@ -28,18 +29,14 @@ {# ------------------------------------------------------ #} {# Attach Group Section #} {# ------------------------------------------------------ #} -{# Don't need to attach vrfs if there are no msd_switches #} -{% if msd_switches|length > 0 %} {% if vrf['vrf_attach_group'] is defined %} attach: -{% if MD_Extended.vxlan.multisite.overlay.vrf_attach_groups_dict is defined and MD_Extended.vxlan.multisite.overlay.vrf_attach_groups_dict %} -{% set vrf_attach_groups_dict = MD_Extended.vxlan.multisite.overlay.vrf_attach_groups_dict %} +{% if MD_Msite.overlay_attach_groups.vrf_attach_groups_dict is defined and MD_Msite.overlay_attach_groups.vrf_attach_groups_dict %} +{% set vrf_attach_groups_dict = MD_Msite.overlay_attach_groups.vrf_attach_groups_dict %} {% endif %} {% for attach in vrf_attach_groups_dict[vrf['vrf_attach_group']] %} - - ip_address: {{ msd_switches[attach['hostname']] }} + - ip_address: {{ attach['mgmt_ip_address'] }} {% endfor %} - deploy: false -{% endif %} {% endif %} - + deploy: false {% endfor %} diff --git a/roles/dtc/create/tasks/msd/child_fabrics.yml b/roles/dtc/create/tasks/msd/child_fabrics.yml index a3129cf5..6e05df96 100644 --- a/roles/dtc/create/tasks/msd/child_fabrics.yml +++ b/roles/dtc/create/tasks/msd/child_fabrics.yml @@ -28,20 +28,41 @@ - "+ Manage Fabric {{ MD_Extended.vxlan.fabric.name }}" - "----------------------------------------------------------------" -- name: Get Fabric Association Data from NDFC - cisco.dcnm.dcnm_rest: - method: GET - path: /appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations - register: fabric_associations +# - name: Get Fabric Association Data from NDFC +# cisco.dcnm.dcnm_rest: +# method: GET +# path: /appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations +# register: fabric_associations -- ansible.builtin.debug: - var: fabric_associations +# - ansible.builtin.debug: +# var: fabric_associations - name: Add Child Fabrics To Fabric - {{ MD_Extended.vxlan.fabric.name }} cisco.nac_dc_vxlan.dtc.manage_child_fabrics: - fabric_associations: "{{ fabric_associations }}" - parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" - child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" - operation: add - when: fabric_associations is defined and fabric_associations - register: fabric_move_result + parent_fabric: "{{ MD_Extended.vxlan.fabric.name }}" + child_fabrics: "{{ MD_Msite.child_fabrics_to_be_associated }}" + state: present + when: + - MD_Msite.child_fabrics_to_be_associated is defined + - MD_Msite.child_fabrics_to_be_associated + # register: managed_child_fabrics + +# - name: Set Associated Child Fabric Attribute Data +# ansible.builtin.set_fact: +# associated_child_fabric_data: "{{ child_fabric_results.child_fabric_data }}" +# when: child_fabric_results is defined and child_fabric_results + +# - ansible.builtin.debug: +# var: managed_child_fabrics + +# - name: Prepare Multisite Data +# cisco.nac_dc_vxlan.dtc.prepare_msite: +# model_data: "{{ MD_Extended }}" +# associated_child_fabrics: "{{ managed_child_fabrics.associated_child_fabrics }}" +# when: managed_child_fabrics.associated_child_fabrics is defined and managed_child_fabrics.associated_child_fabrics +# register: MD_Msite + +# - ansible.builtin.debug: +# var: MD_Msite + +# - ansible.builtin.meta: end_play diff --git a/roles/dtc/remove/tasks/msd/child_fabrics.yml b/roles/dtc/remove/tasks/msd/child_fabrics.yml index 0a14762a..4c5dedf3 100644 --- a/roles/dtc/remove/tasks/msd/child_fabrics.yml +++ b/roles/dtc/remove/tasks/msd/child_fabrics.yml @@ -37,12 +37,12 @@ - name: Remove Unmanaged Child Fabrics from NDFC cisco.nac_dc_vxlan.dtc.manage_child_fabrics: - fabric_associations: "{{ fabric_associations }}" - parent_fabric_name: "{{ MD_Extended.vxlan.fabric.name }}" - child_fabrics: "{{ MD_Extended.vxlan.multisite.child_fabrics }}" - operation: remove + parent_fabric: "{{ MD_Extended.vxlan.fabric.name }}" + child_fabrics: "{{ MD_Msite.child_fabrics_to_be_removed }}" + state: absent when: - - fabric_associations is defined and fabric_associations + - MD_Msite.child_fabrics_to_be_removed is defined + - MD_Msite.child_fabrics_to_be_removed - (child_fabric_delete_mode is defined) and (child_fabric_delete_mode is true|bool) From f89bb1ba412b4277963f6c4f0ee486938fe84e9a Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 30 Jan 2025 08:15:45 -0500 Subject: [PATCH 59/66] fix lint errors --- plugins/action/dtc/manage_child_fabrics.py | 2 +- plugins/action/dtc/prepare_msite.py | 22 +++++++++++----------- tests/sanity/ignore-2.14.txt | 1 + tests/sanity/ignore-2.15.txt | 1 + tests/sanity/ignore-2.16.txt | 1 + 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/plugins/action/dtc/manage_child_fabrics.py b/plugins/action/dtc/manage_child_fabrics.py index d3a81c50..cefbbb84 100644 --- a/plugins/action/dtc/manage_child_fabrics.py +++ b/plugins/action/dtc/manage_child_fabrics.py @@ -81,7 +81,7 @@ def run(self, tmp=None, task_vars=None): results['changed'] = True - # associated_child_fabrics.append(fabric['name']) + # associated_child_fabrics.append(fabric['name']) if state == 'absent': for fabric in child_fabrics: diff --git a/plugins/action/dtc/prepare_msite.py b/plugins/action/dtc/prepare_msite.py index 557486a4..eaf2895b 100644 --- a/plugins/action/dtc/prepare_msite.py +++ b/plugins/action/dtc/prepare_msite.py @@ -47,13 +47,13 @@ def run(self, tmp=None, task_vars=None): # Therefore, we need to get the fabric associations response and filter out the fabrics that are not associated with the parent fabric (MSD) msd_fabric_associations = self._execute_module( module_name="cisco.dcnm.dcnm_rest", - module_args={ - "method": "GET", - "path": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations", - }, - task_vars=task_vars, - tmp=tmp - ) + module_args={ + "method": "GET", + "path": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/msd/fabric-associations", + }, + task_vars=task_vars, + tmp=tmp + ) # Build a list of child fabrics that are associated with the parent fabric (MSD) associated_child_fabrics = [] @@ -77,12 +77,12 @@ def run(self, tmp=None, task_vars=None): for fabric in child_fabrics: if fabric.get('name') not in associated_child_fabrics: child_fabrics_to_be_associated.append(fabric.get('name')) - + results['child_fabrics_to_be_associated'] = child_fabrics_to_be_associated # Merge the lists of currently associated child fabrics and child fabrics to be associated # The assumption here is that the child fabric(s) that will be associated with the parent fabric (MSD) - # in the create role will either be sucessful and we have the prepared data to work with or + # in the create role will either be sucessful and we have the prepared data to work with or # the association will fail, resulting in runtime execution stopping, thus it doens't matter what prepared data we have. associated_child_fabrics = associated_child_fabrics + child_fabrics_to_be_associated @@ -112,7 +112,7 @@ def run(self, tmp=None, task_vars=None): for child_fabric in child_fabrics_data.keys(): for sw in child_fabrics_data[child_fabric]['switches']: if switch['hostname'] == sw['hostname']: - switch['mgmt_ip_address'] = sw['mgmt_ip_address'] + switch['mgmt_ip_address'] = sw['mgmt_ip_address'] # Append switch to a flat list of switches for cross comparison later when we query the # MSD fabric information. We need to stop execution if the list returned by the MSD query @@ -140,7 +140,7 @@ def run(self, tmp=None, task_vars=None): for child_fabric in child_fabrics_data.keys(): for sw in child_fabrics_data[child_fabric]['switches']: if switch['hostname'] == sw['hostname']: - switch['mgmt_ip_address'] = sw['mgmt_ip_address'] + switch['mgmt_ip_address'] = sw['mgmt_ip_address'] # Append switch to a flat list of switches for cross comparison later when we query the # MSD fabric information. We need to stop execution if the list returned by the MSD query # does not include one of these switches. diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 75bf9e02..7a09377b 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -15,6 +15,7 @@ plugins/action/common/run_map.py action-plugin-docs # action plugin has no match plugins/action/common/read_run_map.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/merge_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/add_device_check.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/dtc/prepare_msite.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/vpc_pair_check.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/verify_tags.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/diff_model_changes.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 75bf9e02..7a09377b 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -15,6 +15,7 @@ plugins/action/common/run_map.py action-plugin-docs # action plugin has no match plugins/action/common/read_run_map.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/merge_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/add_device_check.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/dtc/prepare_msite.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/vpc_pair_check.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/verify_tags.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/diff_model_changes.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.16.txt b/tests/sanity/ignore-2.16.txt index 75bf9e02..7a09377b 100644 --- a/tests/sanity/ignore-2.16.txt +++ b/tests/sanity/ignore-2.16.txt @@ -15,6 +15,7 @@ plugins/action/common/run_map.py action-plugin-docs # action plugin has no match plugins/action/common/read_run_map.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/merge_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/add_device_check.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/dtc/prepare_msite.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/vpc_pair_check.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/verify_tags.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/dtc/diff_model_changes.py action-plugin-docs # action plugin has no matching module to provide documentation From 2cd93f032e9d6473c51728ee153e6cb5c85bc772 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 30 Jan 2025 11:03:11 -0500 Subject: [PATCH 60/66] add msd child fabric vrfs template & fix lint errors --- plugins/action/dtc/manage_child_fabrics.py | 2 -- plugins/action/dtc/prepare_msite.py | 3 +- roles/dtc/common/tasks/sub_main_msd.yml | 3 ++ .../dtc/common/templates/ndfc_attach_vrfs.j2 | 1 + .../child_fabric/msd_child_fabric_vrfs.j2 | 28 +++++++++++++++++++ 5 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrfs.j2 diff --git a/plugins/action/dtc/manage_child_fabrics.py b/plugins/action/dtc/manage_child_fabrics.py index cefbbb84..3eaf6870 100644 --- a/plugins/action/dtc/manage_child_fabrics.py +++ b/plugins/action/dtc/manage_child_fabrics.py @@ -26,8 +26,6 @@ from ansible.utils.display import Display from ansible.plugins.action import ActionBase -from ...plugin_utils.helper_functions import ndfc_get_fabric_attributes -from ...plugin_utils.helper_functions import ndfc_get_fabric_switches display = Display() diff --git a/plugins/action/dtc/prepare_msite.py b/plugins/action/dtc/prepare_msite.py index eaf2895b..b36984fe 100644 --- a/plugins/action/dtc/prepare_msite.py +++ b/plugins/action/dtc/prepare_msite.py @@ -37,7 +37,6 @@ class ActionModule(ActionBase): def run(self, tmp=None, task_vars=None): results = super(ActionModule, self).run(tmp, task_vars) results['failed'] = False - results['md_msite'] = {} model_data = self._task.args["model_data"] parent_fabric = self._task.args["parent_fabric"] @@ -89,6 +88,8 @@ def run(self, tmp=None, task_vars=None): # Can probably remove this as I don't think it will be used results['end_state_associated_child_fabrics'] = associated_child_fabrics + # Get the fabric attributes and switches for each child fabric + # These queries are potentially trying to get data for a fabric that is not associated with the parent fabric (MSD) yet child_fabrics_data = {} for fabric in associated_child_fabrics: child_fabrics_data.update({fabric: {}}) diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index d0eebb26..497d4cbf 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -71,6 +71,9 @@ - name: Build NDFC Fabric VRFs Attach List From Template ansible.builtin.import_tasks: msd/ndfc_vrfs.yml +- name: Build NDFC Fabric VRFs Attach List From Template + ansible.builtin.import_tasks: msd/ndfc_child_fabric_vrfs.yml + # -------------------------------------------------------------------- # Build NDFC Fabric Networks Attach List From Template # -------------------------------------------------------------------- diff --git a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 index 3c4d3367..e25ac709 100644 --- a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 @@ -12,6 +12,7 @@ {# Include NDFC MSD Base Template #} {% include '/ndfc_vrfs/msd_fabric/msd_fabric_vrfs.j2' %} +{# {% include '/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrfs.j2' %} #} {# Supported fabric types are: DC VXLAN EVPN and ISN #} {% endif %} 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 new file mode 100644 index 00000000..4b32397a --- /dev/null +++ b/roles/dtc/common/templates/ndfc_vrfs/msd_fabric/child_fabric/msd_child_fabric_vrfs.j2 @@ -0,0 +1,28 @@ +{# Auto-generated NDFC DC VXLAN EVPN 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) }} + 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 %} + +{% endfor %} From 5627f6b5b80a17c00eec1864cbed1ffa7d97b163 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 30 Jan 2025 12:14:41 -0500 Subject: [PATCH 61/66] fixes --- roles/dtc/common/tasks/sub_main_msd.yml | 4 ++-- .../templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/dtc/common/tasks/sub_main_msd.yml b/roles/dtc/common/tasks/sub_main_msd.yml index 497d4cbf..50f21546 100644 --- a/roles/dtc/common/tasks/sub_main_msd.yml +++ b/roles/dtc/common/tasks/sub_main_msd.yml @@ -71,8 +71,8 @@ - name: Build NDFC Fabric VRFs Attach List From Template ansible.builtin.import_tasks: msd/ndfc_vrfs.yml -- name: Build NDFC Fabric VRFs Attach List From Template - ansible.builtin.import_tasks: msd/ndfc_child_fabric_vrfs.yml +# - name: Build NDFC Fabric VRFs Attach List From Template +# ansible.builtin.import_tasks: msd/ndfc_child_fabric_vrfs.yml # -------------------------------------------------------------------- # Build NDFC Fabric Networks Attach List From Template diff --git a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 index c3d190aa..d9594eab 100644 --- a/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 +++ b/roles/dtc/common/templates/ndfc_fabric/isn_fabric/isn_fabric_base.j2 @@ -13,7 +13,7 @@ {% include '/ndfc_fabric/isn_fabric/resources/isn_fabric_resources.j2' %} {# Include NDFC ISN Bootstrap Template #} -{# {% include '/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2' %} #} +{% include '/ndfc_fabric/isn_fabric/bootstrap/isn_fabric_bootstrap.j2' %} {# Include NDFC ISN Flow Monitor Template #} {% include '/ndfc_fabric/isn_fabric/flow_monitor/isn_fabric_flow_monitor.j2' %} From cf01600054d97f72a3bc66cd3d0695974ac4c9c6 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Thu, 30 Jan 2025 12:45:05 -0500 Subject: [PATCH 62/66] set msite prepare defaults --- plugins/action/dtc/prepare_msite.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/action/dtc/prepare_msite.py b/plugins/action/dtc/prepare_msite.py index b36984fe..df24cb98 100644 --- a/plugins/action/dtc/prepare_msite.py +++ b/plugins/action/dtc/prepare_msite.py @@ -37,6 +37,11 @@ class ActionModule(ActionBase): def run(self, tmp=None, task_vars=None): results = super(ActionModule, self).run(tmp, task_vars) results['failed'] = False + results['current_associated_child_fabrics'] = [] + results['child_fabrics_to_be_removed'] = [] + results['child_fabrics_to_be_associated'] = [] + results['end_state_associated_child_fabrics'] = [] + results['child_fabrics_data'] = {} model_data = self._task.args["model_data"] parent_fabric = self._task.args["parent_fabric"] From 81156d2ce7e4589a8fa400d8c37b7e1795fc143f Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Sat, 1 Feb 2025 21:05:15 -0500 Subject: [PATCH 63/66] updated existing rules to allow empty vrfs & add first msite rule --- .../001_supported_via_child_fabric.py | 49 ++++++ .../vxlan/401_overlay_cross_reference.py | 128 ++++++++++++++ .../401_overlay_services_cross_reference.py | 166 ------------------ ...y_services_vrfs.py => 402_overlay_vrfs.py} | 6 - ...es_networks.py => 403_overlay_networks.py} | 0 5 files changed, 177 insertions(+), 172 deletions(-) create mode 100644 roles/validate/files/rules/multisite/001_supported_via_child_fabric.py create mode 100644 roles/validate/files/rules/vxlan/401_overlay_cross_reference.py delete mode 100644 roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py rename roles/validate/files/rules/vxlan/{402_overlay_services_vrfs.py => 402_overlay_vrfs.py} (94%) rename roles/validate/files/rules/vxlan/{403_overlay_services_networks.py => 403_overlay_networks.py} (100%) diff --git a/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py b/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py new file mode 100644 index 00000000..6059a9e2 --- /dev/null +++ b/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py @@ -0,0 +1,49 @@ +class Rule: + id = "001" + description = "Verify the data model for what should be supported via child fabric(s)." + severity = "HIGH" + + @classmethod + def match(cls, inventory): + results = [] + + # Keys supported via child fabric(s) + child_fabric_supported_keys = ['global', 'topology', 'underlay', 'overlay_extensions', 'policy'] + for child_fabric_supported_key in child_fabric_supported_keys: + check = cls.data_model_key_check(inventory, ['vxlan', child_fabric_supported_key]) + if child_fabric_supported_key in check['keys_found']: + results.append( + f"Key '{child_fabric_supported_key}' is supported via child fabric(s) respective host_vars data model file(s)." + ) + + return results + + return results + + @classmethod + def data_model_key_check(cls, tested_object, keys): + dm_key_dict = {'keys_found': [], 'keys_not_found': [], 'keys_data': [], 'keys_no_data': []} + for key in keys: + if tested_object and key in tested_object: + dm_key_dict['keys_found'].append(key) + tested_object = tested_object[key] + if tested_object: + dm_key_dict['keys_data'].append(key) + else: + dm_key_dict['keys_no_data'].append(key) + else: + dm_key_dict['keys_not_found'].append(key) + return dm_key_dict + + @classmethod + def safeget(cls, dict, keys): + # Utility function to safely get nested dictionary values + for key in keys: + if dict is None: + return None + if key in dict: + dict = dict[key] + else: + return None + + return dict diff --git a/roles/validate/files/rules/vxlan/401_overlay_cross_reference.py b/roles/validate/files/rules/vxlan/401_overlay_cross_reference.py new file mode 100644 index 00000000..ba1a400a --- /dev/null +++ b/roles/validate/files/rules/vxlan/401_overlay_cross_reference.py @@ -0,0 +1,128 @@ +class Rule: + id = "401" + description = "Cross Reference VRFs and Networks items in the Service Model" + severity = "HIGH" + + @classmethod + def match(cls, inventory): + results = [] + + switches = None + sm_networks = None + sm_vrfs = None + network_attach_groups = None + vrf_attach_groups = None + + switch_keys = ['vxlan', 'topology', 'switches'] + + # Remove the check for overlay_services after deprecation + # Remove lines 21 - 23 + overlay_key = 'overlay' + check = cls.data_model_key_check(inventory, ['vxlan', overlay_key]) + if overlay_key in check['keys_not_found'] or overlay_key in check['keys_no_data']: + overlay_key = 'overlay_services' + + check = cls.data_model_key_check(inventory, ['vxlan', overlay_key]) + if overlay_key in check['keys_found'] and overlay_key in check['keys_data']: + network_keys = ['vxlan', overlay_key, 'networks'] + vrf_keys = ['vxlan', overlay_key, 'vrfs'] + network_attach_keys = ['vxlan', overlay_key, 'network_attach_groups'] + vrf_attach_keys = ['vxlan', overlay_key, 'vrf_attach_groups'] + + # Check if vrfs, network and switch data is defined in the service model + check = cls.data_model_key_check(inventory, switch_keys) + if 'switches' in check['keys_data']: + switches = cls.safeget(inventory, switch_keys) + if not switches: + # No switches defined in the service model, no reason to continue + return results + + check = cls.data_model_key_check(inventory, network_keys) + if 'networks' in check['keys_data']: + sm_networks = cls.safeget(inventory, network_keys) + + check = cls.data_model_key_check(inventory, vrf_keys) + if 'vrfs' in check['keys_data']: + sm_vrfs = cls.safeget(inventory, vrf_keys) + + check = cls.data_model_key_check(inventory, vrf_attach_keys) + if 'vrf_attach_groups' in check['keys_data']: + vrf_attach_groups = cls.safeget(inventory, vrf_attach_keys) + + check = cls.data_model_key_check(inventory, network_attach_keys) + if 'network_attach_groups' in check['keys_data']: + network_attach_groups = cls.safeget(inventory, network_attach_keys) + + # Ensure Network is not referencing a VRF that is not defined in the service model + results = cls.cross_reference_vrfs_nets(sm_vrfs, sm_networks, results) + + if sm_vrfs and vrf_attach_groups: + results = cls.cross_reference_switches(vrf_attach_groups, switches, 'vrf', results) + if sm_networks and network_attach_groups: + results = cls.cross_reference_switches(network_attach_groups, switches, 'network', results) + + return results + + @classmethod + def data_model_key_check(cls, tested_object, keys): + dm_key_dict = {'keys_found': [], 'keys_not_found': [], 'keys_data': [], 'keys_no_data': []} + for key in keys: + if tested_object and key in tested_object: + dm_key_dict['keys_found'].append(key) + tested_object = tested_object[key] + if tested_object: + dm_key_dict['keys_data'].append(key) + else: + dm_key_dict['keys_no_data'].append(key) + else: + dm_key_dict['keys_not_found'].append(key) + return dm_key_dict + + @classmethod + def safeget(cls, dict, keys): + # Utility function to safely get nested dictionary values + for key in keys: + if dict is None: + return None + if key in dict: + dict = dict[key] + else: + return None + + return dict + + @classmethod + def cross_reference_vrfs_nets(cls, sm_vrfs, sm_networks, results): + if not sm_vrfs or not sm_networks: + return results + + vrf_names = [] + for vrf in sm_vrfs: + vrf_names.append(vrf.get("name")) + # Compare the two lists and generate an error message if a network is found + # in network_vrf_names that is not in vrf_names + for net in sm_networks: + if net.get("vrf_name") is not None: + if net.get("vrf_name") not in vrf_names: + results.append( + f"Network ({net.get('name')}) is referencing VRF ({net.get('vrf_name')}) " + "which is not defined in the service model. Add the VRF to the service model or remove the network from the service model " + "and re-run the playbook." + ) + + return results + + @classmethod + def cross_reference_switches(cls, attach_groups, switches, target, results): + # target is either vrf or network + for attach_group in attach_groups: + for switch in attach_group.get("switches"): + if switch.get("hostname"): + if not any(s.get("name") == switch.get("hostname") for s in switches): + if not any(s.get('management').get('management_ipv4_address') == switch.get("hostname") for s in switches): + if not any(s.get('management').get('management_ipv6_address') == switch.get("hostname") for s in switches): + ag = attach_group.get("name") + hn = switch.get("hostname") + results.append(f"{target} attach group {ag} hostname {hn} does not match any switch in the topology.") + + return results diff --git a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py b/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py deleted file mode 100644 index d651e224..00000000 --- a/roles/validate/files/rules/vxlan/401_overlay_services_cross_reference.py +++ /dev/null @@ -1,166 +0,0 @@ -class Rule: - id = "401" - description = "Cross Reference VRFs and Networks items in the Service Model" - severity = "HIGH" - - @classmethod - def match(cls, inventory): - results = [] - - switches = None - sm_networks = None - sm_vrfs = None - network_attach_groups = None - vrf_attach_groups = None - - switch_keys = ['vxlan', 'topology', 'switches'] - - # Remove the check for overlay_services after deprecation - # Remove lines 21 - 23 - overlay_key = 'overlay' - check = cls.data_model_key_check(inventory, ['vxlan', overlay_key]) - if overlay_key in check['keys_not_found'] or overlay_key in check['keys_no_data']: - overlay_key = 'overlay_services' - check = cls.data_model_key_check(inventory, ['vxlan', overlay_key]) - if overlay_key in check['keys_not_found'] or overlay_key in check['keys_no_data']: - results.append('Overlay data not found!') - return results - - network_keys = ['vxlan', overlay_key, 'networks'] - vrf_keys = ['vxlan', overlay_key, 'vrfs'] - network_attach_keys = ['vxlan', overlay_key, 'network_attach_groups'] - vrf_attach_keys = ['vxlan', overlay_key, 'vrf_attach_groups'] - - # Check if vrfs, network and switch data is defined in the service model - check = cls.data_model_key_check(inventory, switch_keys) - if 'switches' in check['keys_data']: - switches = cls.safeget(inventory, switch_keys) - if not switches: - # No switches defined in the service model, no reason to continue - return results - - check = cls.data_model_key_check(inventory, network_keys) - if 'networks' in check['keys_data']: - sm_networks = cls.safeget(inventory, network_keys) - - check = cls.data_model_key_check(inventory, vrf_keys) - if 'vrfs' in check['keys_data']: - sm_vrfs = cls.safeget(inventory, vrf_keys) - - check = cls.data_model_key_check(inventory, vrf_attach_keys) - if 'vrf_attach_groups' in check['keys_data']: - vrf_attach_groups = cls.safeget(inventory, vrf_attach_keys) - - check = cls.data_model_key_check(inventory, network_attach_keys) - if 'network_attach_groups' in check['keys_data']: - network_attach_groups = cls.safeget(inventory, network_attach_keys) - - # Ensure Network is not referencing a VRF that is not defined in the service model - results = cls.cross_reference_vrfs_nets(sm_vrfs, sm_networks, results) - - if sm_vrfs and vrf_attach_groups: - results = cls.cross_reference_switches(vrf_attach_groups, switches, 'vrf', results) - if sm_networks and network_attach_groups: - results = cls.cross_reference_switches(network_attach_groups, switches, 'network', results) - - # For backwards compatibility - # Lines 54 - 88 will be removed after the deprecation in a future release - # sm_networks = None - # sm_vrfs = None - # network_attach_groups = None - # vrf_attach_groups = None - - # network_keys = ['vxlan', 'overlay_services', 'networks'] - # vrf_keys = ['vxlan', 'overlay_services', 'vrfs'] - # network_attach_keys = ['vxlan', 'overlay_services', 'network_attach_groups'] - # vrf_attach_keys = ['vxlan', 'overlay_services', 'vrf_attach_groups'] - - # check = cls.data_model_key_check(inventory, network_keys) - # if 'networks' in check['keys_data']: - # sm_networks = cls.safeget(inventory, network_keys) - - # check = cls.data_model_key_check(inventory, vrf_keys) - # if 'vrfs' in check['keys_data']: - # sm_vrfs = cls.safeget(inventory, vrf_keys) - - # check = cls.data_model_key_check(inventory, vrf_attach_keys) - # if 'vrf_attach_groups' in check['keys_data']: - # vrf_attach_groups = cls.safeget(inventory, vrf_attach_keys) - - # check = cls.data_model_key_check(inventory, network_attach_keys) - # if 'network_attach_groups' in check['keys_data']: - # network_attach_groups = cls.safeget(inventory, network_attach_keys) - - # # Ensure Network is not referencing a VRF that is not defined in the service model - # results = cls.cross_reference_vrfs_nets(sm_vrfs, sm_networks, results) - - # if sm_vrfs and vrf_attach_groups: - # results = cls.cross_reference_switches(vrf_attach_groups, switches, 'vrf', results) - # if sm_networks and network_attach_groups: - # results = cls.cross_reference_switches(network_attach_groups, switches, 'network', results) - - return results - - @classmethod - def data_model_key_check(cls, tested_object, keys): - dm_key_dict = {'keys_found': [], 'keys_not_found': [], 'keys_data': [], 'keys_no_data': []} - for key in keys: - if tested_object and key in tested_object: - dm_key_dict['keys_found'].append(key) - tested_object = tested_object[key] - if tested_object: - dm_key_dict['keys_data'].append(key) - else: - dm_key_dict['keys_no_data'].append(key) - else: - dm_key_dict['keys_not_found'].append(key) - return dm_key_dict - - @classmethod - def safeget(cls, dict, keys): - # Utility function to safely get nested dictionary values - for key in keys: - if dict is None: - return None - if key in dict: - dict = dict[key] - else: - return None - - return dict - - @classmethod - def cross_reference_vrfs_nets(cls, sm_vrfs, sm_networks, results): - if not sm_vrfs or not sm_networks: - return results - - vrf_names = [] - for vrf in sm_vrfs: - vrf_names.append(vrf.get("name")) - # Compare the two lists and generate an error message if a network is found - # in network_vrf_names that is not in vrf_names - for net in sm_networks: - if net.get("vrf_name") is not None: - if net.get("vrf_name") not in vrf_names: - results.append( - f"Network ({net.get('name')}) is referencing VRF ({net.get('vrf_name')}) " - "which is not defined in the service model. Add the VRF to the service model or remove the network from the service model " - "and re-run the playbook." - ) - - return results - - @classmethod - def cross_reference_switches(cls, attach_groups, switches, target, results): - # target is either vrf or network - for attach_group in attach_groups: - for switch in attach_group.get("switches"): - if switch.get("hostname"): - if not any(s.get("name") == switch.get("hostname") for s in switches): - if not any(s.get('management').get('management_ipv4_address') == switch.get("hostname") for s in switches): - if not any(s.get('management').get('management_ipv6_address') == switch.get("hostname") for s in switches): - ag = attach_group.get("name") - hn = switch.get("hostname") - results.append(f"{target} attach group {ag} hostname {hn} does not match any switch in the topology.") - - return results diff --git a/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py b/roles/validate/files/rules/vxlan/402_overlay_vrfs.py similarity index 94% rename from roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py rename to roles/validate/files/rules/vxlan/402_overlay_vrfs.py index 8a28aadc..55a53b64 100644 --- a/roles/validate/files/rules/vxlan/402_overlay_services_vrfs.py +++ b/roles/validate/files/rules/vxlan/402_overlay_vrfs.py @@ -29,12 +29,6 @@ def match(cls, inventory): if 'vrfs' in check['keys_data']: vrfs = inventory["vxlan"]["overlay_services"]["vrfs"] - # if inventory["vxlan"].get("overlay", None) or inventory["vxlan"].get("overlay_services", None): - # if inventory["vxlan"].get("overlay").get("vrfs", None): - # vrfs = inventory["vxlan"]["overlay"]["vrfs"] - # elif inventory["vxlan"].get("overlay_services").get("vrfs", None): - # vrfs = inventory["vxlan"]["overlay_services"]["vrfs"] - for vrf in vrfs: current_vrf_netflow_status = vrf.get("netflow_enable", None) if current_vrf_netflow_status is not None: diff --git a/roles/validate/files/rules/vxlan/403_overlay_services_networks.py b/roles/validate/files/rules/vxlan/403_overlay_networks.py similarity index 100% rename from roles/validate/files/rules/vxlan/403_overlay_services_networks.py rename to roles/validate/files/rules/vxlan/403_overlay_networks.py From 5aa76773266b7fa62b8b025b8c66a831f8441676 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Sat, 1 Feb 2025 21:09:36 -0500 Subject: [PATCH 64/66] fix lint errors --- .../files/rules/multisite/001_supported_via_child_fabric.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py b/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py index 6059a9e2..ef9bb961 100644 --- a/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py +++ b/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py @@ -13,8 +13,8 @@ def match(cls, inventory): check = cls.data_model_key_check(inventory, ['vxlan', child_fabric_supported_key]) if child_fabric_supported_key in check['keys_found']: results.append( - f"Key '{child_fabric_supported_key}' is supported via child fabric(s) respective host_vars data model file(s)." - ) + f"Key '{child_fabric_supported_key}' "is supported via child fabric(s) respective host_vars data model file(s)." + ) return results From e29c17ea356d2834a4270c1fafd601054f382c20 Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Sat, 1 Feb 2025 21:17:28 -0500 Subject: [PATCH 65/66] add msite cross-ref rule --- .../multisite/201_overlay_cross_reference.py | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 roles/validate/files/rules/multisite/201_overlay_cross_reference.py diff --git a/roles/validate/files/rules/multisite/201_overlay_cross_reference.py b/roles/validate/files/rules/multisite/201_overlay_cross_reference.py new file mode 100644 index 00000000..62e2c906 --- /dev/null +++ b/roles/validate/files/rules/multisite/201_overlay_cross_reference.py @@ -0,0 +1,78 @@ +class Rule: + id = "401" + description = "Cross Reference VRFs and Networks items in the Service Model" + severity = "HIGH" + + @classmethod + def match(cls, inventory): + results = [] + + sm_networks = None + sm_vrfs = None + + check = cls.data_model_key_check(inventory, ['vxlan', 'multisite', 'overlay']) + if 'overlay' in check['keys_found'] and 'overlay' in check['keys_data']: + network_keys = ['vxlan', 'multisite', 'overlay', 'networks'] + vrf_keys = ['vxlan', 'multisite', 'overlay', 'vrfs'] + + check = cls.data_model_key_check(inventory, network_keys) + if 'networks' in check['keys_data']: + sm_networks = cls.safeget(inventory, network_keys) + + check = cls.data_model_key_check(inventory, vrf_keys) + if 'vrfs' in check['keys_data']: + sm_vrfs = cls.safeget(inventory, vrf_keys) + + # Ensure Network is not referencing a VRF that is not defined in the service model + results = cls.cross_reference_vrfs_nets(sm_vrfs, sm_networks, results) + + return results + + @classmethod + def data_model_key_check(cls, tested_object, keys): + dm_key_dict = {'keys_found': [], 'keys_not_found': [], 'keys_data': [], 'keys_no_data': []} + for key in keys: + if tested_object and key in tested_object: + dm_key_dict['keys_found'].append(key) + tested_object = tested_object[key] + if tested_object: + dm_key_dict['keys_data'].append(key) + else: + dm_key_dict['keys_no_data'].append(key) + else: + dm_key_dict['keys_not_found'].append(key) + return dm_key_dict + + @classmethod + def safeget(cls, dict, keys): + # Utility function to safely get nested dictionary values + for key in keys: + if dict is None: + return None + if key in dict: + dict = dict[key] + else: + return None + + return dict + + @classmethod + def cross_reference_vrfs_nets(cls, sm_vrfs, sm_networks, results): + if not sm_vrfs or not sm_networks: + return results + + vrf_names = [] + for vrf in sm_vrfs: + vrf_names.append(vrf.get("name")) + # Compare the two lists and generate an error message if a network is found + # in network_vrf_names that is not in vrf_names + for net in sm_networks: + if net.get("vrf_name") is not None: + if net.get("vrf_name") not in vrf_names: + results.append( + f"Network ({net.get('name')}) is referencing VRF ({net.get('vrf_name')}) " + "which is not defined in the service model. Add the VRF to the service model or remove the network from the service model " + "and re-run the playbook." + ) + + return results From fd4c73c85ef0f5dccba7f960a29cf56df9f9a75b Mon Sep 17 00:00:00 2001 From: Matt Tarkington Date: Sat, 1 Feb 2025 21:18:44 -0500 Subject: [PATCH 66/66] fix typo --- .../files/rules/multisite/001_supported_via_child_fabric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py b/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py index ef9bb961..968ccdd7 100644 --- a/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py +++ b/roles/validate/files/rules/multisite/001_supported_via_child_fabric.py @@ -13,7 +13,7 @@ def match(cls, inventory): check = cls.data_model_key_check(inventory, ['vxlan', child_fabric_supported_key]) if child_fabric_supported_key in check['keys_found']: results.append( - f"Key '{child_fabric_supported_key}' "is supported via child fabric(s) respective host_vars data model file(s)." + f"Key '{child_fabric_supported_key}' is supported via child fabric(s) respective host_vars data model file(s)." ) return results