diff --git a/.gitignore b/.gitignore index 0395d2bc..485f7b95 100644 --- a/.gitignore +++ b/.gitignore @@ -142,3 +142,5 @@ roles/validate/files/schema.yaml !roles/validate/files/rules/enhanced_rules/.gitkeep !roles/validate/files/rules/required_rules/* roles/validate/defaults/* +*service_model_extended*.json +*service_model_golden*.json diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d363ef0b..9aa14238 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,34 @@ This project adheres to `Semantic Versioning `_. .. contents:: ``Release Versions`` +`0.2.0`_ +===================== + +**Release Date:** ``2024-06-28`` + +Added +----- + +* Support for the following device inventory roles. Only applies to adding devices to a fabric with these role types. + - border_spine + - border_gateway + - border_gateway_spine + - super_spine + - border_super_spine + - border_gateway_super_spine +* Added SysLog Server Support - Fabric Creation Stage +* Added DHCP Support and Secondary IP Address Support - Network Creation Stage +* Support for Ansible Tags + - Tags to limit execution and target specific roles in the collection + - Tags to limit execution and target specific stages inside a role + +Fixed +----- +- https://github.com/netascode/ansible-dc-vxlan/issues/111 +- https://github.com/netascode/ansible-dc-vxlan/issues/112 +- https://github.com/netascode/ansible-dc-vxlan/issues/127 +- https://github.com/netascode/ansible-dc-vxlan/issues/135 + `0.1.0`_ ===================== @@ -28,4 +56,5 @@ The following roles have been added to the collection: This version of the collection includes support for an IPv4 Underlay only. Support for IPv6 Underlay will be available in the next release. +.. _0.2.0: https://github.com/netascode/ansible-dc-vxlan/compare/0.1.0...0.2.0 .. _0.1.0: https://github.com/netascode/ansible-dc-vxlan/compare/0.1.0...0.1.0 diff --git a/README.md b/README.md index 726dcca3..692c9d7e 100644 --- a/README.md +++ b/README.md @@ -2,50 +2,50 @@ [![Actions Status](https://github.com/netascode/ansible-dc-vxlan/workflows/CI/badge.svg)](https://github.com/netascode/ansible-dc-vxlan/actions) -Ansible collection for configuring Cisco VXLAN/EVPN fabric using Cisco Nexus Dashboard Fabric Controller (NDFC). Utilizing a foundation of a data model, this collection simplifies the configuration of VXLAN fabrics by abstracting the automation and utilizing a data model that represents the desired state of the fabric. An operator utilizing this collection will only have to modify the configuration state in the data model instead of creating the modules and the associated parameters. +Ansible Collection for configuring Cisco VXLAN EVPN fabrics using the Cisco Nexus Dashboard Fabric Controller (NDFC). This collection simplifies the configuration of VXLAN fabrics by abstracting the automation using a data model that represents the desired state of the fabric. With this collection, an operator only needs to modify the configuration state in the data model instead of creating custom playbooks with modules and the associated parameters. -This approach allows for a more consistent and repeatable configuration of VXLAN fabrics and is aligned with the methodology of infrastructure as code, where the configuration of NDFC would be saved in a version control system and managed as code. +This approach allows for consistent and repeatable configuration of VXLAN fabrics and aligns with Infrastructure as Code (IaC) methodology, where the configuration state of NDFC is saved in a version control system and managed as code. -Infrastructure as code (IaC) is a DevOps methodology that uses code to manage and provision IT infrastructure, instead of manual procedures. IaC uses a descriptive coding language to automate provisioning servers, operating systems, network devices and more. The NetAsCode VXLAN EVPN collection allows you to configure, in easy-to-understand YAML, data structures with the intended configuration state of a VXLAN fabric using Cisco Nexus Dashboard Fabric Controller. +Infrastructure as code (IaC) is a DevOps methodology that uses code to manage and provision IT infrastructure, bypassing manual procedures. IaC uses a descriptive coding language to automate the provisioning of servers, operating systems, network devices and more. -The NetAsCode VXLAN collection provides the capability to create a declarative method of configuration of VXLAN for [Cisco Nexus](https://www.cisco.com/site/us/en/products/networking/cloud-networking-switches/index.html) datacenter solution utilizing [Cisco Nexus Dashboard](https://www.cisco.com/site/us/en/products/networking/cloud-networking/nexus-platform/index.html). This allows the separation of data from execution logic. With little to no knowledge about automation, you can instantiate a VXLAN EVPN fabric with this collection. +The NetAsCode VXLAN EVPN collection allows you to configure, in easy-to-understand YAML, data structures describing the configuration state of a VXLAN fabric for [Cisco Nexus](https://www.cisco.com/site/us/en/products/networking/cloud-networking-switches/index.html) datacenters and then deploys this state using Ansible and the [Cisco Nexus Dashboard](https://www.cisco.com/site/us/en/products/networking/cloud-networking/nexus-platform/index.html). With little to no knowledge about automation, you can use this collection to instantiate a VXLAN EVPN fabric. -This is achieved by creating YAML files that contain a pre-determined data schema that is translated into underlying Ansible modules and resources. The core Ansible collection is open source and available. The collection is designed to be used in a CI/CD pipeline, which allows you to establish a declarative method of configuration of VXLAN for Cisco Nexus datacenter solution. +YAML files are created that contain a pre-determined data schema which is translated into underlying Ansible modules and resources. The core Ansible Collection is open source and available. This collection is designed to be used in a CI/CD pipeline in order to drive this declarative method of configuring a VXLAN fabric. > **Note**: For complete support and additional capabilities, Cisco provides a professional services capability under the Services as Code portfolio of services which can provide feature creation, end to end support and more. -## Understanding our Ansible roles +## Understanding our Ansible Roles -### Validate role +### Validate Role Role: [cisco.nac_dc_vxlan.validate](https://github.com/netascode/ansible-dc-vxlan/blob/develop/roles/validate/README.md) -The validate role function is to ensure that the data model is correct, and that the data model is going to be able to be processed by the subsequent roles. The validate role is going to read all the files in the `host_vars` directory and create a single data model in memory for execution. +The `validate` role ensures that the data model is correct and that the data model can be processed by the subsequent roles. The validate role reads all the files in the `host_vars` directory and create a single data model in memory for execution. -As part of the VXLAN as Code service from Cisco, you will also be able to utilize the semantic validation to make sure that the data model matches the intended expected values. This is a powerful feature that allows you to ensure that the data model is correct before it is deployed to the network. Also, part of the validate role is the ability to create rules that can be used to avoid operators from making specific configurations that are not allowed in the network. These can be as simple as ensuring naming convention to more complex rules for interconnectivity that would need to be avoided. These would be coded in python and can be constructed as part of the Services as Code offer. +As part of the VXLAN as Code service from Cisco, you will also be able to utilize the semantic validation feature to make sure that the data model matches the intended expected values. This is a powerful feature that allows you to ensure that the data model is correct before it is deployed to the network. Additonally the validate role allows creation of rules that can be used to prevent operators from making specific configurations that are not allowed in the network. These can be as simple as enforcing proper naming conventions to more complex rules for interconnectivity issues that should be avoided. These rules are coded in Python and can be constructed as part of the Services as Code offer. -### Create role +### Create Role Role: [cisco.nac_dc_vxlan.dtc.create](https://github.com/netascode/ansible-dc-vxlan/blob/develop/roles/dtc/create/README.md) -This role is going to create all the templates and variable parameters that are going to be used in the deployment of the VXLAN fabric. This role converts the data model into the proper templates that are required by the Ansible module to be able to communicate with the NDFC controller. +The `create` role builds all of the templates and variable parameters required to deploy the VXLAN fabric and creates fabric state in NDFC. The data model is converted into the proper templates required by the Ansible modules used to communicate with the NDFC controller and manage the fabric state. The `create` role has a dependency on the `validate` role. -### Deploy role +### Deploy Role Role: [cisco.nac_dc_vxlan.dtc.deploy](https://github.com/netascode/ansible-dc-vxlan/blob/develop/roles/dtc/deploy/README.md) -The deploy role is going to deploy those changes to the NDFC controller. This role is going to take the templates and variable parameters that were created in the `create` role and deploy them to the NDFC controller. This is the role that is going to make the changes in the NDFC controller. +The `deploy` role deploys the fabric state created using the Create role to the NDFC managed devices. The `deploy` role has a dependency on the `validate` role. -### Remove role +### Remove Role Role: [cisco.nac_dc_vxlan.dtc.remove](https://github.com/netascode/ansible-dc-vxlan/blob/develop/roles/dtc/remove/README.md) -The remove role is the opposite of the deploy role and removes what is represented in the data model from the NDFC controller. For this reason, this role requires the settings of some variables to true under the `group_vars` directory. This is to avoid accidental removal of configuration from NDFC that might impact the network. +The `remove` role removes state from the NDFC controller and the devices managed by the NDFC controller. When the collection discoveres managed state in NDFC that is not defined the the data model it gets removed by this role. For this reason this role requires the following variables to be set to `true` under the `group_vars` directory. This avoids accidental removal of configuration from NDFC that might impact the network. The `remove` role has a dependency on the `validate` role. -Inside the example repository under `group_vars/ndfc` is a file called `ndfc.yml` that contains some variables that need to be set to true to allow the removal of the configuration from the NDFC controller. The variables are: +Inside the [example repository](https://github.com/netascode/ansible-dc-vxlan-example) under `group_vars/ndfc` is a file called `ndfc.yaml` that contains the variables: ```yaml -# Parameters for the tasks in the 'Remove' role +# Control Parameters for 'Remove' role tasks interface_delete_mode: false network_delete_mode: false vrf_delete_mode: false @@ -53,23 +53,21 @@ inventory_delete_mode: false vpc_peering_delete_mode: false ``` -These variables are set to false by default to avoid accidental removal of configuration from NDFC that might impact the network. +**Note:** These variables are set to `false` by default to avoid accidental removal of configuration from NDFC that might impact the network. -### Advantages of the roles in the workflow +### Advantages of the Roles in the Workflow -The primary advantage of the workflow is that you can insert these in different stages of the data model preparation and changes without having to worry about impacts to the network. In a SCM repository environment, pipelines can be configured to run the validate role before approvals in pull requests. - -The roles are designed to be idempotent and only make changes when there are changes in the data model. For different stages of changes in the network, you can comment out the roles that are not required to be executed. You can leave the final full execution potentially to only happen from a pipeline, yet allow for operators to validate changes before they are executed. +These roles when run in sequence (validate, create, deploy, remove) are designed to build out the entire fabric and can be executed by a pipeline. The roles can also be run in isolation by simply commenting out the roles that are not required during testing and fabric buildout to validate incremental changes. ## Quick Start Guide -### Set environment for the collection +### Set Environment for the Collection -The first procedure for execution of the collection is going to be the installation of a virtual environment to be able to install the collection and it's requirements. Recommendation is to utilize [pyenv](https://github.com/pyenv/pyenv) which provides a robust python virtual environment capability that also includes management of python versions. These instructions will be detailed around pyenv. For the pipeline execution please refer to *pipeline section* where it is documented at container level. +Installation of a Python virtual environment is needed in order to install the collection and it's requirements. We recommend [pyenv](https://github.com/pyenv/pyenv) which provides a robust Python virtual environment capability that also allows for management of different Python versions. The following instructions are detailed around using pyenv. For pipeline execution please refer to the pipeline section which is documented at container level. -#### Step 1 - Installing the example repository +#### Step 1 - Installing the Example Repository -To simplify the usage of the collection we are providing you with an [example repository](https://github.com/netascode/ansible-dc-vxlan-example) that you can clone from GitHub which creates the proper skeleton required, including examples for pipelines. To clone the repository requires the installation of [git client](https://git-scm.com/downloads) that is available for all platforms. +To simplify getting started with this collection we provide you with an [example repository](https://github.com/netascode/ansible-dc-vxlan-example). Simply clone this repo from GitHub to create the required skeleton, including examples for pipelines. Cloaning the repository requires the installation of [git client](https://git-scm.com/downloads) which is available for all platforms. Run the following command in the location of interest. @@ -77,11 +75,12 @@ Run the following command in the location of interest. git clone https://github.com/netascode/ansible-dc-vxlan-example.git nac-vxlan ``` -This will clone the example repository into the directory nac-vxlan. Then you will delete the `.git` repository to remove the connection to the example repository. Which then allows you to create your own repository from this built structure. +This will clone the example repository into the directory `nac-vxlan`. Next delete the `.git` repository to remove the connection to the example repository. Now you can create your own repository from this pre-built structure. + +#### Step 2 - Create the Virtual Environment with pyenv -#### Step 2 - Create the virtual environment with pyenv +In this directory create a new virtual environment and install a Python version of your choice. At the time of this writting, a commonly used version is Python version 3.10.13. Command pyenv install 3.10.13 will install this version. For detailed instructions please visit the [pyenv](https://github.com/pyenv/pyenv) site. -In this directory you will now create the new virtual environment. For pyenv to work you must install a version of Python that you want to utilize. At the _time of this writing_, a common version utilized is python version 3.10.13 so to install this with pyenv would be the command `pyenv install 3.10.13`. For detailed instructions please visit the [pyenv](https://github.com/pyenv/pyenv) site. ```bash cd nac-vxlan @@ -89,9 +88,9 @@ pyenv virtualenv nac-ndfc pyenv local nac-ndfc ``` -The final command is `pyenv local` which sets the environment so that whenever you enter the directory it will change into the right virtual environment. +Executing command pyenv local nac-ndfc sets the environment so that whenever the directory is entered it will change into the right virtual environment. -#### Step 3 - Install Ansible and additional required tools +#### Step 3 - Install Ansible and Additional Required Tools Included in the example repository is the requirements file to install ansible. First upgrade PIP to latest version. @@ -100,25 +99,25 @@ pip install --upgrade pip pip install -r requirements.txt ``` -#### Step 4 - Install Ansible Galaxy Collection (default placement) +#### Step 4 - (Option 1) - Install Ansible Galaxy Collection (default placement) The default placement of the ansible galaxy collections would be in your home directory under `.ansible/collections/ansible_collections/`. To install the collection in the default location run the following command: ```bash -ansible-galaxy collection install -r requirements.yml +ansible-galaxy collection install -r requirements.yaml ``` -#### Step 5 - Install Ansible Galaxy collection (non-default placement) +#### Step 4 - (Option 2) Install Ansible Galaxy Collection (non-default placement) If you wish to install the galaxy collection inside the repository you are creating with this example repository, you can run the following command: ```bash -ansible-galaxy collection install -p collections/ansible_collections/ -r requirements.yml +ansible-galaxy collection install -p collections/ansible_collections/ -r requirements.yaml ``` -You will need to then configure your ansible.cfg file to point to the correct location of the collection. +The `ansible.cfg` file needs to be configured to point to the location of the collection. -This is the path for all the python modules and libraries of the virtual environment that were created. If you look in that directory, you will find the collections package locations. Here is the base ansible.cfg, you will need to adjust the collection_path to your environment paths: +This is the path for all the python modules and libraries of the virtual environment that were created. If you look in that directory, you will find the collections package locations. Here is the base ansible.cfg, you will need to adjust the collections_path to your environment paths: ```bash [defaults] @@ -126,7 +125,7 @@ collections_path = ./collections/ansible_collections/ ``` -#### Step 6 - Change Ansible callbacks +#### Step 5 - Change Ansible Callbacks If you wish to add any ansible callbacks ( the listed below expand on displaying time execution ) you can add the following to the ansible.cfg file: @@ -136,7 +135,7 @@ callbacks_enabled=ansible.posix.timer,ansible.posix.profile_tasks,ansible.posix. bin_ansible_callbacks = True ``` -#### Step 7 - Verify the installation +#### Step 6 - Verify the Installation Verify that the ansible configuration file is being read and all the paths are correct inside of this virtual environment. @@ -154,9 +153,9 @@ ansible [core 2.16.3] libyaml = True ``` -### Inventory host files +### Inventory Host Files -As is standard with Ansible best practices, inventory files provide the destination targets for the automation. For this collection, the inventory file is a YAML file that contains the information about the devices that are going to be configured. The inventory files is called `inventory.yml` and is located in the root of the repository. +As is standard with Ansible best practices, inventory files provide the destination targets for the automation. For this collection, the inventory file is a YAML file that contains the information about the devices that are going to be configured. The inventory files is called `inventory.yaml` and is located in the root of the repository. The inventory file is going to contain a structure similar to this: @@ -177,24 +176,24 @@ graph root-->group_vars root-->host_vars group_vars-->ndfc - ndfc-->connection.yml + ndfc-->connection.yaml host_vars-->nac-ndfc1 nac-ndfc1-->data_model_files ``` -The data model is **required** to exist under the `host_vars` directory structure. The inventory file is organizing how the variables are read through both the group_vars and the host_vars. Under the group_vars is where you will set the `connection.yml` file that has the credentials of the NDFC controller. Under the `host_vars` is where we will place the inventory. +The data model is **required** to exist under the `host_vars` directory structure. The inventory file is organizing how the variables are read through both the group_vars and the host_vars. Under the group_vars is where you will set the `connection.yaml` file that has the credentials of the NDFC controller. Under the `host_vars` is where we will place the inventory. The collection is **pre-built** to utilize the `group_vars` and `host_vars` matching what is already constructed in the repository. Currently this methodology is a 1:1 relationship between code repository and NDFC fabric. For more complex environments, the inventory file can be expanded to include multiple groups and hosts including the usage of multi-site fabrics, explained in a separate document. -#### Step 1 - Update the inventory file +#### Step 1 - Update the Inventory File -In the provided `inventory.yml` file on the root directory, update the `ansible_host` variable to point to your NDFC controller by replacing `10.X.X.X` with the IP address of the NDFC controller. +In the provided `inventory.yaml` file on the root directory, update the `ansible_host` variable to point to your NDFC controller by replacing `10.X.X.X` with the IP address of the NDFC controller. -#### Step 2 - Configure ansible connection file +#### Step 2 - Configure Ansible Connection File -In the directory `group_vars/ndfc` is a file called `connection.yml` that contains example data as: +In the directory `group_vars/ndfc` is a file called `connection.yaml` that contains example data as: ```yaml --- @@ -207,11 +206,11 @@ ansible_httpapi_use_ssl: true ansible_httpapi_validate_certs: false ansible_network_os: cisco.dcnm.dcnm # NDFC API Credentials -ansible_user: "{{ lookup('env', 'ansible_user') }}" -ansible_password: "{{ lookup('env', 'ansible_password') }}" +ansible_user: "{{ lookup('env', 'ND_USERNAME') }}" +ansible_password: "{{ lookup('env', 'ND_PASSWORD') }}" # Credentials for devices in Inventory -ndfc_device_username: "{{ lookup('env', 'ndfc_device_username') }}" -ndfc_device_password: "{{ lookup('env', 'ndfc_device_password') }}" +ndfc_switch_username: "{{ lookup('env', 'NDFC_SW_USERNAME') }}" +ndfc_switch_password: "{{ lookup('env', 'NDFC_SW_PASSWORD') }}" ``` @@ -221,7 +220,7 @@ Also, if you plan to eventually utilize a pipeline, the environment variables ca The usage of [Ansible vault](https://docs.ansible.com/ansible/latest/vault_guide/index.html) is also possible to encrypt the contents of the connection file or simply encrypt the variables. -#### Step 3 - Set environment variables +#### Step 3 - Set Environment Variables The environment variables are set in the shell that is going to execute the playbook. The environment variables are configured via the `export` command in the shell (bash). Using this template set the environment variables to the correct credentials for the NDFC controller and the devices in the inventory on your topology. @@ -230,8 +229,8 @@ The environment variables are set in the shell that is going to execute the play export ansible_user=admin export ansible_password=Admin_123 # These are the credentials for the devices in the inventory -export ndfc_device_username=admin -export ndfc_device_password=Admin_123 +export ndfc_switch_username=admin +export ndfc_switch_password=Admin_123 ``` The following quickstart repository is available to provide a step by step guide for using this collection @@ -243,7 +242,7 @@ This collection is intended for use with the following release versions: * `NDFC Release 12.2.1` or later. -## Ansible version compatibility +## Ansible Version Compatibility This collection has been tested against following Ansible versions: **>=2.14.15**. @@ -252,9 +251,9 @@ A collection may contain metadata that identifies these versions. PEP440 is the schema used to describe the versions of Ansible. -## Building the primary playbook +## Building the Primary Playbook -The playbook for the NDFC as Code collection is the execution point of the this automation collection. In difference to other automation with collections, what is in this playbook is mostly static and not going to change. What is executed during automation is based on changes in the data model. Hence as changes happen in the data model, the playbook will call the modules and based on what has changed in the data model, is what is going to execute. +The following playbook for the NDFC as Code collection is the central execution point for this collection. Compared to automation in other collections, this playbook is designed to be mostly static and typically will not change. What gets executed during automation is based entirely on changes in the data model. When changes are made in the data model, the playbook will call the various roles and underlying modules to process the changes and update the NDFC managed fabric. The playbook is located in the root of the repository and is called `vxlan.yaml`. It contains the following: @@ -269,33 +268,57 @@ The playbook is located in the root of the repository and is called `vxlan.yaml` roles: # Prepare service model for all subsequent roles # - # - role: cisco.nac_dc_vxlan.validate + - role: cisco.nac_dc_vxlan.validate + tags: 'role_validate' # ----------------------- # DataCenter Roles # Role: cisco.netascode_dc_vxlan.dtc manages direct to controller NDFC workflows # - role: cisco.nac_dc_vxlan.dtc.create + tags: 'role_create' + - role: cisco.nac_dc_vxlan.dtc.deploy + tags: 'role_deploy' + - role: cisco.nac_dc_vxlan.dtc.remove + tags: 'role_remove' ``` -The `host` is defined as nac-ndfc1 which references back to the inventory file. The `roles` section is where the collection is going to be called. +The `host` is defined as nac-ndfc1 which references back to the `inventory.yaml` file. The `roles` section is where the various collection roles are called. + +The first role is `cisco.nac_dc_vxlan.validate` which is going to validate the data model. This is a required step to ensure that the data model is correct and that the data model is going to be able to be processed by the subsequent roles. + +The subsequent roles are the `cisco.nac_dc_vxlan.dtc.create`, `cisco.nac_dc_vxlan.dtc.deploy`, and `cisco.nac_dc_vxlan.dtc.remove` roles. These roles are the primary roles that will invoke changes in NDFC as described earlier. -The first role is `cisco.nac_dc_vxlan.validate` which is going to validate the data model. This is a required step to ensure that the data model is correct and that the data model is going to be able to be processed by the subsequent roles. **This role is going to execute by default even if not defined as it is required for the subsequent roles to execute.** In this example we are commenting out the role to show that it is not required to be defined in the playbook, but if you want to define a playbook that just runs the validation, you would uncomment this role. -The next roles are the `cisco.nac_dc_vxlan.dtc.create`, `cisco.nac_dc_vxlan.dtc.deploy`, and `cisco.nac_dc_vxlan.dtc.remove`. These roles are the primary roles that will invoke change in NDFC. The `create` role will create all the templates and variable parameters. The `deploy` role will deploy those changes to the NDFC controller. The `remove` role would remove the data model from the devices in the inventory. +> **Note**: For your safety as indicated ealier, the `remove` role also requires setting some variables to `true` under the `group_vars` directory. This is to avoid accidental removal of configuration from NDFC that might impact the network. This will be covered in more detail below. -> **Note**: For your safety, the `remove` role also requires settings some variables to true under the `group_vars` directory. This is done to avoid accidental removal of configuration from NDFC that might impact the network. This will be covered in a section below. +The playbook can be configured to execute only the roles that are required. For example, as you are building your data model and familiarizing yourself with the collection, you may comment out the `deploy` and `remove` roles and only execute the `validate` and `create` roles. This provides a quick way to make sure that the data model is structured correctly. +------ +**Role Level Tags:** -Since each of these roles are separate, you may configure the playbook to only execute the roles that are required. For example, as you are building your data model and getting to know the collection, you may comment out the `deploy` and `remove` roles to only execute the `validate` and `create` role. This provides a quick way to make sure that the data model is structured correctly. +To speed up execution when only certain roles need to be run the following role level tags are provided: + + * role_validate - Select and run `cisco.nac_dc_vxlan.validate` role + * role_create - Select and run `cisco.nac_dc_vxlan.create` role + * role_deploy - Select and run `cisco.nac_dc_vxlan.deploy` role + * role_remove - Select and run `cisco.nac_dc_vxlan.remove` role + +The validate role will automatically run if tags `role_create, role_deploy, role_remove` are specified. + +Example: Selectively Run `cisco.nac_dc_vxlan.create` role alone + +```bash +ansible-playbook -i inventory.yml vxlan.yml --tags role_create +``` ### See Also * [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details. -## Contributing to this collection +## Contributing to this Collection Ongoing development efforts and contributions to this collection are focused on new roles when needed and enhancements to current roles. @@ -305,7 +328,7 @@ We welcome community contributions to this collection. If you find problems, ple * [Changelog](https://github.com/netascode/ansible-dc-vxlan/blob/develop/CHANGELOG.rst) -## More information +## More Information - [NDFC installation and configuration guides](https://www.cisco.com/c/en/us/td/docs/dcn/ndfc/1201/installation/cisco-ndfc-install-and-upgrade-guide-1201.html) - [Ansible User guide](https://docs.ansible.com/ansible/latest/user_guide/index.html) diff --git a/galaxy.yml b/galaxy.yml index a0f1e0f1..4d0d73a6 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: nac_dc_vxlan -version: 0.1.0 +version: 0.2.0 readme: README.md authors: - Devendra Gupta diff --git a/plugins/action/common/get_credentials.py b/plugins/action/common/get_credentials.py index d355404b..041158f5 100644 --- a/plugins/action/common/get_credentials.py +++ b/plugins/action/common/get_credentials.py @@ -34,21 +34,23 @@ class ActionModule(ActionBase): def run(self, tmp=None, task_vars=None): - # self._supports_async = True results = super(ActionModule, self).run(tmp, task_vars) - results['failed'] = False + results['retrieve_failed'] = False - inv_list = self._task.args['inv_list'] - username = task_vars.get('ndfc_device_username') - password = task_vars.get('ndfc_device_password') + key_username = 'ndfc_switch_username' + key_password = 'ndfc_switch_password' + + ndfc_host_name = task_vars['inventory_hostname'] + username = task_vars['hostvars'][ndfc_host_name].get(key_username, '') + password = task_vars['hostvars'][ndfc_host_name].get(key_password, '') # Fail if username and password are not set - if username is None or password is None: - results['failed'] = True - results['msg'] = "ndfc_device_username and ndfc_device_username must be set in group_vars or as environment variables!" - # TODO: Add support for environemnt variables + if username == '' or password == '': + results['retrieve_failed'] = True + results['msg'] = "{0} and {1} must be set in group_vars or as environment variables!".format(key_username, key_password) return results + inv_list = self._task.args['inv_list'] # Create a new list and deep copy each dict item to avoid modifying the original and dict items updated_inv_list = [] for device in inv_list: diff --git a/plugins/action/common/nac_dc_validate.py b/plugins/action/common/nac_dc_validate.py index 1a2cfc8d..62498bb8 100644 --- a/plugins/action/common/nac_dc_validate.py +++ b/plugins/action/common/nac_dc_validate.py @@ -47,9 +47,9 @@ def run(self, tmp=None, task_vars=None): mdata = self._task.args.get('mdata') # Generate a warning if the Schema and Rules are not provided - if schema and not os.path.exists(schema): + if 'schema' in locals() and (schema == "" or not os.path.exists(schema)): display.warning("The schema ({0}) does not appear to exist! ".format(schema)) - if not os.path.exists(rules): + if 'rules' in locals() and (rules == "" or not os.path.exists(rules)): display.warning("The rules directory ({0}) does not appear to exist! ".format(rules)) # The rules directory is considered empty if it is an empty dir or only contains the .gitkeep file if os.path.exists(rules) and (not os.listdir(rules) or (len(os.listdir(rules)) == 1 and '.gitkeep' in os.listdir(rules))): 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 f4384f3d..b462778e 100644 --- a/plugins/action/common/prepare_plugins/prep_103_topology_switches.py +++ b/plugins/action/common/prepare_plugins/prep_103_topology_switches.py @@ -27,10 +27,17 @@ def __init__(self, **kwargs): def prepare(self): model_data = self.kwargs['results']['model_extended'] - + # Loop over all the roles in vxlan.topology.switches.role model_data['vxlan']['topology']['spine'] = {} model_data['vxlan']['topology']['leaf'] = {} model_data['vxlan']['topology']['border'] = {} + model_data['vxlan']['topology']['border_spine'] = {} + model_data['vxlan']['topology']['border_gateway'] = {} + model_data['vxlan']['topology']['border_gateway_spine'] = {} + model_data['vxlan']['topology']['super_spine'] = {} + model_data['vxlan']['topology']['border_super_spine'] = {} + model_data['vxlan']['topology']['border_gateway_super_spine'] = {} + model_data['vxlan']['topology']['tor'] = {} sm_switches = model_data['vxlan']['topology']['switches'] for switch in sm_switches: # Build list of switch IP's based on role keyed by switch name diff --git a/plugins/action/dtc/verify_tags.py b/plugins/action/dtc/verify_tags.py new file mode 100644 index 00000000..543b63ce --- /dev/null +++ b/plugins/action/dtc/verify_tags.py @@ -0,0 +1,52 @@ +# 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): + # self._supports_async = True + results = super(ActionModule, self).run(tmp, task_vars) + results['failed'] = False + + all_tags = self._task.args['all_tags'] + play_tags = self._task.args['play_tags'] + + if 'all' in play_tags: + return results + + for tag in play_tags: + if tag not in all_tags: + results['failed'] = True + results['msg'] = "Tag '{0}' not found in list of supported tags".format(tag) + results['supported_tags'] = all_tags + + return results diff --git a/roles/common_global/tasks/main.yml b/roles/common_global/tasks/main.yml new file mode 100644 index 00000000..f0ed1f7e --- /dev/null +++ b/roles/common_global/tasks/main.yml @@ -0,0 +1,27 @@ +# 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: Verify User Tags + cisco.nac_dc_vxlan.dtc.verify_tags: + all_tags: "{{ nac_tags.all }}" + play_tags: "{{ ansible_run_tags }}" + tags: "{{ ansible_run_tags }}" \ No newline at end of file diff --git a/roles/common_global/vars/main.yml b/roles/common_global/vars/main.yml new file mode 100644 index 00000000..825d9955 --- /dev/null +++ b/roles/common_global/vars/main.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 + +--- + +nac_tags: + # All Create and Remove Tags + all: + - cr_manage_fabric + - cr_manage_switches + - cr_manage_vpc_peers + - cr_manage_interfaces + - cr_manage_vrfs_networks + # ------------------------- + - rr_manage_interfaces + - rr_manage_networks + - rr_manage_vrfs + - rr_manage_vpc_peers + - rr_manage_links + - rr_manage_switches + # ------------------------- + - role_validate + - role_create + - role_deploy + - role_remove + # All Create Tags + create: + - cr_manage_fabric + - cr_manage_switches + - cr_manage_vpc_peers + - cr_manage_interfaces + - cr_manage_vrfs_networks + create_fabric: + - cr_manage_fabric + create_switches: + - cr_manage_switches + create_vpc_peers: + - cr_manage_vpc_peers + create_interfaces: + - cr_manage_interfaces + create_vrfs_networks: + - cr_manage_vrfs_networks + # All Remove Tags + remove: + - rr_manage_interfaces + - rr_manage_networks + - rr_manage_vrfs + - rr_manage_vpc_peers + - rr_manage_links + - rr_manage_switches + remove_interfaces: + - rr_manage_interfaces + remove_networks: + - rr_manage_networks + remove_vrfs: + - rr_manage_vrfs + remove_vpc_peers: + - rr_manage_vpc_peers + remove_links: + - rr_manage_links + remove_switches: + - rr_manage_switches + + \ No newline at end of file diff --git a/roles/dtc/common/meta/main.yml b/roles/dtc/common/meta/main.yml index b2d888f8..a307327f 100644 --- a/roles/dtc/common/meta/main.yml +++ b/roles/dtc/common/meta/main.yml @@ -23,4 +23,6 @@ galaxy_info: author: Cisco description: Common infrastructure role dependency used by other roles in this collection license: LICENSE - min_ansible_version: 2.14.15 \ No newline at end of file + min_ansible_version: 2.14.15 + +dependencies: [cisco.nac_dc_vxlan.common_global] diff --git a/roles/dtc/common/tasks/main.yml b/roles/dtc/common/tasks/main.yml index 03c08e8d..23badea6 100644 --- a/roles/dtc/common/tasks/main.yml +++ b/roles/dtc/common/tasks/main.yml @@ -21,135 +21,6 @@ --- -- ansible.builtin.fail: msg="Service Model Not Defined. Role cisco.nac_dc_vxlan.validate Must Be Called First" - when: MD is undefined -# -------------------------------------------------------------------- -# Remove all files from the previous run -# -------------------------------------------------------------------- -- name: Delete content & directory - ansible.builtin.file: - state: absent - path: "{{ role_path }}/files/" - -- name: Recreate the directory - ansible.builtin.file: - path: "{{ role_path }}/files/" - state: directory - mode: '0755' - -- name: Add gitkeep file back to the directory - ansible.builtin.file: - path: "{{ role_path }}/files/.gitkeep" - state: touch - -# -------------------------------------------------------------------- -# Build Create Fabric parameter List From Template -# -------------------------------------------------------------------- - -- name: Build Fabric Create Parameters - ansible.builtin.include_tasks: 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 - -# -------------------------------------------------------------------- -# 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 - -# -------------------------------------------------------------------- -# Build VPC Peering parameter List From Template -# -------------------------------------------------------------------- - -- name: Build VPC Peering Parameters - ansible.builtin.include_tasks: 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 - -# -------------------------------------------------------------------- -# Build NDFC Fabric Networks Attach List From Template -# -------------------------------------------------------------------- - -- name: Build NDFC Fabric Networks Attach List From Template - ansible.builtin.include_tasks: 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 - -# -------------------------------------------------------------------- -# 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 - -# -------------------------------------------------------------------- -# 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 - -# -------------------------------------------------------------------- -# 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 - -# -------------------------------------------------------------------- -# 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 - -# -------------------------------------------------------------------- -# 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 - -# -------------------------------------------------------------------- -# Build Trunk Interfaces List From Template -# -------------------------------------------------------------------- - -- name: Build Trunk Interfaces List From Template - ansible.builtin.include_tasks: 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 - -# -------------------------------------------------------------------- -# Build Fabric interface VPC List From Template -# -------------------------------------------------------------------- - -- name: Build Fabric interface VPC List From Template - ansible.builtin.include_tasks: 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 +- name: Import Role Tasks + ansible.builtin.import_tasks: sub_main.yml + tags: "{{ nac_tags.all }}" # Tags defined in roles/common_global/vars/main.yml diff --git a/roles/dtc/common/tasks/ndfc_fabric.yml b/roles/dtc/common/tasks/ndfc_fabric.yml index 161a022d..da16b8e1 100644 --- a/roles/dtc/common/tasks/ndfc_fabric.yml +++ b/roles/dtc/common/tasks/ndfc_fabric.yml @@ -23,12 +23,15 @@ - ansible.builtin.set_fact: fabric_file_name: "{{ MD.vxlan.global.name }}_ndfc_create_fabric.yml" + delegate_to: localhost - name: Build Fabric Creation Parameters From Template ansible.builtin.template: src: ndfc_create_fabric.j2 dest: "{{ role_path }}/files/{{ fabric_file_name }}" + delegate_to: localhost - ansible.builtin.set_fact: fabric_config: "{{ lookup('file', fabric_file_name) | from_yaml }}" when: MD.vxlan.global + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_interface_access.yml b/roles/dtc/common/tasks/ndfc_interface_access.yml index 546ded88..178f7bbd 100644 --- a/roles/dtc/common/tasks/ndfc_interface_access.yml +++ b/roles/dtc/common/tasks/ndfc_interface_access.yml @@ -24,17 +24,21 @@ - name: Set interface_access_file_name Var ansible.builtin.set_fact: interface_access_file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_access.yml" + delegate_to: localhost - name: Build Interface ansible.builtin.template: src: ndfc_interface_access.j2 dest: "{{ role_path }}/files/{{ interface_access_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', interface_access_file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_interface_access_po.yml b/roles/dtc/common/tasks/ndfc_interface_access_po.yml index 1221b406..3755a4b8 100644 --- a/roles/dtc/common/tasks/ndfc_interface_access_po.yml +++ b/roles/dtc/common/tasks/ndfc_interface_access_po.yml @@ -24,17 +24,21 @@ - name: Set interface_access_po_file_name Var ansible.builtin.set_fact: interface_access_po_file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_access_po.yml" + delegate_to: localhost - name: Build Interface ansible.builtin.template: src: ndfc_interface_access_po.j2 dest: "{{ role_path }}/files/{{ interface_access_po_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', interface_access_po_file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_interface_all.yml b/roles/dtc/common/tasks/ndfc_interface_all.yml index 9387e1c3..8b98ce21 100644 --- a/roles/dtc/common/tasks/ndfc_interface_all.yml +++ b/roles/dtc/common/tasks/ndfc_interface_all.yml @@ -24,17 +24,21 @@ - name: Set interface_all_file_name Var ansible.builtin.set_fact: ndfc_interface_all_file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_all.yml" + delegate_to: localhost - 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 + 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/{{ ndfc_interface_all_file_name }}" + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_interface_loopback.yml b/roles/dtc/common/tasks/ndfc_interface_loopback.yml index 7b4606bf..8135d772 100644 --- a/roles/dtc/common/tasks/ndfc_interface_loopback.yml +++ b/roles/dtc/common/tasks/ndfc_interface_loopback.yml @@ -24,17 +24,21 @@ - name: Set int_loopback_file_name Var ansible.builtin.set_fact: int_loopback_file_name: "{{ MD.vxlan.global.name }}_ndfc_loopback_interfaces.yml" + delegate_to: localhost - name: Build Loopback Interfaces List From Template ansible.builtin.template: src: ndfc_loopback_interfaces.j2 dest: "{{ role_path }}/files/{{ int_loopback_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', int_loopback_file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_interface_po_routed.yml b/roles/dtc/common/tasks/ndfc_interface_po_routed.yml index 7d011809..329dc177 100644 --- a/roles/dtc/common/tasks/ndfc_interface_po_routed.yml +++ b/roles/dtc/common/tasks/ndfc_interface_po_routed.yml @@ -24,17 +24,21 @@ - name: Set interface_po_routed_file_name Var ansible.builtin.set_fact: interface_po_routed_file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_po_routed.yml" + delegate_to: localhost - name: Build Interface Po ansible.builtin.template: src: ndfc_interface_po_routed.j2 dest: "{{ role_path }}/files/{{ interface_po_routed_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', interface_po_routed_file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_interface_routed.yml b/roles/dtc/common/tasks/ndfc_interface_routed.yml index e3bde81e..987c2604 100644 --- a/roles/dtc/common/tasks/ndfc_interface_routed.yml +++ b/roles/dtc/common/tasks/ndfc_interface_routed.yml @@ -24,17 +24,21 @@ - name: Set interface_routed_file_name Var ansible.builtin.set_fact: interface_routed_file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_routed.yml" + delegate_to: localhost - name: Build Interface ansible.builtin.template: src: ndfc_interface_routed.j2 dest: "{{ role_path }}/files/{{ interface_routed_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', interface_routed_file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_interface_trunk.yml b/roles/dtc/common/tasks/ndfc_interface_trunk.yml index e766e8dd..da9aaa8f 100644 --- a/roles/dtc/common/tasks/ndfc_interface_trunk.yml +++ b/roles/dtc/common/tasks/ndfc_interface_trunk.yml @@ -24,17 +24,21 @@ - name: Set interface_trunk_file_name Var ansible.builtin.set_fact: interface_trunk_file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_trunk.yml" + delegate_to: localhost - name: Build Interface ansible.builtin.template: src: ndfc_interface_trunk.j2 dest: "{{ role_path }}/files/{{ interface_trunk_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', interface_trunk_file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_interface_trunk_po.yml b/roles/dtc/common/tasks/ndfc_interface_trunk_po.yml index 94d697bb..97d7b958 100644 --- a/roles/dtc/common/tasks/ndfc_interface_trunk_po.yml +++ b/roles/dtc/common/tasks/ndfc_interface_trunk_po.yml @@ -24,17 +24,21 @@ - name: Set interface_trunk_po_file_name Var ansible.builtin.set_fact: interface_trunk_po_file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_trunk_po.yml" + delegate_to: localhost - name: Build Interface ansible.builtin.template: src: ndfc_interface_trunk_po.j2 dest: "{{ role_path }}/files/{{ interface_trunk_po_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', interface_trunk_po_file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_interface_vpc.yml b/roles/dtc/common/tasks/ndfc_interface_vpc.yml index 810897dd..a97b96a4 100644 --- a/roles/dtc/common/tasks/ndfc_interface_vpc.yml +++ b/roles/dtc/common/tasks/ndfc_interface_vpc.yml @@ -24,17 +24,21 @@ - name: Set interface_vpc_file_name Var ansible.builtin.set_fact: interface_vpc_file_name: "{{ MD.vxlan.global.name }}_ndfc_interface_vpc.yml" + delegate_to: localhost - name: Build VPC interface ansible.builtin.template: src: ndfc_interface_vpc.j2 dest: "{{ role_path }}/files/{{ interface_vpc_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', interface_vpc_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 + 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 diff --git a/roles/dtc/common/tasks/ndfc_inventory.yml b/roles/dtc/common/tasks/ndfc_inventory.yml index 45b178a1..5d15a9ff 100644 --- a/roles/dtc/common/tasks/ndfc_inventory.yml +++ b/roles/dtc/common/tasks/ndfc_inventory.yml @@ -24,27 +24,38 @@ - name: Set inv_file_name Var ansible.builtin.set_fact: inv_file_name: "{{ MD.vxlan.global.name }}_ndfc_inventory.yml" + delegate_to: localhost - name: Set Path For Inventory File Lookup ansible.builtin.set_fact: inv_file_path: "{{ role_path }}/files/{{ inv_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', inv_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 diff --git a/roles/dtc/common/tasks/ndfc_link_vpc_peering.yml b/roles/dtc/common/tasks/ndfc_link_vpc_peering.yml index f3cc837d..86dccd0a 100644 --- a/roles/dtc/common/tasks/ndfc_link_vpc_peering.yml +++ b/roles/dtc/common/tasks/ndfc_link_vpc_peering.yml @@ -24,17 +24,21 @@ - name: Set link_vpc_peering_file_name Var ansible.builtin.set_fact: link_vpc_peering_file_name: "{{ MD.vxlan.global.name }}_ndfc_link_vpc_peering_.yml" + delegate_to: localhost - name: Build Links for VPC Peering ansible.builtin.template: src: ndfc_links_vpc_peering.j2 dest: "{{ role_path }}/files/{{ link_vpc_peering_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', link_vpc_peering_file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.vpc_peers | length > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_networks.yml b/roles/dtc/common/tasks/ndfc_networks.yml index b73ee818..54aaf68d 100644 --- a/roles/dtc/common/tasks/ndfc_networks.yml +++ b/roles/dtc/common/tasks/ndfc_networks.yml @@ -24,17 +24,21 @@ - name: Set net_file_name Var ansible.builtin.set_fact: net_file_name: "{{ MD.vxlan.global.name }}_ndfc_attach_networks.yml" + delegate_to: localhost - name: Build Networks Attach List From Template ansible.builtin.template: src: ndfc_attach_networks.j2 dest: "{{ role_path }}/files/{{ net_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', net_file_name) | from_yaml }}" when: (MD_Extended.vxlan.overlay_services.networks | default([])) | length > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_sub_interface_routed.yml b/roles/dtc/common/tasks/ndfc_sub_interface_routed.yml index b1a8ad0c..56b18a07 100644 --- a/roles/dtc/common/tasks/ndfc_sub_interface_routed.yml +++ b/roles/dtc/common/tasks/ndfc_sub_interface_routed.yml @@ -24,17 +24,21 @@ - name: Set sub_interface_routed_file_name Var ansible.builtin.set_fact: sub_interface_routed_file_name: "{{ MD.vxlan.global.name }}_ndfc_sub_interface_routed.yml" + delegate_to: localhost - name: Build sub_interface ansible.builtin.template: src: ndfc_sub_interface_routed.j2 dest: "{{ role_path }}/files/{{ sub_interface_routed_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', sub_interface_routed_file_name) | from_yaml }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_vpc_peering.yml b/roles/dtc/common/tasks/ndfc_vpc_peering.yml index 5801edb1..3de86670 100644 --- a/roles/dtc/common/tasks/ndfc_vpc_peering.yml +++ b/roles/dtc/common/tasks/ndfc_vpc_peering.yml @@ -24,17 +24,21 @@ - name: Set vpc_peering_file_name Var ansible.builtin.set_fact: vpc_peering_file_name: "{{ MD.vxlan.global.name }}_ndfc_vpc_peering.yml" + delegate_to: localhost - name: Build vPC Peering ansible.builtin.template: src: ndfc_vpc_peering.j2 dest: "{{ role_path }}/files/{{ vpc_peering_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', vpc_peering_file_name) | from_yaml }}" when: MD_Extended.vxlan.topology.vpc_peers | length > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/ndfc_vrfs.yml b/roles/dtc/common/tasks/ndfc_vrfs.yml index ddbc0bee..a1de55c9 100644 --- a/roles/dtc/common/tasks/ndfc_vrfs.yml +++ b/roles/dtc/common/tasks/ndfc_vrfs.yml @@ -24,17 +24,21 @@ - name: Set vrf_file_name Var ansible.builtin.set_fact: vrf_file_name: "{{ MD.vxlan.global.name }}_attach_vrfs.yml" + delegate_to: localhost - name: Build VRFs Attach List From Template ansible.builtin.template: src: ndfc_attach_vrfs.j2 dest: "{{ role_path }}/files/{{ vrf_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', vrf_file_name) | from_yaml }}" when: (MD_Extended.vxlan.overlay_services.vrfs | default([])) | length > 0 + delegate_to: localhost diff --git a/roles/dtc/common/tasks/sub_main.yml b/roles/dtc/common/tasks/sub_main.yml new file mode 100644 index 00000000..0e7bd601 --- /dev/null +++ b/roles/dtc/common/tasks/sub_main.yml @@ -0,0 +1,160 @@ +# 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 +# -------------------------------------------------------------------- +- name: Delete content & directory + ansible.builtin.file: + state: absent + path: "{{ role_path }}/files/" + delegate_to: localhost + +- name: Recreate the directory + ansible.builtin.file: + path: "{{ role_path }}/files/" + 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 + +# -------------------------------------------------------------------- +# Build Create Fabric parameter List From Template +# -------------------------------------------------------------------- + +- name: Build Fabric Create Parameters + ansible.builtin.include_tasks: 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 + +# -------------------------------------------------------------------- +# 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 + +# -------------------------------------------------------------------- +# Build vPC Peering parameter List From Template +# -------------------------------------------------------------------- + +- name: Build vPC Peering Parameters + ansible.builtin.include_tasks: 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 + +# -------------------------------------------------------------------- +# Build NDFC Fabric Networks Attach List From Template +# -------------------------------------------------------------------- + +- name: Build NDFC Fabric Networks Attach List From Template + ansible.builtin.include_tasks: 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 + +# -------------------------------------------------------------------- +# 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 + +# -------------------------------------------------------------------- +# 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 + +# -------------------------------------------------------------------- +# 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 + +# -------------------------------------------------------------------- +# 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 + +# -------------------------------------------------------------------- +# 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 + +# -------------------------------------------------------------------- +# Build Trunk Interfaces List From Template +# -------------------------------------------------------------------- + +- name: Build Trunk Interfaces List From Template + ansible.builtin.include_tasks: 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 + +# -------------------------------------------------------------------- +# Build Fabric interface VPC List From Template +# -------------------------------------------------------------------- + +- name: Build Fabric interface VPC List From Template + ansible.builtin.include_tasks: 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 \ No newline at end of file diff --git a/roles/dtc/common/templates/ndfc_attach_networks.j2 b/roles/dtc/common/templates/ndfc_attach_networks.j2 index 3cb9ca95..c0d1ea08 100644 --- a/roles/dtc/common/templates/ndfc_attach_networks.j2 +++ b/roles/dtc/common/templates/ndfc_attach_networks.j2 @@ -7,14 +7,50 @@ {# ------------------------------------------------------ #} {# Properties Section #} {# ------------------------------------------------------ #} - vrf_name: {{ net['vrf_name'] | default(omit) }} is_l2only: {{ net['is_l2_only'] | default(defaults.vxlan.overlay_services.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) }} - gw_ipv6_subnet: {{ net['gw_ipv6_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_services.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_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) }} diff --git a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 index 86a31805..ffad954e 100644 --- a/roles/dtc/common/templates/ndfc_attach_vrfs.j2 +++ b/roles/dtc/common/templates/ndfc_attach_vrfs.j2 @@ -10,7 +10,8 @@ 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_description) }} + 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) }} diff --git a/roles/dtc/common/templates/ndfc_create_fabric.j2 b/roles/dtc/common/templates/ndfc_create_fabric.j2 index bf6ceef3..c5906cea 100644 --- a/roles/dtc/common/templates/ndfc_create_fabric.j2 +++ b/roles/dtc/common/templates/ndfc_create_fabric.j2 @@ -26,37 +26,64 @@ 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) }} -{% if global.dns_servers is defined %} +{# ------------------------------------------------------ #} +{# 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 is defined %} -{% set dns_ips = dns.ip_address|string %} -{% set dns_server_ips = dns_server_ips.append(dns_ips) %} +{% 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 is defined %} -{% set dns_vrfs = dns.vrf|string %} -{% set dns_server_vrfs = dns_server_vrfs.append(dns_vrfs) %} +{% 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(',') }} - DNS_SERVER_VRF: {{ dns_server_vrfs|join(',') }} + 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 %} +{% 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 %} -{% set ntp_ips = ntp.ip_address|string %} -{% set ntp_server_ips = ntp_server_ips.append(ntp_ips) %} +{% 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 %} -{% set ntp_vrfs = ntp.vrf|string %} -{% set ntp_server_vrfs = ntp_server_vrfs.append(ntp_vrfs) %} +{% 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(',') }} - NTP_SERVER_VRF: {{ ntp_server_vrfs|join(',') }} + 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 %} {# ------------------------------------------------------ #} {# VPC Parameters #} diff --git a/roles/dtc/create/README.md b/roles/dtc/create/README.md index 777edd0f..a6d2ed13 100644 --- a/roles/dtc/create/README.md +++ b/roles/dtc/create/README.md @@ -27,6 +27,22 @@ Example Playbook - role: cisco.nac_dc_vxlan.dtc.create ``` +------- +The following tags can be used to selectively execute stages within the `cisco.nac_dc_vxlan.create` role + +`cr` stands for `create_role` + +* cr_manage_fabric +* cr_manage_switches +* cr_manage_vpc_peers +* cr_manage_interfaces +* cr_manage_vrfs_networks + +```bash +# Selectively run stage to add VRFs and Networks and skip all other stages +ansible-playbook -i inventory.yml vxlan.yml --tags cr_manage_vrfs_networks +``` + License ------- diff --git a/roles/dtc/create/meta/main.yml b/roles/dtc/create/meta/main.yml index ea454907..7afbb83d 100644 --- a/roles/dtc/create/meta/main.yml +++ b/roles/dtc/create/meta/main.yml @@ -25,4 +25,7 @@ galaxy_info: license: LICENSE min_ansible_version: 2.14.15 -dependencies: [cisco.nac_dc_vxlan.dtc.common] \ No newline at end of file +dependencies: + - cisco.nac_dc_vxlan.validate + - cisco.nac_dc_vxlan.common_global + - cisco.nac_dc_vxlan.dtc.common diff --git a/roles/dtc/create/tasks/build_hostname_policy_payload.yml b/roles/dtc/create/tasks/build_hostname_policy_payload.yml index dd9b677f..a0a83475 100644 --- a/roles/dtc/create/tasks/build_hostname_policy_payload.yml +++ b/roles/dtc/create/tasks/build_hostname_policy_payload.yml @@ -24,29 +24,36 @@ - name: Build Policy ID Query using Switch Serial Number ansible.builtin.set_fact: query: "response.DATA[?(@.templateName==`host_11_1` && @.serialNumber=='{{ item }}')]" + delegate_to: localhost - name: Get Hostname Policy for {{ item }} from NDFC Response ansible.builtin.set_fact: policy: "{{ result | community.general.json_query(query) }}" + delegate_to: localhost - name: Get Current Hostname from Policy for {{ item }} from NDFC Response ansible.builtin.set_fact: ndfc_switch_hostname: "{{ policy[0].switchName }}" + delegate_to: localhost - name: Build Hostname Query using Switch Serial Number ansible.builtin.set_fact: query: "[?(@.serial_number=='{{ item }}')].name" + delegate_to: localhost - name: Get Hostname for {{ item }} from Data Model ansible.builtin.set_fact: md_switch_hostname: "{{ MD.vxlan.topology.switches | community.general.json_query(query) }}" + delegate_to: localhost - name: Update Hostname Policy for {{ item }} from NDFC Response ansible.builtin.set_fact: policy: "{{ policy[0] | combine({'nvPairs': {'SWITCH_NAME': md_switch_hostname[0]}}, recursive=True) }}" when: ndfc_switch_hostname != md_switch_hostname[0] + delegate_to: localhost - name: Update Hostname Policy Payload List ansible.builtin.set_fact: policy_payload: "{{ policy_payload + [policy] }}" when: ndfc_switch_hostname != md_switch_hostname[0] + delegate_to: localhost diff --git a/roles/dtc/create/tasks/devices_discovery.yml b/roles/dtc/create/tasks/devices_discovery.yml index 929a6aee..aaa19e14 100644 --- a/roles/dtc/create/tasks/devices_discovery.yml +++ b/roles/dtc/create/tasks/devices_discovery.yml @@ -36,10 +36,12 @@ - name: Create List of Switch Serial Numbers from Data Model ansible.builtin.set_fact: md_serial_numbers_list: "{{ MD_Extended.vxlan.topology.switches | map(attribute='serial_number') | list }}" + delegate_to: localhost - name: Concatenate Switch Serial Numbers ansible.builtin.set_fact: md_serial_numbers: "{{ md_serial_numbers_list | join('%2C') }}" + delegate_to: localhost - name: Get NDFC Fabric Default Switch Policies cisco.dcnm.dcnm_rest: @@ -50,6 +52,7 @@ - name: Default Policy Payload Variable ansible.builtin.set_fact: policy_payload: [] + delegate_to: localhost - name: Build Payload for NDFC Switch Hostname Policy Update ansible.builtin.include_tasks: build_hostname_policy_payload.yml @@ -58,11 +61,13 @@ - name: Build Policy ID Query from NDFC Response ansible.builtin.set_fact: query: "response.DATA[?(@.templateName==`host_11_1`)].policyId" + delegate_to: localhost - name: Create List of Switch Hostname Policy IDs from NDFC ansible.builtin.set_fact: policy_ids: "{{ policy_payload | map(attribute='policyId') | list | join('%2C') }}" when: policy_payload | length > 0 + delegate_to: localhost - name: Update Switch Hostname Policy in NDFC cisco.dcnm.dcnm_rest: diff --git a/roles/dtc/create/tasks/interfaces.yml b/roles/dtc/create/tasks/interfaces.yml index abfbe548..af086ecf 100644 --- a/roles/dtc/create/tasks/interfaces.yml +++ b/roles/dtc/create/tasks/interfaces.yml @@ -37,7 +37,7 @@ fabric: "{{ MD.vxlan.global.name }}" state: replaced config: "{{ interface_access_po }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.access_po.count > 0 # -------------------------------------------------------------------- # Manage Interface Trunk Portchannel Configuration on NDFC @@ -48,7 +48,7 @@ fabric: "{{ MD.vxlan.global.name }}" state: replaced config: "{{ interface_trunk_po }}" - when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.trunk_po.count > 0 # -------------------------------------------------------------------- # Manage Interface Routed Configuration on NDFC @@ -59,7 +59,7 @@ fabric: "{{ MD.vxlan.global.name }}" state: replaced config: "{{ interface_routed }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.routed.count > 0 # -------------------------------------------------------------------- # Manage Sub-interface Routed Configuration on NDFC @@ -70,8 +70,7 @@ fabric: "{{ MD.vxlan.global.name }}" state: replaced config: "{{ sub_interface_routed }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count >0 - + when: MD_Extended.vxlan.topology.interfaces.modes.routed_sub.count > 0 # -------------------------------------------------------------------- # Manage interface Port-Channel Routed Configuration on NDFC @@ -82,7 +81,7 @@ fabric: "{{ MD.vxlan.global.name }}" state: replaced config: "{{ interface_po_routed }}" - when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.routed_po.count > 0 # -------------------------------------------------------------------- # Manage interface Loopback Configuration on NDFC @@ -93,7 +92,7 @@ fabric: "{{ MD.vxlan.global.name }}" state: replaced config: "{{ int_loopback_config }}" - when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.loopback.count > 0 # -------------------------------------------------------------------- # Manage Interface Trunk Configuration on NDFC @@ -104,8 +103,7 @@ fabric: "{{ MD.vxlan.global.name }}" state: replaced config: "{{ interface_trunk }}" - when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count >0 - + when: MD_Extended.vxlan.topology.interfaces.modes.trunk.count > 0 # -------------------------------------------------------------------- # Manage Interface Access Routed Configuration on NDFC @@ -116,18 +114,18 @@ fabric: "{{ MD.vxlan.global.name }}" state: replaced config: "{{ interface_access }}" - when: MD_Extended.vxlan.topology.interfaces.modes.access.count >0 + when: MD_Extended.vxlan.topology.interfaces.modes.access.count > 0 # -------------------------------------------------------------------- -# Manage interface VPC Configuration on NDFC +# Manage interface vPC Configuration on NDFC # -------------------------------------------------------------------- -- name: Manage NDFC Fabric VPCs +- name: Manage NDFC Fabric vPCs cisco.dcnm.dcnm_interface: fabric: "{{ MD.vxlan.global.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 + 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 # # -------------------------------------------------------------------- @@ -142,4 +140,5 @@ # vars: # ansible_command_timeout: 3000 # ansible_connect_timeout: 3000 -# when: MD_Extended.vxlan.topology.interfaces.modes.all.count >0 +# when: MD_Extended.vxlan.topology.interfaces.modes.all.count > 0 +# delegate_to: localhost diff --git a/roles/dtc/create/tasks/main.yml b/roles/dtc/create/tasks/main.yml index b5bd4d96..2d1c3fe1 100644 --- a/roles/dtc/create/tasks/main.yml +++ b/roles/dtc/create/tasks/main.yml @@ -21,48 +21,5 @@ --- -- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.create] - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Calling Role - [cisco.nac_dc_vxlan.dtc.create] +" - - "----------------------------------------------------------------" - -- ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" - -- name: Create NDFC Fabric - ansible.builtin.include_tasks: fabric.yml - when: MD_Extended.vxlan.global is defined - -- name: Manage NDFC Fabric Switches - ansible.builtin.include_tasks: devices.yml - when: MD_Extended.vxlan.topology.switches | length > 0 - -- name: Manage VPC Peering - ansible.builtin.include_tasks: vpc_peering.yml - when: MD_Extended.vxlan.topology.vpc_peers | length > 0 - -- name: Manage NDFC Fabric Interfaces - ansible.builtin.include_tasks: interfaces.yml - when: (MD_Extended.vxlan.topology.interfaces.modes.all.count >0) and (MD_Extended.vxlan.topology.switches | length > 0) - - -- name: Manage NDFC Fabric VRFs and Networks - ansible.builtin.include_tasks: vrfs_networks.yml - when: (MD.vxlan.overlay_services is defined) and (MD_Extended.vxlan.topology.switches | length > 0) - -# - name: Manage NDFC VRF-Lite Extensions -# ansible.builtin.include_tasks: vrflite.yml -# when: MD.vxlan is defined - -# - name: Manage NDFC Templates -# ansible.builtin.include_tasks: templates.yml -# when: MD.vxlan is defined - -# - name: Manage NDFC Policies -# ansible.builtin.include_tasks: policies.yml -# when: MD.vxlan is defined - -# Other areas to enable -# 1. Diff between git source data model files and only call stage that is needed. -# 2. Build data model from NDFC queries (brown field) DTC feature only +- name: Import Role Tasks + ansible.builtin.import_tasks: sub_main.yml diff --git a/roles/dtc/create/tasks/sub_main.yml b/roles/dtc/create/tasks/sub_main.yml new file mode 100644 index 00000000..12a7b83d --- /dev/null +++ b/roles/dtc/create/tasks/sub_main.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: 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 Fabric + ansible.builtin.import_tasks: fabric.yml + when: MD_Extended.vxlan.global is defined + tags: "{{ nac_tags.create_fabric }}" + +- name: Manage NDFC Fabric Switches + ansible.builtin.import_tasks: devices.yml + when: MD_Extended.vxlan.topology.switches | length > 0 + tags: "{{ nac_tags.create_switches }}" + +- name: Manage VPC Peering + ansible.builtin.import_tasks: vpc_peering.yml + when: MD_Extended.vxlan.topology.vpc_peers | length > 0 + tags: "{{ nac_tags.create_vpc_peers }}" + +- name: Manage NDFC Fabric Interfaces + ansible.builtin.import_tasks: interfaces.yml + when: (MD_Extended.vxlan.topology.interfaces.modes.all.count >0) and (MD_Extended.vxlan.topology.switches | length > 0) + tags: "{{ nac_tags.create_interfaces }}" + +- name: Manage NDFC Fabric VRFs and Networks + ansible.builtin.import_tasks: vrfs_networks.yml + when: (MD.vxlan.overlay_services is defined) and (MD_Extended.vxlan.topology.switches | length > 0) + tags: "{{ nac_tags.create_vrfs_networks }}" diff --git a/roles/dtc/create/tasks/vpc_peering.yml b/roles/dtc/create/tasks/vpc_peering.yml index 8610fcce..a5ab3a56 100644 --- a/roles/dtc/create/tasks/vpc_peering.yml +++ b/roles/dtc/create/tasks/vpc_peering.yml @@ -21,6 +21,13 @@ --- +- name: Manage Fabric vPC Peers Entry Point + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Manage Fabric vPC Peers {{ MD.vxlan.global.name }}" + - "----------------------------------------------------------------" + # -------------------------------------------------------------------- # Manage Intra Fabric Links Configuration on NDFC (prepare links for vpc peering) # -------------------------------------------------------------------- diff --git a/roles/dtc/deploy/meta/main.yml b/roles/dtc/deploy/meta/main.yml index 71a8e433..a8d23bea 100644 --- a/roles/dtc/deploy/meta/main.yml +++ b/roles/dtc/deploy/meta/main.yml @@ -25,4 +25,7 @@ galaxy_info: license: LICENSE min_ansible_version: 2.14.15 -dependencies: [cisco.nac_dc_vxlan.dtc.common] +dependencies: + - cisco.nac_dc_vxlan.validate + - cisco.nac_dc_vxlan.common_global + - cisco.nac_dc_vxlan.dtc.common diff --git a/roles/dtc/deploy/tasks/main.yml b/roles/dtc/deploy/tasks/main.yml index e4199984..93eafc06 100644 --- a/roles/dtc/deploy/tasks/main.yml +++ b/roles/dtc/deploy/tasks/main.yml @@ -21,28 +21,6 @@ --- -- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.deploy] - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Calling Role - [cisco.nac_dc_vxlan.dtc.deploy] +" - - "----------------------------------------------------------------" - -- ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" - -- name: Config-Save for Fabric {{ MD.vxlan.global.name }} - cisco.dcnm.dcnm_rest: - method: POST - path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD.vxlan.global.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 }} - cisco.dcnm.dcnm_rest: - path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD.vxlan.global.name }}/config-deploy?forceShowRun=false" - method: POST - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - when: MD_Extended.vxlan.topology.switches | length > 0 - # TODO: Need to add logic to only deploy if changes are made +- name: Import Role Tasks + ansible.builtin.import_tasks: sub_main.yml + tags: "{{ nac_tags.create }}" # Tags defined in roles/common_global/vars/main.yml \ No newline at end of file diff --git a/roles/dtc/deploy/tasks/sub_main.yml b/roles/dtc/deploy/tasks/sub_main.yml new file mode 100644 index 00000000..c45587cd --- /dev/null +++ b/roles/dtc/deploy/tasks/sub_main.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.deploy] + ansible.builtin.debug: + msg: + - "----------------------------------------------------------------" + - "+ Calling Role - [cisco.nac_dc_vxlan.dtc.deploy] +" + - "----------------------------------------------------------------" + +- ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" + +- name: Config-Save for Fabric {{ MD.vxlan.global.name }} + cisco.dcnm.dcnm_rest: + method: POST + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD.vxlan.global.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 }} + cisco.dcnm.dcnm_rest: + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD.vxlan.global.name }}/config-deploy?forceShowRun=false" + method: POST + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: MD_Extended.vxlan.topology.switches | length > 0 + # TODO: Need to add logic to only deploy if changes are made \ No newline at end of file diff --git a/roles/dtc/remove/README.md b/roles/dtc/remove/README.md index ce17a17c..5cde68b7 100644 --- a/roles/dtc/remove/README.md +++ b/roles/dtc/remove/README.md @@ -27,6 +27,23 @@ Example Playbook - role: cisco.nac_dc_vxlan.dtc.remove ``` +------- +The following tags can be used to selectively execute stages within the `cisco.nac_dc_vxlan.create` role + +`rr` stands for `remove_role` + +* rr_manage_interfaces +* rr_manage_networks +* rr_manage_vrfs +* rr_manage_vpc_peers +* rr_manage_links +* rr_manage_switches + +```bash +# Selectively run stage to remove networks and vrfs and skip all other stages +ansible-playbook -i inventory.yml vxlan.yml --tags "rr_manage_networks, rr_manage_vrfs" +``` + License ------- diff --git a/roles/dtc/remove/meta/main.yml b/roles/dtc/remove/meta/main.yml index e76725f6..02d7de21 100644 --- a/roles/dtc/remove/meta/main.yml +++ b/roles/dtc/remove/meta/main.yml @@ -25,4 +25,7 @@ galaxy_info: license: LICENSE min_ansible_version: 2.14.15 -dependencies: [cisco.nac_dc_vxlan.dtc.common] +dependencies: + - cisco.nac_dc_vxlan.validate + - cisco.nac_dc_vxlan.common_global + - cisco.nac_dc_vxlan.dtc.common diff --git a/roles/dtc/remove/tasks/interfaces.yml b/roles/dtc/remove/tasks/interfaces.yml new file mode 100644 index 00000000..57f28df1 --- /dev/null +++ b/roles/dtc/remove/tasks/interfaces.yml @@ -0,0 +1,44 @@ +# 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 all 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) + +- cisco.dcnm.dcnm_interface: + fabric: "{{ MD.vxlan.global.name }}" + state: overridden + config: "{{ interface_all }}" + vars: + ansible_command_timeout: 3000 + ansible_connect_timeout: 3000 + when: + - 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/links.yml b/roles/dtc/remove/tasks/links.yml new file mode 100644 index 00000000..39677bac --- /dev/null +++ b/roles/dtc/remove/tasks/links.yml @@ -0,0 +1,38 @@ +# 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 all Unmanaged 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) + +- name: Remove Intra Fabric Links for vpc peering + cisco.dcnm.dcnm_links: + state: replaced + src_fabric: "{{ MD_Extended.vxlan.global.name }}" + config: "{{ 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) diff --git a/roles/dtc/remove/tasks/main.yml b/roles/dtc/remove/tasks/main.yml index 41c91d46..2d1c3fe1 100644 --- a/roles/dtc/remove/tasks/main.yml +++ b/roles/dtc/remove/tasks/main.yml @@ -21,130 +21,5 @@ --- -- name: Role Entry Point - [cisco.nac_dc_vxlan.dtc.remove] - ansible.builtin.debug: - msg: - - "----------------------------------------------------------------" - - "+ Calling Role - [cisco.nac_dc_vxlan.dtc.remove] +" - - "----------------------------------------------------------------" - -- ansible.builtin.debug: msg="Configuring NXOS Devices using NDFC (Direct to Controller)" - -- ansible.builtin.debug: msg="Query NDFC for List of Fabric Switches" - -- cisco.dcnm.dcnm_rest: - method: GET - path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD.vxlan.global.name }}/inventory/switchesByFabric" - register: switch_list - -- ansible.builtin.debug: msg="Removing all Unmanaged Fabric Interfaces. This could take several minutes..." - -- cisco.dcnm.dcnm_interface: - fabric: "{{ MD.vxlan.global.name }}" - state: overridden - config: "{{ interface_all }}" - vars: - ansible_command_timeout: 3000 - ansible_connect_timeout: 3000 - when: - - 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)) - -- ansible.builtin.debug: msg="Removing Unmanaged Fabric Networks. This could take several minutes..." - -- cisco.dcnm.dcnm_network: - fabric: "{{ MD.vxlan.global.name }}" - state: overridden - config: "{{ net_config }}" - 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)) - -- ansible.builtin.debug: msg="Removing Unmanaged Fabric VRFs. This could take several minutes..." - -- cisco.dcnm.dcnm_vrf: - fabric: "{{ MD.vxlan.global.name }}" - state: overridden - config: "{{ vrf_config }}" - 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)) - -- ansible.builtin.debug: msg="Removing all Unmanaged vPC Peering. This could take several minutes..." - -- name: Remove vPC Peering - cisco.dcnm.dcnm_vpc_pair: - src_fabric: "{{ MD.vxlan.global.name }}" - deploy: true - state: overridden - config: "{{ vpc_peering }}" - vars: - ansible_command_timeout: 1000 - ansible_connect_timeout: 1000 - when: - - switch_list.response.DATA | length > 0 - - (vpc_delete_mode is defined) and (vpc_delete_mode is true|bool) - -- ansible.builtin.debug: - msg: - - "-------------------------------------------------------------------------------------------------------" - - "+ SKIPPING Remove Unmanaged vPC Peering task because vpc_peering_delete_mode flag is set to False +" - - "-------------------------------------------------------------------------------------------------------" - when: not ((vpc_peering_delete_mode is defined) and (vpc_peering_delete_mode is true|bool)) - -- ansible.builtin.debug: msg="Removing all Unmanaged links. This could take several minutes..." - -- name: Remove Intra Fabric Links for vpc peering - cisco.dcnm.dcnm_links: - state: replaced - src_fabric: "{{ MD_Extended.vxlan.global.name }}" - config: "{{ 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) - -- ansible.builtin.debug: msg="Removing Unmanaged Fabric Switches. This could take several minutes..." - -- name: Remove NDFC Fabric Devices {{ MD.vxlan.global.name }} - cisco.dcnm.dcnm_inventory: - fabric: "{{ MD.vxlan.global.name }}" - config: "{{ 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)) +- name: Import Role Tasks + ansible.builtin.import_tasks: sub_main.yml diff --git a/roles/dtc/remove/tasks/networks.yml b/roles/dtc/remove/tasks/networks.yml new file mode 100644 index 00000000..3ae54cdd --- /dev/null +++ b/roles/dtc/remove/tasks/networks.yml @@ -0,0 +1,44 @@ +# 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) + +- cisco.dcnm.dcnm_network: + fabric: "{{ MD.vxlan.global.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/sub_main.yml b/roles/dtc/remove/tasks/sub_main.yml new file mode 100644 index 00000000..5cb45a5c --- /dev/null +++ b/roles/dtc/remove/tasks/sub_main.yml @@ -0,0 +1,66 @@ +# 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 }}" + +- ansible.builtin.debug: msg="Query NDFC for List of Fabric Switches" + tags: "{{ nac_tags.remove }}" + +- cisco.dcnm.dcnm_rest: + method: GET + path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ MD.vxlan.global.name }}/inventory/switchesByFabric" + register: switch_list + tags: "{{ nac_tags.remove }}" + +- name: Remove Fabric Interfaces + ansible.builtin.import_tasks: interfaces.yml + tags: "{{ nac_tags.remove_interfaces }}" + +- name: Remove Fabric Networks + ansible.builtin.import_tasks: networks.yml + tags: "{{ nac_tags.remove_networks }}" + +- name: Remove Fabric VRFs + ansible.builtin.import_tasks: vrfs.yml + tags: "{{ nac_tags.remove_vrfs }}" + +- name: Remove Fabric vPC Peering + ansible.builtin.import_tasks: vpc_peers.yml + tags: "{{ nac_tags.remove_vpc_peers }}" + +- name: Remove Fabric Links + ansible.builtin.import_tasks: links.yml + tags: "{{ nac_tags.remove_links }}" + +- name: Remove Fabric Switches + ansible.builtin.import_tasks: switches.yml + tags: "{{ nac_tags.remove_switches }}" \ No newline at end of file diff --git a/roles/dtc/remove/tasks/switches.yml b/roles/dtc/remove/tasks/switches.yml new file mode 100644 index 00000000..d7e70044 --- /dev/null +++ b/roles/dtc/remove/tasks/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 NDFC Fabric Devices {{ MD.vxlan.global.name }} + cisco.dcnm.dcnm_inventory: + fabric: "{{ MD.vxlan.global.name }}" + config: "{{ 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)) \ No newline at end of file diff --git a/roles/dtc/remove/tasks/vpc_peers.yml b/roles/dtc/remove/tasks/vpc_peers.yml new file mode 100644 index 00000000..3d798217 --- /dev/null +++ b/roles/dtc/remove/tasks/vpc_peers.yml @@ -0,0 +1,46 @@ +# 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 all Unmanaged vPC Peering. This could take several minutes..." + when: + - switch_list.response.DATA | length > 0 + - (vpc_delete_mode is defined) and (vpc_delete_mode is true|bool) + +- name: Remove vPC Peering + cisco.dcnm.dcnm_vpc_pair: + src_fabric: "{{ MD.vxlan.global.name }}" + deploy: true + state: overridden + config: "{{ vpc_peering }}" + vars: + ansible_command_timeout: 1000 + ansible_connect_timeout: 1000 + when: + - switch_list.response.DATA | length > 0 + - (vpc_delete_mode is defined) and (vpc_delete_mode is true|bool) + +- ansible.builtin.debug: + msg: + - "-------------------------------------------------------------------------------------------------------" + - "+ SKIPPING Remove Unmanaged vPC Peering task because vpc_peering_delete_mode flag is set to False +" + - "-------------------------------------------------------------------------------------------------------" + when: not ((vpc_peering_delete_mode is defined) and (vpc_peering_delete_mode is true|bool)) diff --git a/roles/dtc/remove/tasks/vrfs.yml b/roles/dtc/remove/tasks/vrfs.yml new file mode 100644 index 00000000..83aa51b3 --- /dev/null +++ b/roles/dtc/remove/tasks/vrfs.yml @@ -0,0 +1,44 @@ +# 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) + +- cisco.dcnm.dcnm_vrf: + fabric: "{{ MD.vxlan.global.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/validate/defaults/main.yml b/roles/validate/defaults/main.yml index b3f4f894..ad97b05d 100644 --- a/roles/validate/defaults/main.yml +++ b/roles/validate/defaults/main.yml @@ -67,7 +67,7 @@ defaults: enable_bpdu_guard: true topology_switch_trunk_po_interface: description: 'NetAsCode Trunk PO Interface' - mtu: jumbo + mtu: jumbo speed: auto enabled: true trunk_allowed_vlans: none @@ -156,6 +156,7 @@ defaults: overlay_services: 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 diff --git a/roles/validate/meta/main.yml b/roles/validate/meta/main.yml index fccaf260..22774274 100644 --- a/roles/validate/meta/main.yml +++ b/roles/validate/meta/main.yml @@ -25,4 +25,4 @@ galaxy_info: license: LICENSE min_ansible_version: 2.14.15 -dependencies: [] +dependencies: [cisco.nac_dc_vxlan.common_global] diff --git a/roles/validate/tasks/main.yml b/roles/validate/tasks/main.yml index 42c4334b..23badea6 100644 --- a/roles/validate/tasks/main.yml +++ b/roles/validate/tasks/main.yml @@ -20,81 +20,7 @@ # 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 - block: - - 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: "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: - schema_path: "{{ role_path }}/files/schema.yaml" - data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - rules_path: "{{ role_path }}/files/rules/required_rules/" - - - name: "Perform Enhanced Syntax and Semantic Model Validation" - cisco.nac_dc_vxlan.common.nac_dc_validate: - schema: "{{ schema_path }}" - mdata: "{{ data_path }}" - rules: "{{ rules_path }}" - vars: - schema_path: "{{ role_path }}/files/schema.yaml" - data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}" - rules_path: "{{ role_path }}/files/rules/enhanced_rules/" - - - 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 - - - name: Store Golden Service Model Data - ansible.builtin.set_fact: - MD: "{{ smd['model_golden'] }}" - - - name: Store Extended Service Model Data - ansible.builtin.set_fact: - MD_Extended: "{{ smd['model_extended'] }}" - - - name: "Check Roles" - cisco.nac_dc_vxlan.common.check_roles: - role_list: "{{ role_names }}" - register: check_roles - - - 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'] - - - name: Stat Host Specific Defaults - ansible.builtin.stat: path="{{ role_path }}/defaults/{{ inventory_hostname }}/defaults.yml" - register: host_defaults - - - name: Include Host Specific Defaults if Available - ansible.builtin.include_vars: - file: "{{ role_path }}/defaults/{{ inventory_hostname }}/defaults.yml" - when: host_defaults.stat.exists \ No newline at end of file +- name: Import Role Tasks + ansible.builtin.import_tasks: sub_main.yml + tags: "{{ nac_tags.all }}" # Tags defined in roles/common_global/vars/main.yml diff --git a/roles/validate/tasks/manage_model_files_current.yml b/roles/validate/tasks/manage_model_files_current.yml index 7fa5d87b..2711fc3c 100644 --- a/roles/validate/tasks/manage_model_files_current.yml +++ b/roles/validate/tasks/manage_model_files_current.yml @@ -27,6 +27,7 @@ content: "{{ MD | to_nice_json }}" dest: "{{ role_path }}/files/{{ MD.vxlan.global.name }}_service_model_golden.json" force: yes + delegate_to: localhost # Copy the extended golden and extended service model data to the host - name: Copy Extended Service Model Data to Host @@ -34,15 +35,18 @@ content: "{{ MD_Extended | to_nice_json }}" dest: "{{ role_path }}/files/{{ MD.vxlan.global.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" register: smd_golden_current + delegate_to: localhost - name: Display Model File Changes ansible.utils.fact_diff: before: "{{ smd_golden_previous }}" after: "{{ smd_golden_current }}" - when: check_roles['save_previous'] \ No newline at end of file + when: check_roles['save_previous'] + delegate_to: localhost diff --git a/roles/validate/tasks/manage_model_files_previous.yml b/roles/validate/tasks/manage_model_files_previous.yml index b1adb638..25fa16da 100644 --- a/roles/validate/tasks/manage_model_files_previous.yml +++ b/roles/validate/tasks/manage_model_files_previous.yml @@ -25,15 +25,18 @@ cisco.nac_dc_vxlan.common.check_roles: role_list: "{{ role_names }}" register: check_roles + delegate_to: localhost # 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" 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" 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 @@ -41,13 +44,16 @@ file: "{{ role_path }}/files/{{ MD.vxlan.global.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" 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" - when: extended_stat.stat.exists and check_roles['save_previous'] \ No newline at end of file + 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 new file mode 100644 index 00000000..f6e837fa --- /dev/null +++ b/roles/validate/tasks/sub_main.yml @@ -0,0 +1,116 @@ +# 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/" + 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 }}" + 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: 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'] + +- name: Stat Host Specific Defaults + ansible.builtin.stat: path="{{ role_path }}/defaults/{{ inventory_hostname }}/defaults.yml" + register: host_defaults + delegate_to: localhost + +- name: Include Host Specific Defaults if Available + ansible.builtin.include_vars: + file: "{{ role_path }}/defaults/{{ inventory_hostname }}/defaults.yml" + when: host_defaults.stat.exists + delegate_to: localhost \ No newline at end of file diff --git a/tests/integration/fabric_vars_example.yml b/tests/integration/fabric_vars_example.yml index 73525f5e..d667a9c2 100644 --- a/tests/integration/fabric_vars_example.yml +++ b/tests/integration/fabric_vars_example.yml @@ -53,3 +53,11 @@ border: hostname: << border_hostname >> serial: << border_serial >> ip: << border_ip >> +border_gateway: + hostname: << border_gateway_hostname >> + serial: << border_gateway_serial >> + ip: << border_gateway_ip >> +border_spine: + hostname: << border_spine_hostname >> + serial: << border_spine_serial >> + ip: << border_spine_ip >> \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_empty_example/global.yaml b/tests/integration/host_vars/examples/fabric_empty_example/global.yaml index 9304c246..b579cbd8 100644 --- a/tests/integration/host_vars/examples/fabric_empty_example/global.yaml +++ b/tests/integration/host_vars/examples/fabric_empty_example/global.yaml @@ -27,22 +27,6 @@ vxlan: route_reflectors: 4 anycast_gateway_mac: 20:20:00:00:00:aa auth_proto: MD5 - dns_servers: - - ip_address: 1.1.1.1 - vrf: test - - ip_address: 5.5.5.1 - vrf: test - - ip_address: 8.8.8.8 - vrf: engineering - ntp_servers: - - ip_address: 15.3.3.3 - vrf: test - - ip_address: 16.3.3.3 - vrf: engineering - - ip_address: 17.3.3.3 - vrf: engineering - - ip_address: 18.3.3.3 - vrf: engineering vpc: peer_link_vlan: 3600 peer_keep_alive: management diff --git a/tests/integration/host_vars/examples/fabric_full_large_example/global.yaml b/tests/integration/host_vars/examples/fabric_full_large_example/global.yaml index 9304c246..d28b1d38 100644 --- a/tests/integration/host_vars/examples/fabric_full_large_example/global.yaml +++ b/tests/integration/host_vars/examples/fabric_full_large_example/global.yaml @@ -43,6 +43,13 @@ vxlan: vrf: engineering - ip_address: 18.3.3.3 vrf: engineering + syslog_servers: + - ip_address: 172.16.255.251 + vrf: management + severity: 3 + - ip_address: 172.16.255.252 + vrf: management + severity: 3 vpc: peer_link_vlan: 3600 peer_keep_alive: management 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 9e5560ae..8308aee5 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 @@ -81,7 +81,7 @@ vxlan: route_target_both: True route_tag: 12345 secondary_ip_addresses: - - ip_address: 10.10.10.1 + - ip_address: 10.10.10.1/24 route_tag: 12345 trm_enable: False vlan_netflow_monitor: vlan55 @@ -104,4 +104,4 @@ vxlan: - {hostname: << leaf1_ip >>, ports: []} - name: leaf2 switches: - - {hostname: << leaf2_ip >>, ports: []} \ No newline at end of file + - {hostname: << leaf2_ip >>, ports: []} diff --git a/tests/integration/host_vars/examples/fabric_full_large_example/topology_switches.yaml b/tests/integration/host_vars/examples/fabric_full_large_example/topology_switches.yaml index 0ff26531..1536c700 100644 --- a/tests/integration/host_vars/examples/fabric_full_large_example/topology_switches.yaml +++ b/tests/integration/host_vars/examples/fabric_full_large_example/topology_switches.yaml @@ -98,4 +98,26 @@ vxlan: management_ipv4_address: << border_ip >> management_ipv6_address: 2055:55:55:55::55/64 routing_loopback_id: 0 + vtep_loopback_id: 1 + + - name: << border_gateway_hostname >> + serial_number: << border_gateway_serial >> + role: border_gateway + management: + default_gateway_v4: << default_gateway_v4 >> + default_gateway_v6: 2055:55:55:55::55/64 + management_ipv4_address: << border_gateway_ip >> + management_ipv6_address: 2055:55:55:55::55/64 + routing_loopback_id: 0 + vtep_loopback_id: 1 + + - name: << border_spine_hostname >> + serial_number: << border_spine_serial >> + role: border_spine + management: + default_gateway_v4: << default_gateway_v4 >> + default_gateway_v6: 2055:55:55:55::55/64 + management_ipv4_address: << border_spine_ip >> + management_ipv6_address: 2055:55:55:55::55/64 + routing_loopback_id: 0 vtep_loopback_id: 1 \ No newline at end of file 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 c0052f75..686894fd 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 @@ -71,12 +71,12 @@ vxlan: no_rp: False overlay_multicast_group: "" redist_direct_routemap: "" - rp_address: 192.168.1.1/24 + rp_address: 192.168.1.1 rp_external: False - rp_loopback_id: 0 - trm_enable: False + rp_loopback_id: 2 + trm_enable: True trm_bgw_msite: False - underlay_mcast_ip: "224.1.1.1/32" + underlay_mcast_ip: "224.1.1.1" attach_group: all_leaf vrf_attach_groups: diff --git a/tests/integration/host_vars/examples/fabric_full_small_example/global.yaml b/tests/integration/host_vars/examples/fabric_full_small_example/global.yaml index 9304c246..d28b1d38 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_example/global.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_example/global.yaml @@ -43,6 +43,13 @@ vxlan: vrf: engineering - ip_address: 18.3.3.3 vrf: engineering + syslog_servers: + - ip_address: 172.16.255.251 + vrf: management + severity: 3 + - ip_address: 172.16.255.252 + vrf: management + severity: 3 vpc: peer_link_vlan: 3600 peer_keep_alive: management diff --git a/tests/integration/host_vars/examples/fabric_full_small_example/networks.yaml b/tests/integration/host_vars/examples/fabric_full_small_example/networks.yaml index 68038437..122709a2 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_example/networks.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_example/networks.yaml @@ -81,7 +81,7 @@ vxlan: route_target_both: True route_tag: 12345 secondary_ip_addresses: - - ip_address: 10.10.10.1 + - ip_address: 10.10.10.1/24 route_tag: 12345 trm_enable: False vlan_netflow_monitor: vlan55 @@ -101,4 +101,4 @@ vxlan: - {hostname: << leaf1_ip >>, ports: []} - name: leaf2 switches: - - {hostname: << leaf2_ip >>, ports: []} \ No newline at end of file + - {hostname: << leaf2_ip >>, ports: []} diff --git a/tests/integration/host_vars/examples/fabric_full_small_example/vrfs.yaml b/tests/integration/host_vars/examples/fabric_full_small_example/vrfs.yaml index f0c71288..43c567b5 100644 --- a/tests/integration/host_vars/examples/fabric_full_small_example/vrfs.yaml +++ b/tests/integration/host_vars/examples/fabric_full_small_example/vrfs.yaml @@ -71,12 +71,12 @@ vxlan: no_rp: False overlay_multicast_group: "" redist_direct_routemap: "" - rp_address: 192.168.1.1/24 + rp_address: 192.168.1.1 rp_external: False - rp_loopback_id: 0 - trm_enable: False + rp_loopback_id: 2 + trm_enable: True trm_bgw_msite: False - underlay_mcast_ip: "224.1.1.1/32" + underlay_mcast_ip: "224.1.1.1" attach_group: all_leaf vrf_attach_groups: diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/global.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/global.yaml new file mode 100644 index 00000000..4600a829 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/global.yaml @@ -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 + +--- +vxlan: + global: + name: << fabric_name >> + bgp_asn: 787878 + route_reflectors: 4 + anycast_gateway_mac: 20:20:00:00:00:aa + auth_proto: SHA + dns_servers: + - ip_address: 1.1.1.1 + vrf: test + - ip_address: 5.5.5.1 + vrf: test + - ip_address: 8.8.8.8 + vrf: engineering + ntp_servers: + - ip_address: 15.3.3.3 + vrf: test + - ip_address: 16.3.3.3 + vrf: engineering + - ip_address: 17.3.3.3 + vrf: engineering + - ip_address: 18.3.3.3 + vrf: engineering + vpc: + peer_link_vlan: 3600 + peer_keep_alive: management + auto_recovery_time: 300 + delay_restore_time: 175 + peer_link_port_channel_id: 555 + advertise_pip: False + advertise_pip_border_only: True + domain_id_range: 1-100 \ No newline at end of file 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 new file mode 100644 index 00000000..122709a2 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/networks.yaml @@ -0,0 +1,104 @@ +# 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 + +--- +vxlan: + overlay_services: + networks: + - name: NetAsCodeNet1 + vrf_name: NetAsCodeVrf1 + vlan_id: 2301 + net_id: 130001 + vlan_name: NetAsCodeNet1_vlan2301 + gw_ip_address: "192.168.12.1/24" + attach_group: all_leaf + + - name: NetAsCodeNet2 + vrf_name: NetAsCodeVrf2 + net_id: 130002 + vlan_id: 2302 + vlan_name: NetAsCodeNet2_vlan2302 + gw_ip_address: "192.168.12.2/24" + attach_group: leaf1_leaf2 + + - name: NetAsCodeNet3 + vrf_name: NetAsCodeVrf3 + net_id: 130003 + vlan_id: 2303 + vlan_name: NetAsCodeNet3_vlan2303 + gw_ip_address: "192.168.12.3/24" + gw_ipv6_address: '2001::1/64' + route_target_both: True + l3gw_on_border: True + mtu_l3intf: 7600 + int_desc: "Configured by NetAsCode" + attach_group: leaf1_leaf2 + + - name: NetAsCodeNet4 + vrf_name: NetAsCodeVrf4 + net_id: 130004 + vlan_id: 2304 + vlan_name: NetAsCodeNet4_vlan2304 + gw_ip_address: "192.168.12.4/24" + attach_group: leaf1_leaf2 + + - name: NetAsCodeNet_Default + is_l2_only: False + vrf_name: NetAsCodeVrf_Default + net_id: 130020 + vlan_id: 2320 + vlan_name: NetAsCodeVrf_Default_vlan2320 + gw_ip_address: "192.168.12.1/24" + arp_suppress: False + dhcp_loopback_id: 55 + dhcp_servers: + - ip_address: 172.55.1.1 + vrf: NetAsCodeVrf_Default + gw_ipv6_address: '2001::1/64' + int_desc: "Configured by NetAsCode" + l3gw_on_border: True + mtu_l3intf: 7600 + multicast_group_address: 239.1.1.1 + netflow_enable: False + route_target_both: True + route_tag: 12345 + secondary_ip_addresses: + - ip_address: 10.10.10.1/24 + route_tag: 12345 + trm_enable: False + vlan_netflow_monitor: vlan55 + attach_group: all_leaf + + network_attach_groups: + - name: all_leaf + switches: + - {hostname: << leaf1_ip >>, ports: [Ethernet1/13, Ethernet1/14]} + - {hostname: << leaf2_ip >>, ports: [Ethernet1/13, Ethernet1/14]} + - name: leaf1_leaf2 + switches: + - {hostname: << leaf1_ip >>, ports: []} + - {hostname: << leaf2_ip >>, ports: []} + - name: leaf1 + switches: + - {hostname: << leaf1_ip >>, ports: []} + - name: leaf2 + switches: + - {hostname: << leaf2_ip >>, ports: []} diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_edge_connections.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_edge_connections.yaml new file mode 100644 index 00000000..5da35024 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_edge_connections.yaml @@ -0,0 +1,35 @@ +# 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 + +--- +vxlan: + topology: + edge_connections: + - dest_fabric: "dest_fabric" + source_device: "source_device" + dest_device: "dest_device" + source_interface: "Ethernet1/1" + dest_interface: "Ethernet1/2" + - dest_fabric: "dest_fabric2" + source_device: "source_device" + dest_device: "dest_device" + source_interface: "Ethernet1/1" + dest_interface: "Ethernet1/2" \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_fabric_links.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_fabric_links.yaml new file mode 100644 index 00000000..01074ec6 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_fabric_links.yaml @@ -0,0 +1,33 @@ +# 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 + +--- +vxlan: + topology: + fabric_links: + - source_device: "source_device" + source_interface: "Ethernet1/1" + dest_device: "dest_device" + dest_interface: "Ethernet1/2" + - source_device: "source_device2" + source_interface: "Ethernet1/1" + dest_device: "dest_device2" + dest_interface: "Ethernet1/2" \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_access.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_access.yaml new file mode 100644 index 00000000..98828bb3 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_access.yaml @@ -0,0 +1,44 @@ +# 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 + +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + interfaces: [] + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + interfaces: + - name: Ethernet1/30 + mode: access + description: "NaC Access for vlan55 leaf1" + mtu: default + speed: auto + enabled: true + access_vlan: 55 + spanning_tree_portfast: false + enable_bpdu_guard: false + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + interfaces: [] diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_access_po.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_access_po.yaml new file mode 100644 index 00000000..39314c23 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_access_po.yaml @@ -0,0 +1,63 @@ +# 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 + +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + interfaces: [] + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + interfaces: + - name: Port-Channel55 + mode: access + description: "NaC Access Port-Channel for vlan 55 leaf1" + # vpc_id: 1 + mtu: default + speed: auto + enabled: true + spanning_tree_portfast: false + enable_bpdu_guard: false + pc_mode: passive + members: + - Ethernet1/32 + - Ethernet1/33 + access_vlan: 55 + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + interfaces: + - name: Port-Channel55 + mode: access + description: "NaC Access Port-Channel for vlan 55 leaf2" + # vpc_id: 1 + mtu: default + speed: auto + enabled: true + spanning_tree_portfast: false + enable_bpdu_guard: false + pc_mode: passive + members: + - Ethernet1/32 + - Ethernet1/33 + access_vlan: 55 diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_loopback.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_loopback.yaml new file mode 100644 index 00000000..4b422419 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_loopback.yaml @@ -0,0 +1,122 @@ +# 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 + +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + interfaces: + - name: lo55 + mode: loopback + description: 'NaC Loopback Interface Spine1' + vrf: red + enabled: true + ipv4_address: 10.55.55.1 + ipv4_route_tag: 12345 + # Secondary not supported on NDFC? + # -------------------------------- + # secondary_ipv4_addresses: + # - ip_address: 192.10.55.1/32 + # route_tag: 56789 + ipv6_address: 2055:55:55:55::1 + ipv6_route_tag: 12345 + # Secondary not supported on NDFC? + # -------------------------------- + # secondary_ipv6_addresses: + # - ip_address: 2056:55:55:55::1 + # route_tag: 8888 + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + interfaces: + - name: lo55 + mode: loopback + description: 'NaC Loopback Interface Leaf1' + vrf: red + enabled: true + ipv4_address: 10.55.55.21 + ipv4_route_tag: 12345 + secondary_ipv4_addresses: + - ip_address: 192.10.55.21/32 + route_tag: 56789 + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + interfaces: + - name: Loopback55 + mode: loopback + description: 'NaC Loopback Interface Leaf2' + vrf: red + enabled: true + ipv4_address: 10.55.55.22 + ipv4_route_tag: 12345 + secondary_ipv4_addresses: + - ip_address: 192.10.55.22/32 + route_tag: 56789 + - name: Loopback56 + mode: loopback + ipv4_address: 10.55.55.56 + - name: Loopback57 + mode: loopback + ipv4_address: 10.55.55.57 + - name: Loopback58 + mode: loopback + ipv4_address: 10.55.55.58 + - name: Loopback59 + mode: loopback + ipv4_address: 10.55.55.59 + - name: Loopback60 + mode: loopback + ipv4_address: 10.55.55.60 + - name: Loopback61 + mode: loopback + ipv4_address: 10.55.55.61 + - name: Loopback62 + mode: loopback + ipv4_address: 10.55.55.62 + - name: Loopback63 + mode: loopback + ipv4_address: 10.55.55.63 + - name: Loopback64 + mode: loopback + ipv4_address: 10.55.55.64 + - name: Loopback65 + mode: loopback + ipv4_address: 10.55.55.65 + - name: Loopback66 + mode: loopback + ipv4_address: 10.55.55.66 + - name: Loopback67 + mode: loopback + ipv4_address: 10.55.55.67 + - name: Loopback68 + mode: loopback + ipv4_address: 10.55.55.68 + - name: Loopback69 + mode: loopback + ipv4_address: 10.55.55.69 + - name: Loopback70 + mode: loopback + ipv4_address: 10.55.55.70 + - name: Loopback71 + mode: loopback + ipv4_address: 10.55.55.71 \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_loopback_fabric.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_loopback_fabric.yaml new file mode 100644 index 00000000..bc38174e --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_loopback_fabric.yaml @@ -0,0 +1,39 @@ +# 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 + +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + interfaces: [] + # - name: lo0 + # description: 'NetAsCode Fabric Loopback Interface' + # mode: fabric_loopback + # ipv4_address: 10.2.0.3 + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + interfaces: [] + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + interfaces: [] diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_routed.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_routed.yaml new file mode 100644 index 00000000..25c63ac2 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_routed.yaml @@ -0,0 +1,35 @@ +# 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 + +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + interfaces: [] + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + interfaces: [] + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + interfaces: [] \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_routed_po.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_routed_po.yaml new file mode 100644 index 00000000..7e40eb03 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_routed_po.yaml @@ -0,0 +1,35 @@ +# 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 + +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + interfaces: [] + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + interfaces: [] + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + interfaces: [] diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_routed_subint.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_routed_subint.yaml new file mode 100644 index 00000000..25c63ac2 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_routed_subint.yaml @@ -0,0 +1,35 @@ +# 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 + +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + interfaces: [] + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + interfaces: [] + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + interfaces: [] \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_trunk.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_trunk.yaml new file mode 100644 index 00000000..4c728920 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_trunk.yaml @@ -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 + +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + interfaces: [] + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + interfaces: + - name: Ethernet1/31 + mode: trunk + description: "NaC Trunk for leaf1" + mtu: default + speed: auto + enabled: true + trunk_allowed_vlans: + - from: 10 + to: 100 + - from: 150 + to: 200 + spanning_tree_portfast: false + enable_bpdu_guard: false + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + interfaces: [] \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_trunk_po.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_trunk_po.yaml new file mode 100644 index 00000000..130624f1 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_int_trunk_po.yaml @@ -0,0 +1,57 @@ +# 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 + +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + interfaces: [] + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + interfaces: + - name: Port-Channel56 + mode: trunk + description: "NaC Trunk Port-Channel for leaf1" + # This is not working check with Rameez + # ---------- + # vpc_id: 1 + mtu: default + speed: auto + enabled: true + spanning_tree_portfast: false + enable_bpdu_guard: false + pc_mode: passive + members: + - Ethernet1/34 + - Ethernet1/35 + trunk_allowed_vlans: + - from: 25 + to: 99 + - from: 101 + to: 155 + - from: 158 + to: 159 + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + interfaces: [] \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_switches.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_switches.yaml new file mode 100644 index 00000000..efcce9f4 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_switches.yaml @@ -0,0 +1,57 @@ +# 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 + +--- +vxlan: + topology: + switches: + - name: << spine1_hostname >> + serial_number: << spine1_serial >> + role: spine + management: + default_gateway_v4: << default_gateway_v4 >> + default_gateway_v6: 2055:55:55:55::55/64 + management_ipv4_address: << spine1_ip >> + management_ipv6_address: 2055:55:55:55::55/64 + routing_loopback_id: 0 + vtep_loopback_id: 1 + + - name: << leaf1_hostname >> + serial_number: << leaf1_serial >> + role: leaf + management: + default_gateway_v4: << default_gateway_v4 >> + default_gateway_v6: 2055:55:55:55::55/64 + management_ipv4_address: << leaf1_ip >> + management_ipv6_address: 2055:55:55:55::55/64 + routing_loopback_id: 0 + vtep_loopback_id: 1 + + - name: << leaf2_hostname >> + serial_number: << leaf2_serial >> + role: leaf + management: + default_gateway_v4: << default_gateway_v4 >> + default_gateway_v6: 2055:55:55:55::55/64 + management_ipv4_address: << leaf2_ip >> + management_ipv6_address: 2055:55:55:55::55/64 + routing_loopback_id: 0 + vtep_loopback_id: 1 diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_vpc.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_vpc.yaml new file mode 100644 index 00000000..fe53ffc2 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/topology_vpc.yaml @@ -0,0 +1,38 @@ +# 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 + +--- +vxlan: + topology: + vpc_peers: + - peer1: << leaf1_hostname >> + peer1_peerlink_interfaces: + - name: Ethernet1/3 + - name: Ethernet1/4 + peer2: << leaf2_hostname >> + peer2_peerlink_interfaces: + - name: Ethernet1/3 + - name: Ethernet1/4 + fabric_peering: false + domain_id: 100 + vtep_vip: "10.10.88.1" + vpc_interfaces: + - vpc_id: 30 \ No newline at end of file diff --git a/tests/integration/host_vars/examples/fabric_full_small_sha_example/underlay.yaml b/tests/integration/host_vars/examples/fabric_full_small_sha_example/underlay.yaml new file mode 100644 index 00000000..a1f900ec --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/underlay.yaml @@ -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 + +--- +vxlan: + 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: 3 + 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: 64 + ospf: + area_id: 0.0.0.0 + authentication_enable: False + authentication_key_id: 0 + authentication_key: "" + bgp: + authentication_enable: False + authentication_key_type: 3 + authentication_key: "" + isis: + level: level-2 + network_point_to_point: True + authentication_enable: False + authentication_key_id: 0 + authentication_key: "" + overload_bit: False + overload_bit_elapsed_time: 5 + 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: 0 + underlay_backup_rp_loopback_id: 1 + underlay_second_backup_rp_loopback_id: 2 + underlay_third_backup_rp_loopback_id: 3 + bfd: + enable: False + ibgp: False + ospf: False + isis: False + pim: False + authentication_enable: False + authentication_key_id: 0 + authentication_key: "" 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 new file mode 100644 index 00000000..43c567b5 --- /dev/null +++ b/tests/integration/host_vars/examples/fabric_full_small_sha_example/vrfs.yaml @@ -0,0 +1,96 @@ +# 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 + +--- +vxlan: + overlay_services: + vrfs: + - name: NetAsCodeVrf1 + vrf_id: 150001 + vlan_id: 2001 + attach_group: all_leaf + + - name: NetAsCodeVrf2 + vrf_id: 150002 + vlan_id: 2002 + attach_group: leaf1_leaf2 + + - name: NetAsCodeVrf3 + vrf_id: 150003 + vlan_id: 2003 + attach_group: leaf1_leaf2 + + - name: NetAsCodeVrf4 + vrf_id: 150004 + vlan_id: 2004 + attach_group: leaf1_leaf2 + + - name: NetAsCodeVrf_Default + vrf_id: 150020 + vlan_id: 2020 + vrf_vlan_name: NetAsCodeVrf_Default_vlan2020 + vrf_intf_desc: NetAsCodeVrf_Default + vrf_description: NetAsCodeVrf_Default + vrf_int_mtu: 9216 + loopback_route_tag: 12345 + max_bgp_paths: 8 + max_ibgp_paths: 8 + ipv6_linklocal_enable: True + adv_host_routes: True + adv_default_routes: True + static_default_route: True + # bgp_password: cisco + # bgp_password_encryption_type: 3 + disable_rt_auto: True + export_evpn_rt: "" + export_mvpn_rt: "" + export_vpn_rt: "" + import_evpn_rt: "" + import_mvpn_rt: "" + import_vpn_rt: "" + netflow_enable: False + netflow_monitor: "" + no_rp: False + overlay_multicast_group: "" + redist_direct_routemap: "" + rp_address: 192.168.1.1 + rp_external: False + rp_loopback_id: 2 + trm_enable: True + trm_bgw_msite: False + underlay_mcast_ip: "224.1.1.1" + attach_group: all_leaf + + vrf_attach_groups: + - name: all_leaf + switches: + - {hostname: << leaf1_ip >>} + - {hostname: << leaf2_ip >>} + - name: leaf1_leaf2 + switches: + - {hostname: << leaf1_ip >>} + - {hostname: << leaf2_ip >>} + - name: leaf1 + switches: + - {hostname: << leaf1_ip >>} + - name: leaf2 + switches: + - {hostname: << leaf2_ip >>} \ No newline at end of file diff --git a/tests/integration/roles/test_common/tasks/main.yml b/tests/integration/roles/test_common/tasks/main.yml index 8a20e1fa..b045a7fa 100644 --- a/tests/integration/roles/test_common/tasks/main.yml +++ b/tests/integration/roles/test_common/tasks/main.yml @@ -22,12 +22,16 @@ --- - ansible.builtin.import_role: name: cisco.nac_dc_vxlan.validate + tags: 'role_validate' - ansible.builtin.import_role: name: cisco.nac_dc_vxlan.dtc.create + tags: 'role_create' - ansible.builtin.import_role: name: cisco.nac_dc_vxlan.dtc.deploy + tags: 'role_deploy' - ansible.builtin.import_role: name: cisco.nac_dc_vxlan.dtc.remove + tags: 'role_remove' diff --git a/tests/integration/roles/test_create/defaults/main.yml b/tests/integration/roles/test_create/defaults/main.yml deleted file mode 100644 index 8a3e0513..00000000 --- a/tests/integration/roles/test_create/defaults/main.yml +++ /dev/null @@ -1,188 +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 - ---- -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 - 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: level2 - 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_services: - vrfs: - vrf_description: "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 - 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: [] - overlay_extension: diff --git a/tests/integration/roles/test_remove/defaults/main.yml b/tests/integration/roles/test_remove/defaults/main.yml deleted file mode 100644 index 8a3e0513..00000000 --- a/tests/integration/roles/test_remove/defaults/main.yml +++ /dev/null @@ -1,188 +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 - ---- -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 - 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: level2 - 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_services: - vrfs: - vrf_description: "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 - 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: [] - overlay_extension: diff --git a/tests/integration/roles/test_update_model_data/tasks/main.yml b/tests/integration/roles/test_update_model_data/tasks/main.yml index e0fd484d..937c1ed4 100644 --- a/tests/integration/roles/test_update_model_data/tasks/main.yml +++ b/tests/integration/roles/test_update_model_data/tasks/main.yml @@ -256,3 +256,53 @@ replace: "{{ border.ip }}" loop: "{{ files_names }}" delegate_to: 127.0.0.1 + +# -- Border Gateway -- +- name: Replace << border_gateway_hostname >> in test data model files + ansible.builtin.replace: + path: "{{ playbook_dir }}/host_vars/{{ inventory_hostname}}/{{ item}}" + regexp: '<< border_gateway_hostname >>' + replace: "{{ border_gateway.hostname }}" + loop: "{{ files_names }}" + delegate_to: 127.0.0.1 + +- name: Replace << border_gateway_serial >> in test data model files + ansible.builtin.replace: + path: "{{ playbook_dir }}/host_vars/{{ inventory_hostname}}/{{ item}}" + regexp: '<< border_gateway_serial >>' + replace: "{{ border_gateway.serial }}" + loop: "{{ files_names }}" + delegate_to: 127.0.0.1 + +- name: Replace << border_gateway_ip >> in test data model files + ansible.builtin.replace: + path: "{{ playbook_dir }}/host_vars/{{ inventory_hostname}}/{{ item}}" + regexp: '<< border_gateway_ip >>' + replace: "{{ border_gateway.ip }}" + loop: "{{ files_names }}" + delegate_to: 127.0.0.1 + +# -- Border Spine -- +- name: Replace << border_spine_hostname >> in test data model files + ansible.builtin.replace: + path: "{{ playbook_dir }}/host_vars/{{ inventory_hostname}}/{{ item}}" + regexp: '<< border_spine_hostname >>' + replace: "{{ border_spine.hostname }}" + loop: "{{ files_names }}" + delegate_to: 127.0.0.1 + +- name: Replace << border_spine_serial >> in test data model files + ansible.builtin.replace: + path: "{{ playbook_dir }}/host_vars/{{ inventory_hostname}}/{{ item}}" + regexp: '<< border_spine_serial >>' + replace: "{{ border_spine.serial }}" + loop: "{{ files_names }}" + delegate_to: 127.0.0.1 + +- name: Replace << border_spine_ip >> in test data model files + ansible.builtin.replace: + path: "{{ playbook_dir }}/host_vars/{{ inventory_hostname}}/{{ item}}" + regexp: '<< border_spine_ip >>' + replace: "{{ border_spine.ip }}" + loop: "{{ files_names }}" + delegate_to: 127.0.0.1 \ No newline at end of file diff --git a/tests/integration/test_inventory_example.yml b/tests/integration/test_inventory_example.yml index 869b2229..c15c5528 100644 --- a/tests/integration/test_inventory_example.yml +++ b/tests/integration/test_inventory_example.yml @@ -33,5 +33,7 @@ all: ansible_host: << ndfc_ip >> fabric_full_small: ansible_host: < ndfc_ip >> + fabric_full_small_sha: + ansible_host: << ndfc_ip >> fabric_full_large: ansible_host: << ndfc_ip >> \ No newline at end of file diff --git a/tests/integration/test_update_model_data.yml b/tests/integration/test_update_model_data.yml index 0c5d7981..175f8b63 100644 --- a/tests/integration/test_update_model_data.yml +++ b/tests/integration/test_update_model_data.yml @@ -53,7 +53,7 @@ gather_facts: no tasks: - - name: Create New Directories for fabric_empty, fabric_full_large, fabric_full_small + - name: Create New Directories for fabric_empty, fabric_full_large, fabric_full_small, fabric_full_small_sha ansible.builtin.file: path: "{{ playbook_dir }}/host_vars/{{ item }}" state: directory @@ -62,8 +62,9 @@ - fabric_empty - fabric_full_large - fabric_full_small + - fabric_full_small_sha - - name: Copy content from host_vars/examples/fabric_* to fabric_empty, fabric_full_large, fabric_full_small + - name: Copy content from host_vars/examples/fabric_* to fabric_empty, fabric_full_large, fabric_full_small, fabric_full_small_sha ansible.builtin.copy: src: "{{ playbook_dir }}/host_vars/examples/{{ item.source_name }}/" dest: "{{ playbook_dir }}/host_vars/{{ item.dest_name }}" @@ -75,6 +76,8 @@ dest_name: fabric_full_large - source_name: fabric_full_small_example dest_name: fabric_full_small + - source_name: fabric_full_small_sha_example + dest_name: fabric_full_small_sha - name: Copy content from group_vars/ndfc/examples/main.yml group_vars/ndfc/main.yml ansible.builtin.copy: @@ -88,8 +91,10 @@ dest_name: fabric_full_large - source_name: fabric_full_small_example dest_name: fabric_full_small + - source_name: fabric_full_small_sha_example + dest_name: fabric_full_small_sha -- hosts: fabric_empty, fabric_full_small, fabric_full_large +- hosts: fabric_empty, fabric_full_small, fabric_full_large, fabric_full_small_sha gather_facts: no roles: diff --git a/tests/integration/test_vxlan_small_sha.yml b/tests/integration/test_vxlan_small_sha.yml new file mode 100644 index 00000000..00bc8e10 --- /dev/null +++ b/tests/integration/test_vxlan_small_sha.yml @@ -0,0 +1,51 @@ +# 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 playbook runs tests agains the data under tests/integration/host_vars/fabric_full_small_sha + +# Instructions for using this playbook: +# +# 1. Make sure you run the tests/integration/test_update_model_data playbook first +# +# 3. Run the playbook with the following command: +# ansible-playbook -i tests/integration/test_inventory.yml tests/integration/test_vxlan_small_sha.yml + +# Reset Fabric +- hosts: fabric_empty + gather_facts: no + + roles: + - test_remove + +# Create and Deploy Fabric Configuration +- hosts: fabric_full_small_sha + gather_facts: no + + roles: + - test_create + +# Reset Fabric Back to Empty +- hosts: fabric_empty + gather_facts: no + + roles: + - test_remove diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 2614ab8a..ba721d80 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -10,6 +10,7 @@ plugins/action/common/prepare_service_model.py action-plugin-docs # action plugi plugins/action/common/get_credentials.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/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/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/helper_functions.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 2614ab8a..ba721d80 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -10,6 +10,7 @@ plugins/action/common/prepare_service_model.py action-plugin-docs # action plugi plugins/action/common/get_credentials.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/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/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/helper_functions.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 2614ab8a..ba721d80 100644 --- a/tests/sanity/ignore-2.16.txt +++ b/tests/sanity/ignore-2.16.txt @@ -10,6 +10,7 @@ plugins/action/common/prepare_service_model.py action-plugin-docs # action plugi plugins/action/common/get_credentials.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/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/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/helper_functions.py action-plugin-docs # action plugin has no matching module to provide documentation