From 75858f788e303645fc2b93d6c612619fc380b28c Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Tue, 1 Sep 2020 17:25:31 -0400 Subject: [PATCH 01/71] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 088c638b7..8633b14d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## 1.0.0 - 2020-09 +## 1.0.0 - 2020-09-01 ### Added From 83530cbfdf591f480c8f72d106b9d5a4cda614b1 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Tue, 1 Sep 2020 17:31:35 -0400 Subject: [PATCH 02/71] Add tag compare --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8633b14d2..d1e5dd441 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## 1.0.0 - 2020-09-01 +## [1.0.0] - 2020-09-01 ### Added @@ -52,3 +52,4 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[1.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/0.9.0...1.0.0 From 4461ff8e1e69fe9a18b61945739635e032617a37 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Tue, 1 Sep 2020 18:32:21 -0400 Subject: [PATCH 03/71] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1e5dd441..fdea768a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added * cisco.dcnm.dcnm_network: - * New propery `routing_tag:` + * New parameter `routing_tag:` ### Changed From ebd8aafc008417d5b5edc7463ad84919569ae92c Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Thu, 15 Apr 2021 13:12:49 -0400 Subject: [PATCH 04/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3682333a3..4d70b8e2b 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 1.0.0 + version: 1.1.0 ``` ## Using this collection From f2b5a56a608406d1be532a66aa12b22748a9e169 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Thu, 15 Apr 2021 13:20:05 -0400 Subject: [PATCH 05/71] Remove modules still in development --- docs/cisco.dcnm.dcnm_service_node_module.rst | 403 ---------- plugins/modules/dcnm_service_node.py | 748 ------------------- 2 files changed, 1151 deletions(-) delete mode 100644 docs/cisco.dcnm.dcnm_service_node_module.rst delete mode 100644 plugins/modules/dcnm_service_node.py diff --git a/docs/cisco.dcnm.dcnm_service_node_module.rst b/docs/cisco.dcnm.dcnm_service_node_module.rst deleted file mode 100644 index ad0520735..000000000 --- a/docs/cisco.dcnm.dcnm_service_node_module.rst +++ /dev/null @@ -1,403 +0,0 @@ -.. _cisco.dcnm.dcnm_service_node_module: - - -**************************** -cisco.dcnm.dcnm_service_node -**************************** - -**Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric.** - - -Version added: 0.9.0 - -.. contents:: - :local: - :depth: 1 - - -Synopsis --------- -- Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric. - - - - -Parameters ----------- - -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterChoices/DefaultsComments
-
- config - -
- list - / elements=dictionary - / required -
-
- -
List of details of service nodes being managed
-
-
- attach_interface - -
- string - / required -
-
- -
List of switch interfaces where the service node will be attached
-
-
- form_factor - -
- string - / required -
-
- Default:
"physical"
-
-
Name of the form factor of the service node
-
-
- name - -
- string - / required -
-
- -
Name of service node
-
-
- svc_int_name - -
- string - / required -
-
- -
Name of the service interface
-
-
- switches - -
- list - / required -
-
- -
IP address of the switch where service node will be added/deleted
-
-
- type - -
- string - / required -
-
- Default:
"firewall"
-
-
Name of the service node type
-
-
- fabric - -
- string - / required -
-
- -
Name of attached easy fabric to which service node is attached
-
-
- service_fabric - -
- string - / required -
-
- -
Name of external fabric where the service node is located
-
-
- state - -
- string -
-
-
    Choices: -
  • merged ←
  • -
  • replaced
  • -
  • overridden
  • -
  • deleted
  • -
  • query
  • -
-
-
The state of DCNM after module completion.
-
-
- - - - -Examples --------- - -.. code-block:: yaml+jinja - - This module supports the following states: - - Merged: - Service Nodes defined in the playbook will be merged into the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Service Nodes that are not specified in the playbook will be untouched. - - Replaced: - Service Nodes defined in the playbook will be replaced in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be untouched. - - Overridden: - Service Node defined in the playbook will be overridden in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be deleted. - - Deleted: - Service Node defined in the playbook will be deleted. - If no Service Nodes are provided in the playbook, all service node present on that DCNM fabric will be deleted. - - Query: - Returns the current DCNM state for the service node listed in the playbook. - - - name: Merge Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - - - name: Replace Service Nodes form factor/type parameter - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: replaced - config: - - name: SN-11 - type: firewall - # Replace can only modify the form factor - # form_factor: virtual # the virtual will be changed to new physical - # form_factor: physical - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Nothing will be replaced in the below service node as there is no change - # Dont touch this if its present on DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - - - name: Override Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: overridden - config: - # Create this service node - - name: SN-13 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-11 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: Ethernet1/1 - # switches: - # - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - - - name: Delete selected Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - - - name: Delete all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - - - name: Query Service Nodes state for SN-11 and SN-12 - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - - - name: Query all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query - - - - -Status ------- - - -Authors -~~~~~~~ - -- Karthik Babu Harichandra Babu diff --git a/plugins/modules/dcnm_service_node.py b/plugins/modules/dcnm_service_node.py deleted file mode 100644 index b6a184277..000000000 --- a/plugins/modules/dcnm_service_node.py +++ /dev/null @@ -1,748 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2021 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import time -import copy -import re -from ansible_collections.cisco.dcnm.plugins.module_utils.network.dcnm.dcnm import get_fabric_inventory_details, \ - dcnm_send, validate_list_of_dicts, dcnm_get_ip_addr_info, get_ip_sn_dict -from ansible.module_utils.basic import AnsibleModule - -__author__ = "Karthik Babu Harichandra Babu" - -DOCUMENTATION = ''' ---- -module: dcnm_service_node -short_description: Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric. -version_added: "0.9.0" -description: - - "Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric." -author: Karthik Babu Harichandra Babu -options: - fabric: - description: - - 'Name of attached easy fabric to which service node is attached' - type: str - required: yes - service_fabric: - description: - - 'Name of external fabric where the service node is located' - type: str - required: yes - state: - description: - - The state of DCNM after module completion. - type: str - choices: - - merged - - replaced - - overridden - - deleted - - query - default: merged - - config: - description: 'List of details of service nodes being managed' - type: list - elements: dict - required: true - note: Not required for state deleted - suboptions: - name: - description: 'Name of service node' - type: str - required: true - type: - description: 'Name of the service node type' - type: str - required: true - default: 'firewall' - form_factor: - description: 'Name of the form factor of the service node' - type: str - required: true - default: 'physical' - svc_int_name: - description: 'Name of the service interface' - type: str - required: true - switches: - description: 'IP address of the switch where service node will be added/deleted' - type: list - required: true - attach_interface: - description: 'List of switch interfaces where the service node will be attached' - type: str - required: true -''' - -EXAMPLES = ''' -This module supports the following states: - -Merged: - Service Nodes defined in the playbook will be merged into the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Service Nodes that are not specified in the playbook will be untouched. - -Replaced: - Service Nodes defined in the playbook will be replaced in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be untouched. - -Overridden: - Service Node defined in the playbook will be overridden in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be deleted. - -Deleted: - Service Node defined in the playbook will be deleted. - If no Service Nodes are provided in the playbook, all service node present on that DCNM fabric will be deleted. - -Query: - Returns the current DCNM state for the service node listed in the playbook. - -- name: Merge Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - -- name: Replace Service Nodes form factor/type parameter - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: replaced - config: - - name: SN-11 - type: firewall - # Replace can only modify the form factor - # form_factor: virtual # the virtual will be changed to new physical - # form_factor: physical - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Nothing will be replaced in the below service node as there is no change - # Dont touch this if its present on DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - -- name: Override Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: overridden - config: - # Create this service node - - name: SN-13 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-11 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: Ethernet1/1 - # switches: - # - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - -- name: Delete selected Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - -- name: Delete all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - -- name: Query Service Nodes state for SN-11 and SN-12 - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - -- name: Query all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query -''' - - -class DcnmServiceNode: - - def __init__(self, module): - self.module = module - self.params = module.params - self.fabric = module.params['fabric'] - self.service_fabric = module.params['service_fabric'] - self.config = copy.deepcopy(module.params.get('config')) - self.check_mode = False - self.have_create = [] - self.want_create = [] - self.diff_create = [] - self.diff_replace = [] - self.diff_delete = {} - self.query = [] - self.validated = [] - self.inventory_data = get_fabric_inventory_details(self.module, self.fabric) - self.ip_sn, self.hn_sn = get_ip_sn_dict(self.inventory_data) - - self.result = dict( - changed=False, - diff=[], - response=[], - warnings=[] - ) - - self.failed_to_rollback = False - self.WAIT_TIME_FOR_DELETE_LOOP = 5 # in seconds - - def update_create_params(self, snode): - - if not snode: - return snode - - state = self.params['state'] - - if state == 'query': - snode_upd = { - "name": snode['name'] - } - else: - - serial = [] - for sw in snode['switches']: - sw = dcnm_get_ip_addr_info(self.module, sw, None, None) - for ip, ser in self.ip_sn.items(): - if ip == sw: - serial.append(ser) - - if not serial: - self.module.fail_json(msg='Fabric: {} does not have the switch: {}' - .format(self.fabric, snode['switches'])) - - switchsn = "" - if len(snode['switches']) == 2: - switchsn = str(serial[0]) + "," + str(serial[1]) - if 'vPC' not in snode['attach_interface']: - self.module.fail_json(msg='Fabric: {} - if two switches are provided, vpc is only interface option' - .format(self.fabric)) - elif len(snode['switches']) == 1: - switchsn = str(serial[0]) - if 'vPC' in snode['attach_interface']: - self.module.fail_json(msg='Fabric: {} - For 1 switch, vpc is not the interface option' - .format(self.fabric)) - else: - self.module.fail_json(msg='Fabric: {} - Upto 2 switches only allowed' - .format(self.fabric)) - - if snode['type'] == 'firewall': - s_type = snode['type'].title() - elif snode['type'] == 'load_balancer': - s_type = 'ADC' - elif snode['type'] == 'virtual_network_function': - s_type = 'VNF' - - snode_upd = { - "name": snode['name'], - "type": s_type, - "formFactor": snode['form_factor'].title(), - "fabricName": self.service_fabric, - "interfaceName": snode['svc_int_name'], - "attachedSwitchSn": switchsn, - "attachedSwitchInterfaceName": snode['attach_interface'], - "linkTemplateName": "service_link_trunk", - "nvPairs": { - "MTU": "jumbo", - "SPEED": "Auto", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "PORTTYPE_FAST_ENABLED": "true", - "ADMIN_STATE": "true" - }, - "attachedFabricName": self.fabric - } - - return snode_upd - - def get_have(self): - - method = 'GET' - path = '/appcenter/Cisco/elasticservice/elasticservice-api/?attached-fabric={}'.format(self.fabric) - - snode_objects = dcnm_send(self.module, method, path) - missing_fabric, not_ok = self.handle_response(snode_objects, 'query_dcnm') - - if missing_fabric or not_ok: - msg1 = "Fabric {} not present on DCNM".format(self.fabric) - msg2 = "Unable to Service Node under fabric: {}".format(self.fabric) - - self.module.fail_json(msg=msg1 if missing_fabric else msg2) - return - - if not snode_objects['DATA']: - return - - have_switch = [] - for snode in snode_objects['DATA']: - get_snode = {} - get_snode.update({'name': snode['name']}) - get_snode.update({'formFactor': snode['formFactor']}) - get_snode.update({'interfaceName': snode['interfaceName']}) - get_snode.update({'type': snode['type']}) - get_snode.update({'attachedFabricName': snode['attachedFabricName']}) - get_snode.update({'attachedSwitchInterfaceName': snode['attachedSwitchInterfaceName']}) - get_snode.update({'attachedSwitchSn': snode['attachedSwitchSn']}) - get_snode.update({'fabricName': snode['fabricName']}) - have_switch.append(get_snode) - - self.have_create = have_switch - - def get_want(self): - - want_create = [] - - if not self.config: - return - - for snode in self.validated: - want_create.append(self.update_create_params(snode)) - - self.want_create = want_create - - def get_diff_delete(self): - - diff_delete = [] - - if self.config: - for want_c in self.want_create: - for have_c in self.have_create: - if (have_c['name'] == want_c['name']): - diff_delete.append(have_c['name']) - continue - - else: - for have_c in self.have_create: - diff_delete.append(have_c['name']) - - self.diff_delete = diff_delete - - def get_diff_override(self): - - self.get_diff_replace() - self.get_diff_replace_delete() - - diff_create = self.diff_create - diff_delete = self.diff_delete - - self.diff_create = diff_create - self.diff_delete = diff_delete - self.diff_replace = [] - - def get_diff_replace(self): - - self.get_diff_merge() - diff_replace = self.diff_create - - self.diff_replace = diff_replace - - found = False - for replace_c in self.diff_replace: - for have_c in self.have_create: - if have_c['name'] == replace_c['name'] : - found = True - - if not found: - self.diff_replace = [] - else: - self.diff_create = [] - - def get_diff_replace_delete(self): - - diff_delete = [] - - for have_c in self.have_create: - match_found = False - for want_c in self.want_create: - if want_c['name'] == have_c['name']: - if want_c['type'] == have_c['type'] and want_c['attachedFabricName'] == have_c['attachedFabricName'] \ - and want_c['fabricName'] == have_c['fabricName'] and \ - want_c['attachedSwitchInterfaceName'] == have_c['attachedSwitchInterfaceName'] and \ - want_c['attachedSwitchSn'] == have_c['attachedSwitchSn'] and \ - want_c['interfaceName'] == have_c['interfaceName']: - match_found = True - if match_found: - continue - else: - diff_delete.append(have_c['name']) - - self.diff_delete = diff_delete - - def get_diff_merge(self, replace=False): - - diff_create = [] - - for want_c in self.want_create: - found = False - for have_c in self.have_create: - if want_c['name'] == have_c['name'] and want_c['type'] == have_c['type'] and \ - want_c['attachedFabricName'] == have_c['attachedFabricName'] and want_c['fabricName'] == have_c[ - 'fabricName'] and \ - want_c['attachedSwitchInterfaceName'] == have_c['attachedSwitchInterfaceName'] and \ - want_c['attachedSwitchSn'] == have_c['attachedSwitchSn'] and \ - want_c['interfaceName'] == have_c['interfaceName'] and \ - want_c['formFactor'] == have_c['formFactor']: - found = True - if not found: - diff_create.append(want_c) - - self.diff_create = diff_create - - def get_diff_query(self): - - query = [] - method = 'GET' - path = '/appcenter/Cisco/elasticservice/elasticservice-api/?attached-fabric={}'.format(self.fabric) - - snode_objects = dcnm_send(self.module, method, path) - - missing_fabric, not_ok = self.handle_response(snode_objects, 'query_dcnm') - - if missing_fabric or not_ok: - msg1 = "Fabric {} not present on DCNM".format(self.fabric) - msg2 = "Unable to find Service Node under fabric: {}".format(self.fabric) - - self.module.fail_json(msg=msg1 if missing_fabric else msg2) - return - - if not snode_objects['DATA']: - return - - if self.config: - for want_c in self.want_create: - for snode in snode_objects['DATA']: - if want_c['name'] == snode['name']: - query.append(snode) - continue - else: - for snode in snode_objects['DATA']: - query.append(snode) - - self.query = query - - def push_to_remote(self, is_rollback=False): - - method = 'DELETE' - if self.diff_delete: - for name in self.diff_delete: - delete_path = '/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/{}/service-nodes/{}'.format( - self.service_fabric, name) - resp = dcnm_send(self.module, method, delete_path) - - self.result['response'].append(resp) - fail, self.result['changed'] = self.handle_response(resp, "delete") - - if fail: - if is_rollback: - self.failed_to_rollback = True - return - self.failure(resp) - - method = 'POST' - if self.diff_create: - for create in self.diff_create: - deploy_path = '/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/{}/service-nodes'.format( - self.service_fabric) - resp = dcnm_send(self.module, method, deploy_path, json.dumps(create)) - self.result['response'].append(resp) - fail, self.result['changed'] = self.handle_response(resp, "create") - - if fail: - if is_rollback: - self.failed_to_rollback = True - return - self.failure(resp) - - method = 'PUT' - if self.diff_replace: - for replace in self.diff_replace: - replace_path = '/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/{}/service-nodes/{}'.format( - self.service_fabric, replace['name']) - resp = dcnm_send(self.module, method, replace_path, json.dumps(replace)) - - self.result['response'].append(resp) - fail, self.result['changed'] = self.handle_response(resp, "create") - - if fail: - if is_rollback: - self.failed_to_rollback = True - return - self.failure(resp) - - def validate_input(self): - - """Parse the playbook values, validate to param specs.""" - - state = self.params['state'] - - if state == 'query': - - snode_spec = dict( - name=dict(required=True, type='str', length_max=64), - ) - - if self.config: - # Validate service node params - valid_snode, invalid_params = validate_list_of_dicts(self.config, snode_spec) - for snode in valid_snode: - self.validated.append(snode) - - if invalid_params: - msg = 'Invalid parameters in playbook: {}'.format('\n'.join(invalid_params)) - self.module.fail_json(msg=msg) - - else: - - snode_spec = dict( - name=dict(required=True, type='str', length_max=64), - type=dict(required=True, type='str', - choices=['firewall', 'load_balancer', 'virtual_network_function'], - default='firewall'), - form_factor=dict(required=True, type='str', - choices=['physical', 'virtual'], - default='physical'), - svc_int_name=dict(required=True, type='str', length_max=64), - switches=dict(required=True, type='list'), - attach_interface=dict(required=True, type='str'), - ) - - if self.config: - msg = None - # Validate service node params - valid_snode, invalid_params = validate_list_of_dicts(self.config, snode_spec) - for snode in valid_snode: - self.validated.append(snode) - - if invalid_params: - msg = 'Invalid parameters in playbook: {}'.format('\n'.join(invalid_params)) - self.module.fail_json(msg=msg) - - else: - state = self.params['state'] - msg = None - - if state == 'merged' or state == 'overridden' or \ - state == 'replaced': - msg = "config: element is mandatory for this state {}".format(state) - - if msg: - self.module.fail_json(msg=msg) - - def handle_response(self, resp, op): - - fail = False - changed = True - - res = resp.copy() - - if op == 'query_dcnm': - # This if blocks handles responses to the query APIs against DCNM. - # Basically all GET operations. - # - if res.get('ERROR') == 'Not Found' and res['RETURN_CODE'] == 404: - return True, False - if res['RETURN_CODE'] != 200 or res['MESSAGE'] != "": - return False, True - return False, False - - # Responses to all other operations POST and PUT are handled here. - if res.get('MESSAGE') != "" or res.get('RETURN_CODE') != 200: - fail = True - changed = False - return fail, changed - - return fail, changed - - def failure(self, resp): - - # Implementing a per task rollback logic here so that we rollback DCNM to the have state - # whenever there is a failure in any of the APIs. - # The idea would be to run overridden state with want=have and have=dcnm_state - self.want_create = self.have_create - self.have_create = [] - self.get_have() - self.get_diff_override() - - self.push_to_remote(True) - - if self.failed_to_rollback: - msg1 = "FAILED - Attempted rollback of the task has failed, may need manual intervention" - else: - msg1 = 'SUCCESS - Attempted rollback of the task has succeeded' - - res = copy.deepcopy(resp) - res.update({'ROLLBACK_RESULT': msg1}) - - if not resp.get('DATA'): - data = copy.deepcopy(resp.get('DATA')) - if data.get('stackTrace'): - data.update({'stackTrace': 'Stack trace is hidden, use \'-vvvvv\' to print it'}) - res.update({'DATA': data}) - - if self.module._verbosity >= 5: - self.module.fail_json(msg=res) - - self.module.fail_json(msg=res) - -def main(): - """ main entry point for module execution - """ - - element_spec = dict( - fabric=dict(required=True, type='str'), - service_fabric=dict(required=True, type='str'), - config=dict(required=False, type='list'), - state=dict(default='merged', - choices=['merged', 'replaced', 'deleted', 'overridden', 'query']), - check_mode=dict(required=False, type="bool", default=False) - ) - - module = AnsibleModule(argument_spec=element_spec, - supports_check_mode=True) - - dcnm_snode = DcnmServiceNode(module) - - if not dcnm_snode.ip_sn: - module.fail_json(msg="Fabric {} missing on DCNM or does not have any switches".format(dcnm_snode.fabric)) - - dcnm_snode.validate_input() - - dcnm_snode.get_want() - dcnm_snode.get_have() - - if module.params['state'] == 'merged': - dcnm_snode.get_diff_merge() - - if module.params['state'] == 'replaced': - dcnm_snode.get_diff_replace() - - if module.params['state'] == 'overridden': - dcnm_snode.get_diff_override() - - if module.params['state'] == 'deleted': - dcnm_snode.get_diff_delete() - # - if module.params['state'] == 'query': - dcnm_snode.get_diff_query() - dcnm_snode.result['response'] = dcnm_snode.query - - if module.params['check_mode']: - dcnm_snode.result['changed'] = False - module.exit_json(**dcnm_snode.result) - - if dcnm_snode.diff_create or dcnm_snode.diff_delete or dcnm_snode.diff_replace: - dcnm_snode.result['changed'] = True - else: - module.exit_json(**dcnm_snode.result) - - dcnm_snode.push_to_remote() - - module.exit_json(**dcnm_snode.result) - -if __name__ == '__main__': - main() From 7b31adf816f7d8a307ada6549fe1993d5c9147b3 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Thu, 15 Apr 2021 13:20:36 -0400 Subject: [PATCH 06/71] Remove doc reference link --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 4d70b8e2b..3799941fa 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ Name | Description [cisco.dcnm.dcnm_network](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_network_module.rst)|Add and remove Networks from a DCNM managed VXLAN fabric. [cisco.dcnm.dcnm_policy](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_policy_module.rst)|DCNM Ansible Module for managing policies. [cisco.dcnm.dcnm_rest](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_rest_module.rst)|Send REST API requests to DCNM controller. -[cisco.dcnm.dcnm_service_node](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_service_node_module.rst)|Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric. [cisco.dcnm.dcnm_template](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_template_module.rst)|DCNM Ansible Module for managing templates. [cisco.dcnm.dcnm_vrf](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_vrf_module.rst)|Add and remove VRFs from a DCNM managed VXLAN fabric. From 858b761e46fccbc10f06635befcbb8e5c6874c4f Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Thu, 15 Apr 2021 13:36:13 -0400 Subject: [PATCH 07/71] Update CI trigger branch for main --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 33298a818..8482c244f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,9 +6,9 @@ name: CI on: # Triggers the workflow on push or pull request events but only for the develop branch push: - branches: [ develop ] + branches: [ main ] pull_request: - branches: [ develop ] + branches: [ main ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: From 753e399709dda68b06cb3a6c85267469f0d51fc8 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Thu, 15 Apr 2021 13:41:37 -0400 Subject: [PATCH 08/71] Remove service node tests --- .../dcnm_service_node/defaults/main.yaml | 2 - .../targets/dcnm_service_node/meta/main.yaml | 1 - .../targets/dcnm_service_node/tasks/dcnm.yaml | 20 - .../targets/dcnm_service_node/tasks/main.yaml | 2 - .../dcnm_service_node/tests/dcnm/deleted.yaml | 344 -------- .../dcnm_service_node/tests/dcnm/merged.yaml | 768 ------------------ .../tests/dcnm/overridden.yaml | 281 ------- .../dcnm_service_node/tests/dcnm/query.yaml | 396 --------- .../tests/dcnm/replaced.yaml | 421 ---------- .../dcnm/fixtures/dcnm_service_node.json | 612 -------------- .../modules/dcnm/test_dcnm_service_node.py | 499 ------------ 11 files changed, 3346 deletions(-) delete mode 100644 tests/integration/targets/dcnm_service_node/defaults/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/meta/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tasks/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml delete mode 100644 tests/unit/modules/dcnm/fixtures/dcnm_service_node.json delete mode 100644 tests/unit/modules/dcnm/test_dcnm_service_node.py diff --git a/tests/integration/targets/dcnm_service_node/defaults/main.yaml b/tests/integration/targets/dcnm_service_node/defaults/main.yaml deleted file mode 100644 index 55a93fc23..000000000 --- a/tests/integration/targets/dcnm_service_node/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/meta/main.yaml b/tests/integration/targets/dcnm_service_node/meta/main.yaml deleted file mode 100644 index 5514b6a40..000000000 --- a/tests/integration/targets/dcnm_service_node/meta/main.yaml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml b/tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml deleted file mode 100644 index 7081e21b6..000000000 --- a/tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: collect dcnm test cases - find: - paths: "{{ role_path }}/tests/dcnm" - patterns: "{{ testcase }}.yaml" - connection: local - register: dcnm_cases - -- set_fact: - test_cases: - files: "{{ dcnm_cases.files }}" - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=httpapi) - include: "{{ test_case_to_run }} ansible_connection=httpapi connection={{ dcnm }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tasks/main.yaml b/tests/integration/targets/dcnm_service_node/tasks/main.yaml deleted file mode 100644 index 78c5fb834..000000000 --- a/tests/integration/targets/dcnm_service_node/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: dcnm.yaml, tags: ['dcnm'] } \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml deleted file mode 100644 index 7066c3c7e..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml +++ /dev/null @@ -1,344 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: DELETED - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: DELETED - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: DELETED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### DELETED ## -############################################### - -- name: DELETED - Delete Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: DELETED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - Delete Service Node with single switch - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with 2 switches and vPC Interface - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - Delete Service Node - WITHOUT ANY CONFIG ELEMENT - cisco.dcnm.dcnm_service_node: &conf2 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - conf2 - Idempotence - cisco.dcnm.dcnm_service_node: *conf2 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - Delete Service Node - WITHOUT ANY CONFIG ELEMENT - cisco.dcnm.dcnm_service_node: &conf3 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - conf3 - Idempotence - cisco.dcnm.dcnm_service_node: *conf3 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -################################################ -#### CLEAN-UP ## -################################################ - -- name: DELETED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml deleted file mode 100644 index 8ac75ef5f..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml +++ /dev/null @@ -1,768 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: MERGED - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: MERGED - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -############################################### -### MERGED ## -############################################### - -- name: MERGED - Create Service Node with form factor virtual - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with form factor physical - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with type load balancer - cisco.dcnm.dcnm_service_node: &conf2 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: load_balancer - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "ADC"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf2 - Idempotence - cisco.dcnm.dcnm_service_node: *conf2 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with type virtual network function - cisco.dcnm.dcnm_service_node: &conf3 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf3 - Idempotence - cisco.dcnm.dcnm_service_node: *conf3 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with check mode set to true - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - check_mode: true - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - '(result["response"] | length) == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: &conf4 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf4 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 2 switches and vPC Interface with type load balancer - cisco.dcnm.dcnm_service_node: &conf5 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: load_balancer - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "ADC"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf5 - Idempotence - cisco.dcnm.dcnm_service_node: *conf5 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 2 switches and vPC Interface with type virtual network function - cisco.dcnm.dcnm_service_node: &conf6 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf6 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with default state 'merged'/ without providing state explicitily - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 3 tasks having 3 different types of type and single form factor virtual - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-13 - type: load_balancer - form_factor: virtual - svc_int_name: svc3 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Virtual"' - - 'result.response[1].DATA.interfaceName == "svc2"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "Firewall"' - - 'result.response[1].DATA.name == "SN-12"' - - 'result.response[2].RETURN_CODE == 200' - - 'result.response[2].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[2].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[2].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[2].DATA.formFactor == "Virtual"' - - 'result.response[2].DATA.interfaceName == "svc3"' - - 'result.response[2].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[2].DATA.type == "ADC"' - - 'result.response[2].DATA.name == "SN-13"' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 3 tasks having 3 different types of type and form factor physical - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-12 - type: firewall - form_factor: physical - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-13 - type: load_balancer - form_factor: physical - svc_int_name: svc3 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Physical"' - - 'result.response[1].DATA.interfaceName == "svc2"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "Firewall"' - - 'result.response[1].DATA.name == "SN-12"' - - 'result.response[2].RETURN_CODE == 200' - - 'result.response[2].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[2].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[2].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[2].DATA.formFactor == "Physical"' - - 'result.response[2].DATA.interfaceName == "svc3"' - - 'result.response[2].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[2].DATA.type == "ADC"' - - 'result.response[2].DATA.name == "SN-13"' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 2 switches and invalid vpc interface - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc2 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -- name: MERGED - Create Service Node with 2 switches and invalid vpc name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPortchannel12 - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"if two switches are provided, vpc is only interface option" in result.msg' - -- name: MERGED - Create Service Node with 1 switch and valid vpc name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"For 1 switch, vpc is not the interface option" in result.msg' - -- name: MERGED - Create Service Node with more than 2 switch and valid vpc name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch1 }}" - - "{{ ansible_switch2 }}" - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Upto 2 switches only allowed" in result.msg' - -- name: MERGED - Create Service Node without required parameter - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Required parameter not found" in result.msg' - -- name: MERGED - Create Service Node with wrong type - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: karth - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Invalid choice provided" in result.msg' - -- name: MERGED - Create Service Node with wrong formfactor - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: not - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Invalid choice provided" in result.msg' - -############################################### -### CLEAN-UP ## -############################################### - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml deleted file mode 100644 index e28ea2877..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml +++ /dev/null @@ -1,281 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: OVERRIDDEN - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: OVERRIDDEN - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: OVERRIDDEN - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: OVERRIDDEN - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: OVERRIDDEN - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### OVERRIDDEN ## -############################################### - -- name: OVERRIDDEN - Update service node - delete and create - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: overridden - config: - - name: SN-12 - type: load_balancer - form_factor: physical - svc_int_name: svc12 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].METHOD == "DELETE"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Physical"' - - 'result.response[1].DATA.interfaceName == "svc12"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "ADC"' - - 'result.response[1].DATA.name == "SN-12"' - -- name: OVERRIDDEN - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: OVERRIDDEN - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: OVERRIDDEN - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: OVERRIDDEN - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: OVERRIDDEN - Create 2 Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc11 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: SN-12 - type: load_balancer - form_factor: virtual - svc_int_name: svc12 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch2 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc11"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Virtual"' - - 'result.response[1].DATA.interfaceName == "svc12"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "ADC"' - - 'result.response[1].DATA.name == "SN-12"' - -- name: OVERRIDDEN - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: OVERRIDDEN - Create and Delete new service nodes - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: overridden - config: - - name: SN-13 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc13 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: SN-14 - type: firewall - form_factor: virtual - svc_int_name: svc14 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch2 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].METHOD == "DELETE"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].METHOD == "DELETE"' - - 'result.response[2].RETURN_CODE == 200' - - 'result.response[2].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[2].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[2].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[2].DATA.formFactor == "Virtual"' - - 'result.response[2].DATA.interfaceName == "svc13"' - - 'result.response[2].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[2].DATA.type == "VNF"' - - 'result.response[2].DATA.name == "SN-13"' - - 'result.response[3].RETURN_CODE == 200' - - 'result.response[3].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[3].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[3].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[3].DATA.formFactor == "Virtual"' - - 'result.response[3].DATA.interfaceName == "svc14"' - - 'result.response[3].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[3].DATA.type == "Firewall"' - - 'result.response[3].DATA.name == "SN-14"' - -- name: OVERRIDDEN - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: OVERRIDDEN - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: OVERRIDDEN - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -############################################## -## CLEAN-UP ## -############################################## - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml deleted file mode 100644 index 756b3d973..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml +++ /dev/null @@ -1,396 +0,0 @@ -############################################## -## SETUP ## -############################################## -- -- name: QUERY - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: QUERY - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: QUERY - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: QUERY - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### QUERY ## -############################################### - -- name: QUERY - Query the Service Node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: QUERY - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: QUERY - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query the - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query without the config element - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: QUERY - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: QUERY - Create Service Node with single/mutiple switch - 2 tasks - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Virtual"' - - 'result.response[1].DATA.interfaceName == "svc2"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "Firewall"' - - 'result.response[1].DATA.name == "SN-12"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query the - Create Service Node with single/mutiple switch - 2 tasks - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - "{{ ansible_switch1 }}" - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - - 'result.response[1].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].formFactor == "Virtual"' - - 'result.response[1].interfaceName == "svc2"' - - 'result.response[1].linkTemplateName == "service_link_trunk"' - - 'result.response[1].type == "Firewall"' - - 'result.response[1].name == "SN-12"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query without the config element - 2 tasks - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - - 'result.response[1].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].formFactor == "Virtual"' - - 'result.response[1].interfaceName == "svc2"' - - 'result.response[1].linkTemplateName == "service_link_trunk"' - - 'result.response[1].type == "Firewall"' - - 'result.response[1].name == "SN-12"' - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: QUERY - Query the non available Service Node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11111111 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -############################################### -### CLEAN-UP ## -############################################### - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml deleted file mode 100644 index 8f2f95ff6..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml +++ /dev/null @@ -1,421 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: REPLACED - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: REPLACED - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: REPLACED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: REPLACED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: REPLACED - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### REPLACED ## -############################################### - -- name: REPLACED - Replace Service Node with form factor physical - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: REPLACED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with form factor virtual - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: REPLACED - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: REPLACED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: REPLACED - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with form factor physical - cisco.dcnm.dcnm_service_node: &conf2 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - conf2 - Idempotence - cisco.dcnm.dcnm_service_node: *conf2 - register: result - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with type load balancer - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: load_balancer - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "ADC"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with type virtual network function - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: virtual_network_function - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with a new creation of service node, since the sn is not created already - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11111111111 - type: firewall - form_factor: physical - svc_int_name: svc11 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc11"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11111111111"' - -- name: REPLACED - Replace Service Node with not supported change of already created svc int name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc111111111 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - Replace Service Node with not supported change of already created attach interface - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc11 - attach_interface: "{{ ansible_int2 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - Replace Service Node with not supported change of already created attached switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc11 - attach_interface: "{{ ansible_int2 }}" - switches: - - "{{ ansible_switch5 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -############################################### -### CLEAN-UP ## -############################################### - -- name: REPLACED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted \ No newline at end of file diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_service_node.json b/tests/unit/modules/dcnm/fixtures/dcnm_service_node.json deleted file mode 100644 index bb2f81728..000000000 --- a/tests/unit/modules/dcnm/fixtures/dcnm_service_node.json +++ /dev/null @@ -1,612 +0,0 @@ -{ - "mock_ip_sn" : { - "10.10.10.224": "XYZKSJHSMK1", - "10.10.10.225": "XYZKSJHSMK2", - "10.10.10.226": "XYZKSJHSMK3", - "10.10.10.227": "XYZKSJHSMK4", - "10.10.10.228": "XYZKSJHSMK5" - }, - - "playbook_config" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_replace_new" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_replace_new1" : [ - { - "name": "SN-11", - "type": "load_balancer", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_new_config" : [ - { - "name": "SN-12", - "type": "load_balancer", - "form_factor": "virtual", - "svc_int_name": "svc12", - "attach_interface": "Ethernet1/12", - "switches": "10.10.10.225" - } - ], - - "playbook_over_config" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "scv1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_name" : [ - { - "name": "SN-11" - } - ], - - "playbook_config_virtual" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "virtual", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_load" : [ - { - "name": "SN-11", - "type": "load_balancer", - "form_factor": "virtual", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_vnf" : [ - { - "name": "SN-11", - "type": "virtual_network_function", - "form_factor": "virtual", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_vpc" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPC1", - "switches": ["10.10.10.224", "10.10.10.225"] - } - ], - - "playbook_config_invalid_vpc" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPortchannel12", - "switches": ["10.10.10.224", "10.10.10.225"] - } - ], - - "playbook_config_more_switch" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPC1", - "switches": ["10.10.10.224", "10.10.10.225", "10.10.10.226"] - } - ], - - "playbook_config_noparams" : [ - { - "name": "", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_no_type" : [ - { - "name": "SN-11", - "type": "karth", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_no_ff" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "babu", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_no_vpc" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPC1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_query" : [ - { - "switches": "10.10.10.224" - } - ], - - "mock_sn_1_object": { - "ERROR": "", - "RETURN_CODE": 200, - "MESSAGE":"", - "DATA": [ - { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "svc1", - "lastUpdated": 1611748269292, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-141180", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "DEST_FABRIC_NAME": "external", - "DEST_SWITCH_NAME": "SN-11", - "IS_METASWITCH": "false", - "LINK_UUID": "LINK-UUID-141180", - "MTU": "jumbo", - "POLICY_DESC": "", - "POLICY_ID": "POLICY-141190", - "PORTTYPE_FAST_ENABLED": "true", - "PRIORITY": "500", - "SOURCE_FABRIC_NAME": "test_fabric", - "SOURCE_SWITCH_NAME": "dt-n9k1", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - ] - }, - - "mock_sn_merge_1_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_2_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_3_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "AVB", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_4_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "VNF", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_5_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "vPC1", - "attachedSwitchSn": "XYZKSJHSMK1, XYZKSJHSMK2", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_6_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/2", - "attachedSwitchSn": "XYZKSJHSMK2", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv12", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-12", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "ADC", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_replace_1_success": { - "MESSAGE": "", - "METHOD": "PUT", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv11", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_replace_2_success": { - "MESSAGE": "", - "METHOD": "PUT", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv11", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "ADC", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_have_success": { - "MESSAGE": "", - "METHOD": "GET", - "RETURN_CODE": 200, - "DATA": [ - { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612604671520, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-304470", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "DEST_FABRIC_NAME": "external", - "DEST_IF_NAME": "scv1", - "DEST_SERIAL_NUMBER": "SN-11-external", - "DEST_SWITCH_NAME": "SN-11", - "IS_METASWITCH": "true", - "LINK_UUID": "LINK-UUID-304470", - "MTU": "jumbo", - "POLICY_DESC": "", - "POLICY_ID": "POLICY-304480", - "PORTTYPE_FAST_ENABLED": "true", - "PRIORITY": "500", - "SOURCE_FABRIC_NAME": "test_fabric", - "SOURCE_IF_NAME": "Ethernet1/1", - "SOURCE_SERIAL_NUMBER": "XYZKSJHSMK1", - "SOURCE_SWITCH_NAME": "XYZKSJHSMK1", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - ] - }, - - "mock_sn_query_success": { - "attachedFabricName": "Fabric1", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "SAL1812NTBP", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612606479781, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-304710", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "DEST_FABRIC_NAME": "external", - "DEST_IF_NAME": "scv1", - "DEST_SERIAL_NUMBER": "SN-11-external", - "DEST_SWITCH_NAME": "SN-11", - "IS_METASWITCH": "true", - "LINK_UUID": "LINK-UUID-304710", - "MTU": "jumbo", - "POLICY_DESC": "", - "POLICY_ID": "POLICY-304720", - "PORTTYPE_FAST_ENABLED": "true", - "PRIORITY": "500", - "SOURCE_FABRIC_NAME": "Fabric1", - "SOURCE_IF_NAME": "Ethernet1/1", - "SOURCE_SERIAL_NUMBER": "SAL1812NTBP", - "SOURCE_SWITCH_NAME": "SAL1812NTBP", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - }, - - "blank_data": { - "DATA": [], - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200 - }, - "blank_get_data": { - "DATA": [], - "MESSAGE": "", - "METHOD": "GET", - "RETURN_CODE": 200 - }, - - "blank_data_null": { - "DATA": [], - "MESSAGE": "", - "METHOD": "", - "RETURN_CODE": 0 - }, - - - "get_have_failure": { - "DATA": "Invalid JSON response: Invalid Fabric: demo-fabric-123", - "ERROR": "Not Found", - "METHOD": "GET", - "RETURN_CODE": 404, - "MESSAGE": "OK" - }, - "error1": { - "DATA": "None", - "ERROR": "There is an error", - "METHOD": "POST", - "RETURN_CODE": 400, - "MESSAGE": "OK" - }, - - "sn_delete_success_resp": { - "DATA": {}, - "ERROR": "", - "METHOD": "DELETE", - "RETURN_CODE": 200, - "MESSAGE": "" - }, - "sn_query_success_resp": { - "DATA": {}, - "ERROR": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "MESSAGE": "" - }, - - "sn_inv_data": { - "10.10.10.224":{ - "ipAddress": "10.10.10.224", - "logicalName": "dt-n9k1", - "serialNumber": "XYZKSJHSMK1", - "switchRole": "leaf" - }, - "10.10.10.225":{ - "ipAddress": "10.10.10.225", - "logicalName": "dt-n9k2", - "serialNumber": "XYZKSJHSMK2", - "switchRole": "leaf" - }, - "10.10.10.226":{ - "ipAddress": "10.10.10.226", - "logicalName": "dt-n9k3", - "serialNumber": "XYZKSJHSMK3", - "switchRole": "leaf" - }, - "10.10.10.227":{ - "ipAddress": "10.10.10.227", - "logicalName": "dt-n9k4", - "serialNumber": "XYZKSJHSMK4", - "switchRole": "border spine" - }, - "10.10.10.228":{ - "ipAddress": "10.10.10.228", - "logicalName": "dt-n9k5", - "serialNumber": "XYZKSJHSMK5", - "switchRole": "border" - } - } -} \ No newline at end of file diff --git a/tests/unit/modules/dcnm/test_dcnm_service_node.py b/tests/unit/modules/dcnm/test_dcnm_service_node.py deleted file mode 100644 index 94aff6f2e..000000000 --- a/tests/unit/modules/dcnm/test_dcnm_service_node.py +++ /dev/null @@ -1,499 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2021 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from ansible_collections.ansible.netcommon.tests.unit.compat.mock import patch - -from ansible_collections.cisco.dcnm.plugins.modules import dcnm_service_node -from .dcnm_module import TestDcnmModule, set_module_args, loadPlaybookData - -import json, copy - -__copyright__ = "Copyright (c) 2021 Cisco and/or its affiliates." -__author__ = "Karthik Babu Harichandra Babu" - -class TestDcnmServiceNodeModule(TestDcnmModule): - - module = dcnm_service_node - - test_data = loadPlaybookData('dcnm_service_node') - - SUCCESS_RETURN_CODE = 200 - - mock_ip_sn = test_data.get('mock_ip_sn') - sn_inv_data = test_data.get('sn_inv_data') - playbook_config = test_data.get('playbook_config') - playbook_config_replace_new = test_data.get('playbook_config_replace_new') - playbook_config_replace_new1 = test_data.get('playbook_config_replace_new1') - playbook_new_config = test_data.get('playbook_new_config') - playbook_config_virtual = test_data.get('playbook_config_virtual') - playbook_config_load = test_data.get('playbook_config_load') - playbook_config_vnf = test_data.get('playbook_config_vnf') - playbook_config_vpc = test_data.get('playbook_config_vpc') - playbook_config_invalid_vpc = test_data.get('playbook_config_invalid_vpc') - playbook_config_no_params = test_data.get('playbook_config_no_params') - playbook_config_no_type = test_data.get('playbook_config_no_type') - playbook_config_no_ff = test_data.get('playbook_config_no_ff') - playbook_config_no_vpc = test_data.get('playbook_config_no_vpc') - playbook_config_more_switch = test_data.get('playbook_config_more_switch') - playbook_config_name = test_data.get('playbook_config_name') - playbook_over_config = test_data.get('playbook_over_config') - playbook_config_query = test_data.get('playbook_config_query') - get_have_failure = test_data.get('get_have_failure') - blank_data = test_data.get('blank_data') - blank_data_null = test_data.get('blank_data_null') - blank_get_data = test_data.get('blank_get_data') - error1 = test_data.get('error1') - sn_delete_success_resp = test_data.get('sn_delete_success_resp') - sn_query_success_resp = test_data.get('sn_query_success_resp') - - def init_data(self): - # Some of the mock data is re-initialized after each test as previous test might have altered portions - # of the mock data. - - self.mock_sn_1_object = copy.deepcopy(self.test_data.get('mock_sn_1_object')) - self.mock_sn_merge_1_success = copy.deepcopy(self.test_data.get('mock_sn_merge_1_success')) - self.mock_sn_merge_2_success = copy.deepcopy(self.test_data.get('mock_sn_merge_2_success')) - self.mock_sn_merge_3_success = copy.deepcopy(self.test_data.get('mock_sn_merge_3_success')) - self.mock_sn_merge_4_success = copy.deepcopy(self.test_data.get('mock_sn_merge_4_success')) - self.mock_sn_merge_5_success = copy.deepcopy(self.test_data.get('mock_sn_merge_5_success')) - self.mock_sn_merge_6_success = copy.deepcopy(self.test_data.get('mock_sn_merge_6_success')) - self.mock_sn_replace_1_success = copy.deepcopy(self.test_data.get('mock_sn_replace_1_success')) - self.mock_sn_replace_2_success = copy.deepcopy(self.test_data.get('mock_sn_replace_2_success')) - self.mock_sn_have_success = copy.deepcopy(self.test_data.get('mock_sn_have_success')) - self.mock_sn_query_success = copy.deepcopy(self.test_data.get('mock_sn_query_success')) - - def setUp(self): - super(TestDcnmServiceNodeModule, self).setUp() - - self.mock_dcnm_ip_sn = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_node.get_fabric_inventory_details') - self.run_dcnm_ip_sn = self.mock_dcnm_ip_sn.start() - - self.mock_dcnm_send = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_node.dcnm_send') - self.run_dcnm_send = self.mock_dcnm_send.start() - - def tearDown(self): - super(TestDcnmServiceNodeModule, self).tearDown() - self.mock_dcnm_send.stop() - self.mock_dcnm_ip_sn.stop() - - def load_fixtures(self, response=None, device=''): - - if 'sn_blank_fabric' in self._testMethodName: - self.run_dcnm_ip_sn.side_effect = [{}] - else: - self.run_dcnm_ip_sn.side_effect = [self.sn_inv_data] - - if 'get_have_failure' in self._testMethodName: - self.run_dcnm_send.side_effect = [self.get_have_failure] - - elif '_check_mode' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_get_data] - - elif '_merged_one' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_1_success] - - elif '_merged_two' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_2_success] - - elif '_merged_three' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_3_success] - - elif '_merged_four' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_4_success] - - elif '_merged_five' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_5_success] - - elif 'error1' in self._testMethodName: - self.run_dcnm_send.side_effect = [self.blank_data, self.error1, self.blank_data] - - elif '_merged_invalid_vpc' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_params' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_type' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_ff' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_more_switch' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_vpc' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif 'delete_std' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.sn_delete_success_resp] - - elif 'delete_all' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.sn_delete_success_resp] - - elif 'query_no' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.sn_query_success_resp] - - elif 'query_on' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success,self.mock_sn_have_success] - - elif 'query_without_config' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success,self.mock_sn_have_success] - - elif 'query_withonly_name' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success,self.mock_sn_have_success] - - elif 'query_invalid_param' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif 'query_null' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data_null] - - elif 'override_with_additions' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_1_success] - - elif 'override_with_deletions' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.sn_delete_success_resp, self.mock_sn_merge_6_success] - - elif 'override_without_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success] - - elif 'replace_with_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.mock_sn_replace_1_success] - - elif 'replace_with_type_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.mock_sn_replace_2_success] - - elif 'replace_without_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success] - - else: - pass - - def test_dcnm_sn_blank_fabric(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric test_fabric missing on DCNM or does not have any switches') - - def test_dcnm_sn_get_have_failure(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric test_fabric not present on DCNM') - - def test_dcnm_sn_check_mode(self): - set_module_args(dict(check_mode=True, state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertFalse(result.get('response')) - - def test_dcnm_sn_merged_one(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_two(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_virtual)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_three(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_load)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'AVB') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_four(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_vnf)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'VNF') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_five(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_vpc)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'vPC1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_error1(self): - set_module_args(dict(state='merged', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result['msg']['RETURN_CODE'], 400) - self.assertEqual(result['msg']['ERROR'], 'There is an error') - - def test_dcnm_sn_merged_invalid_vpc(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_invalid_vpc)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric: test_fabric - if two switches are provided, vpc is only interface option') - - def test_dcnm_sn_merged_more_switch(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_more_switch)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric: test_fabric - Upto 2 switches only allowed') - - def test_dcnm_sn_merged_no_params(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_params)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'config: element is mandatory for this state merged') - - def test_dcnm_sn_merged_no_type(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_type)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Invalid parameters in playbook: karth : Invalid choice provided') - - def test_dcnm_sn_merged_no_ff(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_ff)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Invalid parameters in playbook: babu : Invalid choice provided') - - def test_dcnm_sn_merged_no_vpc(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_vpc)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric: test_fabric - For 1 switch, vpc is not the interface option') - - def test_dcnm_sn_delete_std(self): - set_module_args(dict(state='deleted', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'DELETE') - - def test_dcnm_sn_delete_all(self): - set_module_args(dict(state='deleted', fabric='test_fabric', - service_fabric='external', config=[])) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'DELETE') - - def test_dcnm_sn_query_no(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result.get('response'), []) - - def test_dcnm_sn_query_on(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result['response'][0]['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['fabricName'], 'external') - self.assertEqual(result['response'][0]['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['name'], 'SN-11') - self.assertEqual(result['response'][0]['type'], 'Firewall') - - def test_dcnm_sn_query_without_config(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=[])) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result['response'][0]['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['fabricName'], 'external') - self.assertEqual(result['response'][0]['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['name'], 'SN-11') - self.assertEqual(result['response'][0]['type'], 'Firewall') - - def test_dcnm_sn_query_withonly_name(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_name)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result['response'][0]['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['fabricName'], 'external') - self.assertEqual(result['response'][0]['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['name'], 'SN-11') - self.assertEqual(result['response'][0]['type'], 'Firewall') - - def test_dcnm_sn_query_invalid_param(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_query)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Invalid parameters in playbook: name : Required parameter not found') - - def test_dcnm_sn_query_null(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Unable to Service Node under fabric: test_fabric') - - def test_dcnm_sn_override_with_additions(self): - set_module_args(dict(state='overridden', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_override_with_deletions(self): - set_module_args(dict(state='overridden', fabric='test_fabric', - service_fabric='external', config=self.playbook_new_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'DELETE') - self.assertEqual(result['response'][1]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][1]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/2') - self.assertEqual(result['response'][1]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][1]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][1]['DATA']['interfaceName'], 'scv12') - self.assertEqual(result['response'][1]['DATA']['name'], 'SN-12') - self.assertEqual(result['response'][1]['DATA']['type'], 'ADC') - self.assertEqual(result['response'][1]['RETURN_CODE'], 200) - - def test_dcnm_sn_override_without_changes(self): - set_module_args(dict(state='overridden', fabric='test_fabric', - service_fabric='external', config=self.playbook_over_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertFalse(result.get('response')) - - def test_dcnm_sn_replace_with_changes(self): - set_module_args(dict(state='replaced', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_replace_new)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'PUT') - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv11') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_replace_with_type_changes(self): - set_module_args(dict(state='replaced', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_replace_new1)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'PUT') - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv11') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'ADC') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_replace_without_changes(self): - set_module_args(dict(state='replaced', fabric='test_fabric', - service_fabric='external', config=self.playbook_over_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertFalse(result.get('response')) From acc42d1b56ecafd2e42101c583eb1a877364b299 Mon Sep 17 00:00:00 2001 From: mmudigon <62759545+mmudigon@users.noreply.github.com> Date: Tue, 11 May 2021 19:24:36 +0530 Subject: [PATCH 09/71] Update CHANGELOG.md --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f6c08b97..537a80e93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [1.1.1] - 2021-05 + +### Fixed + +* https://github.com/CiscoDevNet/ansible-dcnm/issues/66 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/65 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/63 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/62 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/60 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/57 + ## [1.1.0] - 2021-04 ### Added @@ -67,5 +78,6 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[1.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.1.0...1.1.1 [1.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.0.0...1.1.0 [1.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/0.9.0...1.0.0 From b4a4042e5814c49f4e2c45b6fc2e534d41ca54f1 Mon Sep 17 00:00:00 2001 From: mmudigon <62759545+mmudigon@users.noreply.github.com> Date: Tue, 11 May 2021 19:27:04 +0530 Subject: [PATCH 10/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d70b8e2b..08fba957a 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 1.1.0 + version: 1.1.1 ``` ## Using this collection From 239d4b3ba764dbc5fba1ea567846ec079139e32a Mon Sep 17 00:00:00 2001 From: Mallik M J Date: Tue, 11 May 2021 19:39:42 +0530 Subject: [PATCH 11/71] Removed unsupported modules --- plugins/modules/dcnm_service_node.py | 748 ---- plugins/modules/dcnm_service_route_peering.py | 3589 ----------------- .../dcnm_service_node/defaults/main.yaml | 2 - .../targets/dcnm_service_node/meta/main.yaml | 1 - .../targets/dcnm_service_node/tasks/dcnm.yaml | 20 - .../targets/dcnm_service_node/tasks/main.yaml | 2 - .../dcnm_service_node/tests/dcnm/deleted.yaml | 344 -- .../dcnm_service_node/tests/dcnm/merged.yaml | 768 ---- .../tests/dcnm/overridden.yaml | 281 -- .../dcnm_service_node/tests/dcnm/query.yaml | 396 -- .../tests/dcnm/replaced.yaml | 421 -- .../defaults/main.yaml | 2 - .../dcnm_service_route_peering/meta/main.yaml | 2 - .../tasks/dcnm.yaml | 105 - .../tasks/main.yaml | 2 - ...dcnm_service_route_peering_delete.yaml.swp | Bin 16384 -> 0 bytes ...m_service_route_peering_adc_po_change.yaml | 453 --- .../dcnm_service_route_peering_checkmode.yaml | 329 -- .../dcnm_service_route_peering_delete.yaml | 370 -- ...nm_service_route_peering_fw_po_change.yaml | 302 -- .../dcnm_service_route_peering_merge.yaml | 356 -- ..._service_route_peering_merge_existing.yaml | 878 ---- ...nm_service_route_peering_no_opt_elems.yaml | 257 -- .../dcnm_service_route_peering_no_state.yaml | 354 -- .../dcnm_service_route_peering_override.yaml | 945 ----- .../dcnm_service_route_peering_query.yaml | 426 -- .../dcnm_service_route_peering_replace.yaml | 883 ---- .../tasks/main.yaml | 184 - .../dcnm/fixtures/dcnm_service_node.json | 612 --- .../dcnm/fixtures/dcnm_srp_configs.json | 1672 -------- .../dcnm/fixtures/dcnm_srp_payloads.json | 3084 -------------- .../modules/dcnm/test_dcnm_service_node.py | 499 --- .../dcnm/test_dcnm_service_route_peering.py | 1839 --------- 33 files changed, 20126 deletions(-) delete mode 100644 plugins/modules/dcnm_service_node.py delete mode 100644 plugins/modules/dcnm_service_route_peering.py delete mode 100644 tests/integration/targets/dcnm_service_node/defaults/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/meta/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tasks/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/defaults/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/meta/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tasks/dcnm.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tasks/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/.dcnm_service_route_peering_delete.yaml.swp delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_adc_po_change.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_checkmode.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_delete.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_fw_po_change.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_merge.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_merge_existing.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_no_opt_elems.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_no_state.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_override.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_query.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_replace.yaml delete mode 100644 tests/integration/targets/prepare_dcnm_service_route_peering/tasks/main.yaml delete mode 100644 tests/unit/modules/dcnm/fixtures/dcnm_service_node.json delete mode 100644 tests/unit/modules/dcnm/fixtures/dcnm_srp_configs.json delete mode 100644 tests/unit/modules/dcnm/fixtures/dcnm_srp_payloads.json delete mode 100644 tests/unit/modules/dcnm/test_dcnm_service_node.py delete mode 100644 tests/unit/modules/dcnm/test_dcnm_service_route_peering.py diff --git a/plugins/modules/dcnm_service_node.py b/plugins/modules/dcnm_service_node.py deleted file mode 100644 index b6a184277..000000000 --- a/plugins/modules/dcnm_service_node.py +++ /dev/null @@ -1,748 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2021 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import time -import copy -import re -from ansible_collections.cisco.dcnm.plugins.module_utils.network.dcnm.dcnm import get_fabric_inventory_details, \ - dcnm_send, validate_list_of_dicts, dcnm_get_ip_addr_info, get_ip_sn_dict -from ansible.module_utils.basic import AnsibleModule - -__author__ = "Karthik Babu Harichandra Babu" - -DOCUMENTATION = ''' ---- -module: dcnm_service_node -short_description: Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric. -version_added: "0.9.0" -description: - - "Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric." -author: Karthik Babu Harichandra Babu -options: - fabric: - description: - - 'Name of attached easy fabric to which service node is attached' - type: str - required: yes - service_fabric: - description: - - 'Name of external fabric where the service node is located' - type: str - required: yes - state: - description: - - The state of DCNM after module completion. - type: str - choices: - - merged - - replaced - - overridden - - deleted - - query - default: merged - - config: - description: 'List of details of service nodes being managed' - type: list - elements: dict - required: true - note: Not required for state deleted - suboptions: - name: - description: 'Name of service node' - type: str - required: true - type: - description: 'Name of the service node type' - type: str - required: true - default: 'firewall' - form_factor: - description: 'Name of the form factor of the service node' - type: str - required: true - default: 'physical' - svc_int_name: - description: 'Name of the service interface' - type: str - required: true - switches: - description: 'IP address of the switch where service node will be added/deleted' - type: list - required: true - attach_interface: - description: 'List of switch interfaces where the service node will be attached' - type: str - required: true -''' - -EXAMPLES = ''' -This module supports the following states: - -Merged: - Service Nodes defined in the playbook will be merged into the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Service Nodes that are not specified in the playbook will be untouched. - -Replaced: - Service Nodes defined in the playbook will be replaced in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be untouched. - -Overridden: - Service Node defined in the playbook will be overridden in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be deleted. - -Deleted: - Service Node defined in the playbook will be deleted. - If no Service Nodes are provided in the playbook, all service node present on that DCNM fabric will be deleted. - -Query: - Returns the current DCNM state for the service node listed in the playbook. - -- name: Merge Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - -- name: Replace Service Nodes form factor/type parameter - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: replaced - config: - - name: SN-11 - type: firewall - # Replace can only modify the form factor - # form_factor: virtual # the virtual will be changed to new physical - # form_factor: physical - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Nothing will be replaced in the below service node as there is no change - # Dont touch this if its present on DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - -- name: Override Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: overridden - config: - # Create this service node - - name: SN-13 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-11 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: Ethernet1/1 - # switches: - # - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - -- name: Delete selected Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - -- name: Delete all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - -- name: Query Service Nodes state for SN-11 and SN-12 - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - -- name: Query all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query -''' - - -class DcnmServiceNode: - - def __init__(self, module): - self.module = module - self.params = module.params - self.fabric = module.params['fabric'] - self.service_fabric = module.params['service_fabric'] - self.config = copy.deepcopy(module.params.get('config')) - self.check_mode = False - self.have_create = [] - self.want_create = [] - self.diff_create = [] - self.diff_replace = [] - self.diff_delete = {} - self.query = [] - self.validated = [] - self.inventory_data = get_fabric_inventory_details(self.module, self.fabric) - self.ip_sn, self.hn_sn = get_ip_sn_dict(self.inventory_data) - - self.result = dict( - changed=False, - diff=[], - response=[], - warnings=[] - ) - - self.failed_to_rollback = False - self.WAIT_TIME_FOR_DELETE_LOOP = 5 # in seconds - - def update_create_params(self, snode): - - if not snode: - return snode - - state = self.params['state'] - - if state == 'query': - snode_upd = { - "name": snode['name'] - } - else: - - serial = [] - for sw in snode['switches']: - sw = dcnm_get_ip_addr_info(self.module, sw, None, None) - for ip, ser in self.ip_sn.items(): - if ip == sw: - serial.append(ser) - - if not serial: - self.module.fail_json(msg='Fabric: {} does not have the switch: {}' - .format(self.fabric, snode['switches'])) - - switchsn = "" - if len(snode['switches']) == 2: - switchsn = str(serial[0]) + "," + str(serial[1]) - if 'vPC' not in snode['attach_interface']: - self.module.fail_json(msg='Fabric: {} - if two switches are provided, vpc is only interface option' - .format(self.fabric)) - elif len(snode['switches']) == 1: - switchsn = str(serial[0]) - if 'vPC' in snode['attach_interface']: - self.module.fail_json(msg='Fabric: {} - For 1 switch, vpc is not the interface option' - .format(self.fabric)) - else: - self.module.fail_json(msg='Fabric: {} - Upto 2 switches only allowed' - .format(self.fabric)) - - if snode['type'] == 'firewall': - s_type = snode['type'].title() - elif snode['type'] == 'load_balancer': - s_type = 'ADC' - elif snode['type'] == 'virtual_network_function': - s_type = 'VNF' - - snode_upd = { - "name": snode['name'], - "type": s_type, - "formFactor": snode['form_factor'].title(), - "fabricName": self.service_fabric, - "interfaceName": snode['svc_int_name'], - "attachedSwitchSn": switchsn, - "attachedSwitchInterfaceName": snode['attach_interface'], - "linkTemplateName": "service_link_trunk", - "nvPairs": { - "MTU": "jumbo", - "SPEED": "Auto", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "PORTTYPE_FAST_ENABLED": "true", - "ADMIN_STATE": "true" - }, - "attachedFabricName": self.fabric - } - - return snode_upd - - def get_have(self): - - method = 'GET' - path = '/appcenter/Cisco/elasticservice/elasticservice-api/?attached-fabric={}'.format(self.fabric) - - snode_objects = dcnm_send(self.module, method, path) - missing_fabric, not_ok = self.handle_response(snode_objects, 'query_dcnm') - - if missing_fabric or not_ok: - msg1 = "Fabric {} not present on DCNM".format(self.fabric) - msg2 = "Unable to Service Node under fabric: {}".format(self.fabric) - - self.module.fail_json(msg=msg1 if missing_fabric else msg2) - return - - if not snode_objects['DATA']: - return - - have_switch = [] - for snode in snode_objects['DATA']: - get_snode = {} - get_snode.update({'name': snode['name']}) - get_snode.update({'formFactor': snode['formFactor']}) - get_snode.update({'interfaceName': snode['interfaceName']}) - get_snode.update({'type': snode['type']}) - get_snode.update({'attachedFabricName': snode['attachedFabricName']}) - get_snode.update({'attachedSwitchInterfaceName': snode['attachedSwitchInterfaceName']}) - get_snode.update({'attachedSwitchSn': snode['attachedSwitchSn']}) - get_snode.update({'fabricName': snode['fabricName']}) - have_switch.append(get_snode) - - self.have_create = have_switch - - def get_want(self): - - want_create = [] - - if not self.config: - return - - for snode in self.validated: - want_create.append(self.update_create_params(snode)) - - self.want_create = want_create - - def get_diff_delete(self): - - diff_delete = [] - - if self.config: - for want_c in self.want_create: - for have_c in self.have_create: - if (have_c['name'] == want_c['name']): - diff_delete.append(have_c['name']) - continue - - else: - for have_c in self.have_create: - diff_delete.append(have_c['name']) - - self.diff_delete = diff_delete - - def get_diff_override(self): - - self.get_diff_replace() - self.get_diff_replace_delete() - - diff_create = self.diff_create - diff_delete = self.diff_delete - - self.diff_create = diff_create - self.diff_delete = diff_delete - self.diff_replace = [] - - def get_diff_replace(self): - - self.get_diff_merge() - diff_replace = self.diff_create - - self.diff_replace = diff_replace - - found = False - for replace_c in self.diff_replace: - for have_c in self.have_create: - if have_c['name'] == replace_c['name'] : - found = True - - if not found: - self.diff_replace = [] - else: - self.diff_create = [] - - def get_diff_replace_delete(self): - - diff_delete = [] - - for have_c in self.have_create: - match_found = False - for want_c in self.want_create: - if want_c['name'] == have_c['name']: - if want_c['type'] == have_c['type'] and want_c['attachedFabricName'] == have_c['attachedFabricName'] \ - and want_c['fabricName'] == have_c['fabricName'] and \ - want_c['attachedSwitchInterfaceName'] == have_c['attachedSwitchInterfaceName'] and \ - want_c['attachedSwitchSn'] == have_c['attachedSwitchSn'] and \ - want_c['interfaceName'] == have_c['interfaceName']: - match_found = True - if match_found: - continue - else: - diff_delete.append(have_c['name']) - - self.diff_delete = diff_delete - - def get_diff_merge(self, replace=False): - - diff_create = [] - - for want_c in self.want_create: - found = False - for have_c in self.have_create: - if want_c['name'] == have_c['name'] and want_c['type'] == have_c['type'] and \ - want_c['attachedFabricName'] == have_c['attachedFabricName'] and want_c['fabricName'] == have_c[ - 'fabricName'] and \ - want_c['attachedSwitchInterfaceName'] == have_c['attachedSwitchInterfaceName'] and \ - want_c['attachedSwitchSn'] == have_c['attachedSwitchSn'] and \ - want_c['interfaceName'] == have_c['interfaceName'] and \ - want_c['formFactor'] == have_c['formFactor']: - found = True - if not found: - diff_create.append(want_c) - - self.diff_create = diff_create - - def get_diff_query(self): - - query = [] - method = 'GET' - path = '/appcenter/Cisco/elasticservice/elasticservice-api/?attached-fabric={}'.format(self.fabric) - - snode_objects = dcnm_send(self.module, method, path) - - missing_fabric, not_ok = self.handle_response(snode_objects, 'query_dcnm') - - if missing_fabric or not_ok: - msg1 = "Fabric {} not present on DCNM".format(self.fabric) - msg2 = "Unable to find Service Node under fabric: {}".format(self.fabric) - - self.module.fail_json(msg=msg1 if missing_fabric else msg2) - return - - if not snode_objects['DATA']: - return - - if self.config: - for want_c in self.want_create: - for snode in snode_objects['DATA']: - if want_c['name'] == snode['name']: - query.append(snode) - continue - else: - for snode in snode_objects['DATA']: - query.append(snode) - - self.query = query - - def push_to_remote(self, is_rollback=False): - - method = 'DELETE' - if self.diff_delete: - for name in self.diff_delete: - delete_path = '/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/{}/service-nodes/{}'.format( - self.service_fabric, name) - resp = dcnm_send(self.module, method, delete_path) - - self.result['response'].append(resp) - fail, self.result['changed'] = self.handle_response(resp, "delete") - - if fail: - if is_rollback: - self.failed_to_rollback = True - return - self.failure(resp) - - method = 'POST' - if self.diff_create: - for create in self.diff_create: - deploy_path = '/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/{}/service-nodes'.format( - self.service_fabric) - resp = dcnm_send(self.module, method, deploy_path, json.dumps(create)) - self.result['response'].append(resp) - fail, self.result['changed'] = self.handle_response(resp, "create") - - if fail: - if is_rollback: - self.failed_to_rollback = True - return - self.failure(resp) - - method = 'PUT' - if self.diff_replace: - for replace in self.diff_replace: - replace_path = '/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/{}/service-nodes/{}'.format( - self.service_fabric, replace['name']) - resp = dcnm_send(self.module, method, replace_path, json.dumps(replace)) - - self.result['response'].append(resp) - fail, self.result['changed'] = self.handle_response(resp, "create") - - if fail: - if is_rollback: - self.failed_to_rollback = True - return - self.failure(resp) - - def validate_input(self): - - """Parse the playbook values, validate to param specs.""" - - state = self.params['state'] - - if state == 'query': - - snode_spec = dict( - name=dict(required=True, type='str', length_max=64), - ) - - if self.config: - # Validate service node params - valid_snode, invalid_params = validate_list_of_dicts(self.config, snode_spec) - for snode in valid_snode: - self.validated.append(snode) - - if invalid_params: - msg = 'Invalid parameters in playbook: {}'.format('\n'.join(invalid_params)) - self.module.fail_json(msg=msg) - - else: - - snode_spec = dict( - name=dict(required=True, type='str', length_max=64), - type=dict(required=True, type='str', - choices=['firewall', 'load_balancer', 'virtual_network_function'], - default='firewall'), - form_factor=dict(required=True, type='str', - choices=['physical', 'virtual'], - default='physical'), - svc_int_name=dict(required=True, type='str', length_max=64), - switches=dict(required=True, type='list'), - attach_interface=dict(required=True, type='str'), - ) - - if self.config: - msg = None - # Validate service node params - valid_snode, invalid_params = validate_list_of_dicts(self.config, snode_spec) - for snode in valid_snode: - self.validated.append(snode) - - if invalid_params: - msg = 'Invalid parameters in playbook: {}'.format('\n'.join(invalid_params)) - self.module.fail_json(msg=msg) - - else: - state = self.params['state'] - msg = None - - if state == 'merged' or state == 'overridden' or \ - state == 'replaced': - msg = "config: element is mandatory for this state {}".format(state) - - if msg: - self.module.fail_json(msg=msg) - - def handle_response(self, resp, op): - - fail = False - changed = True - - res = resp.copy() - - if op == 'query_dcnm': - # This if blocks handles responses to the query APIs against DCNM. - # Basically all GET operations. - # - if res.get('ERROR') == 'Not Found' and res['RETURN_CODE'] == 404: - return True, False - if res['RETURN_CODE'] != 200 or res['MESSAGE'] != "": - return False, True - return False, False - - # Responses to all other operations POST and PUT are handled here. - if res.get('MESSAGE') != "" or res.get('RETURN_CODE') != 200: - fail = True - changed = False - return fail, changed - - return fail, changed - - def failure(self, resp): - - # Implementing a per task rollback logic here so that we rollback DCNM to the have state - # whenever there is a failure in any of the APIs. - # The idea would be to run overridden state with want=have and have=dcnm_state - self.want_create = self.have_create - self.have_create = [] - self.get_have() - self.get_diff_override() - - self.push_to_remote(True) - - if self.failed_to_rollback: - msg1 = "FAILED - Attempted rollback of the task has failed, may need manual intervention" - else: - msg1 = 'SUCCESS - Attempted rollback of the task has succeeded' - - res = copy.deepcopy(resp) - res.update({'ROLLBACK_RESULT': msg1}) - - if not resp.get('DATA'): - data = copy.deepcopy(resp.get('DATA')) - if data.get('stackTrace'): - data.update({'stackTrace': 'Stack trace is hidden, use \'-vvvvv\' to print it'}) - res.update({'DATA': data}) - - if self.module._verbosity >= 5: - self.module.fail_json(msg=res) - - self.module.fail_json(msg=res) - -def main(): - """ main entry point for module execution - """ - - element_spec = dict( - fabric=dict(required=True, type='str'), - service_fabric=dict(required=True, type='str'), - config=dict(required=False, type='list'), - state=dict(default='merged', - choices=['merged', 'replaced', 'deleted', 'overridden', 'query']), - check_mode=dict(required=False, type="bool", default=False) - ) - - module = AnsibleModule(argument_spec=element_spec, - supports_check_mode=True) - - dcnm_snode = DcnmServiceNode(module) - - if not dcnm_snode.ip_sn: - module.fail_json(msg="Fabric {} missing on DCNM or does not have any switches".format(dcnm_snode.fabric)) - - dcnm_snode.validate_input() - - dcnm_snode.get_want() - dcnm_snode.get_have() - - if module.params['state'] == 'merged': - dcnm_snode.get_diff_merge() - - if module.params['state'] == 'replaced': - dcnm_snode.get_diff_replace() - - if module.params['state'] == 'overridden': - dcnm_snode.get_diff_override() - - if module.params['state'] == 'deleted': - dcnm_snode.get_diff_delete() - # - if module.params['state'] == 'query': - dcnm_snode.get_diff_query() - dcnm_snode.result['response'] = dcnm_snode.query - - if module.params['check_mode']: - dcnm_snode.result['changed'] = False - module.exit_json(**dcnm_snode.result) - - if dcnm_snode.diff_create or dcnm_snode.diff_delete or dcnm_snode.diff_replace: - dcnm_snode.result['changed'] = True - else: - module.exit_json(**dcnm_snode.result) - - dcnm_snode.push_to_remote() - - module.exit_json(**dcnm_snode.result) - -if __name__ == '__main__': - main() diff --git a/plugins/modules/dcnm_service_route_peering.py b/plugins/modules/dcnm_service_route_peering.py deleted file mode 100644 index 49625216a..000000000 --- a/plugins/modules/dcnm_service_route_peering.py +++ /dev/null @@ -1,3589 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2021 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -__author__ = "Mallik Mudigonda" - -DOCUMENTATION = """ ---- -module: dcnm_service_route_peering -short_description: DCNM Ansible Module for managing Service Route Peerings. -version_added: "1.1.0" -description: - - DCNM Ansible Module for Creating, Deleting, Querying and Modifying Route Peerings -author: Mallik Mudigonda -options: - fabric: - description: - - 'Name of the target fabric for route peering operations' - type: str - required: true - service_fabric: - description: - - 'Name of the external fabric attached to the service node for route peering operations' - type: str - required: true - state: - description: - - The required state of the configuration after module completion. - type: str - required: false - choices: - - merged - - replaced - - overridden - - deleted - - query - default: merged - attach: - description: - - A flag specifying if the given route peering is to be attached to the specified service node - type: bool - required: false - default: true - deploy: - description: - - A flag specifying if a route peering is to be deployed on the switches - type: bool - required: false - default: true - config: - description: - - A list of dictionaries containing route peering and switch information - type: list - elements: dict - suboptions: - name: - description: - - A unique name which identifies the route peering - type: str - required: true - node_name: - description: - - Name of the service node where the route peering is to be deployed - type: str - required: true - deploy_mode: - description: - - Type of service node. - type: str - required: true - choices: ['intra_tenant_fw', 'inter_tenant_fw', 'one_arm_adc', 'two_arm_adc'] - peering_option: - description: - - Specifies the type of peering - NOTE: This object is applicable only when 'deploy_mode' is either 'inter_tenant_fw' - or 'one_arm_adc' or 'two_arm_adc' - type: str - required: False - default: 'static' - choices: ['static', 'ebgp'] - next_hop: - description: - - Nexthop IPV4 information, e.g., 192.168.1.100 - NOTE: This object is applicable only when 'deploy_mode' is 'intra_tenant_fw' - type: int - required: true - rev_next_hop: - description: - - Reverse Nexthop IPV4 information, e.g., 192.169.1.100 - NOTE: This object is applicable only when 'deploy_mode' is either 'intra_tenant_fw' - or 'one_arm_adc' or 'two_arm_adc' - type: int - required: false - default: "" - inside_network: - description: - - Details regarding inside network of the route peering - - NOTE: This object is applicable only when 'deploy_mode' is 'intra_tenant_fw' - or 'inter_tenant_fw' - type: dict - required: true - suboptions: - vrf: - description: - - VRF name for the inside network - type: str - required: true - name: - description: - - Network name - type: str - required: true - vlan_id: - description: - - Vlan Id for the inside network - type: int - required: true - profile: - description: - - Profile information for the inside network - type: dict - required: true - suboptions: - ipv4_gw: - description: - - IPV4 gateway information including the mask e.g. 192.168.1.1/24 - type: ipv4 - required: true - ipv6_gw: - description: - - IPV6 gateway information including the mask e.g., 2000:01:01::01/64 - type: ipv6 - required: false - default: "" - vlan_name: - description: - - Vlan name - type: str - required: false - default: "" - int_descr: - description: - - Description of the interface - type: str - required: false - default: "" - tag: - description: - - Route tag information - type: int - required: false - default: 12345 - static_route: - description: - - Static route information - - NOTE: This object is applicable only when 'peering_option' is 'static' - type: list - elements: dict - required: false - default: '' - suboptions: - subnet: - description: - - Subnet information, for e.g., 11.0.0.0/24 - type: ipv4 - required: True - next_hop: - description: - - Gateway IP addresses, for e.g., 192.168.1.1 - type: list - elements: ipv4 - required: True - ipv4_neighobor: - description: - - IPv4 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_lo: - - IPv4 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_vpc_peer_lo: - - IPv4 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp'. This - object will be mandatory if the service node switch is part of VPC - pair - type: ipv4 - required: False - default: '' - ipv6_neighobor: - - IPv6 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_lo: - - IPv6 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_vpc_peer_lo: - - IPv6 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp'. This - object will be mandatory if the service node switch is part of VPC - pair - type: ipv6 - required: False - default: '' - route_map_tag: - - Route Tag - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: True - default: 12345 - neigh_int_descr: - - Description of the interface - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: str - required: False - default: '' - local_asn: - - Local ASN number - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: False - default: 12345 - adv_host: - - Flag indicating if the host is to be advertised - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: bool - required: False - default: True - outside_network: - description: - - Details regarding outside network of the route peering - - NOTE: This object is applicable only when 'deploy_mode' is 'intra_tenant_fw' - or 'inter_tenant_fw' - type: dict - required: true - suboptions: - vrf: - description: - - VRF name for the outside network - type: str - required: true - name: - description: - - Network name - type: str - required: true - vlan_id: - description: - - Vlan Id for the outside network - type: int - required: true - profile: - description: - - Profile information for the outside network - type: dict - required: true - suboptions: - ipv4_gw: - description: - - IPV4 gateway information including the mask e.g. 192.168.1.1/24 - type: ipv4 - required: true - ipv6_gw: - description: - - IPV6 gateway information including the mask e.g., 2000:01:01::01/64 - type: ipv6 - required: false - default: "" - vlan_name: - description: - - Vlan name - type: str - required: false - default: "" - int_descr: - description: - - Description of the interface - type: str - required: false - default: "" - tag: - description: - - Route tag information - type: int - required: false - default: 12345 - static_route: - description: - - Static route information - - NOTE: This object is applicable only when 'peering_option' is 'static' and - 'deploy_mode' is 'intra_tenant_fw' - type: list - elements: dict - required: false - default: '' - suboptions: - subnet: - description: - - Subnet information, for e.g., 11.0.0.0/24 - type: ipv4 - required: True - next_hop: - description: - - Gateway IP addresses, for e.g., 192.168.1.1 - type: list - elements: ipv4 - required: True - ipv4_neighobor: - description: - - IPv4 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_lo: - description: - - IPv4 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_vpc_peer_lo: - description: - - IPv4 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: False - default: '' - ipv6_neighobor: - description: - - IPv6 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_lo: - description: - - IPv6 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_vpc_peer_lo: - description: - - IPv6 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - route_map_tag: - description: - - Route Tag - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: True - default: 12345 - neigh_int_descr: - description: - - Description of the interface - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: str - required: False - default: '' - local_asn: - description: - - Local ASN number - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: False - default: 12345 - adv_host: - description: - - Flag indicating if the host is to be advertised - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: bool - required: False - default: true - first_arm: - description: - - Details regarding firast arm of the route peering - - NOTE: This object is applicable only when 'deploy_mode' is either - 'one_arm_adc' or 'two_arm_adc' - type: dict - required: true - suboptions: - vrf: - description: - - VRF name for the first arm - type: str - required: true - name: - description: - - Network name - type: str - required: true - vlan_id: - description: - - Vlan Id for the first arm - type: int - required: true - profile: - description: - - Profile information for the first arm - type: dict - required: true - suboptions: - ipv4_gw: - description: - - IPV4 gateway information including the mask e.g. 192.168.1.1/24 - type: ipv4 - required: true - ipv6_gw: - description: - - IPV6 gateway information including the mask e.g., 2000:01:01::01/64 - type: ipv6 - required: false - default: "" - vlan_name: - description: - - Vlan name - type: str - required: false - default: "" - int_descr: - description: - - Description of the interface - type: str - required: false - default: "" - tag: - description: - - Route tag information - type: int - required: false - default: 12345 - static_route: - description: - - Static route information - - NOTE: This object is applicable only when 'peering_option' is 'static' - type: list - elements: dict - required: false - default: '' - suboptions: - subnet: - description: - - Subnet information, for e.g., 11.0.0.0/24 - type: ipv4 - required: True - next_hop: - description: - - Gateway IP addresses, for e.g., 192.168.1.1 - type: list - elements: ipv4 - required: True - ipv4_neighobor: - description: - - IPv4 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_lo: - description: - - IPv4 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_vpc_peer_lo: - description: - - IPv4 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: False - default: '' - ipv6_neighobor: - description: - - IPv6 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_lo: - description: - - IPv6 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_vpc_peer_lo: - description: - - IPv6 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - route_map_tag: - description: - - Route Tag - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: True - default: 12345 - neigh_int_descr: lb-two-arm - description: - - Description of the interface - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: str - required: False - default: '' - local_asn: 65101 - description: - - Local ASN number - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: False - default: 12345 - adv_host: true - description: - - Flag indicating if the host is to be advertised - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: bool - required: False - default: True - second_arm: - description: - - Details regarding second arm of the route peering - - NOTE: This object is applicable only when 'deploy_mode' is either - 'one_arm_adc' or 'two_arm_adc' - type: dict - required: true - suboptions: - vrf: - description: - - VRF name for the second arm - type: str - required: true - name: - description: - - Network name - type: str - required: true - vlan_id: - description: - - Vlan Id for the second arm - type: int - required: true - profile: - description: - - Profile information for the second arm - type: dict - required: true - suboptions: - ipv4_gw: - description: - - IPV4 gateway information including the mask e.g. 192.168.1.1/24 - type: ipv4 - required: true - ipv6_gw: - description: - - IPV6 gateway information including the mask e.g., 2000:01:01::01/64 - type: ipv6 - required: false - default: "" - vlan_name: - description: - - Vlan name - type: str - required: false - default: "" - int_descr: - description: - - Description of the interface - type: str - required: false - default: "" - tag: - description: - - Route tag information - type: int - required: false - default: 12345 -""" - -EXAMPLES = """ - -States: -This module supports the following states: - -Merged: - Route Peerings defined in the playbook will be merged into the target fabric. - - If the Route Peerings does not exist it will be added. - - If the Route Peerings exists but properties managed by the playbook are different - they will be updated if possible. - - Route peerings that are not specified in the playbook will be untouched. - -Replaced: - Route Peerings defined in the playbook will be replaced in the target fabric. - - If the Route Peerings does not exist it will be added. - - If the Route Peerings exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Route Peerings that are not specified in the playbook will be untouched. - -Overridden: - Route Peerings defined in the playbook will be overridden in the target fabric. - - If the Route Peerings does not exist it will be added. - - If the Route Peerings exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Roue Peerings that are not specified in the playbook will be deleted. - -Deleted: - Route Peerings defined in the playbook will be deleted. - -Query: - Returns the current DCNM state for the route peerings listed in the playbook. - -CREATING ROUTE PEERINGS -======================= - -INTRA-TENANT FIREWALL - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP1 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: IT-VRF-11 # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 101 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2001:db01::1/64 # optional, default is '' - vlan_name: rp1-sn1-inside # optional, default is '' - int_descr: "RP1 SN1 inside interface" # optional, default is '' - tag: 11111 # optional, default is 12345 - next_hop: 192.161.1.100 # mandatory - outside_network: # - vrf: IT-VRF-11 # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 102 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2001:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside # optional, default is '' - int_descr: "RP1 SN1 outside interface" # optionL, default is '' - tag: 11112 # optional, default is 12345 - rev_next_hop: 192.161.2.100 # optional, default is '' - attach: true - deploy: true - -INTER-TENANT FIREWALL with STATIC peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP2 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: static # optional, default is static, choices=[static, ebgp] - inside_network: # - vrf: IT-VRF-21 # mandatory - name: rp2-sn1-inside-net # mandatory - vlan_id: 201 # mandatory - profile: - ipv4_gw: 192.162.1.1/24 # mandatory - ipv6_gw: 2002:db01::1/64 # optional, default is '' - vlan_name: rp2-sn1-inside # optional, default is '' - int_descr: "RP2 SN1 inside interface" # optional, default is '' - static_route: # optional, default is '' - - subnet: 20.20.20.0/24 - next_hop: - - 120.120.120.100 - - 121.121.121.100 - tag: 21111 # optional, default is 12345 - outside_network: # - vrf: IT-VRF-22 # mandatory - name: rp2-sn1-outside-net # mandatory - vlan_id: 202 # mandatory - profile: - ipv4_gw: 192.162.2.1/24 # mandatory - ipv6_gw: 2002:db02::1/64 # optional, default is '' - vlan_name: rp2-sn1-outside # optional, default is '' - int_descr: "RP2 SN1 outside interface" # optional, default is '' - static_route: # optional, default is '' - - subnet: 21.21.21.0/24 - next_hop: - - 122.122.122.100 - - 123.123.123.100 - tag: 22222 # optional, default is 12345 - attach: true - deploy: true - -INTER-TENANT FIREWALL with EBGP peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP3 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - inside_network: - vrf: IT-VRF-31 # mandatory - name: rp3-sn1-inside-net # mandatory - vlan_id: 301 # mandatory - profile: - ipv4_gw: 192.163.1.1/24 # mandatory - ipv6_gw: 2003:db01::1/64 # optional, default is '' - vlan_name: rp3-sn1-inside # optional, default is '' - int_descr: "RP3 SN1 inside interface" # optional, default is '' - tag: 31111 # optional, default is 12345 - ipv4_neighbor: 31.31.31.1 # mandatory - ipv4_lo: 31.31.31.2 # mandatory - ipv4_vpc_peer_lo: 31.31.31.3 # optional, default is '' - ipv6_neighbor: 2003:3131::1 # optional, default is '' - ipv6_lo: 2003:3132::1 # optional, default is '' - ipv6_vpc_peer_lo: 2003:3133::1 # optional, default is '' - route_map_tag: 33111 # optional, default is 12345 ???? - neigh_int_descr: "RP3 SN1 inside interface" # optional, default is '' ???? - local_asn: 65301 # optional, default is '' - adv_host: true # optional, default is false - outside_network: - vrf: IT-VRF-32 # mandatory - name: rp3-sn1-outside-net # mandatory - vlan_id: 302 # mandatory - profile: - ipv4_gw: 192.163.2.1/24 # mandatory - ipv6_gw: 2003:db02::1/64 # optional, default is '' - vlan_name: rp3-sn1-outside # optional, default is '' - int_descr: "RP3 SN1 outside interface" # optional, default is '' - tag: 31112 # optional, default is 12345 - ipv4_neighbor: 131.131.131.1 # mandatory - ipv4_lo: 131.131.131.2 # mandatory - ipv4_vpc_peer_lo: 131.131.131.3 # optional, default is '' - ipv6_neighbor: 2003:8383::1 # optional, default is '' - ipv6_lo: 2003:8384::1:100:1 # optional, default is '' - ipv6_vpc_peer_lo: 2003:8385::1 # optional, default is '' - route_map_tag: 31113 # optional, default is 12345 ???? - neigh_int_descr: "RP3 SN1 outside interface" # optional, default is '' ???? - local_asn: 65302 # optional, default is '' - adv_host: true # optional, default is false - attach: true - deploy: true - -ONEARM ADC with EBGP peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-ADC-RP4 - node_name: IT-SN-2 # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: IT-VRF-41 # mandatory - name: rp4-sn2-first-arm # mandatory - vlan_id: 401 # mandatory - profile: - ipv4_gw: 192.164.1.1/24 # mandatory - ipv6_gw: 2004:db01::1/64 # optional, default is '' - vlan_name: rp4-sn2-first-arm # optional, default is '' - int_descr: "RP4 SN2 first arm intf" # optional, default is '' - tag: 41111 # optional, default is 12345 - ipv4_neighbor: 41.41.41.1 # mandatory - ipv4_lo: 41.41.41.2 # mandatory - ipv4_vpc_peer_lo: 41.41.41.3 # optional, default is '' - ipv6_neighbor: 2004:4141::1 # optional, default is '' - ipv6_lo: 2004:4142::1 # optional, default is '' - ipv6_vpc_peer_lo: 2004:4143::1 # optional, default is '' - route_map_tag: 41112 # optional, default is 12345 - neigh_int_descr: "RP4 SN2 first arm" # optional, default is '' - local_asn: 65401 # optional, default is '' - adv_host: true # optional, default is false - rev_next_hop: 192.164.1.100 # mandatory - attach: true - deploy: true - -TWOARM ADC with EBGP peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-ADC-RP5 - node_name: IT-SN-2 # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: IT-VRF-51 " # mandatory - name: rp5-sn2-first-arm # mandatory - vlan_id: 501 # mandatory - profile: - ipv4_gw: 192.165.1.1/24 # mandatory - ipv6_gw: 2005:db01::1/64 # optional, default is '' - vlan_name: rp5-sn2-first-arm # optional, default is '' - int_descr: "RP5 SN2 first arm intf" # optional, default is '' - tag: 51111 # optional, default is 12345 - ipv4_neighbor: 51.51.51.1 # mandatory - ipv4_lo: 51.51.51.2 # mandatory - ipv4_vpc_peer_lo: 51.51.51.3 # optional, default is '' - ipv6_neighbor: 2005:5151::1 # optional, default is '' - ipv6_lo: 2005:5152::1 # optional, default is '' - ipv6_vpc_peer_lo: 2005:5153::1 # optional, default is '' - route_map_tag: 51115 # optional, default is 12345 - neigh_int_descr: "RP5 SN2 first arm" # optional, default is '' - local_asn: 65501 # optional, default is '' - adv_host: true # optional, default is false - second_arm: - vrf: IT-VRF-52 " # mandatory - name: rp5-sn2-second-arm # mandatory - vlan_id: 502 # mandatory - profile: - ipv4_gw: 192.165.2.1/24 # mandatory - ipv6_gw: 2005:db02::1/64 # optional, default is '' - vlan_name: rp5-sn2-second-arm # optional, default is '' - int_descr: "RP5 SN2 second arm intf" # optional, default is '' - tag: 51112 # optional, default is 12345 - rev_next_hop: 192.165.1.100 # mandatory - attach: true - deploy: true - -ONEARM ADC with STATIC peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-ADC-RP6 - node_name: IT-SN-2 # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: IT-VRF-61 # mandatory - name: rp6-sn2-first-arm # mandatory - vlan_id: 601 # mandatory - profile: - ipv4_gw: 192.166.1.1/24 # mandatory - ipv6_gw: 2006:db01::1/64 # optional, default is '' - vlan_name: rp6-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 61111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 61.61.61.1/24 - next_hop: - - 161.161.161.1 - - 162.162.162.1 - - subnet: 22.0.0.0/24 - next_hop: - - 163.163.163.1 - - 164.164.164.1 - rev_next_hop: 192.166.1.100 # mandatory - attach: true - deploy: true - -TWOARM ADC with STATIC peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-ADC-RP7 - node_name: IT-SN-2 # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: IT-VRF-71 # mandatory - name: rp7-sn2-first-arm # mandatory - vlan_id: 701 # mandatory - profile: - ipv4_gw: 192.167.1.1/24 # mandatory - ipv6_gw: 2007:db01::1/64 # optional, default is '' - vlan_name: rp7-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 71111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 71.71.71.1/24 - next_hop: - - 171.171.171.1 - - 172.172.172.1 - second_arm: - vrf: IT-VRF-72 # mandatory - name: rp7-sn2-second-arm # mandatory - vlan_id: 702 # mandatory - profile: - ipv4_gw: 192.167.2.1/24 # mandatory - ipv6_gw: 2007:db02::1/64 # optional, default is '' - vlan_name: rp7-sn2-second-arm # optional, default is '' - int_descr: "RP7 SN2 second arm intf" # optional, default is '' - tag: 71112 # optional, default is 12345 - rev_next_hop: 192.167.1.100 # mandatory - attach: true - deploy: true - -DELETE ROUTE PEERINGS -===================== - -- name: Delete route peerings - cisco.dcnm.dcnm_service_route_peering: - state: deleted - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP1 # mandatory - node_name: IT-SN-1 # mandatory - -OVERRIDE ROUTE PEERINGS -======================= - -- name: Override existing route peerings with new peerings - cisco.dcnm.dcnm_service_route_peering: - state: overridden - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP-OVR1 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: IT-VRF-12 # mandatory - name: rp1-sn1-inside-net-ovr # mandatory - vlan_id: 191 # mandatory - profile: - ipv4_gw: 192.161.91.1/24 # mandatory - ipv6_gw: 2001:db11::1/64 # optional, default is '' - vlan_name: rp1-sn1-inside-ovr # optional, default is '' - int_descr: "RP1 SN1 inside interface ovr" # optional, default is '' - tag: 11191 # optional, default is 12345 - next_hop: 192.161.91.100 # mandatory - outside_network: # - vrf: IT-VRF-12 # mandatory - name: rp1-sn1-outside-net-ovr # mandatory - vlan_id: 192 # mandatory - profile: - ipv4_gw: 192.161.92.1/24 # mandatory - ipv6_gw: 2001:db12::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside-ovr # optional, default is '' - int_descr: "RP1 SN1 outside interface ovr" # optionL, default is '' - tag: 11192 # optional, default is 12345 - rev_next_hop: 192.161.92.100 # optional, default is '' - attach: true - deploy: true - -- name: Override existing route peerings with no new peerings - cisco.dcnm.dcnm_service_route_peering: - state: overridden - fabric: test-fabric - service_fabric: external - attach: true - deploy: true - -- name: Override existing route peerings with just service node names - cisco.dcnm.dcnm_service_route_peering: - state: overridden - fabric: test-fabric - service_fabric: external - config: - - node_name: IT-SN-1 # optional - - node_name: IT-SN-2 # optional - attach: true - deploy: true - -REPLACE ROUTE PEERINGS -====================== - -- name: Replace service route peerings RP1 - cisco.dcnm.dcnm_service_route_peering: &dcnm_srp_rep_13 - state: replaced - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP1 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: IT-VRF-11 # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 191 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2101:db01::01/64 # optional, default is '' - vlan_name: rp1-sn1-inside-rep # optional, default is '' - int_descr: "RP1 SN1 inside interface - REP" # optional, default is '' - tag: 11101 # optional, default is 12345 - next_hop: 192.161.1.200 # mandatory - outside_network: # - vrf: IT-VRF-11 # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 192 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2101:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside-rep # optional, default is '' - int_descr: "RP1 SN1 outside interface- REP" # optionL, default is '' - tag: 11102 # optional, default is 12345 - rev_next_hop: 192.161.2.200 # optional, default is '' - attach: true - deploy: true - -QUERY ROUTE PEERINGS -==================== - -- name: Query existing route peerings with specific peering names - cisco.dcnm.dcnm_service_route_peering: - state: query - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP1 # optional - node_name: IT-SN-1 # mandatory - - - name: IT-FW-RP2 # optional - node_name: IT-SN-1 # mandatory - - - name: IT-FW-RP3 # optional - node_name: IT-SN-1 # mandatory - - - name: IT-ADC-RP4 # optional - node_name: IT-SN-2 # mandatory - - - name: IT-ADC-RP5 # optional - node_name: IT-SN-2 # mandatory - - - name: IT-ADC-RP6 # optional - node_name: IT-SN-2 # mandatory - - - name: IT-ADC-RP7 # optional - node_name: IT-SN-2 # mandatory - -- name: Query existing route peerings without specific peering names - cisco.dcnm.dcnm_service_route_peering: - state: query - fabric: test-fabric - service_fabric: external - config: - node_name: IT-SN-1 # mandatory - node_name: IT-SN-2 # mandatory - -""" - -import time -import json -import re -import copy -import sys - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.connection import Connection -from ansible_collections.cisco.dcnm.plugins.module_utils.network.dcnm.dcnm import ( - dcnm_send, - validate_list_of_dicts, - dcnm_reset_connection, -) - -from datetime import datetime - -# Route Peering Class object which includes all the required methods and data to configure and maintain Roue peering objects -class DcnmServiceRoutePeering: - def __init__(self, module): - self.debug = False - self.module = module - self.params = module.params - self.fabric = module.params["fabric"] - self.config = copy.deepcopy(module.params.get("config")) - self.check_mode = False - self.srp_info = [] - self.want = [] - self.have = [] - self.diff_create = [] - self.diff_modify = [] - self.diff_delete = [] - self.diff_deploy = [] - self.fd = None - self.changed_dict = [ - {"merged": [], "modified": [], "deleted": [], "deploy": [], "query": []} - ] - self.result = dict(changed=False, diff=[], response=[]) - - def log_msg(self, msg): - - if self.fd == None: - self.fd = open("srp.log", "a+") - if self.fd != None: - self.fd.write(msg) - self.fd.flush() - - def dcnm_srp_validate_and_build_srp_info( - self, - cfg, - srp_spec, - srp_network_spec, - srp_prof1_spec, - srp_prof2_spec, - net_name1, - net_name2, - ): - - """ - Routine to validate the playbook input and fill up default values for objects not included. It takes specific profiles - to validate the input against. In this csase we validate the playbook against srp_spec which inlcudes common information - srp_network_spec which inlcudes network specific information and profile_specX which inlciudes network profile information. - For route peering we have two networks or arms and hence two profile specs. This routine updates self.srp_info with validated - playbook information by defaulting values not included - - Parameters: - cfg (dict): The config from playbook - srp_spec (dict): Route peering common spec - srp_network_spec (dict): Rourte peering network related config spec - srp_prof1_spec (dict): Route peering profile spec for inside-network/outside-network/first-arm - srp_prof2_spec (dict): Route peering profile spec for second-arm - net_name1 (string): Name of inside-network/first-arm - net_name2 (string): Name of outside-network/second-arm - - Returns: - None - """ - - srp_static_route_spec = dict( - subnet=dict(required=True, type="ipv4"), - next_hop=dict(required=True, type="list"), - ) - - srp_info, invalid_params = validate_list_of_dicts(cfg, srp_spec) - if invalid_params: - if cfg[0].get("name", " ") != " ": - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - else: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - Unknown, " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - self.srp_info.extend(srp_info) - - in_list = [] - out_list = [] - for item in srp_info: - - in_list.append(item[net_name1]) - # Validate inside and outside network dicts from route peering info - in_net, invalid_params = validate_list_of_dicts(in_list, srp_network_spec) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Network/Arm - " - + net_name1 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - in_list.remove(item[net_name1]) - item[net_name1].update(in_net[0]) - - if item.get(net_name2, "") != "": - out_list.append(item[net_name2]) - out_net, invalid_params = validate_list_of_dicts( - out_list, srp_network_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Network/Arm - " - + net_name2 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - out_list.remove(item[net_name2]) - item[net_name2].update(out_net[0]) - - in_list.append(item[net_name1]["profile"]) - # Validate inside and outside network profile dicts from route peering info - in_net_prof, invalid_params = validate_list_of_dicts( - in_list, srp_prof1_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Profile under Network/Arm - " - + net_name1 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - in_list.remove(item[net_name1]["profile"]) - item[net_name1]["profile"].update(in_net_prof[0]) - - if item.get(net_name2, "") != "": - out_list.append(item[net_name2]["profile"]) - out_net_prof, invalid_params = validate_list_of_dicts( - out_list, srp_prof2_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Profile under Network/Arm - " - + net_name2 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - out_list.remove(item[net_name2]["profile"]) - item[net_name2]["profile"].update(out_net_prof[0]) - - # Check if static route information is included under networks/arms. If yes, validate the same - - if item[net_name1]["profile"].get("static_route", "") != "": - - # Static Route is a list of route dicts - for rt in item[net_name1]["profile"]["static_route"]: - in_list.append(rt) - in_net_route, invalid_params = validate_list_of_dicts( - in_list, srp_static_route_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Static Route under Network/Arm - " - + net_name1 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - in_list.remove(rt) - rt.update(in_net_route[0]) - - if item.get(net_name2, "") != "": - if item[net_name2]["profile"].get("static_route", "") != "": - # Static Route is a list of route dicts - for rt in item[net_name2]["profile"]["static_route"]: - out_list.append(rt) - out_net_route, invalid_params = validate_list_of_dicts( - out_list, srp_static_route_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Static Route under Network/Arm - " - + net_name2 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - out_list.remove(rt) - rt.update(out_net_route[0]) - - def dcnm_srp_translate_deploy_mode(self, item): - - """ - Routine to translate the deploy_mode string from the playbook format to the payload format. The translated - value is updated in the 'item' object directly - - Parameters: - item (dict) : route peering block whose 'deploy_mode' object need to be translated - - Returns: - None - """ - - trans_dict = { - "intra_tenant_fw": "IntraTenantFW", - "inter_tenant_fw": "InterTenantFW", - "one_arm_adc": "OneArmADC", - "two_arm_adc": "TwoArmADC", - } - - if item["deploy_mode"] not in trans_dict.keys(): - mesg = "Invalid 'deploy_mode' = {}, in playbook, Expected values = {}".format( - item["deploy_mode"], trans_dict.keys() - ) - self.module.fail_json(msg=mesg) - - return trans_dict[item["deploy_mode"]] - - def dcnm_srp_validate_input(self): - - """ - Routine to validate the given playbook input based on the type of peering. - This routine updates self.srp_info with validated playbook information by defaulting values - not included. Since each state has a different config structure, this routine handles the - validation based on the given state - - Parameters: - None - - Returns: - None - """ - - if None is self.config: - return - - # Inputs will vary for Firewall and ADC service nodes and for each state. Make specific checks - # for each case. - - cfg = [] - for item in self.config: - - citem = copy.deepcopy(item) - - cfg.append(citem) - - if self.module.params["state"] == "deleted": - # config for delete state is different. So validate deleted state differently - self.dcnm_srp_validate_delete_state_input(cfg) - elif self.module.params["state"] == "query": - # config for query state is different. So validate query state differently - self.dcnm_srp_validate_query_state_input(cfg) - # For 'overridden' state, we can have full config for a peering or just service node name alone. - # In the formar case go down to 'else' block to validate the full config - elif (self.module.params["state"] == "overridden") and ( - item.get("name", None) is None - ): - # config for overridden state is different. So validate overridden state differently - self.dcnm_srp_validate_overridden_state_input(cfg) - else: - if "deploy_mode" not in item: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + item["name"] - + ", deploy_mode - Required parameter not found" - ) - self.module.fail_json(msg=mesg) - - # Translate the deploy_mode from playbook format to a format that DCNM expects - item["deploy_mode"] = self.dcnm_srp_translate_deploy_mode(item) - citem["deploy_mode"] = item["deploy_mode"] - - if (item["deploy_mode"].lower() == "intratenantfw") or ( - item["deploy_mode"].lower() == "intertenantfw" - ): - self.dcnm_srp_validate_firewall_input( - cfg, item["deploy_mode"].lower() - ) - if (item["deploy_mode"].lower() == "onearmadc") or ( - item["deploy_mode"].lower() == "twoarmadc" - ): - self.dcnm_srp_validate_adc_input(cfg, item["deploy_mode"].lower()) - cfg.remove(citem) - - def dcnm_srp_validate_intra_tenant_firewall_input(self, cfg): - - """ - Routine to validate the playbook input based on Firewall perring type intra-tenant. - This routine updates self.srp_info with validated intra-tenant firewall related playbook - information by defaulting values not included - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_spec = dict( - name=dict(required=True, type="str"), - node_name=dict(required=True, type="str"), - deploy_mode=dict(required=True, type="str"), - inside_network=dict(required=True, type="dict"), - outside_network=dict(required=True, type="dict"), - next_hop=dict(required=True, type="ipv4"), - rev_next_hop=dict(type="ipv4", default=""), - ) - - srp_network_spec = dict( - vrf=dict(required=True, type="str"), - name=dict(required=True, type="str"), - vlan_id=dict(required=True, type="int"), - profile=dict(required=True, type="dict"), - ) - - srp_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - ) - - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_prof_spec, - srp_prof_spec, - "inside_network", - "outside_network", - ) - - def dcnm_srp_validate_inter_tenant_firewall_input(self, cfg): - - """ - Routine to validate the playbook input based on Firewall perring type inter-tenant. - This routine updates self.srp_info with validated inter-tenant firewall related playbook - information by defaulting values not included - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_spec = dict( - name=dict(required=True, type="str"), - node_name=dict(required=True, type="str"), - deploy_mode=dict(required=True, type="str"), - peering_option=dict(type="str", default="static"), - inside_network=dict(required=True, type="dict"), - outside_network=dict(required=True, type="dict"), - ) - - srp_network_spec = dict( - vrf=dict(required=True, type="str"), - name=dict(required=True, type="str"), - vlan_id=dict(required=True, type="int"), - profile=dict(required=True, type="dict"), - ) - - srp_static_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - static_route=dict(type="list", default=""), - ) - - srp_ebgp_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - ipv4_neighbor=dict(required=True, type="ipv4"), - ipv4_lo=dict(required=True, type="ipv4"), - ipv4_vpc_peer_lo=dict(type="ipv4", default=""), - ipv6_neighbor=dict(type="ipv6", default=""), - ipv6_lo=dict(type="ipv6", default=""), - ipv6_vpc_peer_lo=dict(type="ipv6", default=""), - route_map_tag=dict(type="int", default=12345), - neigh_int_descr=dict(type="str", default=""), - local_asn=dict(type="int", default=""), - adv_host=dict(type="bool", default=True), - ) - - if (cfg[0].get("peering_option", "none") == "none") or ( - cfg[0]["peering_option"].lower() == "static" - ): - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_static_prof_spec, - srp_static_prof_spec, - "inside_network", - "outside_network", - ) - elif cfg[0]["peering_option"].lower() == "ebgp": - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_ebgp_prof_spec, - srp_ebgp_prof_spec, - "inside_network", - "outside_network", - ) - - def dcnm_srp_validate_adc_input(self, cfg, deploy_mode): - - """ - Routine to validate the playbook input based on Loadbalance perring type one-arm and two-arm. - This routine updates self.srp_info with validated adc related playbook information by defaulting - values not included - - Parameters: - cfg (dict): The config from playbook - deploy_mode (string): Deployment mode identifying the type of ADC - - Returns: - None - """ - - srp_spec = dict( - name=dict(required=True, type="str"), - node_name=dict(required=True, type="str"), - deploy_mode=dict(required=True, type="str"), - peering_option=dict(type="str", default="static"), - first_arm=dict(required=True, type="dict"), - second_arm=dict(type="dict", default=""), - rev_next_hop=dict(required=True, type="ipv4"), - ) - - srp_network_spec = dict( - vrf=dict(required=True, type="str"), - name=dict(required=True, type="str"), - vlan_id=dict(required=True, type="int"), - profile=dict(required=True, type="dict"), - ) - - srp_static_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - static_route=dict(type="list", default=""), - ) - - srp_ebgp_first_arm_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - ipv4_neighbor=dict(required=True, type="ipv4"), - ipv4_lo=dict(required=True, type="ipv4"), - ipv4_vpc_peer_lo=dict(type="ipv4", default=""), - ipv6_neighbor=dict(type="ipv6", default=""), - ipv6_lo=dict(type="ipv6", default=""), - ipv6_vpc_peer_lo=dict(type="ipv6", default=""), - route_map_tag=dict(type="int", default=12345), - neigh_int_descr=dict(type="str", default=""), - local_asn=dict(type="int", default=""), - adv_host=dict(type="bool", default=True), - ) - - srp_ebgp_second_arm_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - ) - - if (cfg[0].get("peering_option", "none") == "none") or ( - cfg[0]["peering_option"].lower() == "static" - ): - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_static_prof_spec, - srp_static_prof_spec, - "first_arm", - "second_arm", - ) - elif cfg[0]["peering_option"].lower() == "ebgp": - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_ebgp_first_arm_prof_spec, - srp_ebgp_second_arm_prof_spec, - "first_arm", - "second_arm", - ) - - def dcnm_srp_validate_firewall_input(self, cfg, deploy_mode): - - if deploy_mode == "intratenantfw": - self.dcnm_srp_validate_intra_tenant_firewall_input(cfg) - elif deploy_mode == "intertenantfw": - self.dcnm_srp_validate_inter_tenant_firewall_input(cfg) - - def dcnm_srp_validate_delete_state_input(self, cfg): - - """ - Playbook input will be different for differnt states. This routine validates the delete state - input. This routine updates self.srp_info with validated playbook information related to delete - state. - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_delete_spec = dict( - name=dict(required=True, type="str"), - node_name=dict(required=True, type="str"), - ) - - srp_info, invalid_params = validate_list_of_dicts(cfg, srp_delete_spec) - if invalid_params: - if cfg[0].get("name", " ") != " ": - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + cfg[0]["name"] - + ", " - + "".join(invalid_params) - ) - else: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - Unknown, " - + "".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - self.srp_info.extend(srp_info) - - def dcnm_srp_validate_query_state_input(self, cfg): - - """ - Playbook input will be different for differnt states. This routine validates the query state - input. This routine updates self.srp_info with validated playbook information related to query - state. - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_query_spec = dict( - name=dict(type="str", default="None"), - node_name=dict(required=True, type="str"), - ) - - srp_info, invalid_params = validate_list_of_dicts(cfg, srp_query_spec) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - self.srp_info.extend(srp_info) - - def dcnm_srp_validate_overridden_state_input(self, cfg): - - """ - Playbook input will be different for differnt states. This routine validates the overridden state - input. This routine updates self.srp_info with validated playbook information related to overridden - state. - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_overridden_spec = dict( - name=dict(required=False, type="str", default=""), - node_name=dict(required=False, type="str", default=""), - ) - - srp_info, invalid_params = validate_list_of_dicts(cfg, srp_overridden_spec) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - self.srp_info.extend(srp_info) - - def dcnm_srp_get_payload_route_info(self, srp, srp_payload): - - """ - This routine builds the route peering payload information from the playbook input - that is related to static of ebgp route information. - - Parameters: - srp (dict): The route peering information from self.want - srp_payload (dict): Route peering information to be filled from the given srp config - - Returns: - None - """ - - in_route_info = {"nvPairs": {}} - - out_route_info = {"nvPairs": {}} - - if (srp["deploy_mode"].lower() == "intratenantfw") or ( - srp["deploy_mode"].lower() == "intertenantfw" - ): - net_name1 = "inside_network" - net_name2 = "outside_network" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - - srp_payload["routes"] = [] - if srp_payload["peeringOption"] == "StaticPeering": - - srp_payload["routes"].append(in_route_info) - srp_payload["routes"][0]["templateName"] = "service_static_route" - - nv = srp_payload["routes"][0]["nvPairs"] - - nv["VRF_NAME"] = srp[net_name1]["vrf"] - srp_payload["routes"][0]["vrfName"] = srp[net_name1]["vrf"] - - # Build Multiroutes object - routes = srp[net_name1]["profile"]["static_route"] - multi_routes = "" - - for rt in routes: - hops = rt["next_hop"] - for nh in hops: - multi_routes += rt["subnet"] + "," + nh + "\n" - - nv["MULTI_ROUTES"] = multi_routes.rstrip("\n") - - if srp_payload["deploymentMode"] == "InterTenantFW": - - srp_payload["routes"].append(out_route_info) - srp_payload["routes"][1]["templateName"] = "service_static_route" - - nv = srp_payload["routes"][1]["nvPairs"] - - nv["VRF_NAME"] = srp[net_name2]["vrf"] - srp_payload["routes"][1]["vrfName"] = srp[net_name2]["vrf"] - - # Build Multiroutes object - routes = srp[net_name2]["profile"]["static_route"] - multi_routes = "" - - for rt in routes: - hops = rt["next_hop"] - for nh in hops: - multi_routes += rt["subnet"] + "," + nh + "\n" - - nv["MULTI_ROUTES"] = multi_routes.rstrip("\n") - - elif srp_payload["peeringOption"] == "EBGPDynamicPeering": - - srp_payload["routes"].append(in_route_info) - srp_payload["routes"][0]["templateName"] = "service_ebgp_route" - - nv = srp_payload["routes"][0]["nvPairs"] - - nv["NEIGHBOR_IP"] = srp[net_name1]["profile"]["ipv4_neighbor"] - nv["LOOPBACK_IP"] = srp[net_name1]["profile"]["ipv4_lo"] - nv["PEER_LOOPBACK_IP"] = srp[net_name1]["profile"]["ipv4_vpc_peer_lo"] - nv["NEIGHBOR_IPV6"] = srp[net_name1]["profile"]["ipv6_neighbor"] - nv["LOOPBACK_IPV6"] = srp[net_name1]["profile"]["ipv6_lo"] - nv["PEER_LOOPBACK_IPV6"] = srp[net_name1]["profile"]["ipv6_vpc_peer_lo"] - nv["ROUTE_MAP_TAG"] = srp[net_name1]["profile"]["route_map_tag"] - nv["DESC"] = srp[net_name1]["profile"]["neigh_int_descr"] - nv["LOCAL_ASN"] = srp[net_name1]["profile"]["local_asn"] - nv["ADVERTISE_HOST_ROUTE"] = srp[net_name1]["profile"]["adv_host"] - nv["ADMIN_STATE"] = True - nv["VRF_NAME"] = srp[net_name1]["vrf"] - - srp_payload["routes"][0]["vrfName"] = srp[net_name1]["vrf"] - - if srp_payload["deploymentMode"] == "InterTenantFW": - - srp_payload["routes"].append(out_route_info) - srp_payload["routes"][1]["templateName"] = "service_ebgp_route" - - nv = srp_payload["routes"][1]["nvPairs"] - - nv["NEIGHBOR_IP"] = srp[net_name2]["profile"]["ipv4_neighbor"] - nv["LOOPBACK_IP"] = srp[net_name2]["profile"]["ipv4_lo"] - nv["PEER_LOOPBACK_IP"] = srp[net_name2]["profile"]["ipv4_vpc_peer_lo"] - nv["NEIGHBOR_IPV6"] = srp[net_name2]["profile"]["ipv6_neighbor"] - nv["LOOPBACK_IPV6"] = srp[net_name2]["profile"]["ipv6_lo"] - nv["PEER_LOOPBACK_IPV6"] = srp[net_name2]["profile"]["ipv6_vpc_peer_lo"] - nv["ROUTE_MAP_TAG"] = srp[net_name2]["profile"]["route_map_tag"] - nv["DESC"] = srp[net_name2]["profile"]["neigh_int_descr"] - nv["LOCAL_ASN"] = srp[net_name2]["profile"]["local_asn"] - nv["ADVERTISE_HOST_ROUTE"] = srp[net_name2]["profile"]["adv_host"] - nv["ADMIN_STATE"] = True - nv["VRF_NAME"] = srp[net_name2]["vrf"] - - srp_payload["routes"][1]["vrfName"] = srp[net_name2]["vrf"] - - def dcnm_srp_get_common_payload(self, srp, deploy_mode): - - """ - This routine builds the common part of the route peering payload. By common we mean information that is common - to both inside and outside networks or one-arm and two-arm adc. - - Parameters: - srp (dict): Route peering information from self.want - deploy_mode (string): Rourte peering deployment mode - - Returns: - srp_payload (dict): Route peering common payload information populated from playbook configuration - """ - - in_network_defaults = { - "templateName": "Service_Network_Universal", - "nvPairs": { - "isLayer2Only": False, - "suppressArp": False, - "enableIR": False, - "trmEnabled": False, - "rtBothAuto": False, - }, - } - - out_network_defaults = { - "templateName": "Service_Network_Universal", - "nvPairs": { - "isLayer2Only": False, - "suppressArp": False, - "enableIR": False, - "trmEnabled": False, - "rtBothAuto": False, - }, - } - - srp_payload = {"serviceNetworks": [], "enabled": self.attach} - - if (deploy_mode == "intratenantfw") or (deploy_mode == "intertenantfw"): - net_name1 = "inside_network" - net_name2 = "outside_network" - networkType1 = "InsideNetworkFW" - networkType2 = "OutsideNetworkFW" - serviceNodeType = "Firewall" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - networkType1 = "ArmOneADC" - networkType2 = "ArmTwoADC" - serviceNodeType = "ADC" - - # Global - srp_payload["peeringName"] = srp["name"] - srp_payload["deploymentMode"] = srp["deploy_mode"] - srp_payload["serviceNodeType"] = serviceNodeType - - # Inside Network - srp_payload["serviceNetworks"].append(in_network_defaults) - - srp_payload["serviceNetworks"][0]["vrfName"] = srp[net_name1]["vrf"] - srp_payload["serviceNetworks"][0]["networkType"] = networkType1 - srp_payload["serviceNetworks"][0]["networkName"] = srp[net_name1]["name"] - srp_payload["serviceNetworks"][0]["vlanId"] = srp[net_name1]["vlan_id"] - - # Inside Network Profile - srp_payload["serviceNetworks"][0]["nvPairs"]["gatewayIpAddress"] = srp[ - net_name1 - ]["profile"]["ipv4_gw"] - srp_payload["serviceNetworks"][0]["nvPairs"]["gatewayIpV6Address"] = srp[ - net_name1 - ]["profile"]["ipv6_gw"] - srp_payload["serviceNetworks"][0]["nvPairs"]["vlanName"] = srp[net_name1][ - "profile" - ]["vlan_name"] - srp_payload["serviceNetworks"][0]["nvPairs"]["intfDescription"] = srp[ - net_name1 - ]["profile"]["int_descr"] - srp_payload["serviceNetworks"][0]["nvPairs"]["tag"] = srp[net_name1]["profile"][ - "tag" - ] - srp_payload["serviceNetworks"][0]["nvPairs"]["vlanId"] = srp[net_name1][ - "vlan_id" - ] - - if deploy_mode != "onearmadc": - - # Outside Network - srp_payload["serviceNetworks"].append(out_network_defaults) - - srp_payload["serviceNetworks"][1]["vrfName"] = srp[net_name2]["vrf"] - srp_payload["serviceNetworks"][1]["networkType"] = networkType2 - srp_payload["serviceNetworks"][1]["networkName"] = srp[net_name2]["name"] - srp_payload["serviceNetworks"][1]["vlanId"] = srp[net_name2]["vlan_id"] - - # Outside Network Profile - srp_payload["serviceNetworks"][1]["nvPairs"]["gatewayIpAddress"] = srp[ - net_name2 - ]["profile"]["ipv4_gw"] - srp_payload["serviceNetworks"][1]["nvPairs"]["gatewayIpV6Address"] = srp[ - net_name2 - ]["profile"]["ipv6_gw"] - srp_payload["serviceNetworks"][1]["nvPairs"]["vlanName"] = srp[net_name2][ - "profile" - ]["vlan_name"] - srp_payload["serviceNetworks"][1]["nvPairs"]["intfDescription"] = srp[ - net_name2 - ]["profile"]["int_descr"] - srp_payload["serviceNetworks"][1]["nvPairs"]["tag"] = srp[net_name2][ - "profile" - ]["tag"] - srp_payload["serviceNetworks"][1]["nvPairs"]["vlanId"] = srp[net_name2][ - "vlan_id" - ] - - # Service Node and Fabric details - srp_payload["serviceNodeName"] = srp["node_name"] - srp_payload["attachedFabricName"] = self.module.params["fabric"] - srp_payload["fabricName"] = self.module.params["service_fabric"] - - return srp_payload - - def dcnm_get_srp_payload(self, srp): - - """ - This routine builds the complete payload step-by-step first by building common part, then other - parts based on the deploy_mode and peering_option. - - Parameters: - srp (dict): Route peering information - - Returns: - self.srp_payuload (dict): SRP payload information populated with appropriate data from playbook config - """ - - deploy_mode = srp["deploy_mode"].lower() - srp_payload = self.dcnm_srp_get_common_payload(srp, deploy_mode) - - # Based on the deployment mode, add the other required objects - if deploy_mode == "intratenantfw": - - srp_payload["peeringOption"] = "None" - # Add NextHop and Reverse NextHop - srp_payload["nextHopIp"] = srp["next_hop"] - srp_payload["reverseNextHopIp"] = srp["rev_next_hop"] - elif deploy_mode == "intertenantfw": - - if srp["peering_option"] == "static": - srp_payload["peeringOption"] = "StaticPeering" - else: - srp_payload["peeringOption"] = "EBGPDynamicPeering" - self.dcnm_srp_get_payload_route_info(srp, srp_payload) - elif deploy_mode == "onearmadc": - - if srp["peering_option"] == "static": - srp_payload["peeringOption"] = "StaticPeering" - else: - srp_payload["peeringOption"] = "EBGPDynamicPeering" - srp_payload["reverseNextHopIp"] = srp["rev_next_hop"] - self.dcnm_srp_get_payload_route_info(srp, srp_payload) - elif deploy_mode == "twoarmadc": - - if srp["peering_option"] == "static": - srp_payload["peeringOption"] = "StaticPeering" - else: - srp_payload["peeringOption"] = "EBGPDynamicPeering" - srp_payload["reverseNextHopIp"] = srp["rev_next_hop"] - self.dcnm_srp_get_payload_route_info(srp, srp_payload) - - return srp_payload - - def dcnm_srp_update_route_info(self, want, have, cfg): - - """ - This routine is invoked after self.want is populated based on playbook info. For merging route peerings - all the information that is not included in the playbook must be left as is and the information which - is included must be updated. This routine checks for playbook info and updates self.want as required - This routine updates self.want with appriopriate route information from playbook and self.have based on - objects included in the playbook. - - Parameters: - cfg (dict): The config from playbook - want (dict): Route peering payload information populated from playbook config - have (dict): Rourte peering information that exists on the DCNM server - - Returns: - None - """ - - if (want["deploymentMode"].lower() == "intratenantfw") or ( - want["deploymentMode"].lower() == "intertenantfw" - ): - net_name1 = "inside_network" - net_name2 = "outside_network" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - - # Check the peeringOption and if not same, just leave 'want' as it is and do not try to compare it with - # 'have' since the fields are completely different - - if want["peeringOption"] != have["peeringOption"]: - return - - # All objects that are not included in the playbook will be copied from have to leave them undisturbed - if cfg.get("peering_option", None) is None: - want["peeringOption"] = have["peeringOption"] - - if want["peeringOption"] == "StaticPeering": - - if cfg.get("vrf", None) is None: - want["routes"][0]["vrfName"] = have["routes"][0]["vrfName"] - - wnv = want["routes"][0]["nvPairs"] - hnv = have["routes"][0]["nvPairs"] - - if cfg.get("vrf", None) is None: - wnv["VRF_NAME"] = hnv["VRF_NAME"] - - if cfg[net_name1]["profile"].get("static_route", None) is None: - wnv["MULTI_ROUTES"] = hnv["MULTI_ROUTES"] - - if want["deploymentMode"] == "InterTenantFW": - - if cfg.get("vrf", None) is None: - want["routes"][1]["vrfName"] = have["routes"][1]["vrfName"] - - wnv = want["routes"][1]["nvPairs"] - hnv = have["routes"][1]["nvPairs"] - - if cfg.get("vrf", None) is None: - wnv["VRF_NAME"] = hnv["VRF_NAME"] - - if cfg[net_name2]["profile"].get("static_route", None) is None: - wnv["MULTI_ROUTES"] = hnv["MULTI_ROUTES"] - - elif want["peeringOption"] == "EBGPDynamicPeering": - - wnv = want["routes"][0]["nvPairs"] - hnv = have["routes"][0]["nvPairs"] - - if cfg[net_name1]["profile"].get("ipv4_neighbor", None) is None: - wnv["NEIGHBOR_IP"] = hnv["NEIGHBOR_IP"] - - if cfg[net_name1]["profile"].get("ipv4_lo", None) is None: - wnv["LOOPBACK_IP"] = hnv["LOOPBACK_IP"] - - if cfg[net_name1]["profile"].get("ipv4_vpc_peer_lo", None) is None: - wnv["PEER_LOOPBACK_IP"] = hnv["PEER_LOOPBACK_IP"] - - if cfg[net_name1]["profile"].get("ipv6_neighbor", None) is None: - wnv["NEIGHBOR_IPV6"] = hnv["NEIGHBOR_IPV6"] - - if cfg[net_name1]["profile"].get("ipv6_lo", None) is None: - wnv["LOOPBACK_IPV6"] = hnv["LOOPBACK_IPV6"] - - if cfg[net_name1]["profile"].get("ipv6_vpc_peer_lo", None) is None: - wnv["PEER_LOOPBACK_IPV6"] = hnv["PEER_LOOPBACK_IPV6"] - - if cfg[net_name1]["profile"].get("route_map_tag", None) is None: - wnv["ROUTE_MAP_TAG"] = hnv["ROUTE_MAP_TAG"] - - if cfg[net_name1]["profile"].get("neigh_int_descr", None) is None: - wnv["DESC"] = hnv["DESC"] - - if cfg[net_name1]["profile"].get("local_asn", None) is None: - wnv["LOCAL_ASN"] = hnv["LOCAL_ASN"] - - if cfg[net_name1]["profile"].get("adv_host", None) is None: - wnv["ADVERTISE_HOST_ROUTE"] = hnv["ADVERTISE_HOST_ROUTE"] - - if cfg.get("vrf", None) is None: - wnv["VRF_NAME"] = hnv["VRF_NAME"] - - if cfg.get("vrf", None) is None: - want["routes"][0]["vrfName"] = have["routes"][0]["vrfName"] - - if want["deploymentMode"] == "InterTenantFW": - - wnv = want["routes"][1]["nvPairs"] - hnv = have["routes"][1]["nvPairs"] - - if cfg[net_name2]["profile"].get("ipv4_neighbor", None) is None: - wnv["NEIGHBOR_IP"] = hnv["NEIGHBOR_IP"] - - if cfg[net_name2]["profile"].get("ipv4_lo", None) is None: - wnv["LOOPBACK_IP"] = hnv["LOOPBACK_IP"] - - if cfg[net_name2]["profile"].get("ipv4_vpc_peer_lo", None) is None: - wnv["PEER_LOOPBACK_IP"] = hnv["PEER_LOOPBACK_IP"] - - if cfg[net_name2]["profile"].get("ipv6_neighbor", None) is None: - wnv["NEIGHBOR_IPV6"] = hnv["NEIGHBOR_IPV6"] - - if cfg[net_name2]["profile"].get("ipv6_lo", None) is None: - wnv["LOOPBACK_IPV6"] = hnv["LOOPBACK_IPV6"] - - if cfg[net_name2]["profile"].get("ipv6_vpc_peer_lo", None) is None: - wnv["PEER_LOOPBACK_IPV6"] = hnv["PEER_LOOPBACK_IPV6"] - - if cfg[net_name2]["profile"].get("route_map_tag", None) is None: - wnv["ROUTE_MAP_TAG"] = hnv["ROUTE_MAP_TAG"] - - if cfg[net_name2]["profile"].get("neigh_int_descr", None) is None: - wnv["DESC"] = hnv["DESC"] - - if cfg[net_name2]["profile"].get("loacl_asn", None) is None: - wnv["LOCAL_ASN"] = hnv["LOCAL_ASN"] - - if cfg[net_name2]["profile"].get("adv_host", None) is None: - wnv["ADVERTISE_HOST_ROUTE"] = hnv["ADVERTISE_HOST_ROUTE"] - - if cfg.get("vrf", None) is None: - wnv["VRF_NAME"] = hnv["VRF_NAME"] - - if cfg.get("vrf", None) is None: - want["routes"][1]["vrfName"] = have["routes"][1]["vrfName"] - - def dcnm_srp_update_common_info(self, want, have, cfg): - - """ - Routine to update the common part of the route peering information in self.want - This routine updates self.want with common information from playbook and self.have based on objects - included in the playbook. - - Parameters: - cfg (dict): The config from playbook - want (dict): Route peering payload information populated from playbook config - have (dict): Rourte peering information that exists on the DCNM server - - Returns: - None - """ - - if (want["deploymentMode"].lower() == "intratenantfw") or ( - want["deploymentMode"].lower() == "intertenantfw" - ): - net_name1 = "inside_network" - net_name2 = "outside_network" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - - # All objects that are not included in the playbook will be copied from have to leave them undisturbed - # Inside Network - if cfg[net_name1].get("vrf", None) is None: - want["serviceNetworks"][0]["vrfName"] = have["serviceNetworks"][0][ - "vrfName" - ] - - if cfg[net_name1].get("name", None) is None: - want["serviceNetworks"][0]["networkName"] = have["serviceNetworks"][0][ - "networkName" - ] - - if cfg[net_name1].get("vlan_id", None) is None: - want["serviceNetworks"][0]["vlanId"] = have["serviceNetworks"][0]["vlanId"] - - # Inside Network Profile - if cfg[net_name1]["profile"].get("ipv4_gw", None) is None: - want["serviceNetworks"][0]["nvPairs"]["gatewayIpAddress"] = have[ - "serviceNetworks" - ][0]["nvPairs"]["gatewayIpAddress"] - - if cfg[net_name1]["profile"].get("ipv6_gw", None) is None: - want["serviceNetworks"][0]["nvPairs"]["gatewayIpV6Address"] = have[ - "serviceNetworks" - ][0]["nvPairs"]["gatewayIpV6Address"] - - if cfg[net_name1]["profile"].get("vlan_name", None) is None: - want["serviceNetworks"][0]["nvPairs"]["vlanName"] = have["serviceNetworks"][ - 0 - ]["nvPairs"]["vlanName"] - - if cfg[net_name1]["profile"].get("int_descr", None) is None: - hif_desc = have["serviceNetworks"][0]["nvPairs"]["intfDescription"].split( - " " - )[:-1] - want["serviceNetworks"][0]["nvPairs"]["intfDescription"] = " ".join( - hif_desc - ) - - if cfg[net_name1]["profile"].get("tag", None) is None: - want["serviceNetworks"][0]["nvPairs"]["tag"] = have["serviceNetworks"][0][ - "nvPairs" - ]["tag"] - - if cfg[net_name1]["profile"].get("vlan_id", None) is None: - want["serviceNetworks"][0]["nvPairs"]["vlanId"] = have["serviceNetworks"][ - 0 - ]["nvPairs"]["vlanId"] - - if want["deploymentMode"].lower() != "onearmadc": - - # Outside Network - if cfg[net_name2].get("vrf", None) is None: - want["serviceNetworks"][1]["vrfName"] = have["serviceNetworks"][1][ - "vrfName" - ] - - if cfg[net_name2].get("name", None) is None: - want["serviceNetworks"][1]["networkName"] = have["serviceNetworks"][1][ - "networkName" - ] - - if cfg[net_name2].get("vlan_id", None) is None: - want["serviceNetworks"][1]["vlanId"] = have["serviceNetworks"][1][ - "vlanId" - ] - - # Outside Network Profile - if cfg[net_name2]["profile"].get("ipv4_gw", None) is None: - want["serviceNetworks"][1]["nvPairs"]["gatewayIpAddress"] = have[ - "serviceNetworks" - ][1]["nvPairs"]["gatewayIpAddress"] - - if cfg[net_name2]["profile"].get("ipv6_gw", None) is None: - want["serviceNetworks"][1]["nvPairs"]["gatewayIpV6Address"] = have[ - "serviceNetworks" - ][1]["nvPairs"]["gatewayIpV6Address"] - - if cfg[net_name2]["profile"].get("vlan_name", None) is None: - want["serviceNetworks"][1]["nvPairs"]["vlanName"] = have[ - "serviceNetworks" - ][1]["nvPairs"]["vlanName"] - - if cfg[net_name2]["profile"].get("int_descr", None) is None: - hif_desc = have["serviceNetworks"][1]["nvPairs"][ - "intfDescription" - ].split(" ")[:-1] - want["serviceNetworks"][1]["nvPairs"]["intfDescription"] = " ".join( - hif_desc - ) - - if cfg[net_name2]["profile"].get("tag", None) is None: - want["serviceNetworks"][1]["nvPairs"]["tag"] = have["serviceNetworks"][ - 1 - ]["nvPairs"]["tag"] - - if cfg[net_name2]["profile"].get("vlan_id", None) is None: - want["serviceNetworks"][1]["nvPairs"]["vlanId"] = have[ - "serviceNetworks" - ][1]["nvPairs"]["vlanId"] - - # if self.module.params["attach"] is "default, then attach is not given in Playbook - if self.module.params["attach"] == "default": - want["enabled"] = have["enabled"] - - def dcnm_srp_update_want(self): - - """ - Routine to compare want and have and make approriate changes to want. This routine checks the existing - informationm with the config from playbook and populates the payloads in self.want apropriately. - This routine updates self.want with final paylload information after comparing self.want and self.have and - the playbook information. - - Parameters: - None - - Returns: - None - """ - - # only for 'merged' state we need to update the objects that are not included in playbook with - # values from self.have. - - if self.module.params["state"] != "merged": - return - - if self.want == []: - return - - for srp in self.want: - - # Get the matching have to copy values if required - match_have = [ - have - for have in self.have - if ( - (srp["peeringName"] == have["peeringName"]) - and (srp["fabricName"] == have["fabricName"]) - and (srp["serviceNodeName"] == have["serviceNodeName"]) - and (srp["attachedFabricName"] == have["attachedFabricName"]) - ) - ] - if match_have == []: - continue - - # Get the SRP from self.config to check if a particular object is included or not - match_cfg = [ - cfg - for cfg in self.config - if ( - (srp["peeringName"] == cfg["name"]) - and (srp["fabricName"] == self.module.params["service_fabric"]) - and (srp["serviceNodeName"] == cfg["node_name"]) - and (srp["attachedFabricName"] == self.module.params["fabric"]) - ) - ] - if match_cfg == []: - continue - - self.dcnm_srp_update_common_info(srp, match_have[0], match_cfg[0]) - self.dcnm_srp_update_route_info(srp, match_have[0], match_cfg[0]) - - def dcnm_srp_get_want(self): - - """ - This routine updates self.want with the payload information based on the playbook configuration. - - Parameters: - None - - Returns: - None - """ - - if None is self.config: - return - - if not self.srp_info: - return - - # self.srp_info is a list of directories each having config related to a particular srp - for srp_elem in self.srp_info: - # If route peering name is not given, then that means we are handling the case of Playbook - # including just the service node name. In such a casse we don't have to worry about filling want - if srp_elem.get("name", "") == "": - continue - srp_payload = self.dcnm_get_srp_payload(srp_elem) - if srp_payload not in self.want: - self.want.append(srp_payload) - - def dcnm_srp_get_srp_info_with_service_node(self, node_name): - - """ - Routine to get all route peerings based on the Service Node information included in the playbook. - - Parameters: - node_name (string): service node name to fetch the route peerings information from - - Returns: - resp["DATA"] (dict): All route peerings present on the specified service node - """ - - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + self.module.params["service_fabric"] - + "/service-nodes/" - + node_name - + "/peerings/" - + self.module.params["fabric"] - ) - - retries = 0 - while retries < 5: - retries += 1 - resp = dcnm_send(self.module, "GET", path) - - if resp and resp["RETURN_CODE"] != 200: - time.sleep(10) - continue - else: - break - - if resp and (resp["RETURN_CODE"] == 200) and resp["DATA"]: - resp["RETRIES"] = retries - return resp["DATA"] - else: - return [] - - def dcnm_srp_get_service_nodes_from_dcnm(self): - - """ - Routine to get list of all service nodes from DCNM. - - Parameters: - None - - Returns: - resp["DATA"] (dict): All service nodes on the specified fabric - """ - - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/?attached-fabric=" - + self.module.params["fabric"] - ) - - retries = 0 - while retries < 5: - retries += 1 - resp = dcnm_send(self.module, "GET", path) - - if resp and resp["RETURN_CODE"] != 200: - time.sleep(10) - continue - else: - break - - if resp and (resp["RETURN_CODE"] == 200) and resp["DATA"]: - resp["RETRIES"] = retries - return resp["DATA"] - else: - return [] - - def dcnm_srp_get_srp_info_from_dcnm(self, srp, srp_type): - - """ - Routine to get existing Route peering information from DCNM which matches the given SRP. - - Parameters: - srp (dict): Route peering information - srp_type (string): String indicating whether the 'srp' passed is in 'PLAYBOOK' format - or 'PAYLOAD' format - Returns: - resp["DATA"] (dict): SRP informatikon obtained from the DCNM server if it exists - [] otherwise - """ - - if srp_type == "PAYLOAD": - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - ) - else: - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + self.module.params["service_fabric"] - + "/service-nodes/" - + srp["node_name"] - + "/peerings/" - + self.module.params["fabric"] - + "/" - + srp["name"] - ) - - retries = 0 - while retries < 5: - retries += 1 - resp = dcnm_send(self.module, "GET", path) - - if resp and resp["RETURN_CODE"] != 200: - # Check if the error is "ResourceNotFound". In that case we can return without - # retrying. - if resp.get("error", None) is not None: - if resp["error"].get("code") is "ResourceNotFound": - break - time.sleep(10) - continue - else: - break - - if resp and (resp["RETURN_CODE"] == 200) and resp["DATA"]: - resp["RETRIES"] = retries - return resp["DATA"] - else: - return [] - - def dcnm_srp_get_have(self): - - """ - Routine to get exisitng roue peering information from DCNM that matches information in self.want. - This routine updates self.have with all the route peerings that match the given playbook configuration - - Parameters: - None - - Returns: - None - """ - - if self.want == []: - return - - for srp in self.want: - have = self.dcnm_srp_get_srp_info_from_dcnm(srp, "PAYLOAD") - if (have != []) and (have not in self.have): - self.have.append(have) - - def dcnm_srp_compare_common_info(self, want, have): - - """ - Routine to compare common information from want and have to decide if the information from self.want is to - be added to the create list/replace list or not. - - Parameters: - want (dict): SRP Payload information populated using playbook config - have (dict): SRP information existing on the DCNM server - - Returns: - DCNM_SRP_NO_MATCH (string): if information in want and have don't match - DCNM_SRP_MATCH (string): if want and have match - mismatch_reasons (list): A list containing strings identifying which objects did not match or [] - """ - - mismatch_reasons = [] - - if want["deploymentMode"] != have["deploymentMode"]: - mismatch_reasons.append("DCNM_SRP_DM_NO_MATCH") - - if (want["deploymentMode"].lower() == "intratenantfw") or ( - want["deploymentMode"].lower() == "intertenantfw" - ): - net_name1 = "inside_network" - net_name2 = "outside_network" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - - # Global - if want["serviceNodeType"] != have["serviceNodeType"]: - mismatch_reasons.append("DCNM_SRP_SNT_NO_MATCH") - - # Inside Network - if ( - want["serviceNetworks"][0]["vrfName"] - != have["serviceNetworks"][0]["vrfName"] - ): - mismatch_reasons.append("DCNM_SRP_IN_VRF_NO_MATCH") - - if ( - want["serviceNetworks"][0]["networkType"] - != have["serviceNetworks"][0]["networkType"] - ): - mismatch_reasons.append("DCNM_SRP_IN_NT_NO_MATCH") - - if ( - want["serviceNetworks"][0]["networkName"] - != have["serviceNetworks"][0]["networkName"] - ): - mismatch_reasons.append("DCNM_SRP_IN_NN_NO_MATCH") - - if want["serviceNetworks"][0]["vlanId"] != have["serviceNetworks"][0]["vlanId"]: - mismatch_reasons.append("DCNM_SRP_IN_VID_NO_MATCH") - - # Inside Network Profile - if ( - want["serviceNetworks"][0]["nvPairs"]["gatewayIpAddress"] - != have["serviceNetworks"][0]["nvPairs"]["gatewayIpAddress"] - ): - mismatch_reasons.append("DCNM_SRP_IN_IPV4GW_NO_MATCH") - if ( - want["serviceNetworks"][0]["nvPairs"]["gatewayIpV6Address"] - != have["serviceNetworks"][0]["nvPairs"]["gatewayIpV6Address"] - ): - mismatch_reasons.append("DCNM_SRP_IN_IPV6GW_NO_MATCH") - if ( - want["serviceNetworks"][0]["nvPairs"]["vlanName"] - != have["serviceNetworks"][0]["nvPairs"]["vlanName"] - ): - mismatch_reasons.append("DCNM_SRP_IN_VNAME_NO_MATCH") - - # When we get the SRP inmformation from have, the intfDescription would have been modified and some meta data added. so ignore the meta data - # when comparing the interface descriptions - if want["serviceNetworks"][0]["nvPairs"]["intfDescription"] != "": - wif_desc = want["serviceNetworks"][0]["nvPairs"]["intfDescription"].split( - " " - ) - else: - wif_desc = [] - hif_desc = have["serviceNetworks"][0]["nvPairs"]["intfDescription"].split(" ")[ - :-1 - ] - if wif_desc != hif_desc: - mismatch_reasons.append("DCNM_SRP_IN_DESCR_NO_MATCH") - if ( - str(want["serviceNetworks"][0]["nvPairs"]["tag"]) - != have["serviceNetworks"][0]["nvPairs"]["tag"] - ): - mismatch_reasons.append("DCNM_SRP_IN_TAG_NO_MATCH") - if ( - str(want["serviceNetworks"][0]["nvPairs"]["vlanId"]) - != have["serviceNetworks"][0]["nvPairs"]["vlanId"] - ): - mismatch_reasons.append("DCNM_SRP_IN_PROF_VID_NO_MATCH") - - if want["deploymentMode"].lower() != "onearmadc": - - # Outside Network - if ( - want["serviceNetworks"][1]["vrfName"] - != have["serviceNetworks"][1]["vrfName"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_VRF_NO_MATCH") - if ( - want["serviceNetworks"][1]["networkType"] - != have["serviceNetworks"][1]["networkType"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_NT_NO_MATCH") - if ( - want["serviceNetworks"][1]["networkName"] - != have["serviceNetworks"][1]["networkName"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_NN_NO_MATCH") - if ( - want["serviceNetworks"][1]["vlanId"] - != have["serviceNetworks"][1]["vlanId"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_VID_NO_MATCH") - - # Outside Network Profile - if ( - want["serviceNetworks"][1]["nvPairs"]["gatewayIpAddress"] - != have["serviceNetworks"][1]["nvPairs"]["gatewayIpAddress"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_IPV4GW_NO_MATCH") - if ( - want["serviceNetworks"][1]["nvPairs"]["gatewayIpV6Address"] - != have["serviceNetworks"][1]["nvPairs"]["gatewayIpV6Address"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_IPV6GW_NO_MATCH") - if ( - want["serviceNetworks"][1]["nvPairs"]["vlanName"] - != have["serviceNetworks"][1]["nvPairs"]["vlanName"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_VNAME_NO_MATCH") - - # When we get the SRP inmformation from have, the intfDescription would have been modified and some meta data added. so ignore the meta data - # when comparing the interface descriptions - if want["serviceNetworks"][1]["nvPairs"]["intfDescription"] != "": - wif_desc = want["serviceNetworks"][1]["nvPairs"][ - "intfDescription" - ].split(" ") - else: - wif_desc = [] - hif_desc = have["serviceNetworks"][1]["nvPairs"]["intfDescription"].split( - " " - )[:-1] - if wif_desc != hif_desc: - mismatch_reasons.append("DCNM_SRP_OUT_DESCR_NO_MATCH") - if ( - str(want["serviceNetworks"][1]["nvPairs"]["tag"]) - != have["serviceNetworks"][1]["nvPairs"]["tag"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_TAG_NO_MATCH") - if ( - str(want["serviceNetworks"][1]["nvPairs"]["vlanId"]) - != have["serviceNetworks"][1]["nvPairs"]["vlanId"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_PROF_VID_NO_MATCH") - - if str(want["enabled"]).lower() != str(have["enabled"]).lower(): - mismatch_reasons.append("DCNM_SRP_ATT_NO_MATCH") - - if mismatch_reasons == []: - return "DCNM_SRP_MATCH", mismatch_reasons - else: - return "DCNM_SRP_NO_MATCH", mismatch_reasons - - def dcnm_srp_compare_multi_routes(self, wmr, hmr): - - """ - Routine to compare MULTIROUTE object of route peerings from self.want and self.have. - - Parameters: - wmr (dict): Multi-Route info object from want - hmr (dict): Multi-Route info object from have - - Returns: - DCNM_MR_NO_MATCH (string): if multi-route objects do not match - DCNM_MR_MATCH (string): if multi-route objects match - """ - - wmrl = wmr.split("\n") - hmrl = hmr.split("\n") - - fwmr = [item.replace(" ", "") for item in wmrl] - fhmr = [item.replace(" ", "") for item in hmrl] - - for rt in fwmr: - if rt not in fhmr: - return "DCNM_MR_NO_MATCH" - return "DCNM_MR_MATCH" - - def dcnm_srp_compare_route_info(self, want, have): - - """ - Routine to compare route objects of route peerings from self.want and self.have. - - Parameters: - want (dict): SRP Payload information populated using playbook config - have (dict): SRP information existing on the DCNM server - - Returns: - DCNM_SRP_MATCH (string): if route information in want and have match - DCNM_SRP_NO_MATCH (string): if route information in want and have do not match - mismatch_reasons (list): A list containing strings indicating which objects did not match - """ - - mismatch_reasons = [] - if (want["deploymentMode"].lower() == "intratenantfw") or ( - want["deploymentMode"].lower() == "intertenantfw" - ): - net_name1 = "inside_network" - net_name2 = "outside_network" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - - if want["peeringOption"] != have["peeringOption"]: - # If peeringOption doesn't match, we cannot compare rest of the fields because they will be - # entirely different. - mismatch_reasons.append("DCNM_SRP_PO_NO_MATCH") - return "DCNM_SRP_NO_MATCH", mismatch_reasons - - if want["peeringOption"] == "StaticPeering": - - if want["routes"][0]["templateName"] != have["routes"][0]["templateName"]: - mismatch_reasons.append("DCNM_SRP_SP_IN_TN_NO_MATCH") - - if want["routes"][0]["vrfName"] != have["routes"][0]["vrfName"]: - mismatch_reasons.append("DCNM_SRP_SP_IN_VRF_NO_MATCH") - - wnv = want["routes"][0]["nvPairs"] - hnv = have["routes"][0]["nvPairs"] - - if wnv["VRF_NAME"] != hnv["VRF_NAME"]: - mismatch_reasons.append("DCNM_SRP_SP_IN_PROF_VRF_NO_MATCH") - - rc = self.dcnm_srp_compare_multi_routes( - wnv["MULTI_ROUTES"], hnv["MULTI_ROUTES"] - ) - - if rc == "DCNM_MR_NO_MATCH": - mismatch_reasons.append("DCNM_SRP_SP_IN_MR_NO_MATCH") - - if want["deploymentMode"] == "InterTenantFW": - - if ( - want["routes"][1]["templateName"] - != have["routes"][1]["templateName"] - ): - mismatch_reasons.append("DCNM_SRP_SP_OUT_TN_NO_MATCH") - - if want["routes"][1]["vrfName"] != have["routes"][1]["vrfName"]: - mismatch_reasons.append("DCNM_SRP_SP_OUT_VRF_NO_MATCH") - - wnv = want["routes"][1]["nvPairs"] - hnv = have["routes"][1]["nvPairs"] - - if wnv["VRF_NAME"] != hnv["VRF_NAME"]: - mismatch_reasons.append("DCNM_SRP_SP_OUT_PROF_VRF_NO_MATCH") - - rc = self.dcnm_srp_compare_multi_routes( - wnv["MULTI_ROUTES"], hnv["MULTI_ROUTES"] - ) - - if rc == "DCNM_MR_NO_MATCH": - mismatch_reasons.append("DCNM_SRP_SP_OUT_MR_NO_MATCH") - - elif want["peeringOption"] == "EBGPDynamicPeering": - - if want["routes"][0]["templateName"] != have["routes"][0]["templateName"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_TN_NO_MATCH") - - wnv = want["routes"][0]["nvPairs"] - hnv = have["routes"][0]["nvPairs"] - - if wnv["NEIGHBOR_IP"] != hnv["NEIGHBOR_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_NIP4_NO_MATCH") - if wnv["LOOPBACK_IP"] != hnv["LOOPBACK_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_LIP4_NO_MATCH") - if wnv["PEER_LOOPBACK_IP"] != hnv["PEER_LOOPBACK_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_PLIP4_NO_MATCH") - if wnv["NEIGHBOR_IPV6"] != hnv["NEIGHBOR_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_NIP6_NO_MATCH") - if wnv["LOOPBACK_IPV6"] != hnv["LOOPBACK_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_LIP6_NO_MATCH") - if wnv["PEER_LOOPBACK_IPV6"] != hnv["PEER_LOOPBACK_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_PLIP6_NO_MATCH") - if str(wnv["ROUTE_MAP_TAG"]) != hnv["ROUTE_MAP_TAG"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_RMT_NO_MATCH") - if wnv["DESC"] != hnv["DESC"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_DESCR_NO_MATCH") - if str(wnv["LOCAL_ASN"]) != hnv["LOCAL_ASN"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_ASN_NO_MATCH") - if str(wnv["ADVERTISE_HOST_ROUTE"]).lower() != hnv["ADVERTISE_HOST_ROUTE"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_ADV_HR_NO_MATCH") - if str(wnv["ADMIN_STATE"]).lower() != hnv["ADMIN_STATE"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_AS_NO_MATCH") - if wnv["VRF_NAME"] != hnv["VRF_NAME"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_PROF_VRF_NO_MATCH") - - if want["routes"][0]["vrfName"] != have["routes"][0]["vrfName"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_VRF_NO_MATCH") - - if want["deploymentMode"] == "InterTenantFW": - - if ( - want["routes"][1]["templateName"] - != have["routes"][1]["templateName"] - ): - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_TN_NO_MATCH") - - wnv = want["routes"][1]["nvPairs"] - hnv = have["routes"][1]["nvPairs"] - - if wnv["NEIGHBOR_IP"] != hnv["NEIGHBOR_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_NIP4_NO_MATCH") - if wnv["LOOPBACK_IP"] != hnv["LOOPBACK_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_LIP4_NO_MATCH") - if wnv["PEER_LOOPBACK_IP"] != hnv["PEER_LOOPBACK_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_PLIP4_NO_MATCH") - if wnv["NEIGHBOR_IPV6"] != hnv["NEIGHBOR_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_NIP6_NO_MATCH") - if wnv["LOOPBACK_IPV6"] != hnv["LOOPBACK_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_LIP6_NO_MATCH") - if wnv["PEER_LOOPBACK_IPV6"] != hnv["PEER_LOOPBACK_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_PLIP6_NO_MATCH") - if str(wnv["ROUTE_MAP_TAG"]) != hnv["ROUTE_MAP_TAG"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_RMT_NO_MATCH") - if wnv["DESC"] != hnv["DESC"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_DESCR_NO_MATCH") - if str(wnv["LOCAL_ASN"]) != hnv["LOCAL_ASN"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_ASN_NO_MATCH") - if ( - str(wnv["ADVERTISE_HOST_ROUTE"]).lower() - != hnv["ADVERTISE_HOST_ROUTE"] - ): - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_ADV_HR_NO_MATCH") - if str(wnv["ADMIN_STATE"]).lower() != hnv["ADMIN_STATE"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_AS_NO_MATCH") - if wnv["VRF_NAME"] != hnv["VRF_NAME"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_PROF_VRF_NO_MATCH") - - if want["routes"][1]["vrfName"] != have["routes"][1]["vrfName"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_VRF_NO_MATCH") - - if mismatch_reasons == []: - return "DCNM_SRP_MATCH", mismatch_reasons - else: - return "DCNM_SRP_NO_MATCH", mismatch_reasons - - def dcnm_srp_compare_route_peerings(self, srp): - - """ - Routine to compare route peerings from self.want and self.have. Used during merge and replace. - - Parameters: - srp (dict): The SRP payload information - - Returns: - DCNM_SRP_ADD_NEW (string): if the given SRP does not exist - DCNM_SRP_DONT_ADD (string): if given SRP already exist and is exactly the same - DCNM_SRP_MERGE (string): if given SRP already exists but not exactly the same - """ - - found = False - match_srp = [] - - if self.have == []: - return ("DCNM_SRP_ADD_NEW", None) - - match_have = [ - have - for have in self.have - if ( - (srp["peeringName"] == have["peeringName"]) - and (srp["fabricName"] == have["fabricName"]) - and (srp["serviceNodeName"] == have["serviceNodeName"]) - and (srp["attachedFabricName"] == have["attachedFabricName"]) - ) - ] - for have in match_have: - found = True - - # A matching SRP found. Check if it exactly matches with what is being requested for - rc, reasons = self.dcnm_srp_compare_common_info(srp, have) - - if rc == "DCNM_SRP_MATCH": - rc, reasons = self.dcnm_srp_compare_route_info(srp, have) - - if rc == "DCNM_SRP_MATCH": - return ("DCNM_SRP_DONT_ADD", have) - - if found == True: - # Found a matching route peering, but some of the objects don't match. - # Go ahead and merge the objects into the existing srp - return ("DCNM_SRP_MERGE", have) - else: - return ("DCNM_SRP_ADD_NEW", None) - - def dcnm_srp_get_srp_attachment_status(self, srp): - - """ - Routine to get the attachment/deployment information for a given route peering. This information - is used to implement idempotent operations. Change is deployment state will be treated as a change - in route peering during merge and replace operations. - - Parameters: - srp (dict): Route peering information - - Returns: - attached (bool): a flag indicating is the given SRP is attached - deployed (bool): a flag indicating is the given SRP is deployed - """ - - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - + "/attachments" - ) - - retries = 0 - while retries < 5: - retries += 1 - resp = dcnm_send(self.module, "GET", path) - - if resp and resp["RETURN_CODE"] != 200: - time.sleep(10) - continue - else: - break - - if resp: - resp["RETRIES"] = retries - self.result["response"].append(resp) - - attached = True - deployed = True - if ( - resp - and (resp["RETURN_CODE"] == 200) - and (resp.get("DATA", None) is not None) - ): - - for item in resp["DATA"]: - for attach in item["switchAttaches"]: - # The API will return status for all switches whether the service node is attached to it or not. - # Hence check only entries that are relevant. We can find this by checking for 'portNames' and - # vlanID which will be updated only for those switches to which the service node is attached. We - # can ignore the rest. - if (attach.get("portNames", None) is None) or ( - attach.get("vlanId", 0) == 0 - ): - continue - if attach["lanAttached"] == False: - attached = False - if (attach["attachState"] == "NA") or ( - attach["attachState"] == "PENDING" - ): - deployed = False - return (attached, deployed) - - def dcnm_srp_get_diff_merge(self): - - """ - Routine to get a list of payload information, self.diff_create/self.diff_modify to create new or modify - existing peerings. This routine updates self.diff_merge/self.diff_modify with route peering payloads - that are to created or modified. - - Parameters: - None - - Returns: - None - """ - - if not self.want: - return - - for srp in self.want: - - rc, have = self.dcnm_srp_compare_route_peerings(srp) - - if rc == "DCNM_SRP_ADD_NEW": - # A srp does not exists, create a new one. - if srp not in self.diff_create: - self.changed_dict[0]["merged"].append(srp) - self.diff_create.append(srp) - elif rc == "DCNM_SRP_MERGE": - # A srp exists and it needs to be updated - self.changed_dict[0]["modified"].append(srp) - self.diff_modify.append(srp) - - # Check the 'deploy' flag and decide if this srp is to be deployed - if have is None: - # A new route peering. If attach and deploy are set, attach and deploy - if self.deploy == True: - ditem = {} - ditem["serviceNodeName"] = srp["serviceNodeName"] - ditem["attachedFabricName"] = srp["attachedFabricName"] - ditem["fabricName"] = srp["fabricName"] - ditem["peeringName"] = srp["peeringName"] - self.diff_deploy.append(ditem) - else: - - attached, deployed = self.dcnm_srp_get_srp_attachment_status(srp) - - if self.deploy == True: - # We deploy when self.deploy is True and: - # 1. there are no changes due to this request(rc is DCNM_SRP_DONT_ADD), but the SRP is not deployed - # 2. there are changes due to this request (rc is DCNM_SRP_MERGE) - if ((rc == "DCNM_SRP_DONT_ADD") and (deployed == False)) or ( - rc == "DCNM_SRP_MERGE" - ): - ditem = {} - ditem["serviceNodeName"] = srp["serviceNodeName"] - ditem["attachedFabricName"] = srp["attachedFabricName"] - ditem["fabricName"] = srp["fabricName"] - ditem["peeringName"] = srp["peeringName"] - self.diff_deploy.append(ditem) - - if self.diff_deploy != []: - self.changed_dict[0]["deploy"].extend(self.diff_deploy) - - def dcnm_srp_get_diff_deleted(self): - - """ - Routine to get a list of payload information that will be used to delete route peerings. - This routine updates self.diff_delete with payloads that are used to delete route peerings - from the server. - - Parameters: - None - - Returns: - None - """ - - for srp in self.srp_info: - - # Get the route peering that is to be deleted. - resp = self.dcnm_srp_get_srp_info_from_dcnm(srp, "PLAYBOOK") - - # For deleting route peerings, it must first be detached and then deployed. - if resp != [] and resp not in self.diff_delete: - self.diff_delete.append(resp) - self.changed_dict[0]["deleted"].append(srp) - - def dcnm_srp_get_diff_query(self): - - """ - Routine to get route peering information based on the playbook configuration. - This routine updates self.result with SRPs requested for in the playbook if they exist on - the DCNM server. - - Parameters: - None - - Returns: - None - """ - - for srp in self.srp_info: - - # Query may or may not include the peeringName. Get the SRP info based on whether - # a peeringName is included or not. If a peeringName is not included, then get all - # peerings from the service-node. Otherwise get the specific peering that is requested - - if srp["name"] != "None": - # peeringName included - resp = self.dcnm_srp_get_srp_info_from_dcnm(srp, "PLAYBOOK") - - if resp != []: - self.result["response"].append(resp) - else: - # peeringName not included - resp = self.dcnm_srp_get_srp_info_with_service_node(srp["node_name"]) - - if resp != []: - self.result["response"].extend(resp) - self.changed_dict[0]["query"].append(srp) - - def dcnm_srp_get_diff_overridden(self): - - """ - Routine to build payload information for overridden state. This routine will build delete list, - merge list, replace list etc. based on what is required and what is already existing on the DCNM server. - This routine updates self.diff_merge that contains all route peerings that are to be created afresh and - self.diff_dlete that contains all route peerings that are to be deleted. - - Parameters: - None - - Returns: - None - """ - - # There are 3 cases with overridden state: - # 1. Peering Name and Service Node Name are given - # 2. Only Service Node Name is given - # 3. Neither given - - if self.srp_info == []: - # In this case we need to get all service nodes and all route peerings from those nodes and delete them - serv_nodes = self.dcnm_srp_get_service_nodes_from_dcnm() - else: - serv_nodes = [{"name": d["node_name"]} for d in self.srp_info] - - srp_list = [] - # From each of the service nodes get the list of all route peerings. - for snode in serv_nodes: - srps = self.dcnm_srp_get_srp_info_with_service_node(snode["name"]) - srp_list.extend(srps) - - # Before we add a route peering to self.diff_delete, make sure a matching route peering - # is not included in the current self.want. If it is, then we need not delete the same. We can just update - # the same - - delete_srps = [] - - for srp in srp_list: - match_want = [ - want - for want in self.want - if ( - (srp["peeringName"] == want["peeringName"]) - and (srp["fabricName"] == want["fabricName"]) - and (srp["serviceNodeName"] == want["serviceNodeName"]) - and (srp["attachedFabricName"] == want["attachedFabricName"]) - ) - ] - if match_want == []: - # There is no matching RP in want. The SRP can be deleted - delete_srps.append(srp) - - self.diff_delete.extend(delete_srps) - self.changed_dict[0]["deleted"].extend(delete_srps) - - # Now go and handle SRPs in self.want - self.dcnm_srp_get_diff_merge() - - def dcnm_srp_create_srp(self, srp, command): - - """ - Routine to send create payload to DCNM. - - Parameters: - srp (dict): Route peering information - command (string): REST API command, either POST or PUT - - Returns: - resp (dict): Response from DCNM server - """ - - if command == "POST": - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings" - ) - else: - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - ) - - json_payload = json.dumps(srp) - - resp = dcnm_send(self.module, command, path, json_payload) - return resp - - def dcnm_srp_detach_srp(self, srp): - - """ - Routine to detach SRP from service node. - - Parameters: - srp (dict): Route peering to be detached - - Returns: - resp (dict): Response from DCNM server - """ - - resp = None - - # First detach the route peerings - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - + "/attachments" - ) - - resp = dcnm_send(self.module, "DELETE", path, "") - return resp - - def dcnm_srp_delete_srp(self, srp): - - """ - Routine to delete an SRP from service node. - - Parameters: - srp (dict): Route peering information that is to be deleted - - Returns: - resp (dict): Response from DCNM server - """ - - # Delete the route peering - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - ) - resp = dcnm_send(self.module, "DELETE", path, "") - return resp - - def dcnm_srp_config_save_and_deploy(self): - - """ - Routine to save and deploy configuration for the entire box. - - Parameters: - None - - Returns: - resp (dict): Response from DCNM server - """ - - path = ( - "/rest/control/fabrics/" + self.module.params["fabric"] + "/config-deploy" - ) - - resp = dcnm_send(self.module, "POST", path, "") - return resp - - def dcnm_srp_deploy_srp(self, srp, command): - - """ - Routine to deploy SRP on the service node. - - Parameters: - srp (dict): Route peering information to be deployed - command (string): REST API command which is POST - - Returns: - resp (dict): Response from DCNM server - """ - - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - + "/deployments" - ) - - resp = dcnm_send(self.module, command, path, "") - return resp - - def dcnm_srp_check_unauthorized_error_in_resp(self, resp): - - """ - Routine to check for "unauthorized" errors in which case the conncetion must be reset by logging out and - logging in again. - - Parameters: - resp (dict): Response which has to be checked for "unauthorized error" - - Returns: - rc (string): unauthorized_error, if resp["DATA"]["error"]["code"] is UserUnauthorized - other_error, otherwise - """ - - rc = "other_error" - if resp.get("DATA"): - if resp["DATA"].get("error"): - if resp["DATA"]["error"].get("code") == "UserUnauthorized": - # We have seen "unauthorized error" from DCNM even though the token has been allocated and the connection timeout - # has not happened. As per suggestions from L4-L7 services team we will reset token by logging out and logging in - # again so that a new token is obtained - dcnm_reset_connection(self.module) - rc = "unauthorized_error" - return rc - - def dcnm_srp_send_message_to_dcnm(self): - - """ - Routine to push payloads to DCNM server. This routine implements reqquired error checks and retry mechanisms to handle - transient errors. This routine checks self.diff_create, self.diff_modify, self.diff_delete and self.diff_deploy lists - and push appropriate requests to DCNM. - - Parameters: - None - - Returns: - None - """ - - resp = None - create_flag = False - modify_flag = False - delete_flag = False - deploy_flag = False - - for srp in self.diff_create: - retries = 0 - command = "POST" - while retries < 10: - retries += 1 - resp = self.dcnm_srp_create_srp(srp, command) - if resp.get("RETURN_CODE") == 200: - create_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - rc = self.dcnm_srp_check_unauthorized_error_in_resp(resp) - - # There may be a temporary issue on the server. so we should try again. In case - # of create or modify, the peering may have been created/updated, but the error may - # be due to the attach. So check if the peering is created and if attach flag is set. - # If so then try attaching the peering and do not try to recreate - get_resp = self.dcnm_srp_get_srp_info_from_dcnm(srp, "PAYLOAD") - if get_resp != []: - # Since the peering is already created, use PUT to update the peering again with - # the same payload - command = "PUT" - time.sleep(10) - continue - resp["RETRIES"] = retries - self.result["response"].append(resp) - - for srp in self.diff_modify: - retries = 0 - while retries < 10: - retries += 1 - resp = self.dcnm_srp_create_srp(srp, "PUT") - if resp.get("RETURN_CODE") == 200: - modify_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - rc = self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - resp["RETRIES"] = retries - self.result["response"].append(resp) - - for srp in self.diff_delete: - retries = 0 - while retries < 10: - retries += 1 - resp = self.dcnm_srp_detach_srp(srp) - if (resp is not None) and (resp.get("RETURN_CODE") == 200): - delete_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - rc = self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - if resp is not None: - resp["RETRIES"] = retries - self.result["response"].append(resp) - - # For delete case we have done a detach. do a deploy before actual delete - for srp in self.diff_delete: - retries = 0 - while retries < 10: - retries += 1 - resp = self.dcnm_srp_deploy_srp(srp, "POST") - - if (resp is not None) and (resp.get("RETURN_CODE") == 200): - delete_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - rc = self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - resp["RETRIES"] = retries - self.result["response"].append(resp) - - if delete_flag is True: - time.sleep(40) - - for srp in self.diff_delete: - retries = 0 - deploy_in_prog = False - while retries < 25: - retries += 1 - resp = self.dcnm_srp_delete_srp(srp) - if (resp is not None) and (resp.get("RETURN_CODE") == 200): - delete_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - rc = self.dcnm_srp_check_unauthorized_error_in_resp(resp) - - if retries == 15: - # We failed to delete even after all retries. Try a config save and deploy which - # may pull out of the situation - - resp = self.dcnm_srp_config_save_and_deploy() - self.result["response"].append(resp) - elif deploy_in_prog == False: - # We will require a deploy here. Otherwise we may see delete errors in some cases - # indicating that a deploy operation is still in progress and peering cannot be deleted - resp = self.dcnm_srp_deploy_srp(srp, "POST") - if resp.get("RETURN_CODE") == 200: - deploy_in_prog = True - else: - rc = self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - if resp is not None: - resp["RETRIES"] = retries - self.result["response"].append(resp) - - for srp in self.diff_deploy: - retries = 0 - while retries < 10: - retries += 1 - resp = self.dcnm_srp_deploy_srp(srp, "POST") - if resp.get("RETURN_CODE") == 200: - deploy_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - rc = self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - resp["RETRIES"] = retries - self.result["response"].append(resp) - - self.result["changed"] = ( - create_flag or modify_flag or delete_flag or deploy_flag - ) - - -def main(): - - """ main entry point for module execution - """ - element_spec = dict( - fabric=dict(required=True, type="str"), - service_fabric=dict(required=True, type="str"), - config=dict(required=False, type="list"), - state=dict( - type="str", - default="merged", - choices=["merged", "deleted", "replaced", "query", "overridden"], - ), - deploy=dict(required=False, type="bool", default=True), - attach=dict(required=False, type="str", default="default"), - check_mode=dict(required=False, type="bool", default=False), - debug=dict(required=False, type="bool", default=False), - ) - - module = AnsibleModule(argument_spec=element_spec, supports_check_mode=True) - - dcnm_srp = DcnmServiceRoutePeering(module) - - dcnm_srp.result["StartTime"] = datetime.now().strftime("%H:%M:%S") - - dcnm_srp.deploy = module.params["deploy"] - if (module.params["attach"] == "default") or ( - module.params["attach"].lower() == "true" - ): - dcnm_srp.attach = True - else: - dcnm_srp.attach = False - - dcnm_srp.debug = module.params["debug"] - - state = module.params["state"] - - if not dcnm_srp.config: - if state == "merged" or state == "deleted" or state == "query": - module.fail_json( - msg="'config' element is mandatory for state '{}', given = '{}'".format( - state, dcnm_srp.config - ) - ) - - dcnm_srp.dcnm_srp_validate_input() - - if (module.params["state"] != "query") and (module.params["state"] != "deleted"): - - dcnm_srp.dcnm_srp_get_want() - dcnm_srp.dcnm_srp_get_have() - - # self.want would have defaulted all optional objects not included in playbook. But the way - # these objects are handled is different between 'merged' and 'replaced' states. For 'merged' - # state, objects not included in the playbook must be left as they are and for state 'replaced' - # they must be purged or defaulted. - - dcnm_srp.dcnm_srp_update_want() - - if (module.params["state"] == "merged") or (module.params["state"] == "replaced"): - dcnm_srp.dcnm_srp_get_diff_merge() - - if module.params["state"] == "deleted": - dcnm_srp.dcnm_srp_get_diff_deleted() - - if module.params["state"] == "query": - dcnm_srp.dcnm_srp_get_diff_query() - - if module.params["state"] == "overridden": - dcnm_srp.dcnm_srp_get_diff_overridden() - - dcnm_srp.result["diff"] = dcnm_srp.changed_dict - - if dcnm_srp.diff_create or dcnm_srp.diff_modify or dcnm_srp.diff_delete: - dcnm_srp.result["changed"] = True - - if module.params["check_mode"]: - dcnm_srp.result["changed"] = False - dcnm_srp.result["EndTime"] = datetime.now().strftime("%H:%M:%S") - module.exit_json(**dcnm_srp.result) - - dcnm_srp.dcnm_srp_send_message_to_dcnm() - - dcnm_srp.result["EndTime"] = datetime.now().strftime("%H:%M:%S") - module.exit_json(**dcnm_srp.result) - - -if __name__ == "__main__": - main() diff --git a/tests/integration/targets/dcnm_service_node/defaults/main.yaml b/tests/integration/targets/dcnm_service_node/defaults/main.yaml deleted file mode 100644 index 55a93fc23..000000000 --- a/tests/integration/targets/dcnm_service_node/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/meta/main.yaml b/tests/integration/targets/dcnm_service_node/meta/main.yaml deleted file mode 100644 index 5514b6a40..000000000 --- a/tests/integration/targets/dcnm_service_node/meta/main.yaml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml b/tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml deleted file mode 100644 index 7081e21b6..000000000 --- a/tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: collect dcnm test cases - find: - paths: "{{ role_path }}/tests/dcnm" - patterns: "{{ testcase }}.yaml" - connection: local - register: dcnm_cases - -- set_fact: - test_cases: - files: "{{ dcnm_cases.files }}" - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=httpapi) - include: "{{ test_case_to_run }} ansible_connection=httpapi connection={{ dcnm }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tasks/main.yaml b/tests/integration/targets/dcnm_service_node/tasks/main.yaml deleted file mode 100644 index 78c5fb834..000000000 --- a/tests/integration/targets/dcnm_service_node/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: dcnm.yaml, tags: ['dcnm'] } \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml deleted file mode 100644 index 7066c3c7e..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml +++ /dev/null @@ -1,344 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: DELETED - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: DELETED - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: DELETED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### DELETED ## -############################################### - -- name: DELETED - Delete Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: DELETED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - Delete Service Node with single switch - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with 2 switches and vPC Interface - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - Delete Service Node - WITHOUT ANY CONFIG ELEMENT - cisco.dcnm.dcnm_service_node: &conf2 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - conf2 - Idempotence - cisco.dcnm.dcnm_service_node: *conf2 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - Delete Service Node - WITHOUT ANY CONFIG ELEMENT - cisco.dcnm.dcnm_service_node: &conf3 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - conf3 - Idempotence - cisco.dcnm.dcnm_service_node: *conf3 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -################################################ -#### CLEAN-UP ## -################################################ - -- name: DELETED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml deleted file mode 100644 index 8ac75ef5f..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml +++ /dev/null @@ -1,768 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: MERGED - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: MERGED - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -############################################### -### MERGED ## -############################################### - -- name: MERGED - Create Service Node with form factor virtual - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with form factor physical - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with type load balancer - cisco.dcnm.dcnm_service_node: &conf2 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: load_balancer - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "ADC"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf2 - Idempotence - cisco.dcnm.dcnm_service_node: *conf2 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with type virtual network function - cisco.dcnm.dcnm_service_node: &conf3 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf3 - Idempotence - cisco.dcnm.dcnm_service_node: *conf3 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with check mode set to true - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - check_mode: true - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - '(result["response"] | length) == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: &conf4 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf4 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 2 switches and vPC Interface with type load balancer - cisco.dcnm.dcnm_service_node: &conf5 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: load_balancer - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "ADC"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf5 - Idempotence - cisco.dcnm.dcnm_service_node: *conf5 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 2 switches and vPC Interface with type virtual network function - cisco.dcnm.dcnm_service_node: &conf6 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf6 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with default state 'merged'/ without providing state explicitily - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 3 tasks having 3 different types of type and single form factor virtual - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-13 - type: load_balancer - form_factor: virtual - svc_int_name: svc3 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Virtual"' - - 'result.response[1].DATA.interfaceName == "svc2"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "Firewall"' - - 'result.response[1].DATA.name == "SN-12"' - - 'result.response[2].RETURN_CODE == 200' - - 'result.response[2].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[2].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[2].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[2].DATA.formFactor == "Virtual"' - - 'result.response[2].DATA.interfaceName == "svc3"' - - 'result.response[2].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[2].DATA.type == "ADC"' - - 'result.response[2].DATA.name == "SN-13"' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 3 tasks having 3 different types of type and form factor physical - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-12 - type: firewall - form_factor: physical - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-13 - type: load_balancer - form_factor: physical - svc_int_name: svc3 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Physical"' - - 'result.response[1].DATA.interfaceName == "svc2"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "Firewall"' - - 'result.response[1].DATA.name == "SN-12"' - - 'result.response[2].RETURN_CODE == 200' - - 'result.response[2].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[2].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[2].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[2].DATA.formFactor == "Physical"' - - 'result.response[2].DATA.interfaceName == "svc3"' - - 'result.response[2].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[2].DATA.type == "ADC"' - - 'result.response[2].DATA.name == "SN-13"' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 2 switches and invalid vpc interface - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc2 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -- name: MERGED - Create Service Node with 2 switches and invalid vpc name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPortchannel12 - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"if two switches are provided, vpc is only interface option" in result.msg' - -- name: MERGED - Create Service Node with 1 switch and valid vpc name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"For 1 switch, vpc is not the interface option" in result.msg' - -- name: MERGED - Create Service Node with more than 2 switch and valid vpc name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch1 }}" - - "{{ ansible_switch2 }}" - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Upto 2 switches only allowed" in result.msg' - -- name: MERGED - Create Service Node without required parameter - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Required parameter not found" in result.msg' - -- name: MERGED - Create Service Node with wrong type - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: karth - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Invalid choice provided" in result.msg' - -- name: MERGED - Create Service Node with wrong formfactor - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: not - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Invalid choice provided" in result.msg' - -############################################### -### CLEAN-UP ## -############################################### - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml deleted file mode 100644 index e28ea2877..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml +++ /dev/null @@ -1,281 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: OVERRIDDEN - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: OVERRIDDEN - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: OVERRIDDEN - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: OVERRIDDEN - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: OVERRIDDEN - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### OVERRIDDEN ## -############################################### - -- name: OVERRIDDEN - Update service node - delete and create - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: overridden - config: - - name: SN-12 - type: load_balancer - form_factor: physical - svc_int_name: svc12 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].METHOD == "DELETE"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Physical"' - - 'result.response[1].DATA.interfaceName == "svc12"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "ADC"' - - 'result.response[1].DATA.name == "SN-12"' - -- name: OVERRIDDEN - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: OVERRIDDEN - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: OVERRIDDEN - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: OVERRIDDEN - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: OVERRIDDEN - Create 2 Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc11 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: SN-12 - type: load_balancer - form_factor: virtual - svc_int_name: svc12 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch2 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc11"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Virtual"' - - 'result.response[1].DATA.interfaceName == "svc12"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "ADC"' - - 'result.response[1].DATA.name == "SN-12"' - -- name: OVERRIDDEN - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: OVERRIDDEN - Create and Delete new service nodes - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: overridden - config: - - name: SN-13 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc13 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: SN-14 - type: firewall - form_factor: virtual - svc_int_name: svc14 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch2 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].METHOD == "DELETE"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].METHOD == "DELETE"' - - 'result.response[2].RETURN_CODE == 200' - - 'result.response[2].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[2].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[2].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[2].DATA.formFactor == "Virtual"' - - 'result.response[2].DATA.interfaceName == "svc13"' - - 'result.response[2].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[2].DATA.type == "VNF"' - - 'result.response[2].DATA.name == "SN-13"' - - 'result.response[3].RETURN_CODE == 200' - - 'result.response[3].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[3].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[3].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[3].DATA.formFactor == "Virtual"' - - 'result.response[3].DATA.interfaceName == "svc14"' - - 'result.response[3].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[3].DATA.type == "Firewall"' - - 'result.response[3].DATA.name == "SN-14"' - -- name: OVERRIDDEN - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: OVERRIDDEN - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: OVERRIDDEN - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -############################################## -## CLEAN-UP ## -############################################## - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml deleted file mode 100644 index 756b3d973..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml +++ /dev/null @@ -1,396 +0,0 @@ -############################################## -## SETUP ## -############################################## -- -- name: QUERY - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: QUERY - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: QUERY - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: QUERY - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### QUERY ## -############################################### - -- name: QUERY - Query the Service Node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: QUERY - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: QUERY - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query the - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query without the config element - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: QUERY - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: QUERY - Create Service Node with single/mutiple switch - 2 tasks - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Virtual"' - - 'result.response[1].DATA.interfaceName == "svc2"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "Firewall"' - - 'result.response[1].DATA.name == "SN-12"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query the - Create Service Node with single/mutiple switch - 2 tasks - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - "{{ ansible_switch1 }}" - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - - 'result.response[1].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].formFactor == "Virtual"' - - 'result.response[1].interfaceName == "svc2"' - - 'result.response[1].linkTemplateName == "service_link_trunk"' - - 'result.response[1].type == "Firewall"' - - 'result.response[1].name == "SN-12"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query without the config element - 2 tasks - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - - 'result.response[1].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].formFactor == "Virtual"' - - 'result.response[1].interfaceName == "svc2"' - - 'result.response[1].linkTemplateName == "service_link_trunk"' - - 'result.response[1].type == "Firewall"' - - 'result.response[1].name == "SN-12"' - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: QUERY - Query the non available Service Node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11111111 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -############################################### -### CLEAN-UP ## -############################################### - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml deleted file mode 100644 index 8f2f95ff6..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml +++ /dev/null @@ -1,421 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: REPLACED - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: REPLACED - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: REPLACED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: REPLACED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: REPLACED - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### REPLACED ## -############################################### - -- name: REPLACED - Replace Service Node with form factor physical - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: REPLACED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with form factor virtual - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: REPLACED - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: REPLACED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: REPLACED - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with form factor physical - cisco.dcnm.dcnm_service_node: &conf2 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - conf2 - Idempotence - cisco.dcnm.dcnm_service_node: *conf2 - register: result - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with type load balancer - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: load_balancer - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "ADC"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with type virtual network function - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: virtual_network_function - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with a new creation of service node, since the sn is not created already - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11111111111 - type: firewall - form_factor: physical - svc_int_name: svc11 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc11"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11111111111"' - -- name: REPLACED - Replace Service Node with not supported change of already created svc int name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc111111111 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - Replace Service Node with not supported change of already created attach interface - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc11 - attach_interface: "{{ ansible_int2 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - Replace Service Node with not supported change of already created attached switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc11 - attach_interface: "{{ ansible_int2 }}" - switches: - - "{{ ansible_switch5 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -############################################### -### CLEAN-UP ## -############################################### - -- name: REPLACED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_route_peering/defaults/main.yaml b/tests/integration/targets/dcnm_service_route_peering/defaults/main.yaml deleted file mode 100644 index 5f709c5aa..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" diff --git a/tests/integration/targets/dcnm_service_route_peering/meta/main.yaml b/tests/integration/targets/dcnm_service_route_peering/meta/main.yaml deleted file mode 100644 index f280ef854..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/meta/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_dcnm_service_route_peering diff --git a/tests/integration/targets/dcnm_service_route_peering/tasks/dcnm.yaml b/tests/integration/targets/dcnm_service_route_peering/tasks/dcnm.yaml deleted file mode 100644 index e54dbdf26..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/tasks/dcnm.yaml +++ /dev/null @@ -1,105 +0,0 @@ ---- -- name: collect dcnm test cases - find: - paths: "{{ role_path }}/tests/dcnm" - patterns: "{{ testcase }}.yaml" - connection: local - register: dcnm_cases - -- set_fact: - test_cases: - files: "{{ dcnm_cases.files }}" - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=httpapi) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - -- name: Cleanup - Delete Service Nodes - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - state: deleted - config: - - name: "{{ ansible_snode_1 }}" - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_att_intf1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: "{{ ansible_snode_2 }}" - type: load_balancer - form_factor: physical - svc_int_name: svc2 - attach_interface: "{{ ansible_att_intf2 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -- name: Cleanup - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: Cleanup - Delete all VRFs - cisco.dcnm.dcnm_vrf: - fabric: "{{ ansible_it_fabric }}" - state: deleted - config: - - vrf_name: "{{ ansible_vrf_11 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_12 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_21 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_22 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_31 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_32 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_41 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_42 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_51 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_52 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_61 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_62 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_71 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_72 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' diff --git a/tests/integration/targets/dcnm_service_route_peering/tasks/main.yaml b/tests/integration/targets/dcnm_service_route_peering/tasks/main.yaml deleted file mode 100644 index 78c5fb834..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: dcnm.yaml, tags: ['dcnm'] } \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/.dcnm_service_route_peering_delete.yaml.swp b/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/.dcnm_service_route_peering_delete.yaml.swp deleted file mode 100644 index 59ebb23a019fbc4a1b2c2077ceee9a2e0706f337..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI3OKjXk7{>?t;MG!~oRDaz2_h|uch{RoTT2yclQasjNl8;)QM7UF*^L{oZESBI zw4tZMrIkRv^#Xze^opQWIUsKI%BvKP2sogY18_m2g}+~0@5WAcQzaZ2OTV=}kI$dK znfW~5WHOa|VW>d&WpV_^Lxc>STbvwzX3K_;G(swss;ZSu!^>LkC=`zM4-JkC3k6{` zx34?3=tfsJ{ZB|`Yv>3BBqa0T9>!+70s!V4t%PhzhJ=G*UgIi!7 zEwGhz9gZ6Y?&22b=*5U>+Di1y6&WUtlKfnq;Es+ZQfGD9C>nBwNz}GP!7)T3656N$rIFMI zeG|lL)@*OFJSWk7E+@j6rHt8XzddxXtetU2}Mz)i;Gc1 z*GWu!q^O zQo2U-BSgctqND-RLZ?d@BB9g-l~WXMW{8MuGepo-cQ8ciI|8M#G16T7H8(~AgQgFW zwI3sa2F(ui+lG#4*dyN->KPO40s*q-Jb7;mWA z8MyY_q9*DdYT#+1_l|oB$4^gk6S0TJ1PL_oSVLpN;THw((sB zt|U*{no{q{G`F@XFUa^Pohr-8~kjmh|P)qQ=*sd zvzhENs%oVYv#}MC8m1wzdChULMUaNCKz(sE+&JiflmR$*wWe1kQ6(rlN3}Z3OO9IJAqSSF=R0*>h zZ||h)6$_4Kdu%@G!?v`iMJ>FX8D$l7mcfIf z3VzGf3m)#=*&l_IJrcEK{ke5#@5TQc5esibZ0yDV(cjlEA;!N5D&Psw4t_w4|2B9F z41!yT?QepQ!3;PKc7bb%?Y{$`gA3q8a2}iiWgvjx5$j(Bi=Yo20^Q(Aa1-(T_uv{h z4XQu}lb{H);0EIRtKeJk1-J~(ftSG!@FU*m0x*FACc!A!12zHgeK!Dpa0_q?a0_q? za0~ozEf7p1nu+whl1)T=Ua=tJ3o68-J}<#LAZ2$D_l>uCF?8F+cy0oh{&EO{$CFfN zM%kU-s4SF6lkSWQJNy=WzksjI0Q#;L2RT4DGB?};lb7ZvZkjg5SiA5|0lU)+D8T8aD4C~1f z?aqa1b28R)N~Rqwr$;mIv7j8}I67k%MFCX7dJ19%)$wop`-ThDHNDxlKE3yLpGzIRtL@XSUA?0&oxX15b-!h!-K4dncmN;uU+= 7' - - - name: Query non-existing route peerings - cisco.dcnm.dcnm_service_route_peering: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1-ABS # optional - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP2-ABS # optional - node_name: "{{ ansible_snode_2 }}" # mandatory - state: query - register: result - - - assert: - that: - - 'result.changed == false' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 0' - - '(result["diff"][0]["query"] | length) == 2' - - '(result.response | length) == 0' - -############################################## -## CLEANUP ## -############################################## - - always: - - - - name: Delete all created route peerings - cisco.dcnm.dcnm_service_route_peering: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-ADC-RP4 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP5 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP6 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP7 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - state: deleted - register: result - when: IT_CONTEXT is not defined - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - when: IT_CONTEXT is not defined - diff --git a/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_replace.yaml b/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_replace.yaml deleted file mode 100644 index 898c6ee19..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_replace.yaml +++ /dev/null @@ -1,883 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: Remove local log file - local_action: command rm -f srp.log - -- name: Delete route peerings - cisco.dcnm.dcnm_service_route_peering: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-ADC-RP4 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP5 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP6 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP7 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - state: deleted - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - - -- block: - -############################################## -## MERGE ## -############################################## - - - name: Create different non-existing service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: &dcnm_srp_all - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 101 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2001:db01::1/64 # optional, default is '' - vlan_name: rp1-sn1-inside # optional, default is '' - int_descr: "RP1 SN1 inside interface" # optional, default is '' - tag: 11111 # optional, default is 12345 - next_hop: 192.161.1.100 # mandatory - outside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 102 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2001:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside # optional, default is '' - int_descr: "RP1 SN1 outside interface" # optionL, default is '' - tag: 11112 # optional, default is 12345 - rev_next_hop: 192.161.2.100 # optional, default is '' - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: static # optional, default is static, choices=[static, ebgp] - inside_network: # - vrf: "{{ ansible_vrf_21 }}" # mandatory - name: rp2-sn1-inside-net # mandatory - vlan_id: 201 # mandatory - profile: - ipv4_gw: 192.162.1.1/24 # mandatory - ipv6_gw: 2002:db01::1/64 # optional, default is '' - vlan_name: rp2-sn1-inside # optional, default is '' - int_descr: "RP2 SN1 inside interface" # optional, default is '' - static_route: # optional, default is '' - - subnet: 20.20.20.0/24 - next_hop: - - 120.120.120.100 - - 121.121.121.100 - tag: 21111 # optional, default is 12345 - outside_network: # - vrf: "{{ ansible_vrf_22 }}" # mandatory - name: rp2-sn1-outside-net # mandatory - vlan_id: 202 # mandatory - profile: - ipv4_gw: 192.162.2.1/24 # mandatory - ipv6_gw: 2002:db02::1/64 # optional, default is '' - vlan_name: rp2-sn1-outside # optional, default is '' - int_descr: "RP2 SN1 outside interface" # optional, default is '' - static_route: # optional, default is '' - - subnet: 21.21.21.0/24 - next_hop: - - 122.122.122.100 - - 123.123.123.100 - tag: 22222 # optional, default is 12345 - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - inside_network: - vrf: "{{ ansible_vrf_31 }}" # mandatory - name: rp3-sn1-inside-net # mandatory - vlan_id: 301 # mandatory - profile: - ipv4_gw: 192.163.1.1/24 # mandatory - ipv6_gw: 2003:db01::1/64 # optional, default is '' - vlan_name: rp3-sn1-inside # optional, default is '' - int_descr: "RP3 SN1 inside interface" # optional, default is '' - tag: 31111 # optional, default is 12345 - ipv4_neighbor: 31.31.31.1 # mandatory - ipv4_lo: 31.31.31.2 # mandatory - ipv4_vpc_peer_lo: 31.31.31.3 # optional, default is '' - ipv6_neighbor: 2003:3131::1 # optional, default is '' - ipv6_lo: 2003:3132::1 # optional, default is '' - ipv6_vpc_peer_lo: 2003:3133::1 # optional, default is '' - route_map_tag: 33111 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 inside interface" # optional, default is '' - local_asn: 65301 # optional, default is '' - adv_host: true # optional, default is false - outside_network: - vrf: "{{ ansible_vrf_32 }}" # mandatory - name: rp3-sn1-outside-net # mandatory - vlan_id: 302 # mandatory - profile: - ipv4_gw: 192.163.2.1/24 # mandatory - ipv6_gw: 2003:db02::1/64 # optional, default is '' - vlan_name: rp3-sn1-outside # optional, default is '' - int_descr: "RP3 SN1 outside interface" # optional, default is '' - tag: 31112 # optional, default is 12345 - ipv4_neighbor: 131.131.131.1 # mandatory - ipv4_lo: 131.131.131.2 # mandatory - ipv4_vpc_peer_lo: 131.131.131.3 # optional, default is '' - ipv6_neighbor: 2003:8383::1 # optional, default is '' - ipv6_lo: 2003:8384::1:100:1 # optional, default is '' - ipv6_vpc_peer_lo: 2003:8385::1 # optional, default is '' - route_map_tag: 31113 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 outside interface" # optional, default is '' - local_asn: 65302 # optional, default is '' - adv_host: true # optional, default is false - - - name: IT-ADC-RP4 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_41 }}" # mandatory - name: rp4-sn2-first-arm # mandatory - vlan_id: 401 # mandatory - profile: - ipv4_gw: 192.164.1.1/24 # mandatory - ipv6_gw: 2004:db01::1/64 # optional, default is '' - vlan_name: rp4-sn2-first-arm # optional, default is '' - int_descr: "RP4 SN2 first arm intf" # optional, default is '' - tag: 41111 # optional, default is 12345 - ipv4_neighbor: 41.41.41.1 # mandatory - ipv4_lo: 41.41.41.2 # mandatory - ipv4_vpc_peer_lo: 41.41.41.3 # optional, default is '' - ipv6_neighbor: 2004:4141::1 # optional, default is '' - ipv6_lo: 2004:4142::1 # optional, default is '' - ipv6_vpc_peer_lo: 2004:4143::1 # optional, default is '' - route_map_tag: 41112 # optional, default is 12345 - neigh_int_descr: "RP4 SN2 first arm" # optional, default is '' - local_asn: 65401 # optional, default is '' - adv_host: true # optional, default is false - rev_next_hop: 192.164.1.100 # mandatory - - - name: IT-ADC-RP5 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-first-arm # mandatory - vlan_id: 501 # mandatory - profile: - ipv4_gw: 192.165.1.1/24 # mandatory - ipv6_gw: 2005:db01::1/64 # optional, default is '' - vlan_name: rp5-sn2-first-arm # optional, default is '' - int_descr: "RP5 SN2 first arm intf" # optional, default is '' - tag: 51111 # optional, default is 12345 - ipv4_neighbor: 51.51.51.1 # mandatory - ipv4_lo: 51.51.51.2 # mandatory - ipv4_vpc_peer_lo: 51.51.51.3 # optional, default is '' - ipv6_neighbor: 2005:5151::1 # optional, default is '' - ipv6_lo: 2005:5152::1 # optional, default is '' - ipv6_vpc_peer_lo: 2005:5153::1 # optional, default is '' - route_map_tag: 51115 # optional, default is 12345 - neigh_int_descr: "RP5 SN2 first arm" # optional, default is '' - local_asn: 65501 # optional, default is '' - adv_host: true # optional, default is false - second_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-second-arm # mandatory - vlan_id: 502 # mandatory - profile: - ipv4_gw: 192.165.2.1/24 # mandatory - ipv6_gw: 2005:db02::1/64 # optional, default is '' - vlan_name: rp5-sn2-second-arm # optional, default is '' - int_descr: "RP5 SN2 second arm intf" # optional, default is '' - tag: 51112 # optional, default is 12345 - rev_next_hop: 192.165.1.100 # mandatory - - - name: IT-ADC-RP6 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_61 }}" # mandatory - name: rp6-sn2-first-arm # mandatory - vlan_id: 601 # mandatory - profile: - ipv4_gw: 192.166.1.1/24 # mandatory - ipv6_gw: 2006:db01::1/64 # optional, default is '' - vlan_name: rp6-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 61111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 61.61.61.1/24 - next_hop: - - 161.161.161.1 - - 162.162.162.1 - - subnet: 22.0.0.0/24 - next_hop: - - 163.163.163.1 - - 164.164.164.1 - rev_next_hop: 192.166.1.100 # mandatory - - - name: IT-ADC-RP7 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-first-arm # mandatory - vlan_id: 701 # mandatory - profile: - ipv4_gw: 192.167.1.1/24 # mandatory - ipv6_gw: 2007:db01::1/64 # optional, default is '' - vlan_name: rp7-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 71111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 71.71.71.1/24 - next_hop: - - 171.171.171.1 - - 172.172.172.1 - second_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-second-arm # mandatory - vlan_id: 702 # mandatory - profile: - ipv4_gw: 192.167.2.1/24 # mandatory - ipv6_gw: 2007:db02::1/64 # optional, default is '' - vlan_name: rp7-sn2-second-arm # optional, default is '' - int_descr: "RP7 SN2 second arm intf" # optional, default is '' - tag: 71112 # optional, default is 12345 - rev_next_hop: 192.167.1.100 # mandatory - attach: true - deploy: true - state: replaced - register: result - - - assert: - that: - - 'result.changed == true' - - '(result["diff"][0]["merged"] | length) == 7' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 0' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 7' - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - - - name: Timeout - sleep for 180 seconds for DCNM to completely update the state - wait_for: - timeout: 180 - - -############################################## -## REPLACE RP1-RP3 ## -############################################## - - - name: Replace service route peerings RP1 to RP3 - cisco.dcnm.dcnm_service_route_peering: &dcnm_srp_rep_13 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 191 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2101:db01::01/64 # optional, default is '' - vlan_name: rp1-sn1-inside-rep # optional, default is '' - int_descr: "RP1 SN1 inside interface - REP" # optional, default is '' - tag: 11101 # optional, default is 12345 - next_hop: 192.161.1.200 # mandatory - outside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 192 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2101:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside-rep # optional, default is '' - int_descr: "RP1 SN1 outside interface- REP" # optionL, default is '' - tag: 11102 # optional, default is 12345 - rev_next_hop: 192.161.2.200 # optional, default is '' - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: static # optional, default is static, choices=[static, ebgp] - inside_network: # - vrf: "{{ ansible_vrf_21 }}" # mandatory - name: rp2-sn1-inside-net # mandatory - vlan_id: 291 # mandatory - profile: - ipv4_gw: 192.162.1.1/24 # mandatory - ipv6_gw: 2102:db01::1/64 # optional, default is '' - vlan_name: rp2-sn1-inside-rep # optional, default is '' - int_descr: "RP2 SN1 inside interface - REP" # optional, default is '' - static_route: # optional, default is '' - - subnet: 20.20.90.0/24 - next_hop: - - 120.120.190.100 - - 121.121.191.100 - tag: 21101 # optional, default is 12345 - outside_network: # - vrf: "{{ ansible_vrf_22 }}" # mandatory - name: rp2-sn1-outside-net # mandatory - vlan_id: 292 # mandatory - profile: - ipv4_gw: 192.162.2.1/24 # mandatory - ipv6_gw: 2102:db02::1/64 # optional, default is '' - vlan_name: rp2-sn1-outside-rep # optional, default is '' - int_descr: "RP2 SN1 outside interface - REP" # optional, default is '' - static_route: # optional, default is '' - - subnet: 21.21.29.0/24 - next_hop: - - 122.122.129.100 - - 123.123.129.100 - tag: 22202 # optional, default is 12345 - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - inside_network: - vrf: "{{ ansible_vrf_31 }}" # mandatory - name: rp3-sn1-inside-net # mandatory - vlan_id: 391 # mandatory - profile: - ipv4_gw: 192.163.1.1/24 # mandatory - ipv6_gw: 2103:db01::1/64 # optional, default is '' - vlan_name: rp3-sn1-inside-rep # optional, default is '' - int_descr: "RP3 SN1 inside interface - REP" # optional, default is '' - tag: 31101 # optional, default is 12345 - ipv4_neighbor: 31.31.39.1 # mandatory - ipv4_lo: 31.31.39.2 # mandatory - ipv4_vpc_peer_lo: 31.31.39.3 # optional, default is '' - ipv6_neighbor: 2103:3131::1 # optional, default is '' - ipv6_lo: 2103:3132::1 # optional, default is '' - ipv6_vpc_peer_lo: 2103:3133::1 # optional, default is '' - route_map_tag: 33101 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 inside interface - REP" # optional, default is '' - local_asn: 65391 # optional, default is '' - adv_host: true # optional, default is false - outside_network: - vrf: "{{ ansible_vrf_32 }}" # mandatory - name: rp3-sn1-outside-net # mandatory - vlan_id: 302 # mandatory - profile: - ipv4_gw: 192.163.2.1/24 # mandatory - ipv6_gw: 2103:db02::1/64 # optional, default is '' - vlan_name: rp3-sn1-outside-rep # optional, default is '' - int_descr: "RP3 SN1 outside interface - REP" # optional, default is '' - tag: 31102 # optional, default is 12345 - ipv4_neighbor: 131.131.139.1 # mandatory - ipv4_lo: 131.131.139.2 # mandatory - ipv4_vpc_peer_lo: 131.131.139.3 # optional, default is '' - ipv6_neighbor: 2103:8383::1 # optional, default is '' - ipv6_lo: 2103:8384::1:100:1 # optional, default is '' - ipv6_vpc_peer_lo: 2103:8385::1 # optional, default is '' - route_map_tag: 31103 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 outside interface - REP" # optional, default is '' - local_asn: 65392 # optional, default is '' - adv_host: true # optional, default is false - - - name: IT-ADC-RP4 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_41 }}" # mandatory - name: rp4-sn2-first-arm # mandatory - vlan_id: 401 # mandatory - profile: - ipv4_gw: 192.164.1.1/24 # mandatory - ipv6_gw: 2004:db01::1/64 # optional, default is '' - vlan_name: rp4-sn2-first-arm # optional, default is '' - int_descr: "RP4 SN2 first arm intf" # optional, default is '' - tag: 41111 # optional, default is 12345 - ipv4_neighbor: 41.41.41.1 # mandatory - ipv4_lo: 41.41.41.2 # mandatory - ipv4_vpc_peer_lo: 41.41.41.3 # optional, default is '' - ipv6_neighbor: 2004:4141::1 # optional, default is '' - ipv6_lo: 2004:4142::1 # optional, default is '' - ipv6_vpc_peer_lo: 2004:4143::1 # optional, default is '' - route_map_tag: 41112 # optional, default is 12345 - neigh_int_descr: "RP4 SN2 first arm" # optional, default is '' - local_asn: 65401 # optional, default is '' - adv_host: true # optional, default is false - rev_next_hop: 192.164.1.100 # mandatory - - - name: IT-ADC-RP5 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-first-arm # mandatory - vlan_id: 501 # mandatory - profile: - ipv4_gw: 192.165.1.1/24 # mandatory - ipv6_gw: 2005:db01::1/64 # optional, default is '' - vlan_name: rp5-sn2-first-arm # optional, default is '' - int_descr: "RP5 SN2 first arm intf" # optional, default is '' - tag: 51111 # optional, default is 12345 - ipv4_neighbor: 51.51.51.1 # mandatory - ipv4_lo: 51.51.51.2 # mandatory - ipv4_vpc_peer_lo: 51.51.51.3 # optional, default is '' - ipv6_neighbor: 2005:5151::1 # optional, default is '' - ipv6_lo: 2005:5152::1 # optional, default is '' - ipv6_vpc_peer_lo: 2005:5153::1 # optional, default is '' - route_map_tag: 51115 # optional, default is 12345 - neigh_int_descr: "RP5 SN2 first arm" # optional, default is '' - local_asn: 65501 # optional, default is '' - adv_host: true # optional, default is false - second_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-second-arm # mandatory - vlan_id: 502 # mandatory - profile: - ipv4_gw: 192.165.2.1/24 # mandatory - ipv6_gw: 2005:db02::1/64 # optional, default is '' - vlan_name: rp5-sn2-second-arm # optional, default is '' - int_descr: "RP5 SN2 second arm intf" # optional, default is '' - tag: 51112 # optional, default is 12345 - rev_next_hop: 192.165.1.100 # mandatory - - - name: IT-ADC-RP6 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_61 }}" # mandatory - name: rp6-sn2-first-arm # mandatory - vlan_id: 601 # mandatory - profile: - ipv4_gw: 192.166.1.1/24 # mandatory - ipv6_gw: 2006:db01::1/64 # optional, default is '' - vlan_name: rp6-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 61111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 61.61.61.1/24 - next_hop: - - 161.161.161.1 - - 162.162.162.1 - - subnet: 22.0.0.0/24 - next_hop: - - 163.163.163.1 - - 164.164.164.1 - rev_next_hop: 192.166.1.100 # mandatory - - - name: IT-ADC-RP7 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-first-arm # mandatory - vlan_id: 701 # mandatory - profile: - ipv4_gw: 192.167.1.1/24 # mandatory - ipv6_gw: 2007:db01::1/64 # optional, default is '' - vlan_name: rp7-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 71111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 71.71.71.1/24 - next_hop: - - 171.171.171.1 - - 172.172.172.1 - second_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-second-arm # mandatory - vlan_id: 702 # mandatory - profile: - ipv4_gw: 192.167.2.1/24 # mandatory - ipv6_gw: 2007:db02::1/64 # optional, default is '' - vlan_name: rp7-sn2-second-arm # optional, default is '' - int_descr: "RP7 SN2 second arm intf" # optional, default is '' - tag: 71112 # optional, default is 12345 - rev_next_hop: 192.167.1.100 # mandatory - attach: true - deploy: true - state: replaced - register: result - - - assert: - that: - - 'result.changed == true' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 3' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 3' - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - - - name: Timeout - sleep for 240 seconds for DCNM to completely update the state - wait_for: - timeout: 240 - - - - name: Replace service route peerings RP1 to RP3 - Idempotence - cisco.dcnm.dcnm_service_route_peering: *dcnm_srp_rep_13 - register: result - - - assert: - that: - - 'result.changed == false' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 0' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 0' - - -############################################## -## REPLACE RP4-RP7 ## -############################################## - - - name: Replace service route peerings RP4 to RP7 - cisco.dcnm.dcnm_service_route_peering: &dcnm_srp_rep_47 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 191 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2101:db01::01/64 # optional, default is '' - vlan_name: rp1-sn1-inside-rep # optional, default is '' - int_descr: "RP1 SN1 inside interface - REP" # optional, default is '' - tag: 11101 # optional, default is 12345 - next_hop: 192.161.1.200 # mandatory - outside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 192 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2101:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside-rep # optional, default is '' - int_descr: "RP1 SN1 outside interface- REP" # optionL, default is '' - tag: 11102 # optional, default is 12345 - rev_next_hop: 192.161.2.200 # optional, default is '' - - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: static # optional, default is static, choices=[static, ebgp] - inside_network: # - vrf: "{{ ansible_vrf_21 }}" # mandatory - name: rp2-sn1-inside-net # mandatory - vlan_id: 291 # mandatory - profile: - ipv4_gw: 192.162.1.1/24 # mandatory - ipv6_gw: 2102:db01::1/64 # optional, default is '' - vlan_name: rp2-sn1-inside-rep # optional, default is '' - int_descr: "RP2 SN1 inside interface - REP" # optional, default is '' - static_route: # optional, default is '' - - subnet: 20.20.90.0/24 - next_hop: - - 120.120.190.100 - - 121.121.191.100 - tag: 21101 # optional, default is 12345 - outside_network: # - vrf: "{{ ansible_vrf_22 }}" # mandatory - name: rp2-sn1-outside-net # mandatory - vlan_id: 292 # mandatory - profile: - ipv4_gw: 192.162.2.1/24 # mandatory - ipv6_gw: 2102:db02::1/64 # optional, default is '' - vlan_name: rp2-sn1-outside-rep # optional, default is '' - int_descr: "RP2 SN1 outside interface - REP" # optional, default is '' - static_route: # optional, default is '' - - subnet: 21.21.29.0/24 - next_hop: - - 122.122.129.100 - - 123.123.129.100 - tag: 22202 # optional, default is 12345 - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - inside_network: - vrf: "{{ ansible_vrf_31 }}" # mandatory - name: rp3-sn1-inside-net # mandatory - vlan_id: 391 # mandatory - profile: - ipv4_gw: 192.163.1.1/24 # mandatory - ipv6_gw: 2103:db01::1/64 # optional, default is '' - vlan_name: rp3-sn1-inside-rep # optional, default is '' - int_descr: "RP3 SN1 inside interface - REP" # optional, default is '' - tag: 31101 # optional, default is 12345 - ipv4_neighbor: 31.31.39.1 # mandatory - ipv4_lo: 31.31.39.2 # mandatory - ipv4_vpc_peer_lo: 31.31.39.3 # optional, default is '' - ipv6_neighbor: 2103:3131::1 # optional, default is '' - ipv6_lo: 2103:3132::1 # optional, default is '' - ipv6_vpc_peer_lo: 2103:3133::1 # optional, default is '' - route_map_tag: 33101 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 inside interface - REP" # optional, default is '' - local_asn: 65391 # optional, default is '' - adv_host: true # optional, default is false - outside_network: - vrf: "{{ ansible_vrf_32 }}" # mandatory - name: rp3-sn1-outside-net # mandatory - vlan_id: 302 # mandatory - profile: - ipv4_gw: 192.163.2.1/24 # mandatory - ipv6_gw: 2103:db02::1/64 # optional, default is '' - vlan_name: rp3-sn1-outside-rep # optional, default is '' - int_descr: "RP3 SN1 outside interface - REP" # optional, default is '' - tag: 31102 # optional, default is 12345 - ipv4_neighbor: 131.131.139.1 # mandatory - ipv4_lo: 131.131.139.2 # mandatory - ipv4_vpc_peer_lo: 131.131.139.3 # optional, default is '' - ipv6_neighbor: 2103:8383::1 # optional, default is '' - ipv6_lo: 2103:8384::1:100:1 # optional, default is '' - ipv6_vpc_peer_lo: 2103:8385::1 # optional, default is '' - route_map_tag: 31103 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 outside interface - REP" # optional, default is '' - local_asn: 65392 # optional, default is '' - adv_host: true # optional, default is false - - - name: IT-ADC-RP4 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_41 }}" # mandatory - name: rp4-sn2-first-arm # mandatory - vlan_id: 491 # mandatory - profile: - ipv4_gw: 192.164.1.1/24 # mandatory - ipv6_gw: 2104:db01::1/64 # optional, default is '' - vlan_name: rp4-sn2-first-arm-rep # optional, default is '' - int_descr: "RP4 SN2 first arm intf - REP" # optional, default is '' - tag: 41101 # optional, default is 12345 - ipv4_neighbor: 41.41.49.1 # mandatory - ipv4_lo: 41.41.49.2 # mandatory - ipv4_vpc_peer_lo: 41.41.49.3 # optional, default is '' - ipv6_neighbor: 2104:4141::1 # optional, default is '' - ipv6_lo: 2104:4142::1 # optional, default is '' - ipv6_vpc_peer_lo: 2104:4143::1 # optional, default is '' - route_map_tag: 41102 # optional, default is 12345 - neigh_int_descr: "RP4 SN2 first arm - REP" # optional, default is '' - local_asn: 65491 # optional, default is '' - adv_host: true # optional, default is false - rev_next_hop: 192.164.1.200 # mandatory - - - name: IT-ADC-RP5 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-first-arm # mandatory - vlan_id: 591 # mandatory - profile: - ipv4_gw: 192.165.1.1/24 # mandatory - ipv6_gw: 2105:db01::1/64 # optional, default is '' - vlan_name: rp5-sn2-first-arm-rep # optional, default is '' - int_descr: "RP5 SN2 first arm intf - REP" # optional, default is '' - tag: 51101 # optional, default is 12345 - ipv4_neighbor: 51.51.59.1 # mandatory - ipv4_lo: 51.51.59.2 # mandatory - ipv4_vpc_peer_lo: 51.51.51.3 # optional, default is '' - ipv6_neighbor: 2105:5151::1 # optional, default is '' - ipv6_lo: 2105:5152::1 # optional, default is '' - ipv6_vpc_peer_lo: 2105:5153::1 # optional, default is '' - route_map_tag: 51105 # optional, default is 12345 - neigh_int_descr: "RP5 SN2 first arm - REP" # optional, default is '' - local_asn: 65591 # optional, default is '' - adv_host: true # optional, default is false - second_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-second-arm # mandatory - vlan_id: 592 # mandatory - profile: - ipv4_gw: 192.165.2.1/24 # mandatory - ipv6_gw: 2105:db02::1/64 # optional, default is '' - vlan_name: rp5-sn2-second-arm-rep # optional, default is '' - int_descr: "RP5 SN2 second arm intf - REP" # optional, default is '' - tag: 51102 # optional, default is 12345 - rev_next_hop: 192.165.1.200 # mandatory - - - name: IT-ADC-RP6 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_61 }}" # mandatory - name: rp6-sn2-first-arm # mandatory - vlan_id: 691 # mandatory - profile: - ipv4_gw: 192.166.1.1/24 # mandatory - ipv6_gw: 2106:db01::1/64 # optional, default is '' - vlan_name: rp6-sn2-first-arm-rep # optional, default is '' - int_descr: "RP6 SN2 first arm intf - REP" # optional, default is '' - tag: 61101 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 61.61.69.1/24 - next_hop: - - 161.161.169.1 - - 162.162.169.1 - - subnet: 29.0.0.0/24 - next_hop: - - 163.163.169.1 - - 164.164.169.1 - rev_next_hop: 192.166.1.200 # mandatory - - - name: IT-ADC-RP7 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-first-arm # mandatory - vlan_id: 791 # mandatory - profile: - ipv4_gw: 192.167.1.1/24 # mandatory - ipv6_gw: 2107:db01::1/64 # optional, default is '' - vlan_name: rp7-sn2-first-arm-rep # optional, default is '' - int_descr: "RP6 SN2 first arm intf - REP" # optional, default is '' - tag: 71101 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 71.71.79.1/24 - next_hop: - - 171.171.179.1 - - 172.172.179.1 - second_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-second-arm # mandatory - vlan_id: 792 # mandatory - profile: - ipv4_gw: 192.167.2.1/24 # mandatory - ipv6_gw: 2107:db02::1/64 # optional, default is '' - vlan_name: rp7-sn2-second-arm-rep # optional, default is '' - int_descr: "RP7 SN2 second arm intf - REP" # optional, default is '' - tag: 71102 # optional, default is 12345 - rev_next_hop: 192.167.1.200 # mandatory - attach: true - deploy: true - state: replaced - register: result - - - assert: - that: - - 'result.changed == true' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 4' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 4' - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - - - name: Timeout - sleep for 240 seconds for DCNM to completely update the state - wait_for: - timeout: 240 - - - - name: Replace service route peerings RP4 to RP7 - Idempotence - cisco.dcnm.dcnm_service_route_peering: *dcnm_srp_rep_47 - register: result - - - assert: - that: - - 'result.changed == false' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 0' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 0' - -############################################## -## CLEANUP ## -############################################## - - always: - - - - name: Delete all created route peerings - cisco.dcnm.dcnm_service_route_peering: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-ADC-RP4 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP5 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP6 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP7 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - state: deleted - register: result - when: IT_CONTEXT is not defined - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - when: IT_CONTEXT is not defined - diff --git a/tests/integration/targets/prepare_dcnm_service_route_peering/tasks/main.yaml b/tests/integration/targets/prepare_dcnm_service_route_peering/tasks/main.yaml deleted file mode 100644 index e430965fd..000000000 --- a/tests/integration/targets/prepare_dcnm_service_route_peering/tasks/main.yaml +++ /dev/null @@ -1,184 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: Initialize the setup - Delete Service Nodes - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - state: deleted - config: - - name: "{{ ansible_snode_1 }}" - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_att_intf1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: "{{ ansible_snode_2 }}" - type: load_balancer - form_factor: physical - svc_int_name: svc2 - attach_interface: "{{ ansible_att_intf2 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -- name: Initialize the setup - Delete VRFs - cisco.dcnm.dcnm_vrf: - fabric: "{{ ansible_it_fabric }}" - state: deleted - config: - - vrf_name: "{{ ansible_vrf_11 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_12 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_21 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_22 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_31 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_32 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_41 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_42 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_51 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_52 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_61 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_62 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_71 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_72 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -- name: Initialize the setup - sleep for 10 seconds for DCNM to completely update the state - wait_for: - timeout: 10 - -- block: - -############################################## -## MERGE VRFs ## -############################################## - - - name: Initialize the setup - Create all VRFs - cisco.dcnm.dcnm_vrf: - fabric: "{{ ansible_it_fabric }}" - state: merged - config: - - vrf_name: "{{ ansible_vrf_11 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_12 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_21 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_22 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_31 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_32 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_41 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_42 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_51 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_52 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_61 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_62 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_71 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_72 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - register: result - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -############################################## -## MERGE SERVICE NODES ## -############################################## - - - name: Initialize the setup - Create all Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - state: merged - config: - - name: "{{ ansible_snode_1 }}" - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_att_intf1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: "{{ ansible_snode_2 }}" - type: load_balancer - form_factor: physical - svc_int_name: svc2 - attach_interface: "{{ ansible_att_intf2 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -- name: Initialize the setup - sleep for 180 seconds for DCNM to completely update the state - wait_for: - timeout: 180 - diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_service_node.json b/tests/unit/modules/dcnm/fixtures/dcnm_service_node.json deleted file mode 100644 index bb2f81728..000000000 --- a/tests/unit/modules/dcnm/fixtures/dcnm_service_node.json +++ /dev/null @@ -1,612 +0,0 @@ -{ - "mock_ip_sn" : { - "10.10.10.224": "XYZKSJHSMK1", - "10.10.10.225": "XYZKSJHSMK2", - "10.10.10.226": "XYZKSJHSMK3", - "10.10.10.227": "XYZKSJHSMK4", - "10.10.10.228": "XYZKSJHSMK5" - }, - - "playbook_config" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_replace_new" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_replace_new1" : [ - { - "name": "SN-11", - "type": "load_balancer", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_new_config" : [ - { - "name": "SN-12", - "type": "load_balancer", - "form_factor": "virtual", - "svc_int_name": "svc12", - "attach_interface": "Ethernet1/12", - "switches": "10.10.10.225" - } - ], - - "playbook_over_config" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "scv1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_name" : [ - { - "name": "SN-11" - } - ], - - "playbook_config_virtual" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "virtual", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_load" : [ - { - "name": "SN-11", - "type": "load_balancer", - "form_factor": "virtual", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_vnf" : [ - { - "name": "SN-11", - "type": "virtual_network_function", - "form_factor": "virtual", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_vpc" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPC1", - "switches": ["10.10.10.224", "10.10.10.225"] - } - ], - - "playbook_config_invalid_vpc" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPortchannel12", - "switches": ["10.10.10.224", "10.10.10.225"] - } - ], - - "playbook_config_more_switch" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPC1", - "switches": ["10.10.10.224", "10.10.10.225", "10.10.10.226"] - } - ], - - "playbook_config_noparams" : [ - { - "name": "", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_no_type" : [ - { - "name": "SN-11", - "type": "karth", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_no_ff" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "babu", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_no_vpc" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPC1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_query" : [ - { - "switches": "10.10.10.224" - } - ], - - "mock_sn_1_object": { - "ERROR": "", - "RETURN_CODE": 200, - "MESSAGE":"", - "DATA": [ - { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "svc1", - "lastUpdated": 1611748269292, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-141180", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "DEST_FABRIC_NAME": "external", - "DEST_SWITCH_NAME": "SN-11", - "IS_METASWITCH": "false", - "LINK_UUID": "LINK-UUID-141180", - "MTU": "jumbo", - "POLICY_DESC": "", - "POLICY_ID": "POLICY-141190", - "PORTTYPE_FAST_ENABLED": "true", - "PRIORITY": "500", - "SOURCE_FABRIC_NAME": "test_fabric", - "SOURCE_SWITCH_NAME": "dt-n9k1", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - ] - }, - - "mock_sn_merge_1_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_2_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_3_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "AVB", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_4_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "VNF", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_5_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "vPC1", - "attachedSwitchSn": "XYZKSJHSMK1, XYZKSJHSMK2", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_6_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/2", - "attachedSwitchSn": "XYZKSJHSMK2", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv12", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-12", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "ADC", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_replace_1_success": { - "MESSAGE": "", - "METHOD": "PUT", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv11", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_replace_2_success": { - "MESSAGE": "", - "METHOD": "PUT", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv11", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "ADC", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_have_success": { - "MESSAGE": "", - "METHOD": "GET", - "RETURN_CODE": 200, - "DATA": [ - { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612604671520, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-304470", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "DEST_FABRIC_NAME": "external", - "DEST_IF_NAME": "scv1", - "DEST_SERIAL_NUMBER": "SN-11-external", - "DEST_SWITCH_NAME": "SN-11", - "IS_METASWITCH": "true", - "LINK_UUID": "LINK-UUID-304470", - "MTU": "jumbo", - "POLICY_DESC": "", - "POLICY_ID": "POLICY-304480", - "PORTTYPE_FAST_ENABLED": "true", - "PRIORITY": "500", - "SOURCE_FABRIC_NAME": "test_fabric", - "SOURCE_IF_NAME": "Ethernet1/1", - "SOURCE_SERIAL_NUMBER": "XYZKSJHSMK1", - "SOURCE_SWITCH_NAME": "XYZKSJHSMK1", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - ] - }, - - "mock_sn_query_success": { - "attachedFabricName": "Fabric1", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "SAL1812NTBP", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612606479781, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-304710", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "DEST_FABRIC_NAME": "external", - "DEST_IF_NAME": "scv1", - "DEST_SERIAL_NUMBER": "SN-11-external", - "DEST_SWITCH_NAME": "SN-11", - "IS_METASWITCH": "true", - "LINK_UUID": "LINK-UUID-304710", - "MTU": "jumbo", - "POLICY_DESC": "", - "POLICY_ID": "POLICY-304720", - "PORTTYPE_FAST_ENABLED": "true", - "PRIORITY": "500", - "SOURCE_FABRIC_NAME": "Fabric1", - "SOURCE_IF_NAME": "Ethernet1/1", - "SOURCE_SERIAL_NUMBER": "SAL1812NTBP", - "SOURCE_SWITCH_NAME": "SAL1812NTBP", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - }, - - "blank_data": { - "DATA": [], - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200 - }, - "blank_get_data": { - "DATA": [], - "MESSAGE": "", - "METHOD": "GET", - "RETURN_CODE": 200 - }, - - "blank_data_null": { - "DATA": [], - "MESSAGE": "", - "METHOD": "", - "RETURN_CODE": 0 - }, - - - "get_have_failure": { - "DATA": "Invalid JSON response: Invalid Fabric: demo-fabric-123", - "ERROR": "Not Found", - "METHOD": "GET", - "RETURN_CODE": 404, - "MESSAGE": "OK" - }, - "error1": { - "DATA": "None", - "ERROR": "There is an error", - "METHOD": "POST", - "RETURN_CODE": 400, - "MESSAGE": "OK" - }, - - "sn_delete_success_resp": { - "DATA": {}, - "ERROR": "", - "METHOD": "DELETE", - "RETURN_CODE": 200, - "MESSAGE": "" - }, - "sn_query_success_resp": { - "DATA": {}, - "ERROR": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "MESSAGE": "" - }, - - "sn_inv_data": { - "10.10.10.224":{ - "ipAddress": "10.10.10.224", - "logicalName": "dt-n9k1", - "serialNumber": "XYZKSJHSMK1", - "switchRole": "leaf" - }, - "10.10.10.225":{ - "ipAddress": "10.10.10.225", - "logicalName": "dt-n9k2", - "serialNumber": "XYZKSJHSMK2", - "switchRole": "leaf" - }, - "10.10.10.226":{ - "ipAddress": "10.10.10.226", - "logicalName": "dt-n9k3", - "serialNumber": "XYZKSJHSMK3", - "switchRole": "leaf" - }, - "10.10.10.227":{ - "ipAddress": "10.10.10.227", - "logicalName": "dt-n9k4", - "serialNumber": "XYZKSJHSMK4", - "switchRole": "border spine" - }, - "10.10.10.228":{ - "ipAddress": "10.10.10.228", - "logicalName": "dt-n9k5", - "serialNumber": "XYZKSJHSMK5", - "switchRole": "border" - } - } -} \ No newline at end of file diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_srp_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_srp_configs.json deleted file mode 100644 index a8c9127c4..000000000 --- a/tests/unit/modules/dcnm/fixtures/dcnm_srp_configs.json +++ /dev/null @@ -1,1672 +0,0 @@ -{ - "delete_rp1_rp7_config": [ - { - "name": "IT-FW-RP1", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP2", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP3", - "node_name": "IT-SN-1" - }, - { - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2" - } - ], - - "delete_no_mand_elems": [ - { - "name": "IT-FW-RP1", - "node_name": "IT-SN-1" - }], - - "merge_rp1_rp7_config" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface - change", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2001:0901::01/64" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface - change", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2001:0902::1/64" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.100" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface - change", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2002:0901::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.120.100", - "121.121.121.100" - ], - "subnet": "20.20.20.0/24" - } - ] - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface - change", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2002:0902::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.122.100", - "123.123.123.100" - ], - "subnet": "21.21.21.0/24" - } - ] - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface - change", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1", - "ipv4_vpc_peer_lo": "31.31.31.3", - "ipv6_gw": "2003:0901::1/64", - "ipv6_lo": "2003:3932::01", - "ipv6_neighbor": "2003:3931::1", - "ipv6_vpc_peer_lo": "2003:3933::01", - "local_asn": 65301, - "neigh_int_descr": "RP3 SN1 inside interface - change", - "route_map_tag": 33111 - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface - change", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1", - "ipv4_vpc_peer_lo": "131.131.131.3", - "ipv6_gw": "2003:0902::1/64", - "ipv6_lo": "2003:8984::1:100:1", - "ipv6_neighbor": "2003:8983::1", - "ipv6_vpc_peer_lo": "2003:8985::1", - "local_asn": 65302, - "neigh_int_descr": "RP3 SN1 outside interface - change", - "route_map_tag": 31113 - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf - change", - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1", - "ipv4_vpc_peer_lo": "41.41.41.3", - "ipv6_gw": "2004:0901::1/64", - "ipv6_lo": "2004:4942::1", - "ipv6_neighbor": "2004:4941::1", - "ipv6_vpc_peer_lo": "2004:4943::1", - "local_asn": 65401, - "neigh_int_descr": "RP4 SN2 first arm - change", - "route_map_tag": 41112 - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP5 SN2 first arm intf - change", - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.51.2", - "ipv4_neighbor": "51.51.51.1", - "ipv4_vpc_peer_lo": "51.51.51.3", - "ipv6_gw": "2005:0901::1/64", - "ipv6_lo": "2005:5952::1", - "ipv6_neighbor": "2005:5951::1", - "ipv6_vpc_peer_lo": "2005:5953::1", - "local_asn": 65501, - "neigh_int_descr": "RP5 SN2 first arm - change", - "route_map_tag": 51115 - }, - "vlan_id": 501, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.100", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "int_descr": "RP5 SN2 second arm intf - change", - "ipv4_gw": "192.165.2.1/24", - "ipv6_gw": "2005:0902::1/64" - }, - "vlan_id": 502, - "vrf": "IT_VRF_51" - } - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - change", - "ipv4_gw": "192.166.1.1/24", - "ipv6_gw": "2006:0901::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.161.1", - "162.162.162.1" - ], - "subnet": "61.61.61.1/24" - }, - { - "next_hop": [ - "163.163.163.1", - "164.164.164.1" - ], - "subnet": "22.0.0.0/24" - } - ] - }, - "vlan_id": 601, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp7-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - change", - "ipv4_gw": "192.167.1.1/24", - "ipv6_gw": "2007:0901::1/64", - "static_route": [ - { - "next_hop": [ - "171.171.171.1", - "172.172.172.1" - ], - "subnet": "71.71.71.1/24" - } - ] - }, - "vlan_id": 701, - "vrf": "IT_VRF_71" - }, - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.167.1.100", - "second_arm": { - "name": "rp7-sn2-second-arm", - "profile": { - "int_descr": "RP7 SN2 second arm intf - change", - "ipv4_gw": "192.167.2.1/24", - "ipv6_gw": "2007:0902::1/64" - }, - "vlan_id": 702, - "vrf": "IT_VRF_71" - } - } - ], - "create_rp1_rp3_rp5_config" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2001:0101::01/64", - "tag": 11111, - "vlan_name": "rp1-sn1-inside" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2001:0102::1/64", - "tag": 11112, - "vlan_name": "rp1-sn1-outside" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.100" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1", - "ipv4_vpc_peer_lo": "31.31.31.3", - "ipv6_gw": "2003:0101::1/64", - "ipv6_lo": "2003:3132::01", - "ipv6_neighbor": "2003:3131::1", - "ipv6_vpc_peer_lo": "2003:3133::01", - "local_asn": 65301, - "neigh_int_descr": "RP3 SN1 inside interface", - "route_map_tag": 33111, - "tag": 31111, - "vlan_name": "rp3-sn1-inside" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1", - "ipv4_vpc_peer_lo": "131.131.131.3", - "ipv6_gw": "2003:0102::1/64", - "ipv6_lo": "2003:8384::1:100:1", - "ipv6_neighbor": "2003:8383::1", - "ipv6_vpc_peer_lo": "2003:8385::1", - "local_asn": 65302, - "neigh_int_descr": "RP3 SN1 outside interface", - "route_map_tag": 31113, - "tag": 31112, - "vlan_name": "rp3-sn1-outside" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP5 SN2 first arm intf", - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.51.2", - "ipv4_neighbor": "51.51.51.1", - "ipv4_vpc_peer_lo": "51.51.51.3", - "ipv6_gw": "2005:0101::1/64", - "ipv6_lo": "2005:5152::1", - "ipv6_neighbor": "2005:5151::1", - "ipv6_vpc_peer_lo": "2005:5153::1", - "local_asn": 65501, - "neigh_int_descr": "RP5 SN2 first arm", - "route_map_tag": 51115, - "tag": 51111, - "vlan_name": "rp5-sn2-first-arm" - }, - "vlan_id": 501, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.100", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "int_descr": "RP5 SN2 second arm intf", - "ipv4_gw": "192.165.2.1/24", - "ipv6_gw": "2005:0102::1/64", - "tag": 51112, - "vlan_name": "rp5-sn2-second-arm" - }, - "vlan_id": 502, - "vrf": "IT_VRF_51" - } - } - ], - "update_rp2_rp4_config" : [ - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface - upd", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2002:0109::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.129.100", - "121.121.121.100" - ], - "subnet": "20.20.20.0/24" - } - ], - "tag": 21111, - "vlan_name": "rp2-sn1-inside" - }, - "vlan_id": 209, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface - upd", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2002:0102::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.122.100", - "123.123.123.100" - ], - "subnet": "21.21.21.0/24" - } - ], - "tag": 22222, - "vlan_name": "rp2-sn1-outside - upd" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf - upd", - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1", - "ipv4_vpc_peer_lo": "41.41.41.3", - "ipv6_gw": "2004:0101::1/64", - "ipv6_lo": "2004:4142::1", - "ipv6_neighbor": "2004:4141::1", - "ipv6_vpc_peer_lo": "2004:4143::1", - "local_asn": 65401, - "neigh_int_descr": "RP4 SN2 first arm - upd", - "route_map_tag": 41119, - "tag": 41119, - "vlan_name": "rp4-sn2-first-arm-upd" - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - } - ], - "create_rp1_rp7_config" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2001:0101::01/64", - "tag": 11111, - "vlan_name": "rp1-sn1-inside" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2001:0102::1/64", - "tag": 11112, - "vlan_name": "rp1-sn1-outside" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.100" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2002:0101::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.120.100", - "121.121.121.100" - ], - "subnet": "20.20.20.0/24" - } - ], - "tag": 21111, - "vlan_name": "rp2-sn1-inside" - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2002:0102::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.122.100", - "123.123.123.100" - ], - "subnet": "21.21.21.0/24" - } - ], - "tag": 22222, - "vlan_name": "rp2-sn1-outside" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1", - "ipv4_vpc_peer_lo": "31.31.31.3", - "ipv6_gw": "2003:0101::1/64", - "ipv6_lo": "2003:3132::01", - "ipv6_neighbor": "2003:3131::1", - "ipv6_vpc_peer_lo": "2003:3133::01", - "local_asn": 65301, - "neigh_int_descr": "RP3 SN1 inside interface", - "route_map_tag": 33111, - "tag": 31111, - "vlan_name": "rp3-sn1-inside" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1", - "ipv4_vpc_peer_lo": "131.131.131.3", - "ipv6_gw": "2003:0102::1/64", - "ipv6_lo": "2003:8384::1:100:1", - "ipv6_neighbor": "2003:8383::1", - "ipv6_vpc_peer_lo": "2003:8385::1", - "local_asn": 65302, - "neigh_int_descr": "RP3 SN1 outside interface", - "route_map_tag": 31113, - "tag": 31112, - "vlan_name": "rp3-sn1-outside" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf", - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1", - "ipv4_vpc_peer_lo": "41.41.41.3", - "ipv6_gw": "2004:0101::1/64", - "ipv6_lo": "2004:4142::1", - "ipv6_neighbor": "2004:4141::1", - "ipv6_vpc_peer_lo": "2004:4143::1", - "local_asn": 65401, - "neigh_int_descr": "RP4 SN2 first arm", - "route_map_tag": 41112, - "tag": 41111, - "vlan_name": "rp4-sn2-first-arm" - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP5 SN2 first arm intf", - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.51.2", - "ipv4_neighbor": "51.51.51.1", - "ipv4_vpc_peer_lo": "51.51.51.3", - "ipv6_gw": "2005:0101::1/64", - "ipv6_lo": "2005:5152::1", - "ipv6_neighbor": "2005:5151::1", - "ipv6_vpc_peer_lo": "2005:5153::1", - "local_asn": 65501, - "neigh_int_descr": "RP5 SN2 first arm", - "route_map_tag": 51115, - "tag": 51111, - "vlan_name": "rp5-sn2-first-arm" - }, - "vlan_id": 501, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.100", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "int_descr": "RP5 SN2 second arm intf", - "ipv4_gw": "192.165.2.1/24", - "ipv6_gw": "2005:0102::1/64", - "tag": 51112, - "vlan_name": "rp5-sn2-second-arm" - }, - "vlan_id": 502, - "vrf": "IT_VRF_51" - } - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf", - "ipv4_gw": "192.166.1.1/24", - "ipv6_gw": "2006:0101::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.161.1", - "162.162.162.1" - ], - "subnet": "61.61.61.1/24" - }, - { - "next_hop": [ - "163.163.163.1", - "164.164.164.1" - ], - "subnet": "22.0.0.0/24" - } - ], - "tag": 61111, - "vlan_name": "rp6-sn2-first-arm" - }, - "vlan_id": 601, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp7-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf", - "ipv4_gw": "192.167.1.1/24", - "ipv6_gw": "2007:0101::1/64", - "static_route": [ - { - "next_hop": [ - "171.171.171.1", - "172.172.172.1" - ], - "subnet": "71.71.71.1/24" - } - ], - "tag": 71111, - "vlan_name": "rp7-sn2-first-arm" - }, - "vlan_id": 701, - "vrf": "IT_VRF_71" - }, - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.167.1.100", - "second_arm": { - "name": "rp7-sn2-second-arm", - "profile": { - "int_descr": "RP7 SN2 second arm intf", - "ipv4_gw": "192.167.2.1/24", - "ipv6_gw": "2007:0102::1/64", - "tag": 71112, - "vlan_name": "rp7-sn2-second-arm" - }, - "vlan_id": 702, - "vrf": "IT_VRF_71" - } - } - ], - "create_no_intra_fw_mand_elems" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "ipv4_gw": "192.161.1.1/24" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "ipv4_gw": "192.161.2.1/24" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - } - }], - "create_no_inter_fw_mand_elems" : [ - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }], - - "create_no_adc_mand_elems" : [ - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1" - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - }], - - "create_rp1_rp7_config_no_opt_elems" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "ipv4_gw": "192.161.1.1/24" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "ipv4_gw": "192.161.2.1/24" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - } - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "ipv4_gw": "192.162.1.1/24" - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "ipv4_gw": "192.162.2.1/24" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - } - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1" - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.51.2", - "ipv4_neighbor": "51.51.51.1" - }, - "vlan_id": 501, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.100", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "ipv4_gw": "192.165.2.1/24" - }, - "vlan_id": 502, - "vrf": "IT_VRF_51" - } - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "ipv4_gw": "192.166.1.1/24" - }, - "vlan_id": 601, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "rev_next_hop": "192.166.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp7-sn2-first-arm", - "profile": { - "ipv4_gw": "192.167.1.1/24" - }, - "vlan_id": 701, - "vrf": "IT_VRF_71" - }, - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2", - "rev_next_hop": "192.167.1.100", - "second_arm": { - "name": "rp7-sn2-second-arm", - "profile": { - "ipv4_gw": "192.167.2.1/24" - }, - "vlan_id": 702, - "vrf": "IT_VRF_71" - } - } - ], - - "query_no_mand_elems": [ - { - "name": "IT-FW-RP1-ABS", - "node_name": "IT-SN-1" - }], - - "config_query_non_exist": [ - { - "name": "IT-FW-RP1-ABS", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP2-ABS", - "node_name": "IT-SN-2" - } - ], - - "config_query_with_node": [ - { - "node_name": "IT-SN-1" - }, - { - "node_name": "IT-SN-2" - } - ], - - "config_query_with_peername": [ - { - "name": "IT-FW-RP1", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP2", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP3", - "node_name": "IT-SN-1" - }, - { - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2" - } - ], - - "replace_rp1_to_rp3_no_opt_elems" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "ipv4_gw": "192.161.1.1/24" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "ipv4_gw": "192.161.2.1/24" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - } - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "ipv4_gw": "192.162.1.1/24" - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "ipv4_gw": "192.162.2.1/24" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - } - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }], - - "replace_rp1_rp3_no_change" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2001:0101::01/64", - "tag": 11111, - "vlan_name": "rp1-sn1-inside" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2001:0102::1/64", - "tag": 11112, - "vlan_name": "rp1-sn1-outside" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.100" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2002:0101::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.120.100", - "121.121.121.100" - ], - "subnet": "20.20.20.0/24" - } - ], - "tag": 21111, - "vlan_name": "rp2-sn1-inside" - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2002:0102::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.122.100", - "123.123.123.100" - ], - "subnet": "21.21.21.0/24" - } - ], - "tag": 22222, - "vlan_name": "rp2-sn1-outside" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1", - "ipv4_vpc_peer_lo": "31.31.31.3", - "ipv6_gw": "2003:0101::1/64", - "ipv6_lo": "2003:3132::01", - "ipv6_neighbor": "2003:3131::1", - "ipv6_vpc_peer_lo": "2003:3133::01", - "local_asn": 65301, - "neigh_int_descr": "RP3 SN1 inside interface", - "route_map_tag": 33111, - "tag": 31111, - "vlan_name": "rp3-sn1-inside" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1", - "ipv4_vpc_peer_lo": "131.131.131.3", - "ipv6_gw": "2003:0102::1/64", - "ipv6_lo": "2003:8384::1:100:1", - "ipv6_neighbor": "2003:8383::1", - "ipv6_vpc_peer_lo": "2003:8385::1", - "local_asn": 65302, - "neigh_int_descr": "RP3 SN1 outside interface", - "route_map_tag": 31113, - "tag": 31112, - "vlan_name": "rp3-sn1-outside" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }], - "replace_rp1_to_rp3": [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface - REP", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2101:0101::01/64", - "tag": 11101, - "vlan_name": "rp1-sn1-inside-rep" - }, - "vlan_id": 191, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.200", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface- REP", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2101:0102::1/64", - "tag": 11102, - "vlan_name": "rp1-sn1-outside-rep" - }, - "vlan_id": 192, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.200" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface - REP", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2102:0101::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.190.100", - "121.121.191.100" - ], - "subnet": "20.20.90.0/24" - } - ], - "tag": 21101, - "vlan_name": "rp2-sn1-inside-rep" - }, - "vlan_id": 291, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface - REP", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2102:0102::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.129.100", - "123.123.129.100" - ], - "subnet": "21.21.29.0/24" - } - ], - "tag": 22202, - "vlan_name": "rp2-sn1-outside-rep" - }, - "vlan_id": 292, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface - REP", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.39.2", - "ipv4_neighbor": "31.31.39.1", - "ipv4_vpc_peer_lo": "31.31.39.3", - "ipv6_gw": "2103:0101::1/64", - "ipv6_lo": "2103:3132::01", - "ipv6_neighbor": "2103:3131::1", - "ipv6_vpc_peer_lo": "2103:3133::01", - "local_asn": 65391, - "neigh_int_descr": "RP3 SN1 inside interface - REP", - "route_map_tag": 33101, - "tag": 31101, - "vlan_name": "rp3-sn1-inside-rep" - }, - "vlan_id": 391, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface - REP", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.139.2", - "ipv4_neighbor": "131.131.139.1", - "ipv4_vpc_peer_lo": "131.131.139.3", - "ipv6_gw": "2103:0102::1/64", - "ipv6_lo": "2103:8384::1:100:1", - "ipv6_neighbor": "2103:8383::1", - "ipv6_vpc_peer_lo": "2103:8385::1", - "local_asn": 65392, - "neigh_int_descr": "RP3 SN1 outside interface - REP", - "route_map_tag": 31103, - "tag": 31102, - "vlan_name": "rp3-sn1-outside-rep" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - } - ], - - "replace_rp4_to_rp7": [ - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf - REP", - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.49.2", - "ipv4_neighbor": "41.41.49.1", - "ipv4_vpc_peer_lo": "41.41.49.3", - "ipv6_gw": "2104:0101::1/64", - "ipv6_lo": "2104:4142::1", - "ipv6_neighbor": "2104:4141::1", - "ipv6_vpc_peer_lo": "2104:4143::1", - "local_asn": 65491, - "neigh_int_descr": "RP4 SN2 first arm - REP", - "route_map_tag": 41102, - "tag": 41101, - "vlan_name": "rp4-sn2-first-arm-rep" - }, - "vlan_id": 491, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.200" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP5 SN2 first arm intf - REP", - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.59.2", - "ipv4_neighbor": "51.51.59.1", - "ipv4_vpc_peer_lo": "51.51.51.3", - "ipv6_gw": "2105:0101::1/64", - "ipv6_lo": "2105:5152::1", - "ipv6_neighbor": "2105:5151::1", - "ipv6_vpc_peer_lo": "2105:5153::1", - "local_asn": 65591, - "neigh_int_descr": "RP5 SN2 first arm - REP", - "route_map_tag": 51105, - "tag": 51101, - "vlan_name": "rp5-sn2-first-arm-rep" - }, - "vlan_id": 591, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.200", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "int_descr": "RP5 SN2 second arm intf - REP", - "ipv4_gw": "192.165.2.1/24", - "ipv6_gw": "2105:0102::1/64", - "tag": 51102, - "vlan_name": "rp5-sn2-second-arm-rep" - }, - "vlan_id": 592, - "vrf": "IT_VRF_51" - } - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - REP", - "ipv4_gw": "192.166.1.1/24", - "ipv6_gw": "2106:0101::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.169.1", - "162.162.169.1" - ], - "subnet": "61.61.69.1/24" - }, - { - "next_hop": [ - "163.163.169.1", - "164.164.169.1" - ], - "subnet": "29.0.0.0/24" - } - ], - "tag": 61101, - "vlan_name": "rp6-sn2-first-arm-rep" - }, - "vlan_id": 691, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.1.200" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp7-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - REP", - "ipv4_gw": "192.167.1.1/24", - "ipv6_gw": "2107:0101::1/64", - "static_route": [ - { - "next_hop": [ - "171.171.179.1", - "172.172.179.1" - ], - "subnet": "71.71.79.1/24" - } - ], - "tag": 71101, - "vlan_name": "rp7-sn2-first-arm-rep" - }, - "vlan_id": 791, - "vrf": "IT_VRF_71" - }, - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.167.1.200", - "second_arm": { - "name": "rp7-sn2-second-arm", - "profile": { - "int_descr": "RP7 SN2 second arm intf - REP", - "ipv4_gw": "192.167.2.1/24", - "ipv6_gw": "2107:0102::1/64", - "tag": 71102, - "vlan_name": "rp7-sn2-second-arm-rep" - }, - "vlan_id": 792, - "vrf": "IT_VRF_71" - } - } - ], - "override_with_no_config" : [], - "override_with_snodes": [ - { - "node_name": "IT-SN-1" - }, - { - "node_name": "IT-SN-2" - } - ], - "override_with_existing_peering": [ - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf", - "ipv4_gw": "192.166.1.1/24", - "ipv6_gw": "2006:0101::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.161.1", - "162.162.162.1" - ], - "subnet": "61.61.61.1/24" - }, - { - "next_hop": [ - "163.163.163.1", - "164.164.164.1" - ], - "subnet": "22.0.0.0/24" - } - ], - "tag": 61111, - "vlan_name": "rp6-sn2-first-arm" - }, - "vlan_id": 601, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.1.100" - } - ], - "override_with_existing_peering_updated": [ - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - ovr", - "ipv4_gw": "192.166.9.1/24", - "ipv6_gw": "2006:0109::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.169.1", - "162.162.169.1" - ], - "subnet": "61.61.69.1/24" - }, - { - "next_hop": [ - "163.163.169.1", - "164.164.169.1" - ], - "subnet": "29.0.0.0/24" - } - ], - "tag": 61111, - "vlan_name": "rp6-sn2-first-arm" - }, - "vlan_id": 609, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.9.100" - } - ], - "override_with_new_peerings": [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net-ovr", - "profile": { - "int_descr": "RP1 SN1 inside interface ovr", - "ipv4_gw": "192.161.91.1/24", - "ipv6_gw": "2001:0901::01/64", - "tag": 11191, - "vlan_name": "rp1-sn1-inside-ovr" - }, - "vlan_id": 191, - "vrf": "IT_VRF_12" - }, - "name": "IT-FW-RP-OVR1", - "next_hop": "192.161.91.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net-ovr", - "profile": { - "int_descr": "RP1 SN1 outside interface ovr", - "ipv4_gw": "192.161.92.1/24", - "ipv6_gw": "2001:0902::1/64", - "tag": 11192, - "vlan_name": "rp1-sn1-outside-ovr" - }, - "vlan_id": 192, - "vrf": "IT_VRF_12" - }, - "rev_next_hop": "192.161.92.100" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm-ovr", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf ovr", - "ipv4_gw": "192.164.91.1/24", - "ipv4_lo": "49.49.49.2", - "ipv4_neighbor": "49.49.49.1", - "ipv4_vpc_peer_lo": "49.49.49.3", - "ipv6_gw": "2004:0901:01::1/64", - "ipv6_lo": "2004:4942::1", - "ipv6_neighbor": "2004:4941::1", - "ipv6_vpc_peer_lo": "2004:4943::1", - "local_asn": 65491, - "neigh_int_descr": "RP4 SN2 first arm ovr", - "route_map_tag": 41192, - "tag": 41191, - "vlan_name": "rp3-sn1-first-arm-ovr" - }, - "vlan_id": 491, - "vrf": "IT_VRF_42" - }, - "name": "IT-ADC-RP-OVR4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.91.100" - } - ] -} diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_srp_payloads.json b/tests/unit/modules/dcnm/fixtures/dcnm_srp_payloads.json deleted file mode 100644 index c4efe6c16..000000000 --- a/tests/unit/modules/dcnm/fixtures/dcnm_srp_payloads.json +++ /dev/null @@ -1,3084 +0,0 @@ -{ - "create_rp7_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 400 - }, - - "create_rp4_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 400 - }, - - "det_rp1_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1/attachments", - "RETURN_CODE": 400 - }, - - "deploy_rp4_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4/deployments", - "RETURN_CODE": 400 - }, - - "delete_rp7_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7", - "RETURN_CODE": 400 - }, - - "create_rp1_resp" : - { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "IntraTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504100184, - "nextHopIp": "192.161.1.100", - "peeringName": "IT-FW-RP1", - "peeringOption": "None", - "reverseNextHopIp": "192.161.2.100", - "routes": [], - "serviceNetworks": [ - { - "networkName": "rp1-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.161.1.1/24", - "gatewayIpV6Address": "2001:0101::01/64", - "intfDescription": "RP1 SN1 inside interface fw:inside:external:IT-SN-1:external-intf:IT-FW-RP1", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp1-sn1-inside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30005", - "suppressArp": "false", - "tag": "11111", - "trmEnabled": "false", - "vlanId": "101", - "vlanName": "rp1-sn1-inside", - "vrfName": "IT_VRF_11" - }, - "templateName": "Service_Network_Universal", - "vlanId": 101, - "vrfName": "IT_VRF_11" - }, - { - "networkName": "rp1-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.161.2.1/24", - "gatewayIpV6Address": "2001:0102::1/64", - "intfDescription": "RP1 SN1 outside interface fw:outside:external:IT-SN-1:external-intf:IT-FW-RP1", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp1-sn1-outside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30006", - "suppressArp": "false", - "tag": "11112", - "trmEnabled": "false", - "vlanId": "102", - "vlanName": "rp1-sn1-outside", - "vrfName": "IT_VRF_11" - }, - "templateName": "Service_Network_Universal", - "vlanId": 102, - "vrfName": "IT_VRF_11" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings", - "RETURN_CODE": 200 - }, - "create_rp2_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "InterTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504107408, - "peeringName": "IT-FW-RP2", - "peeringOption": "StaticPeering", - "routes": [ - { - "nvPairs": { - "MULTI_ROUTES": "20.20.20.0/24,120.120.120.100\n20.20.20.0/24,121.121.121.100", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_21" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_21" - }, - { - "nvPairs": { - "MULTI_ROUTES": "21.21.21.0/24,122.122.122.100\n21.21.21.0/24,123.123.123.100", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_22" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_22" - } - ], - "serviceNetworks": [ - { - "networkName": "rp2-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.162.1.1/24", - "gatewayIpV6Address": "2002:0101::1/64", - "intfDescription": "RP2 SN1 inside interface fw:inside:external:IT-SN-1:external-intf:IT-FW-RP2", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp2-sn1-inside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30007", - "suppressArp": "false", - "tag": "21111", - "trmEnabled": "false", - "vlanId": "201", - "vlanName": "rp2-sn1-inside", - "vrfName": "IT_VRF_21" - }, - "templateName": "Service_Network_Universal", - "vlanId": 201, - "vrfName": "IT_VRF_21" - }, - { - "networkName": "rp2-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.162.2.1/24", - "gatewayIpV6Address": "2002:0102::1/64", - "intfDescription": "RP2 SN1 outside interface fw:outside:external:IT-SN-1:external-intf:IT-FW-RP2", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp2-sn1-outside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30008", - "suppressArp": "false", - "tag": "22222", - "trmEnabled": "false", - "vlanId": "202", - "vlanName": "rp2-sn1-outside", - "vrfName": "IT_VRF_22" - }, - "templateName": "Service_Network_Universal", - "vlanId": 202, - "vrfName": "IT_VRF_22" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings", - "RETURN_CODE": 200 - }, - "create_rp3_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "InterTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504115514, - "peeringName": "IT-FW-RP3", - "peeringOption": "EBGPDynamicPeering", - "routes": [ - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP3 SN1 inside interface", - "LOCAL_ASN": "65301", - "LOOPBACK_IP": "31.31.31.2", - "LOOPBACK_IPV6": "2003:3132::01", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "31.31.31.1", - "NEIGHBOR_IPV6": "2003:3131::1", - "PEER_LOOPBACK_IP": "31.31.31.3", - "PEER_LOOPBACK_IPV6": "2003:3133::01", - "ROUTE_MAP_TAG": "33111", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_31" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_31" - }, - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP3 SN1 outside interface", - "LOCAL_ASN": "65302", - "LOOPBACK_IP": "131.131.131.2", - "LOOPBACK_IPV6": "2003:8384::1:100:1", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "131.131.131.1", - "NEIGHBOR_IPV6": "2003:8383::1", - "PEER_LOOPBACK_IP": "131.131.131.3", - "PEER_LOOPBACK_IPV6": "2003:8385::1", - "ROUTE_MAP_TAG": "31113", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_32" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_32" - } - ], - "serviceNetworks": [ - { - "networkName": "rp3-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.163.1.1/24", - "gatewayIpV6Address": "2003:0101::1/64", - "intfDescription": "RP3 SN1 inside interface fw:inside:external:IT-SN-1:external-intf:IT-FW-RP3", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp3-sn1-inside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30009", - "suppressArp": "false", - "tag": "31111", - "trmEnabled": "false", - "vlanId": "301", - "vlanName": "rp3-sn1-inside", - "vrfName": "IT_VRF_31" - }, - "templateName": "Service_Network_Universal", - "vlanId": 301, - "vrfName": "IT_VRF_31" - }, - { - "networkName": "rp3-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.163.2.1/24", - "gatewayIpV6Address": "2003:0102::1/64", - "intfDescription": "RP3 SN1 outside interface fw:outside:external:IT-SN-1:external-intf:IT-FW-RP3", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp3-sn1-outside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30010", - "suppressArp": "false", - "tag": "31112", - "trmEnabled": "false", - "vlanId": "302", - "vlanName": "rp3-sn1-outside", - "vrfName": "IT_VRF_32" - }, - "templateName": "Service_Network_Universal", - "vlanId": 302, - "vrfName": "IT_VRF_32" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings", - "RETURN_CODE": 200 - }, - "create_rp4_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "OneArmADC", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504123921, - "nextHopIp": "", - "peeringName": "IT-ADC-RP4", - "peeringOption": "EBGPDynamicPeering", - "reverseNextHopIp": "192.164.1.100", - "routes": [ - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP4 SN2 first arm", - "LOCAL_ASN": "65401", - "LOOPBACK_IP": "41.41.41.2", - "LOOPBACK_IPV6": "2004:4142::1", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "41.41.41.1", - "NEIGHBOR_IPV6": "2004:4141::1", - "PEER_LOOPBACK_IP": "41.41.41.3", - "PEER_LOOPBACK_IPV6": "2004:4143::1", - "ROUTE_MAP_TAG": "41112", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_41" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_41" - } - ], - "serviceNetworks": [ - { - "networkName": "rp4-sn1-first-arm", - "networkType": "ArmOneADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.164.1.1/24", - "gatewayIpV6Address": "2004:0101::1/64", - "intfDescription": "RP4 SN1 first arm intf lb:one:external:IT-SN-2:external-intf:IT-ADC-RP4", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp4-sn1-first-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30011", - "suppressArp": "false", - "tag": "41111", - "trmEnabled": "false", - "vlanId": "401", - "vlanName": "rp3-sn1-first-arm", - "vrfName": "IT_VRF_41" - }, - "templateName": "Service_Network_Universal", - "vlanId": 401, - "vrfName": "IT_VRF_41" - } - ], - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 200 - }, - "create_rp5_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "TwoArmADC", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504131111, - "nextHopIp": "", - "peeringName": "IT-ADC-RP5", - "peeringOption": "EBGPDynamicPeering", - "reverseNextHopIp": "192.165.1.100", - "routes": [ - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP5 SN2 first arm", - "LOCAL_ASN": "65501", - "LOOPBACK_IP": "51.51.51.2", - "LOOPBACK_IPV6": "2005:5152::1", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "51.51.51.1", - "NEIGHBOR_IPV6": "2005:5151::1", - "PEER_LOOPBACK_IP": "51.51.51.3", - "PEER_LOOPBACK_IPV6": "2005:5153::1", - "ROUTE_MAP_TAG": "51115", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_51" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_51" - } - ], - "serviceNetworks": [ - { - "networkName": "rp5-sn2-first-arm", - "networkType": "ArmOneADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.165.1.1/24", - "gatewayIpV6Address": "2005:0101::1/64", - "intfDescription": "RP5 SN2 first arm intf lb:one:external:IT-SN-2:external-intf:IT-ADC-RP5", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp5-sn2-first-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30012", - "suppressArp": "false", - "tag": "51111", - "trmEnabled": "false", - "vlanId": "501", - "vlanName": "rp5-sn2-first-arm", - "vrfName": "IT_VRF_51" - }, - "templateName": "Service_Network_Universal", - "vlanId": 501, - "vrfName": "IT_VRF_51" - }, - { - "networkName": "rp5-sn2-second-arm", - "networkType": "ArmTwoADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.165.2.1/24", - "gatewayIpV6Address": "2005:0102::1/64", - "intfDescription": "RP5 SN2 second arm intf lb:two:external:IT-SN-2:external-intf:IT-ADC-RP5", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp5-sn2-second-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30013", - "suppressArp": "false", - "tag": "51112", - "trmEnabled": "false", - "vlanId": "502", - "vlanName": "rp5-sn2-second-arm", - "vrfName": "IT_VRF_51" - }, - "templateName": "Service_Network_Universal", - "vlanId": 502, - "vrfName": "IT_VRF_51" - } - ], - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 200 - }, - "create_rp6_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "OneArmADC", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504137242, - "nextHopIp": "", - "peeringName": "IT-ADC-RP6", - "peeringOption": "StaticPeering", - "reverseNextHopIp": "192.166.1.100", - "routes": [ - { - "nvPairs": { - "MULTI_ROUTES": "61.61.61.1/24,161.161.161.1\n61.61.61.1/24,162.162.162.1\n22.0.0.0/24,163.163.163.1\n22.0.0.0/24,164.164.164.1", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_61" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_61" - } - ], - "serviceNetworks": [ - { - "networkName": "rp6-sn2-first-arm", - "networkType": "ArmOneADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.166.1.1/24", - "gatewayIpV6Address": "2006:0101::1/64", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf:IT-ADC-RP6", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp6-sn2-first-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30014", - "suppressArp": "false", - "tag": "61111", - "trmEnabled": "false", - "vlanId": "601", - "vlanName": "rp6-sn2-first-arm", - "vrfName": "IT_VRF_61" - }, - "templateName": "Service_Network_Universal", - "vlanId": 601, - "vrfName": "IT_VRF_61" - } - ], - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 200 - }, - "create_rp7_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "TwoArmADC", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504143911, - "nextHopIp": "", - "peeringName": "IT-ADC-RP7", - "peeringOption": "StaticPeering", - "reverseNextHopIp": "192.167.1.100", - "routes": [ - { - "nvPairs": { - "MULTI_ROUTES": "71.71.71.1/24,171.171.171.1\n71.71.71.1/24,172.172.172.1", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_71" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_71" - } - ], - "serviceNetworks": [ - { - "networkName": "rp7-sn2-first-arm", - "networkType": "ArmOneADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.167.1.1/24", - "gatewayIpV6Address": "2007:0101::1/64", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf:IT-ADC-RP7", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp7-sn2-first-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30015", - "suppressArp": "false", - "tag": "71111", - "trmEnabled": "false", - "vlanId": "701", - "vlanName": "rp7-sn2-first-arm", - "vrfName": "IT_VRF_71" - }, - "templateName": "Service_Network_Universal", - "vlanId": 701, - "vrfName": "IT_VRF_71" - }, - { - "networkName": "rp7-sn2-second-arm", - "networkType": "ArmTwoADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.167.2.1/24", - "gatewayIpV6Address": "2007:0102::1/64", - "intfDescription": "RP7 SN2 second arm intf lb:two:external:IT-SN-2:external-intf:IT-ADC-RP7", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp7-sn2-second-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30016", - "suppressArp": "false", - "tag": "71112", - "trmEnabled": "false", - "vlanId": "702", - "vlanName": "rp7-sn2-second-arm", - "vrfName": "IT_VRF_71" - }, - "templateName": "Service_Network_Universal", - "vlanId": 702, - "vrfName": "IT_VRF_71" - } - ], - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 200 - }, - - "deploy_rp1_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp2_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp3_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp4_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp5_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp6_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp7_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7/deployments", - "RETURN_CODE": 200 - }, - - "attach_rp1_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1/attachments", - "RETURN_CODE": 200 - }, - "attach_rp2_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2/attachments", - "RETURN_CODE": 200 - }, - "attach_rp3_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3/attachments", - "RETURN_CODE": 200 - }, - "attach_rp4_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4/attachments", - "RETURN_CODE": 200 - }, - "attach_rp5_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5/attachments", - "RETURN_CODE": 200 - }, - "attach_rp6_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6/attachments", - "RETURN_CODE": 200 - }, - "attach_rp7_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7/attachments", - "RETURN_CODE": 200 - }, - "config_deploy_resp" : { - "DATA": { - "status": "Config deployment has been triggered" - }, - "MESSAGE": "OK", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/rest/control/fabrics/mmudigon/config-deploy", - "RETURN_CODE": 200 - }, - "detach_rp1_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1/attachments", - "RETURN_CODE": 200 - }, - "detach_rp2_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2/attachments", - "RETURN_CODE": 200 - }, - "detach_rp3_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3/attachments", - "RETURN_CODE": 200 - }, - "detach_rp4_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4/attachments", - "RETURN_CODE": 200 - }, - "detach_rp5_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5/attachments", - "RETURN_CODE": 200 - }, - "detach_rp6_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6/attachments", - "RETURN_CODE": 200 - }, - "detach_rp7_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7/attachments", - "RETURN_CODE": 200 - }, - "config_deploy_resp" : { - "DATA": { - "status": "Config deployment has been triggered" - }, - "MESSAGE": "OK", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/rest/control/fabrics/mmudigon/config-deploy", - "RETURN_CODE": 200 - }, - "delete_rp1_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1", - "RETURN_CODE": 200 - }, - "delete_rp2_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2", - "RETURN_CODE": 200 - }, - "delete_rp3_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3", - "RETURN_CODE": 200 - }, - "delete_rp4_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4", - "RETURN_CODE": 200 - }, - "delete_rp5_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5", - "RETURN_CODE": 200 - }, - "delete_rp6_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6", - "RETURN_CODE": 200 - }, - "delete_rp7_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7", - "RETURN_CODE": 200 - }, - - "have_it_sn1_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon", - "RETURN_CODE": 200, - "DATA": [{ - "peeringName": "IT-FW-RP1", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "None", - "deploymentMode": "IntraTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_11", - "networkName": "rp1-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 101, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "101", - "gatewayIpAddress": "192.161.1.1/24", - "networkName": "rp1-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp1-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP1 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "segmentId": "30005", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2001:0101::01/64", - "dhcpServerAddr2": "", - "tag": "11111", - "nveId": "1", - "vrfName": "IT_VRF_11" - } - }, - { - "vrfName": "IT_VRF_11", - "networkName": "rp1-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 102, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "102", - "gatewayIpAddress": "192.161.2.1/24", - "networkName": "rp1-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp1-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP1 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "segmentId": "30006", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2001:0102::1/64", - "dhcpServerAddr2": "", - "tag": "11112", - "nveId": "1", - "vrfName": "IT_VRF_11" - } - } - ], - "routes": [ - - ], - "nextHopIp": "192.161.1.100", - "reverseNextHopIp": "192.161.2.100", - "enabled": "True", - "lastUpdated": 1612867982779, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Network", - "resourceName": "rp1-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp1-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-FW-RP2", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "StaticPeering", - "deploymentMode": "InterTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_21", - "networkName": "rp2-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 201, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "201", - "gatewayIpAddress": "192.162.1.1/24", - "networkName": "rp2-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp2-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP2 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "segmentId": "30009", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2002:0101::1/64", - "dhcpServerAddr2": "", - "tag": "21111", - "nveId": "1", - "vrfName": "IT_VRF_21" - } - }, - { - "vrfName": "IT_VRF_22", - "networkName": "rp2-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 202, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "202", - "gatewayIpAddress": "192.162.2.1/24", - "networkName": "rp2-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp2-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP2 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "segmentId": "30010", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2002:0102::1/64", - "dhcpServerAddr2": "", - "tag": "22222", - "nveId": "1", - "vrfName": "IT_VRF_22" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_21", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_21", - "MULTI_ROUTES": "20.20.20.0/24,120.120.120.100\n20.20.20.0/24,121.121.121.100", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - }, - { - "vrfName": "IT_VRF_22", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_22", - "MULTI_ROUTES": "21.21.21.0/24,122.122.122.100\n21.21.21.0/24,123.123.123.100", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "enabled": "True", - "lastUpdated": 1612867989552, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_21~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Policy", - "resourceName": "IT_VRF_22~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp2-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp2-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-FW-RP3", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "InterTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_31", - "networkName": "rp3-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 301, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "301", - "gatewayIpAddress": "192.163.1.1/24", - "networkName": "rp3-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp3-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP3 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "segmentId": "30011", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2003:0101::1/64", - "dhcpServerAddr2": "", - "tag": "31111", - "nveId": "1", - "vrfName": "IT_VRF_31" - } - }, - { - "vrfName": "IT_VRF_32", - "networkName": "rp3-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 302, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "302", - "gatewayIpAddress": "192.163.2.1/24", - "networkName": "rp3-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp3-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP3 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "segmentId": "30012", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2003:0102::1/64", - "dhcpServerAddr2": "", - "tag": "31112", - "nveId": "1", - "vrfName": "IT_VRF_32" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_31", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "31.31.31.1", - "LOOPBACK_IP": "31.31.31.2", - "PEER_LOOPBACK_IP": "31.31.31.3", - "NEIGHBOR_IPV6": "2003:3131::1", - "LOOPBACK_IPV6": "2003:3132::01", - "PEER_LOOPBACK_IPV6": "2003:3133::01", - "ROUTE_MAP_TAG": "33111", - "DESC": "RP3 SN1 inside interface", - "LOCAL_ASN": "65301", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_31", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - }, - { - "vrfName": "IT_VRF_32", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "131.131.131.1", - "LOOPBACK_IP": "131.131.131.2", - "PEER_LOOPBACK_IP": "131.131.131.3", - "NEIGHBOR_IPV6": "2003:8383::1", - "LOOPBACK_IPV6": "2003:8384::1:100:1", - "PEER_LOOPBACK_IPV6": "2003:8385::1", - "ROUTE_MAP_TAG": "31113", - "DESC": "RP3 SN1 outside interface", - "LOCAL_ASN": "65302", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_32", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "enabled": "True", - "lastUpdated": 1612867999301, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_31~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Policy", - "resourceName": "IT_VRF_32~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp3-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp3-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - ] - }, - - "have_it_sn2_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon", - "RETURN_CODE": 200, - "DATA" : [ - { - "peeringName": "IT-ADC-RP4", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "OneArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_41", - "networkName": "rp4-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 401, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "401", - "gatewayIpAddress": "192.164.1.1/24", - "networkName": "rp4-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp4-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP4 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP4", - "segmentId": "30013", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2004:0101::1/64", - "dhcpServerAddr2": "", - "tag": "41111", - "nveId": "1", - "vrfName": "IT_VRF_41" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_41", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "41.41.41.1", - "LOOPBACK_IP": "41.41.41.2", - "PEER_LOOPBACK_IP": "41.41.41.3", - "NEIGHBOR_IPV6": "2004:4141::1", - "LOOPBACK_IPV6": "2004:4142::1", - "PEER_LOOPBACK_IPV6": "2004:4143::1", - "ROUTE_MAP_TAG": "41112", - "DESC": "RP4 SN2 first arm", - "LOCAL_ASN": "65401", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_41", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.164.1.100", - "enabled": "True", - "lastUpdated": 1612868008195, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_41~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp4-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-ADC-RP5", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "TwoArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_51", - "networkName": "rp5-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 501, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "501", - "gatewayIpAddress": "192.165.1.1/24", - "enableL3OnBorder": "false", - "vlanName": "rp5-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP5 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP5", - "segmentId": "30007", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2005:0101::1/64", - "dhcpServerAddr2": "", - "tag": "51111", - "nveId": "1", - "vrfName": "IT_VRF_51" - } - }, - { - "vrfName": "IT_VRF_51", - "networkName": "rp5-sn2-second-arm", - "networkType": "ArmTwoADC", - "vlanId": 502, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "502", - "gatewayIpAddress": "192.165.2.1/24", - "enableL3OnBorder": "false", - "vlanName": "rp5-sn2-second-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP5 SN2 second arm intf lb:two:external:IT-SN-2:external-intf-2:IT-ADC-RP5", - "segmentId": "30008", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2005:0102::1/64", - "dhcpServerAddr2": "", - "tag": "51112", - "nveId": "1", - "vrfName": "IT_VRF_51" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_51", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "51.51.51.1", - "LOOPBACK_IP": "51.51.51.2", - "PEER_LOOPBACK_IP": "51.51.51.3", - "NEIGHBOR_IPV6": "2005:5151::1", - "LOOPBACK_IPV6": "2005:5152::1", - "PEER_LOOPBACK_IPV6": "2005:5153::1", - "ROUTE_MAP_TAG": "51115", - "DESC": "RP5 SN2 first arm", - "LOCAL_ASN": "65501", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_51", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.165.1.100", - "enabled": "True", - "lastUpdated": 1612868017158, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_51~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp5-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp5-sn2-second-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-ADC-RP6", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "StaticPeering", - "deploymentMode": "OneArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_61", - "networkName": "rp6-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 601, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "601", - "gatewayIpAddress": "192.166.1.1/24", - "networkName": "rp6-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp6-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP6", - "segmentId": "30014", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2006:0101::1/64", - "dhcpServerAddr2": "", - "tag": "61111", - "nveId": "1", - "vrfName": "IT_VRF_61" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_61", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_61", - "MULTI_ROUTES": "61.61.61.1/24,161.161.161.1\n61.61.61.1/24,162.162.162.1\n22.0.0.0/24,163.163.163.1\n22.0.0.0/24,164.164.164.1", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.166.1.100", - "enabled": "True", - "lastUpdated": 1612868027172, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_61~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp6-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-ADC-RP7", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "StaticPeering", - "deploymentMode": "TwoArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_71", - "networkName": "rp7-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 701, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "701", - "gatewayIpAddress": "192.167.1.1/24", - "networkName": "rp7-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp7-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP7", - "segmentId": "30015", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2007:0101::1/64", - "dhcpServerAddr2": "", - "tag": "71111", - "nveId": "1", - "vrfName": "IT_VRF_71" - } - }, - { - "vrfName": "IT_VRF_71", - "networkName": "rp7-sn2-second-arm", - "networkType": "ArmTwoADC", - "vlanId": 702, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "702", - "gatewayIpAddress": "192.167.2.1/24", - "networkName": "rp7-sn2-second-arm", - "enableL3OnBorder": "false", - "vlanName": "rp7-sn2-second-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP7 SN2 second arm intf lb:two:external:IT-SN-2:external-intf-2:IT-ADC-RP7", - "segmentId": "30016", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2007:0102::1/64", - "dhcpServerAddr2": "", - "tag": "71112", - "nveId": "1", - "vrfName": "IT_VRF_71" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_71", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_71", - "MULTI_ROUTES": "71.71.71.1/24,171.171.171.1\n71.71.71.1/24,172.172.172.1", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.167.1.100", - "enabled": "True", - "lastUpdated": 1612868035280, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_71~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp7-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp7-sn2-second-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - ] - }, - - "have_rp1_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-ADC-RP1", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-FW-RP1", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "None", - "deploymentMode": "IntraTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_11", - "networkName": "rp1-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 101, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "101", - "gatewayIpAddress": "192.161.1.1/24", - "networkName": "rp1-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp1-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP1 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "segmentId": "30005", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2001:0101::01/64", - "dhcpServerAddr2": "", - "tag": "11111", - "nveId": "1", - "vrfName": "IT_VRF_11" - } - }, - { - "vrfName": "IT_VRF_11", - "networkName": "rp1-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 102, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "102", - "gatewayIpAddress": "192.161.2.1/24", - "networkName": "rp1-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp1-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP1 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "segmentId": "30006", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2001:0102::1/64", - "dhcpServerAddr2": "", - "tag": "11112", - "nveId": "1", - "vrfName": "IT_VRF_11" - } - } - ], - "routes": [ - - ], - "nextHopIp": "192.161.1.100", - "reverseNextHopIp": "192.161.2.100", - "enabled": "True", - "lastUpdated": 1612867982779, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Network", - "resourceName": "rp1-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp1-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp2_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-ADC-RP2", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-FW-RP2", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "StaticPeering", - "deploymentMode": "InterTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_21", - "networkName": "rp2-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 201, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "201", - "gatewayIpAddress": "192.162.1.1/24", - "networkName": "rp2-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp2-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP2 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "segmentId": "30009", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2002:0101::1/64", - "dhcpServerAddr2": "", - "tag": "21111", - "nveId": "1", - "vrfName": "IT_VRF_21" - } - }, - { - "vrfName": "IT_VRF_22", - "networkName": "rp2-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 202, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "202", - "gatewayIpAddress": "192.162.2.1/24", - "networkName": "rp2-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp2-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP2 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "segmentId": "30010", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2002:0102::1/64", - "dhcpServerAddr2": "", - "tag": "22222", - "nveId": "1", - "vrfName": "IT_VRF_22" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_21", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_21", - "MULTI_ROUTES": "20.20.20.0/24,120.120.120.100\n20.20.20.0/24,121.121.121.100", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - }, - { - "vrfName": "IT_VRF_22", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_22", - "MULTI_ROUTES": "21.21.21.0/24,122.122.122.100\n21.21.21.0/24,123.123.123.100", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "enabled": "True", - "lastUpdated": 1612867989552, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_21~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Policy", - "resourceName": "IT_VRF_22~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp2-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp2-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp3_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-ADC-RP3", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-FW-RP3", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "InterTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_31", - "networkName": "rp3-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 301, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "301", - "gatewayIpAddress": "192.163.1.1/24", - "networkName": "rp3-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp3-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP3 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "segmentId": "30011", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2003:0101::1/64", - "dhcpServerAddr2": "", - "tag": "31111", - "nveId": "1", - "vrfName": "IT_VRF_31" - } - }, - { - "vrfName": "IT_VRF_32", - "networkName": "rp3-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 302, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "302", - "gatewayIpAddress": "192.163.2.1/24", - "networkName": "rp3-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp3-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP3 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "segmentId": "30012", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2003:0102::1/64", - "dhcpServerAddr2": "", - "tag": "31112", - "nveId": "1", - "vrfName": "IT_VRF_32" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_31", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "31.31.31.1", - "LOOPBACK_IP": "31.31.31.2", - "PEER_LOOPBACK_IP": "31.31.31.3", - "NEIGHBOR_IPV6": "2003:3131::1", - "LOOPBACK_IPV6": "2003:3132::01", - "PEER_LOOPBACK_IPV6": "2003:3133::01", - "ROUTE_MAP_TAG": "33111", - "DESC": "RP3 SN1 inside interface", - "LOCAL_ASN": "65301", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_31", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - }, - { - "vrfName": "IT_VRF_32", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "131.131.131.1", - "LOOPBACK_IP": "131.131.131.2", - "PEER_LOOPBACK_IP": "131.131.131.3", - "NEIGHBOR_IPV6": "2003:8383::1", - "LOOPBACK_IPV6": "2003:8384::1:100:1", - "PEER_LOOPBACK_IPV6": "2003:8385::1", - "ROUTE_MAP_TAG": "31113", - "DESC": "RP3 SN1 outside interface", - "LOCAL_ASN": "65302", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_32", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "enabled": "True", - "lastUpdated": 1612867999301, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_31~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Policy", - "resourceName": "IT_VRF_32~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp3-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp3-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp4_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-ADC-RP4", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "OneArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_41", - "networkName": "rp4-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 401, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "401", - "gatewayIpAddress": "192.164.1.1/24", - "networkName": "rp4-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp4-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP4 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP4", - "segmentId": "30013", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2004:0101::1/64", - "dhcpServerAddr2": "", - "tag": "41111", - "nveId": "1", - "vrfName": "IT_VRF_41" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_41", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "41.41.41.1", - "LOOPBACK_IP": "41.41.41.2", - "PEER_LOOPBACK_IP": "41.41.41.3", - "NEIGHBOR_IPV6": "2004:4141::1", - "LOOPBACK_IPV6": "2004:4142::1", - "PEER_LOOPBACK_IPV6": "2004:4143::1", - "ROUTE_MAP_TAG": "41112", - "DESC": "RP4 SN2 first arm", - "LOCAL_ASN": "65401", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_41", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.164.1.100", - "enabled": "True", - "lastUpdated": 1612868008195, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_41~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp4-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp5_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-ADC-RP5", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "TwoArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_51", - "networkName": "rp5-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 501, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "501", - "gatewayIpAddress": "192.165.1.1/24", - "enableL3OnBorder": "false", - "vlanName": "rp5-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP5 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP5", - "segmentId": "30007", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2005:0101::1/64", - "dhcpServerAddr2": "", - "tag": "51111", - "nveId": "1", - "vrfName": "IT_VRF_51" - } - }, - { - "vrfName": "IT_VRF_51", - "networkName": "rp5-sn2-second-arm", - "networkType": "ArmTwoADC", - "vlanId": 502, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "502", - "gatewayIpAddress": "192.165.2.1/24", - "enableL3OnBorder": "false", - "vlanName": "rp5-sn2-second-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP5 SN2 second arm intf lb:two:external:IT-SN-2:external-intf-2:IT-ADC-RP5", - "segmentId": "30008", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2005:0102::1/64", - "dhcpServerAddr2": "", - "tag": "51112", - "nveId": "1", - "vrfName": "IT_VRF_51" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_51", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "51.51.51.1", - "LOOPBACK_IP": "51.51.51.2", - "PEER_LOOPBACK_IP": "51.51.51.3", - "NEIGHBOR_IPV6": "2005:5151::1", - "LOOPBACK_IPV6": "2005:5152::1", - "PEER_LOOPBACK_IPV6": "2005:5153::1", - "ROUTE_MAP_TAG": "51115", - "DESC": "RP5 SN2 first arm", - "LOCAL_ASN": "65501", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_51", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.165.1.100", - "enabled": "True", - "lastUpdated": 1612868017158, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_51~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp5-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp5-sn2-second-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp6_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-ADC-RP6", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "StaticPeering", - "deploymentMode": "OneArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_61", - "networkName": "rp6-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 601, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "601", - "gatewayIpAddress": "192.166.1.1/24", - "networkName": "rp6-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp6-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP6", - "segmentId": "30014", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2006:0101::1/64", - "dhcpServerAddr2": "", - "tag": "61111", - "nveId": "1", - "vrfName": "IT_VRF_61" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_61", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_61", - "MULTI_ROUTES": "61.61.61.1/24,161.161.161.1\n61.61.61.1/24,162.162.162.1\n22.0.0.0/24,163.163.163.1\n22.0.0.0/24,164.164.164.1", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.166.1.100", - "enabled": "True", - "lastUpdated": 1612868027172, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_61~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp6-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp7_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-ADC-RP7", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "StaticPeering", - "deploymentMode": "TwoArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_71", - "networkName": "rp7-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 701, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "701", - "gatewayIpAddress": "192.167.1.1/24", - "networkName": "rp7-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp7-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP7", - "segmentId": "30015", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2007:0101::1/64", - "dhcpServerAddr2": "", - "tag": "71111", - "nveId": "1", - "vrfName": "IT_VRF_71" - } - }, - { - "vrfName": "IT_VRF_71", - "networkName": "rp7-sn2-second-arm", - "networkType": "ArmTwoADC", - "vlanId": 702, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "702", - "gatewayIpAddress": "192.167.2.1/24", - "networkName": "rp7-sn2-second-arm", - "enableL3OnBorder": "false", - "vlanName": "rp7-sn2-second-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP7 SN2 second arm intf lb:two:external:IT-SN-2:external-intf-2:IT-ADC-RP7", - "segmentId": "30016", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2007:0102::1/64", - "dhcpServerAddr2": "", - "tag": "71112", - "nveId": "1", - "vrfName": "IT_VRF_71" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_71", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_71", - "MULTI_ROUTES": "71.71.71.1/24,171.171.171.1\n71.71.71.1/24,172.172.172.1", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.167.1.100", - "enabled": "True", - "lastUpdated": 1612868035280, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_71~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp7-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp7-sn2-second-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - - "replaced_rp1_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "IntraTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612942460116, - "nextHopIp": "192.161.1.200", - "peeringName": "IT-FW-RP1", - "peeringOption": "None", - "reverseNextHopIp": "192.161.2.200", - "routes": [], - "serviceNetworks": [ - { - "networkName": "rp1-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.161.1.1/24", - "gatewayIpV6Address": "2101:0101::01/64", - "intfDescription": "RP1 SN1 inside interface - REP fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "11101", - "trmEnabled": "false", - "vlanId": "191", - "vlanName": "rp1-sn1-inside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 191, - "vrfName": "IT_VRF_11" - }, - { - "networkName": "rp1-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.161.2.1/24", - "gatewayIpV6Address": "2101:0102::1/64", - "intfDescription": "RP1 SN1 outside interface- REP fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "11102", - "trmEnabled": "false", - "vlanId": "192", - "vlanName": "rp1-sn1-outside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 192, - "vrfName": "IT_VRF_11" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "PUT", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1", - "RETURN_CODE": 200 - }, - "replaced_rp2_resp": { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "InterTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612942469457, - "peeringName": "IT-FW-RP2", - "peeringOption": "StaticPeering", - "routes": [ - { - "nvPairs": { - "MULTI_ROUTES": "20.20.90.0/24,120.120.190.100\n20.20.90.0/24,121.121.191.100", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_21" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_21" - }, - { - "nvPairs": { - "MULTI_ROUTES": "21.21.29.0/24,122.122.129.100\n21.21.29.0/24,123.123.129.100", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_22" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_22" - } - ], - "serviceNetworks": [ - { - "networkName": "rp2-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.162.1.1/24", - "gatewayIpV6Address": "2102:0101::1/64", - "intfDescription": "RP2 SN1 inside interface - REP fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "21101", - "trmEnabled": "false", - "vlanId": "291", - "vlanName": "rp2-sn1-inside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 291, - "vrfName": "IT_VRF_21" - }, - { - "networkName": "rp2-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.162.2.1/24", - "gatewayIpV6Address": "2102:0102::1/64", - "intfDescription": "RP2 SN1 outside interface - REP fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "22202", - "trmEnabled": "false", - "vlanId": "292", - "vlanName": "rp2-sn1-outside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 292, - "vrfName": "IT_VRF_22" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "PUT", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2", - "RETURN_CODE": 200 - }, - - "replaced_rp3_resp": { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "InterTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612942479141, - "peeringName": "IT-FW-RP3", - "peeringOption": "EBGPDynamicPeering", - "routes": [ - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP3 SN1 inside interface - REP", - "LOCAL_ASN": "65391", - "LOOPBACK_IP": "31.31.39.2", - "LOOPBACK_IPV6": "2103:3132::01", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "31.31.39.1", - "NEIGHBOR_IPV6": "2103:3131::1", - "PEER_LOOPBACK_IP": "31.31.39.3", - "PEER_LOOPBACK_IPV6": "2103:3133::01", - "ROUTE_MAP_TAG": "33101", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_31" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_31" - }, - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP3 SN1 outside interface - REP", - "LOCAL_ASN": "65392", - "LOOPBACK_IP": "131.131.139.2", - "LOOPBACK_IPV6": "2103:8384::1:100:1", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "131.131.139.1", - "NEIGHBOR_IPV6": "2103:8383::1", - "PEER_LOOPBACK_IP": "131.131.139.3", - "PEER_LOOPBACK_IPV6": "2103:8385::1", - "ROUTE_MAP_TAG": "31103", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_32" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_32" - } - ], - "serviceNetworks": [ - { - "networkName": "rp3-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.163.1.1/24", - "gatewayIpV6Address": "2103:0101::1/64", - "intfDescription": "RP3 SN1 inside interface - REP fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "31101", - "trmEnabled": "false", - "vlanId": "391", - "vlanName": "rp3-sn1-inside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 391, - "vrfName": "IT_VRF_31" - }, - { - "networkName": "rp3-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.163.2.1/24", - "gatewayIpV6Address": "2103:0102::1/64", - "intfDescription": "RP3 SN1 outside interface - REP fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "31102", - "trmEnabled": "false", - "vlanId": "302", - "vlanName": "rp3-sn1-outside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 302, - "vrfName": "IT_VRF_32" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "PUT", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3", - "RETURN_CODE": 200 - }, - - "serv_nodes_resp" : { - "MESSAGE": "", - "METHOD": "PUT", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/?atached-fabric=mmudigon", - "RETURN_CODE": 200, - "DATA" :[ - { - "name" : "IT-SN-1" - }, - { - "name" : "IT-SN-2" - } - ] - } -} - diff --git a/tests/unit/modules/dcnm/test_dcnm_service_node.py b/tests/unit/modules/dcnm/test_dcnm_service_node.py deleted file mode 100644 index 94aff6f2e..000000000 --- a/tests/unit/modules/dcnm/test_dcnm_service_node.py +++ /dev/null @@ -1,499 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2021 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from ansible_collections.ansible.netcommon.tests.unit.compat.mock import patch - -from ansible_collections.cisco.dcnm.plugins.modules import dcnm_service_node -from .dcnm_module import TestDcnmModule, set_module_args, loadPlaybookData - -import json, copy - -__copyright__ = "Copyright (c) 2021 Cisco and/or its affiliates." -__author__ = "Karthik Babu Harichandra Babu" - -class TestDcnmServiceNodeModule(TestDcnmModule): - - module = dcnm_service_node - - test_data = loadPlaybookData('dcnm_service_node') - - SUCCESS_RETURN_CODE = 200 - - mock_ip_sn = test_data.get('mock_ip_sn') - sn_inv_data = test_data.get('sn_inv_data') - playbook_config = test_data.get('playbook_config') - playbook_config_replace_new = test_data.get('playbook_config_replace_new') - playbook_config_replace_new1 = test_data.get('playbook_config_replace_new1') - playbook_new_config = test_data.get('playbook_new_config') - playbook_config_virtual = test_data.get('playbook_config_virtual') - playbook_config_load = test_data.get('playbook_config_load') - playbook_config_vnf = test_data.get('playbook_config_vnf') - playbook_config_vpc = test_data.get('playbook_config_vpc') - playbook_config_invalid_vpc = test_data.get('playbook_config_invalid_vpc') - playbook_config_no_params = test_data.get('playbook_config_no_params') - playbook_config_no_type = test_data.get('playbook_config_no_type') - playbook_config_no_ff = test_data.get('playbook_config_no_ff') - playbook_config_no_vpc = test_data.get('playbook_config_no_vpc') - playbook_config_more_switch = test_data.get('playbook_config_more_switch') - playbook_config_name = test_data.get('playbook_config_name') - playbook_over_config = test_data.get('playbook_over_config') - playbook_config_query = test_data.get('playbook_config_query') - get_have_failure = test_data.get('get_have_failure') - blank_data = test_data.get('blank_data') - blank_data_null = test_data.get('blank_data_null') - blank_get_data = test_data.get('blank_get_data') - error1 = test_data.get('error1') - sn_delete_success_resp = test_data.get('sn_delete_success_resp') - sn_query_success_resp = test_data.get('sn_query_success_resp') - - def init_data(self): - # Some of the mock data is re-initialized after each test as previous test might have altered portions - # of the mock data. - - self.mock_sn_1_object = copy.deepcopy(self.test_data.get('mock_sn_1_object')) - self.mock_sn_merge_1_success = copy.deepcopy(self.test_data.get('mock_sn_merge_1_success')) - self.mock_sn_merge_2_success = copy.deepcopy(self.test_data.get('mock_sn_merge_2_success')) - self.mock_sn_merge_3_success = copy.deepcopy(self.test_data.get('mock_sn_merge_3_success')) - self.mock_sn_merge_4_success = copy.deepcopy(self.test_data.get('mock_sn_merge_4_success')) - self.mock_sn_merge_5_success = copy.deepcopy(self.test_data.get('mock_sn_merge_5_success')) - self.mock_sn_merge_6_success = copy.deepcopy(self.test_data.get('mock_sn_merge_6_success')) - self.mock_sn_replace_1_success = copy.deepcopy(self.test_data.get('mock_sn_replace_1_success')) - self.mock_sn_replace_2_success = copy.deepcopy(self.test_data.get('mock_sn_replace_2_success')) - self.mock_sn_have_success = copy.deepcopy(self.test_data.get('mock_sn_have_success')) - self.mock_sn_query_success = copy.deepcopy(self.test_data.get('mock_sn_query_success')) - - def setUp(self): - super(TestDcnmServiceNodeModule, self).setUp() - - self.mock_dcnm_ip_sn = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_node.get_fabric_inventory_details') - self.run_dcnm_ip_sn = self.mock_dcnm_ip_sn.start() - - self.mock_dcnm_send = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_node.dcnm_send') - self.run_dcnm_send = self.mock_dcnm_send.start() - - def tearDown(self): - super(TestDcnmServiceNodeModule, self).tearDown() - self.mock_dcnm_send.stop() - self.mock_dcnm_ip_sn.stop() - - def load_fixtures(self, response=None, device=''): - - if 'sn_blank_fabric' in self._testMethodName: - self.run_dcnm_ip_sn.side_effect = [{}] - else: - self.run_dcnm_ip_sn.side_effect = [self.sn_inv_data] - - if 'get_have_failure' in self._testMethodName: - self.run_dcnm_send.side_effect = [self.get_have_failure] - - elif '_check_mode' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_get_data] - - elif '_merged_one' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_1_success] - - elif '_merged_two' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_2_success] - - elif '_merged_three' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_3_success] - - elif '_merged_four' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_4_success] - - elif '_merged_five' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_5_success] - - elif 'error1' in self._testMethodName: - self.run_dcnm_send.side_effect = [self.blank_data, self.error1, self.blank_data] - - elif '_merged_invalid_vpc' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_params' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_type' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_ff' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_more_switch' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_vpc' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif 'delete_std' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.sn_delete_success_resp] - - elif 'delete_all' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.sn_delete_success_resp] - - elif 'query_no' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.sn_query_success_resp] - - elif 'query_on' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success,self.mock_sn_have_success] - - elif 'query_without_config' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success,self.mock_sn_have_success] - - elif 'query_withonly_name' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success,self.mock_sn_have_success] - - elif 'query_invalid_param' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif 'query_null' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data_null] - - elif 'override_with_additions' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_1_success] - - elif 'override_with_deletions' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.sn_delete_success_resp, self.mock_sn_merge_6_success] - - elif 'override_without_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success] - - elif 'replace_with_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.mock_sn_replace_1_success] - - elif 'replace_with_type_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.mock_sn_replace_2_success] - - elif 'replace_without_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success] - - else: - pass - - def test_dcnm_sn_blank_fabric(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric test_fabric missing on DCNM or does not have any switches') - - def test_dcnm_sn_get_have_failure(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric test_fabric not present on DCNM') - - def test_dcnm_sn_check_mode(self): - set_module_args(dict(check_mode=True, state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertFalse(result.get('response')) - - def test_dcnm_sn_merged_one(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_two(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_virtual)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_three(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_load)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'AVB') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_four(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_vnf)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'VNF') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_five(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_vpc)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'vPC1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_error1(self): - set_module_args(dict(state='merged', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result['msg']['RETURN_CODE'], 400) - self.assertEqual(result['msg']['ERROR'], 'There is an error') - - def test_dcnm_sn_merged_invalid_vpc(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_invalid_vpc)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric: test_fabric - if two switches are provided, vpc is only interface option') - - def test_dcnm_sn_merged_more_switch(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_more_switch)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric: test_fabric - Upto 2 switches only allowed') - - def test_dcnm_sn_merged_no_params(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_params)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'config: element is mandatory for this state merged') - - def test_dcnm_sn_merged_no_type(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_type)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Invalid parameters in playbook: karth : Invalid choice provided') - - def test_dcnm_sn_merged_no_ff(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_ff)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Invalid parameters in playbook: babu : Invalid choice provided') - - def test_dcnm_sn_merged_no_vpc(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_vpc)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric: test_fabric - For 1 switch, vpc is not the interface option') - - def test_dcnm_sn_delete_std(self): - set_module_args(dict(state='deleted', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'DELETE') - - def test_dcnm_sn_delete_all(self): - set_module_args(dict(state='deleted', fabric='test_fabric', - service_fabric='external', config=[])) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'DELETE') - - def test_dcnm_sn_query_no(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result.get('response'), []) - - def test_dcnm_sn_query_on(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result['response'][0]['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['fabricName'], 'external') - self.assertEqual(result['response'][0]['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['name'], 'SN-11') - self.assertEqual(result['response'][0]['type'], 'Firewall') - - def test_dcnm_sn_query_without_config(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=[])) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result['response'][0]['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['fabricName'], 'external') - self.assertEqual(result['response'][0]['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['name'], 'SN-11') - self.assertEqual(result['response'][0]['type'], 'Firewall') - - def test_dcnm_sn_query_withonly_name(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_name)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result['response'][0]['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['fabricName'], 'external') - self.assertEqual(result['response'][0]['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['name'], 'SN-11') - self.assertEqual(result['response'][0]['type'], 'Firewall') - - def test_dcnm_sn_query_invalid_param(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_query)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Invalid parameters in playbook: name : Required parameter not found') - - def test_dcnm_sn_query_null(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Unable to Service Node under fabric: test_fabric') - - def test_dcnm_sn_override_with_additions(self): - set_module_args(dict(state='overridden', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_override_with_deletions(self): - set_module_args(dict(state='overridden', fabric='test_fabric', - service_fabric='external', config=self.playbook_new_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'DELETE') - self.assertEqual(result['response'][1]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][1]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/2') - self.assertEqual(result['response'][1]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][1]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][1]['DATA']['interfaceName'], 'scv12') - self.assertEqual(result['response'][1]['DATA']['name'], 'SN-12') - self.assertEqual(result['response'][1]['DATA']['type'], 'ADC') - self.assertEqual(result['response'][1]['RETURN_CODE'], 200) - - def test_dcnm_sn_override_without_changes(self): - set_module_args(dict(state='overridden', fabric='test_fabric', - service_fabric='external', config=self.playbook_over_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertFalse(result.get('response')) - - def test_dcnm_sn_replace_with_changes(self): - set_module_args(dict(state='replaced', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_replace_new)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'PUT') - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv11') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_replace_with_type_changes(self): - set_module_args(dict(state='replaced', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_replace_new1)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'PUT') - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv11') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'ADC') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_replace_without_changes(self): - set_module_args(dict(state='replaced', fabric='test_fabric', - service_fabric='external', config=self.playbook_over_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertFalse(result.get('response')) diff --git a/tests/unit/modules/dcnm/test_dcnm_service_route_peering.py b/tests/unit/modules/dcnm/test_dcnm_service_route_peering.py deleted file mode 100644 index 80d8582f5..000000000 --- a/tests/unit/modules/dcnm/test_dcnm_service_route_peering.py +++ /dev/null @@ -1,1839 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2020 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from ansible_collections.ansible.netcommon.tests.unit.compat.mock import patch - -from ansible_collections.cisco.dcnm.plugins.modules import dcnm_service_route_peering -from .dcnm_module import TestDcnmModule, set_module_args, loadPlaybookData - -import json, copy - -class TestDcnmServiceRoutePeeringModule(TestDcnmModule): - - module = dcnm_service_route_peering - fd = None - - def init_data(self): - self.fd = None - - def log_msg (self, msg): - - if (self.fd is None): - self.fd = open("srp-ut.log", "w+") - self.fd.write (msg) - - def setUp(self): - - super(TestDcnmServiceRoutePeeringModule, self).setUp() - - self.mock_dcnm_send = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_route_peering.dcnm_send') - self.run_dcnm_send = self.mock_dcnm_send.start() - - self.mock_dcnm_reset_connection = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_route_peering.dcnm_reset_connection') - self.run_dcnm_reset_connection = self.mock_dcnm_reset_connection.start() - def tearDown(self): - - super(TestDcnmServiceRoutePeeringModule, self).tearDown() - self.mock_dcnm_send.stop() - self.mock_dcnm_reset_connection.stop() - -#################################### FIXTURES ############################ - - def load_srp_fixtures (self): - - if ('test_dcnm_srp_merged_new' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - deploy_rp4_resp_unauth_err = self.payloads_data.get('deploy_rp4_resp_unauth_err') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp_unauth_err, deploy_rp4_resp, - deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merged_new_no_opt_elems' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merged_existing_no_opt_elems' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - att_rp4_status = self.payloads_data.get('attach_rp4_resp') - att_rp5_status = self.payloads_data.get('attach_rp5_resp') - att_rp6_status = self.payloads_data.get('attach_rp6_resp') - att_rp7_status = self.payloads_data.get('attach_rp7_resp') - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - att_rp1_status, att_rp2_status, att_rp3_status, - att_rp4_status, att_rp5_status, att_rp6_status, - att_rp7_status, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merged_new_check_mode' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp] - - - if ('test_dcnm_srp_merged_new_unauth_error' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - create_rp7_resp_unauth_err = self.payloads_data.get('create_rp7_resp_unauth_err') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp_unauth_err, have_rp7_resp, create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_config_without_state' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - - deploy_rp7_resp] - if ('test_dcnm_srp_merge_no_deploy' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merge_deploy_false' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp] - - - if ('test_dcnm_srp_merged_existing' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - att_rp4_status = self.payloads_data.get('attach_rp4_resp') - att_rp5_status = self.payloads_data.get('attach_rp5_resp') - att_rp6_status = self.payloads_data.get('attach_rp6_resp') - att_rp7_status = self.payloads_data.get('attach_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - att_rp1_status, att_rp2_status, att_rp3_status, - att_rp4_status, att_rp5_status, att_rp6_status, - att_rp7_status] - - if ('test_dcnm_srp_merged_existing_and_non_existing' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - att_rp5_status = self.payloads_data.get('attach_rp5_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, [], have_rp3_resp, - [], have_rp5_resp, [], [], - att_rp1_status, att_rp3_status, - att_rp5_status, - create_rp2_resp, create_rp4_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp2_resp, deploy_rp4_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merged_update_existing' == self._testMethodName): - - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp4_status = self.payloads_data.get('attach_rp4_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - - self.run_dcnm_send.side_effect = [have_rp2_resp, have_rp4_resp, - att_rp2_status, att_rp4_status, - create_rp2_resp, create_rp4_resp, - deploy_rp2_resp, deploy_rp4_resp] - - if ('test_dcnm_srp_merged_update_existing_unauth_err' == self._testMethodName): - - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp4_status = self.payloads_data.get('attach_rp4_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - - create_rp4_resp_unauth_err = self.payloads_data.get('create_rp4_resp_unauth_err') - - self.run_dcnm_send.side_effect = [have_rp2_resp, have_rp4_resp, - att_rp2_status, att_rp4_status, - create_rp2_resp, - create_rp4_resp_unauth_err, - create_rp4_resp, - deploy_rp2_resp, deploy_rp4_resp] - - if ('test_dcnm_srp_delete_existing' == self._testMethodName): - - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp] - - if ('test_dcnm_srp_delete_existing_unauth_err' == self._testMethodName): - - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - det_rp1_resp_unauth_err = self.payloads_data.get('det_rp1_resp_unauth_err') - deploy_rp4_resp_unauth_err = self.payloads_data.get('deploy_rp4_resp_unauth_err') - delete_rp7_resp_unauth_err = self.payloads_data.get('delete_rp7_resp_unauth_err') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - det_rp1_resp_unauth_err, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp_unauth_err, deploy_rp4_resp, - deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp_unauth_err, deploy_rp7_resp, delete_rp7_resp] - - if ('test_dcnm_srp_delete_existing_and_non_existing' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [have_rp1_resp, [], have_rp3_resp, - [], [], have_rp6_resp, - have_rp7_resp, - det_rp1_resp, det_rp3_resp, - det_rp6_resp, det_rp7_resp, - deploy_rp1_resp, deploy_rp3_resp, - deploy_rp6_resp, deploy_rp7_resp, - delete_rp1_resp, delete_rp3_resp, - delete_rp6_resp, delete_rp7_resp] - - if ('test_dcnm_srp_delete_non_existing' == self._testMethodName): - - self.run_dcnm_send.side_effect = [[], [], [], [], [], [], []] - - if ('test_dcnm_srp_replace_rp1_to_rp3_non_existing' == self._testMethodName): - - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - - self.run_dcnm_send.side_effect = [[], [], [], - create_rp1_resp, create_rp2_resp, create_rp3_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp] - - if ('test_dcnm_srp_replace_rp1_to_rp3_existing' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - att_rp1_status, att_rp2_status, att_rp3_status, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp] - - if ('test_dcnm_srp_replace_rp1_to_rp3_existing_no_change' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - att_rp1_status, att_rp2_status, att_rp3_status] - - if ('test_dcnm_srp_override_rp1_rp7_with_new_peerings' == self._testMethodName): - - have_it_sn1_resp = self.payloads_data.get('have_it_sn1_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [[], [], - have_it_sn1_resp, have_it_sn2_resp, - create_rp1_resp, create_rp2_resp, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp, deploy_rp1_resp, deploy_rp2_resp - ] - - if ('test_dcnm_srp_override_with_existing_peering' == self._testMethodName): - - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - att_rp6_status = self.payloads_data.get('attach_rp6_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [have_rp6_resp, - have_it_sn2_resp, att_rp6_status, - det_rp4_resp, det_rp5_resp, - det_rp7_resp, - deploy_rp4_resp, deploy_rp5_resp, - deploy_rp7_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp7_resp - ] - - if ('test_dcnm_srp_override_with_existing_peering_updated' == self._testMethodName): - - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - att_rp6_status = self.payloads_data.get('attach_rp6_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp6_resp, - have_it_sn2_resp, att_rp6_status, - create_rp6_resp, - det_rp4_resp, det_rp5_resp, - det_rp7_resp, - deploy_rp4_resp, deploy_rp5_resp, - deploy_rp7_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp7_resp, - deploy_rp6_resp - ] - - if ('test_dcnm_srp_override_with_service_nodes_alone' == self._testMethodName): - - have_it_sn1_resp = self.payloads_data.get('have_it_sn1_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [have_it_sn1_resp, have_it_sn2_resp, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp - ] - - if ('test_dcnm_srp_override_with_no_config' == self._testMethodName): - - serv_nodes_resp = self.payloads_data.get('serv_nodes_resp') - have_it_sn1_resp = self.payloads_data.get('have_it_sn1_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [serv_nodes_resp, - have_it_sn1_resp, have_it_sn2_resp, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp - ] - - if ('test_dcnm_srp_query_non_existing' == self._testMethodName): - - self.run_dcnm_send.side_effect = [[],[]] - - if ('test_dcnm_srp_query_with_service_nodes' == self._testMethodName): - - have_it_sn1_resp = self.payloads_data.get('have_it_sn1_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - - self.run_dcnm_send.side_effect = [have_it_sn1_resp, have_it_sn2_resp] - - if ('test_dcnm_srp_query_with_peer_names' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp] - - - def load_fixtures(self, response=None, device=''): - - # Load srp related side-effects - self.load_srp_fixtures () - -#################################### FIXTURES END ############################ -#################################### TEST-CASES ############################## - - def test_dcnm_srp_merged_new (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_new_no_opt_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config_no_opt_elems') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_existing_no_opt_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config_no_opt_elems') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_new_no_intra_fw_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_no_intra_fw_mand_elems') - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - ## No Deploy Mode object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("deploy_mode") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('deploy_mode - Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No name object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("name") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("next_hop") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('next_hop : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No node_name object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("node_name") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('node_name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - nets = ["inside_network", "outside_network"] - - for net in nets: - ## No Inside Name object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net].pop("name") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No Inside Profile IPV4GW object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net]["profile"].pop("ipv4_gw") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('ipv4_gw : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No Inside vlan_id object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net].pop("vlan_id") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('vlan_id : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No Inside vrf object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net].pop("vrf") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('vrf : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - def test_dcnm_srp_merged_new_no_inter_fw_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_no_inter_fw_mand_elems') - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - nets = ["inside_network", "outside_network"] - - for net in nets: - - ## No Inside ipv4_lo object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net]["profile"].pop("ipv4_lo") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('ipv4_lo : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No Inside ipv4_neighbor object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net]["profile"].pop("ipv4_neighbor") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('ipv4_neighbor : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - def test_dcnm_srp_merged_new_no_adc_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_no_adc_mand_elems') - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - ## No rev_next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("rev_next_hop") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('rev_next_hop : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - - def test_dcnm_srp_merged_new_check_mode (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - check_mode=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - def test_dcnm_srp_merged_new_unauth_error (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_config_without_state (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merge_no_deploy (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merge_deploy_false (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=False, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_wrong_state(self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='wrong_state', - attach=True, - deploy=False, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = None - try: - result = self.execute_module(changed=False, failed=False) - except: - self.assertEqual (result, None) - - def test_dcnm_srp_merged_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_existing_and_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 4) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 4) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_update_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('update_rp2_rp4_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 2) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 2) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_update_existing_unauth_err (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('update_rp2_rp4_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 2) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 2) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_rp1_rp7_config') - - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_existing_unauth_err (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_rp1_rp7_config') - - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_existing_and_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_rp1_rp7_config') - - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 4) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_rp1_rp7_config') - - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_no_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_no_mand_elems') - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - ## No rev_next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("name") - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No rev_next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("node_name") - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('node_name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - def test_dcnm_srp_replace_rp1_to_rp3_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('replace_rp1_to_rp3') - - set_module_args(dict(state='replaced', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 3) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 3) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_replace_rp1_to_rp3_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('replace_rp1_to_rp3') - - set_module_args(dict(state='replaced', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 3) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 3) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_replace_rp1_to_rp3_existing_no_change (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('replace_rp1_to_rp3_no_change') - - set_module_args(dict(state='replaced', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_override_rp1_rp7_with_new_peerings (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_new_peerings') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 2) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 2) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_override_with_existing_peering (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_existing_peering') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 3) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - - def test_dcnm_srp_override_with_existing_peering_updated (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_existing_peering_updated') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 3) - self.assertEqual(len(result["diff"][0]["modified"]) , 1) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 1) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_override_with_service_nodes_alone (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_snodes') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_override_with_no_config (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_no_config') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_query_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('config_query_non_exist') - - set_module_args(dict(state='query', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 2) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - def test_dcnm_srp_query_with_service_nodes (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('config_query_with_node') - - set_module_args(dict(state='query', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 2) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - self.assertEqual(len(result["response"]) , 7) - - def test_dcnm_srp_query_with_peer_names (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('config_query_with_peername') - - set_module_args(dict(state='query', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 7) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - self.assertEqual(len(result["response"]) , 7) - - def test_dcnm_srp_query_no_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('query_no_mand_elems') - - set_module_args(dict(state='query', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - ## No rev_next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("node_name") - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('node_name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - From c4bc71ea28206857bf09a6e26d6421906edb9805 Mon Sep 17 00:00:00 2001 From: Mallik M J Date: Tue, 11 May 2021 19:42:39 +0530 Subject: [PATCH 12/71] Removed unsupported doc refs and updated README --- README.md | 1 - docs/cisco.dcnm.dcnm_service_node_module.rst | 403 ------------------- 2 files changed, 404 deletions(-) delete mode 100644 docs/cisco.dcnm.dcnm_service_node_module.rst diff --git a/README.md b/README.md index 08fba957a..9836b27a4 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ Name | Description [cisco.dcnm.dcnm_network](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_network_module.rst)|Add and remove Networks from a DCNM managed VXLAN fabric. [cisco.dcnm.dcnm_policy](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_policy_module.rst)|DCNM Ansible Module for managing policies. [cisco.dcnm.dcnm_rest](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_rest_module.rst)|Send REST API requests to DCNM controller. -[cisco.dcnm.dcnm_service_node](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_service_node_module.rst)|Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric. [cisco.dcnm.dcnm_template](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_template_module.rst)|DCNM Ansible Module for managing templates. [cisco.dcnm.dcnm_vrf](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_vrf_module.rst)|Add and remove VRFs from a DCNM managed VXLAN fabric. diff --git a/docs/cisco.dcnm.dcnm_service_node_module.rst b/docs/cisco.dcnm.dcnm_service_node_module.rst deleted file mode 100644 index ad0520735..000000000 --- a/docs/cisco.dcnm.dcnm_service_node_module.rst +++ /dev/null @@ -1,403 +0,0 @@ -.. _cisco.dcnm.dcnm_service_node_module: - - -**************************** -cisco.dcnm.dcnm_service_node -**************************** - -**Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric.** - - -Version added: 0.9.0 - -.. contents:: - :local: - :depth: 1 - - -Synopsis --------- -- Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric. - - - - -Parameters ----------- - -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterChoices/DefaultsComments
-
- config - -
- list - / elements=dictionary - / required -
-
- -
List of details of service nodes being managed
-
-
- attach_interface - -
- string - / required -
-
- -
List of switch interfaces where the service node will be attached
-
-
- form_factor - -
- string - / required -
-
- Default:
"physical"
-
-
Name of the form factor of the service node
-
-
- name - -
- string - / required -
-
- -
Name of service node
-
-
- svc_int_name - -
- string - / required -
-
- -
Name of the service interface
-
-
- switches - -
- list - / required -
-
- -
IP address of the switch where service node will be added/deleted
-
-
- type - -
- string - / required -
-
- Default:
"firewall"
-
-
Name of the service node type
-
-
- fabric - -
- string - / required -
-
- -
Name of attached easy fabric to which service node is attached
-
-
- service_fabric - -
- string - / required -
-
- -
Name of external fabric where the service node is located
-
-
- state - -
- string -
-
-
    Choices: -
  • merged ←
  • -
  • replaced
  • -
  • overridden
  • -
  • deleted
  • -
  • query
  • -
-
-
The state of DCNM after module completion.
-
-
- - - - -Examples --------- - -.. code-block:: yaml+jinja - - This module supports the following states: - - Merged: - Service Nodes defined in the playbook will be merged into the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Service Nodes that are not specified in the playbook will be untouched. - - Replaced: - Service Nodes defined in the playbook will be replaced in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be untouched. - - Overridden: - Service Node defined in the playbook will be overridden in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be deleted. - - Deleted: - Service Node defined in the playbook will be deleted. - If no Service Nodes are provided in the playbook, all service node present on that DCNM fabric will be deleted. - - Query: - Returns the current DCNM state for the service node listed in the playbook. - - - name: Merge Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - - - name: Replace Service Nodes form factor/type parameter - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: replaced - config: - - name: SN-11 - type: firewall - # Replace can only modify the form factor - # form_factor: virtual # the virtual will be changed to new physical - # form_factor: physical - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Nothing will be replaced in the below service node as there is no change - # Dont touch this if its present on DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - - - name: Override Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: overridden - config: - # Create this service node - - name: SN-13 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-11 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: Ethernet1/1 - # switches: - # - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - - - name: Delete selected Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - - - name: Delete all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - - - name: Query Service Nodes state for SN-11 and SN-12 - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - - - name: Query all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query - - - - -Status ------- - - -Authors -~~~~~~~ - -- Karthik Babu Harichandra Babu From f9e984ef623c1def689eaf5442114fba8079ac76 Mon Sep 17 00:00:00 2001 From: Praveen Ramoorthy Date: Thu, 15 Jul 2021 19:46:30 +0530 Subject: [PATCH 13/71] Remove unsupported modules --- plugins/modules/dcnm_service_node.py | 748 ---- plugins/modules/dcnm_service_route_peering.py | 3578 ----------------- .../dcnm_service_node/defaults/main.yaml | 2 - .../targets/dcnm_service_node/meta/main.yaml | 1 - .../targets/dcnm_service_node/tasks/dcnm.yaml | 20 - .../targets/dcnm_service_node/tasks/main.yaml | 2 - .../dcnm_service_node/tests/dcnm/deleted.yaml | 344 -- .../dcnm_service_node/tests/dcnm/merged.yaml | 768 ---- .../tests/dcnm/overridden.yaml | 281 -- .../dcnm_service_node/tests/dcnm/query.yaml | 396 -- .../tests/dcnm/replaced.yaml | 421 -- .../defaults/main.yaml | 2 - .../dcnm_service_route_peering/meta/main.yaml | 2 - .../tasks/dcnm.yaml | 105 - .../tasks/main.yaml | 2 - ...dcnm_service_route_peering_delete.yaml.swp | Bin 16384 -> 0 bytes ...m_service_route_peering_adc_po_change.yaml | 453 --- .../dcnm_service_route_peering_checkmode.yaml | 329 -- .../dcnm_service_route_peering_delete.yaml | 370 -- ...nm_service_route_peering_fw_po_change.yaml | 302 -- .../dcnm_service_route_peering_merge.yaml | 356 -- ..._service_route_peering_merge_existing.yaml | 878 ---- ...nm_service_route_peering_no_opt_elems.yaml | 257 -- .../dcnm_service_route_peering_no_state.yaml | 354 -- .../dcnm_service_route_peering_override.yaml | 945 ----- .../dcnm_service_route_peering_query.yaml | 426 -- .../dcnm_service_route_peering_replace.yaml | 883 ---- .../tasks/main.yaml | 184 - .../dcnm/fixtures/dcnm_service_node.json | 612 --- .../dcnm/fixtures/dcnm_srp_configs.json | 1672 -------- .../dcnm/fixtures/dcnm_srp_payloads.json | 3084 -------------- .../modules/dcnm/test_dcnm_service_node.py | 499 --- .../dcnm/test_dcnm_service_route_peering.py | 1839 --------- 33 files changed, 20115 deletions(-) delete mode 100644 plugins/modules/dcnm_service_node.py delete mode 100644 plugins/modules/dcnm_service_route_peering.py delete mode 100644 tests/integration/targets/dcnm_service_node/defaults/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/meta/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tasks/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml delete mode 100644 tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/defaults/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/meta/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tasks/dcnm.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tasks/main.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/.dcnm_service_route_peering_delete.yaml.swp delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_adc_po_change.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_checkmode.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_delete.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_fw_po_change.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_merge.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_merge_existing.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_no_opt_elems.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_no_state.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_override.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_query.yaml delete mode 100644 tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_replace.yaml delete mode 100644 tests/integration/targets/prepare_dcnm_service_route_peering/tasks/main.yaml delete mode 100644 tests/unit/modules/dcnm/fixtures/dcnm_service_node.json delete mode 100644 tests/unit/modules/dcnm/fixtures/dcnm_srp_configs.json delete mode 100644 tests/unit/modules/dcnm/fixtures/dcnm_srp_payloads.json delete mode 100644 tests/unit/modules/dcnm/test_dcnm_service_node.py delete mode 100644 tests/unit/modules/dcnm/test_dcnm_service_route_peering.py diff --git a/plugins/modules/dcnm_service_node.py b/plugins/modules/dcnm_service_node.py deleted file mode 100644 index 96664fd98..000000000 --- a/plugins/modules/dcnm_service_node.py +++ /dev/null @@ -1,748 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2021 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import copy -from ansible_collections.cisco.dcnm.plugins.module_utils.network.dcnm.dcnm import get_fabric_inventory_details, \ - dcnm_send, validate_list_of_dicts, dcnm_get_ip_addr_info, get_ip_sn_dict -from ansible.module_utils.basic import AnsibleModule - -__author__ = "Karthik Babu Harichandra Babu" - -DOCUMENTATION = ''' ---- -module: dcnm_service_node -short_description: Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric. -version_added: "0.9.0" -description: - - "Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric." -author: Karthik Babu Harichandra Babu -options: - fabric: - description: - - 'Name of attached easy fabric to which service node is attached' - type: str - required: yes - service_fabric: - description: - - 'Name of external fabric where the service node is located' - type: str - required: yes - state: - description: - - The state of DCNM after module completion. - type: str - choices: - - merged - - replaced - - overridden - - deleted - - query - default: merged - - config: - description: 'List of details of service nodes being managed' - type: list - elements: dict - required: true - note: Not required for state deleted - suboptions: - name: - description: 'Name of service node' - type: str - required: true - type: - description: 'Name of the service node type' - type: str - required: true - default: 'firewall' - form_factor: - description: 'Name of the form factor of the service node' - type: str - required: true - default: 'physical' - svc_int_name: - description: 'Name of the service interface' - type: str - required: true - switches: - description: 'IP address of the switch where service node will be added/deleted' - type: list - required: true - attach_interface: - description: 'List of switch interfaces where the service node will be attached' - type: str - required: true -''' - -EXAMPLES = ''' -This module supports the following states: - -Merged: - Service Nodes defined in the playbook will be merged into the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Service Nodes that are not specified in the playbook will be untouched. - -Replaced: - Service Nodes defined in the playbook will be replaced in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be untouched. - -Overridden: - Service Node defined in the playbook will be overridden in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be deleted. - -Deleted: - Service Node defined in the playbook will be deleted. - If no Service Nodes are provided in the playbook, all service node present on that DCNM fabric will be deleted. - -Query: - Returns the current DCNM state for the service node listed in the playbook. - -- name: Merge Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - -- name: Replace Service Nodes form factor/type parameter - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: replaced - config: - - name: SN-11 - type: firewall - # Replace can only modify the form factor - # form_factor: virtual # the virtual will be changed to new physical - # form_factor: physical - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Nothing will be replaced in the below service node as there is no change - # Dont touch this if its present on DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - -- name: Override Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: overridden - config: - # Create this service node - - name: SN-13 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-11 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: Ethernet1/1 - # switches: - # - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - -- name: Delete selected Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - -- name: Delete all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - -- name: Query Service Nodes state for SN-11 and SN-12 - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - -- name: Query all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query -''' - - -class DcnmServiceNode: - - def __init__(self, module): - self.module = module - self.params = module.params - self.fabric = module.params['fabric'] - self.service_fabric = module.params['service_fabric'] - self.config = copy.deepcopy(module.params.get('config')) - self.check_mode = False - self.have_create = [] - self.want_create = [] - self.diff_create = [] - self.diff_replace = [] - self.diff_delete = {} - self.query = [] - self.validated = [] - self.inventory_data = get_fabric_inventory_details(self.module, self.fabric) - self.ip_sn, self.hn_sn = get_ip_sn_dict(self.inventory_data) - - self.result = dict( - changed=False, - diff=[], - response=[], - warnings=[] - ) - - self.failed_to_rollback = False - self.WAIT_TIME_FOR_DELETE_LOOP = 5 # in seconds - - def update_create_params(self, snode): - - if not snode: - return snode - - state = self.params['state'] - - if state == 'query': - snode_upd = { - "name": snode['name'] - } - else: - - serial = [] - for sw in snode['switches']: - sw = dcnm_get_ip_addr_info(self.module, sw, None, None) - for ip, ser in self.ip_sn.items(): - if ip == sw: - serial.append(ser) - - if not serial: - self.module.fail_json(msg='Fabric: {} does not have the switch: {}' - .format(self.fabric, snode['switches'])) - - switchsn = "" - if len(snode['switches']) == 2: - switchsn = str(serial[0]) + "," + str(serial[1]) - if 'vPC' not in snode['attach_interface']: - self.module.fail_json(msg='Fabric: {} - if two switches are provided, vpc is only interface option' - .format(self.fabric)) - elif len(snode['switches']) == 1: - switchsn = str(serial[0]) - if 'vPC' in snode['attach_interface']: - self.module.fail_json(msg='Fabric: {} - For 1 switch, vpc is not the interface option' - .format(self.fabric)) - else: - self.module.fail_json(msg='Fabric: {} - Upto 2 switches only allowed' - .format(self.fabric)) - - if snode['type'] == 'firewall': - s_type = snode['type'].title() - elif snode['type'] == 'load_balancer': - s_type = 'ADC' - elif snode['type'] == 'virtual_network_function': - s_type = 'VNF' - - snode_upd = { - "name": snode['name'], - "type": s_type, - "formFactor": snode['form_factor'].title(), - "fabricName": self.service_fabric, - "interfaceName": snode['svc_int_name'], - "attachedSwitchSn": switchsn, - "attachedSwitchInterfaceName": snode['attach_interface'], - "linkTemplateName": "service_link_trunk", - "nvPairs": { - "MTU": "jumbo", - "SPEED": "Auto", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "PORTTYPE_FAST_ENABLED": "true", - "ADMIN_STATE": "true" - }, - "attachedFabricName": self.fabric - } - - return snode_upd - - def get_have(self): - - method = 'GET' - path = '/appcenter/Cisco/elasticservice/elasticservice-api/?attached-fabric={}'.format(self.fabric) - - snode_objects = dcnm_send(self.module, method, path) - missing_fabric, not_ok = self.handle_response(snode_objects, 'query_dcnm') - - if missing_fabric or not_ok: - msg1 = "Fabric {} not present on DCNM".format(self.fabric) - msg2 = "Unable to Service Node under fabric: {}".format(self.fabric) - - self.module.fail_json(msg=msg1 if missing_fabric else msg2) - return - - if not snode_objects['DATA']: - return - - have_switch = [] - for snode in snode_objects['DATA']: - get_snode = {} - get_snode.update({'name': snode['name']}) - get_snode.update({'formFactor': snode['formFactor']}) - get_snode.update({'interfaceName': snode['interfaceName']}) - get_snode.update({'type': snode['type']}) - get_snode.update({'attachedFabricName': snode['attachedFabricName']}) - get_snode.update({'attachedSwitchInterfaceName': snode['attachedSwitchInterfaceName']}) - get_snode.update({'attachedSwitchSn': snode['attachedSwitchSn']}) - get_snode.update({'fabricName': snode['fabricName']}) - have_switch.append(get_snode) - - self.have_create = have_switch - - def get_want(self): - - want_create = [] - - if not self.config: - return - - for snode in self.validated: - want_create.append(self.update_create_params(snode)) - - self.want_create = want_create - - def get_diff_delete(self): - - diff_delete = [] - - if self.config: - for want_c in self.want_create: - for have_c in self.have_create: - if (have_c['name'] == want_c['name']): - diff_delete.append(have_c['name']) - continue - - else: - for have_c in self.have_create: - diff_delete.append(have_c['name']) - - self.diff_delete = diff_delete - - def get_diff_override(self): - - self.get_diff_replace() - self.get_diff_replace_delete() - - diff_create = self.diff_create - diff_delete = self.diff_delete - - self.diff_create = diff_create - self.diff_delete = diff_delete - self.diff_replace = [] - - def get_diff_replace(self): - - self.get_diff_merge() - diff_replace = self.diff_create - - self.diff_replace = diff_replace - - found = False - for replace_c in self.diff_replace: - for have_c in self.have_create: - if have_c['name'] == replace_c['name']: - found = True - - if not found: - self.diff_replace = [] - else: - self.diff_create = [] - - def get_diff_replace_delete(self): - - diff_delete = [] - - for have_c in self.have_create: - match_found = False - for want_c in self.want_create: - if want_c['name'] == have_c['name']: - if want_c['type'] == have_c['type'] and want_c['attachedFabricName'] == have_c['attachedFabricName'] \ - and want_c['fabricName'] == have_c['fabricName'] and \ - want_c['attachedSwitchInterfaceName'] == have_c['attachedSwitchInterfaceName'] and \ - want_c['attachedSwitchSn'] == have_c['attachedSwitchSn'] and \ - want_c['interfaceName'] == have_c['interfaceName']: - match_found = True - if match_found: - continue - else: - diff_delete.append(have_c['name']) - - self.diff_delete = diff_delete - - def get_diff_merge(self, replace=False): - - diff_create = [] - - for want_c in self.want_create: - found = False - for have_c in self.have_create: - if want_c['name'] == have_c['name'] and want_c['type'] == have_c['type'] and \ - want_c['attachedFabricName'] == have_c['attachedFabricName'] and want_c['fabricName'] == have_c[ - 'fabricName'] and \ - want_c['attachedSwitchInterfaceName'] == have_c['attachedSwitchInterfaceName'] and \ - want_c['attachedSwitchSn'] == have_c['attachedSwitchSn'] and \ - want_c['interfaceName'] == have_c['interfaceName'] and \ - want_c['formFactor'] == have_c['formFactor']: - found = True - if not found: - diff_create.append(want_c) - - self.diff_create = diff_create - - def get_diff_query(self): - - query = [] - method = 'GET' - path = '/appcenter/Cisco/elasticservice/elasticservice-api/?attached-fabric={}'.format(self.fabric) - - snode_objects = dcnm_send(self.module, method, path) - - missing_fabric, not_ok = self.handle_response(snode_objects, 'query_dcnm') - - if missing_fabric or not_ok: - msg1 = "Fabric {} not present on DCNM".format(self.fabric) - msg2 = "Unable to find Service Node under fabric: {}".format(self.fabric) - - self.module.fail_json(msg=msg1 if missing_fabric else msg2) - return - - if not snode_objects['DATA']: - return - - if self.config: - for want_c in self.want_create: - for snode in snode_objects['DATA']: - if want_c['name'] == snode['name']: - query.append(snode) - continue - else: - for snode in snode_objects['DATA']: - query.append(snode) - - self.query = query - - def push_to_remote(self, is_rollback=False): - - method = 'DELETE' - if self.diff_delete: - for name in self.diff_delete: - delete_path = '/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/{}/service-nodes/{}'.format( - self.service_fabric, name) - resp = dcnm_send(self.module, method, delete_path) - - self.result['response'].append(resp) - fail, self.result['changed'] = self.handle_response(resp, "delete") - - if fail: - if is_rollback: - self.failed_to_rollback = True - return - self.failure(resp) - - method = 'POST' - if self.diff_create: - for create in self.diff_create: - deploy_path = '/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/{}/service-nodes'.format( - self.service_fabric) - resp = dcnm_send(self.module, method, deploy_path, json.dumps(create)) - self.result['response'].append(resp) - fail, self.result['changed'] = self.handle_response(resp, "create") - - if fail: - if is_rollback: - self.failed_to_rollback = True - return - self.failure(resp) - - method = 'PUT' - if self.diff_replace: - for replace in self.diff_replace: - replace_path = '/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/{}/service-nodes/{}'.format( - self.service_fabric, replace['name']) - resp = dcnm_send(self.module, method, replace_path, json.dumps(replace)) - - self.result['response'].append(resp) - fail, self.result['changed'] = self.handle_response(resp, "create") - - if fail: - if is_rollback: - self.failed_to_rollback = True - return - self.failure(resp) - - def validate_input(self): - - """Parse the playbook values, validate to param specs.""" - - state = self.params['state'] - - if state == 'query': - - snode_spec = dict( - name=dict(required=True, type='str', length_max=64), - ) - - if self.config: - # Validate service node params - valid_snode, invalid_params = validate_list_of_dicts(self.config, snode_spec) - for snode in valid_snode: - self.validated.append(snode) - - if invalid_params: - msg = 'Invalid parameters in playbook: {}'.format('\n'.join(invalid_params)) - self.module.fail_json(msg=msg) - - else: - - snode_spec = dict( - name=dict(required=True, type='str', length_max=64), - type=dict(required=True, type='str', - choices=['firewall', 'load_balancer', 'virtual_network_function'], - default='firewall'), - form_factor=dict(required=True, type='str', - choices=['physical', 'virtual'], - default='physical'), - svc_int_name=dict(required=True, type='str', length_max=64), - switches=dict(required=True, type='list'), - attach_interface=dict(required=True, type='str'), - ) - - if self.config: - msg = None - # Validate service node params - valid_snode, invalid_params = validate_list_of_dicts(self.config, snode_spec) - for snode in valid_snode: - self.validated.append(snode) - - if invalid_params: - msg = 'Invalid parameters in playbook: {}'.format('\n'.join(invalid_params)) - self.module.fail_json(msg=msg) - - else: - state = self.params['state'] - msg = None - - if state == 'merged' or state == 'overridden' or \ - state == 'replaced': - msg = "config: element is mandatory for this state {}".format(state) - - if msg: - self.module.fail_json(msg=msg) - - def handle_response(self, resp, op): - - fail = False - changed = True - - res = resp.copy() - - if op == 'query_dcnm': - # This if blocks handles responses to the query APIs against DCNM. - # Basically all GET operations. - # - if res.get('ERROR') == 'Not Found' and res['RETURN_CODE'] == 404: - return True, False - if res['RETURN_CODE'] != 200 or res['MESSAGE'] != "": - return False, True - return False, False - - # Responses to all other operations POST and PUT are handled here. - if res.get('MESSAGE') != "" or res.get('RETURN_CODE') != 200: - fail = True - changed = False - return fail, changed - - return fail, changed - - def failure(self, resp): - - # Implementing a per task rollback logic here so that we rollback DCNM to the have state - # whenever there is a failure in any of the APIs. - # The idea would be to run overridden state with want=have and have=dcnm_state - self.want_create = self.have_create - self.have_create = [] - self.get_have() - self.get_diff_override() - - self.push_to_remote(True) - - if self.failed_to_rollback: - msg1 = "FAILED - Attempted rollback of the task has failed, may need manual intervention" - else: - msg1 = 'SUCCESS - Attempted rollback of the task has succeeded' - - res = copy.deepcopy(resp) - res.update({'ROLLBACK_RESULT': msg1}) - - if not resp.get('DATA'): - data = copy.deepcopy(resp.get('DATA')) - if data.get('stackTrace'): - data.update({'stackTrace': 'Stack trace is hidden, use \'-vvvvv\' to print it'}) - res.update({'DATA': data}) - - if self.module._verbosity >= 5: - self.module.fail_json(msg=res) - - self.module.fail_json(msg=res) - - -def main(): - """ main entry point for module execution - """ - - element_spec = dict( - fabric=dict(required=True, type='str'), - service_fabric=dict(required=True, type='str'), - config=dict(required=False, type='list'), - state=dict(default='merged', - choices=['merged', 'replaced', 'deleted', 'overridden', 'query']), - check_mode=dict(required=False, type="bool", default=False) - ) - - module = AnsibleModule(argument_spec=element_spec, - supports_check_mode=True) - - dcnm_snode = DcnmServiceNode(module) - - if not dcnm_snode.ip_sn: - module.fail_json(msg="Fabric {} missing on DCNM or does not have any switches".format(dcnm_snode.fabric)) - - dcnm_snode.validate_input() - - dcnm_snode.get_want() - dcnm_snode.get_have() - - if module.params['state'] == 'merged': - dcnm_snode.get_diff_merge() - - if module.params['state'] == 'replaced': - dcnm_snode.get_diff_replace() - - if module.params['state'] == 'overridden': - dcnm_snode.get_diff_override() - - if module.params['state'] == 'deleted': - dcnm_snode.get_diff_delete() - # - if module.params['state'] == 'query': - dcnm_snode.get_diff_query() - dcnm_snode.result['response'] = dcnm_snode.query - - if module.params['check_mode']: - dcnm_snode.result['changed'] = False - module.exit_json(**dcnm_snode.result) - - if dcnm_snode.diff_create or dcnm_snode.diff_delete or dcnm_snode.diff_replace: - dcnm_snode.result['changed'] = True - else: - module.exit_json(**dcnm_snode.result) - - dcnm_snode.push_to_remote() - - module.exit_json(**dcnm_snode.result) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/dcnm_service_route_peering.py b/plugins/modules/dcnm_service_route_peering.py deleted file mode 100644 index bebe4f816..000000000 --- a/plugins/modules/dcnm_service_route_peering.py +++ /dev/null @@ -1,3578 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2021 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -__author__ = "Mallik Mudigonda" - -DOCUMENTATION = """ ---- -module: dcnm_service_route_peering -short_description: DCNM Ansible Module for managing Service Route Peerings. -version_added: "1.1.0" -description: - - DCNM Ansible Module for Creating, Deleting, Querying and Modifying Route Peerings -author: Mallik Mudigonda -options: - fabric: - description: - - 'Name of the target fabric for route peering operations' - type: str - required: true - service_fabric: - description: - - 'Name of the external fabric attached to the service node for route peering operations' - type: str - required: true - state: - description: - - The required state of the configuration after module completion. - type: str - required: false - choices: - - merged - - replaced - - overridden - - deleted - - query - default: merged - attach: - description: - - A flag specifying if the given route peering is to be attached to the specified service node - type: bool - required: false - default: true - deploy: - description: - - A flag specifying if a route peering is to be deployed on the switches - type: bool - required: false - default: true - config: - description: - - A list of dictionaries containing route peering and switch information - type: list - elements: dict - suboptions: - name: - description: - - A unique name which identifies the route peering - type: str - required: true - node_name: - description: - - Name of the service node where the route peering is to be deployed - type: str - required: true - deploy_mode: - description: - - Type of service node. - type: str - required: true - choices: ['intra_tenant_fw', 'inter_tenant_fw', 'one_arm_adc', 'two_arm_adc'] - peering_option: - description: - - Specifies the type of peering - - NOTE: This object is applicable only when 'deploy_mode' is either 'inter_tenant_fw' - or 'one_arm_adc' or 'two_arm_adc' - type: str - required: False - default: 'static' - choices: ['static', 'ebgp'] - next_hop: - description: - - Nexthop IPV4 information, e.g., 192.168.1.100 - - NOTE: This object is applicable only when 'deploy_mode' is 'intra_tenant_fw' - type: int - required: true - rev_next_hop: - description: - - Reverse Nexthop IPV4 information, e.g., 192.169.1.100 - - NOTE: This object is applicable only when 'deploy_mode' is either 'intra_tenant_fw' - or 'one_arm_adc' or 'two_arm_adc' - type: int - required: false - default: "" - inside_network: - description: - - Details regarding inside network of the route peering - - NOTE: This object is applicable only when 'deploy_mode' is 'intra_tenant_fw' - or 'inter_tenant_fw' - type: dict - required: true - suboptions: - vrf: - description: - - VRF name for the inside network - type: str - required: true - name: - description: - - Network name - type: str - required: true - vlan_id: - description: - - Vlan Id for the inside network - type: int - required: true - profile: - description: - - Profile information for the inside network - type: dict - required: true - suboptions: - ipv4_gw: - description: - - IPV4 gateway information including the mask e.g. 192.168.1.1/24 - type: ipv4 - required: true - ipv6_gw: - description: - - IPV6 gateway information including the mask e.g., 2000:01:01::01/64 - type: ipv6 - required: false - default: "" - vlan_name: - description: - - Vlan name - type: str - required: false - default: "" - int_descr: - description: - - Description of the interface - type: str - required: false - default: "" - tag: - description: - - Route tag information - type: int - required: false - default: 12345 - static_route: - description: - - Static route information - - NOTE: This object is applicable only when 'peering_option' is 'static' - type: list - elements: dict - required: false - default: '' - suboptions: - subnet: - description: - - Subnet information, for e.g., 11.0.0.0/24 - type: ipv4 - required: True - next_hop: - description: - - Gateway IP addresses, for e.g., 192.168.1.1 - type: list - elements: ipv4 - required: True - ipv4_neighobor: - description: - - IPv4 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_lo: - description: - - IPv4 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_vpc_peer_lo: - description: - - IPv4 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp'. This - object will be mandatory if the service node switch is part of VPC - pair - type: ipv4 - required: False - default: '' - ipv6_neighbor: - description: - - IPv6 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_lo: - description: - - IPv6 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_vpc_peer_lo: - description: - - IPv6 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp'. This - object will be mandatory if the service node switch is part of VPC - pair - type: ipv6 - required: False - default: '' - route_map_tag: - description: - - Route Tag - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: True - default: 12345 - neigh_int_descr: - description: - - Description of the interface - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: str - required: False - default: '' - local_asn: - description: - - Local ASN number - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: False - default: 12345 - adv_host: - description: - - Flag indicating if the host is to be advertised - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: bool - required: False - default: True - outside_network: - description: - - Details regarding outside network of the route peering - - NOTE: This object is applicable only when 'deploy_mode' is 'intra_tenant_fw' - or 'inter_tenant_fw' - type: dict - required: true - suboptions: - vrf: - description: - - VRF name for the outside network - type: str - required: true - name: - description: - - Network name - type: str - required: true - vlan_id: - description: - - Vlan Id for the outside network - type: int - required: true - profile: - description: - - Profile information for the outside network - type: dict - required: true - suboptions: - ipv4_gw: - description: - - IPV4 gateway information including the mask e.g. 192.168.1.1/24 - type: ipv4 - required: true - ipv6_gw: - description: - - IPV6 gateway information including the mask e.g., 2000:01:01::01/64 - type: ipv6 - required: false - default: "" - vlan_name: - description: - - Vlan name - type: str - required: false - default: "" - int_descr: - description: - - Description of the interface - type: str - required: false - default: "" - tag: - description: - - Route tag information - type: int - required: false - default: 12345 - static_route: - description: - - Static route information - - NOTE: This object is applicable only when 'peering_option' is 'static' and - 'deploy_mode' is 'intra_tenant_fw' - type: list - elements: dict - required: false - default: '' - suboptions: - subnet: - description: - - Subnet information, for e.g., 11.0.0.0/24 - type: ipv4 - required: True - next_hop: - description: - - Gateway IP addresses, for e.g., 192.168.1.1 - type: list - elements: ipv4 - required: True - ipv4_neighobor: - description: - - IPv4 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_lo: - description: - - IPv4 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_vpc_peer_lo: - description: - - IPv4 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: False - default: '' - ipv6_neighbor: - description: - - IPv6 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_lo: - description: - - IPv6 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_vpc_peer_lo: - description: - - IPv6 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - route_map_tag: - description: - - Route Tag - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: True - default: 12345 - neigh_int_descr: - description: - - Description of the interface - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: str - required: False - default: '' - local_asn: - description: - - Local ASN number - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: False - default: 12345 - adv_host: - description: - - Flag indicating if the host is to be advertised - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: bool - required: False - default: true - first_arm: - description: - - Details regarding firast arm of the route peering - - NOTE: This object is applicable only when 'deploy_mode' is either - 'one_arm_adc' or 'two_arm_adc' - type: dict - required: true - suboptions: - vrf: - description: - - VRF name for the first arm - type: str - required: true - name: - description: - - Network name - type: str - required: true - vlan_id: - description: - - Vlan Id for the first arm - type: int - required: true - profile: - description: - - Profile information for the first arm - type: dict - required: true - suboptions: - ipv4_gw: - description: - - IPV4 gateway information including the mask e.g. 192.168.1.1/24 - type: ipv4 - required: true - ipv6_gw: - description: - - IPV6 gateway information including the mask e.g., 2000:01:01::01/64 - type: ipv6 - required: false - default: "" - vlan_name: - description: - - Vlan name - type: str - required: false - default: "" - int_descr: - description: - - Description of the interface - type: str - required: false - default: "" - tag: - description: - - Route tag information - type: int - required: false - default: 12345 - static_route: - description: - - Static route information - - NOTE: This object is applicable only when 'peering_option' is 'static' - type: list - elements: dict - required: false - default: '' - suboptions: - subnet: - description: - - Subnet information, for e.g., 11.0.0.0/24 - type: ipv4 - required: True - next_hop: - description: - - Gateway IP addresses, for e.g., 192.168.1.1 - type: list - elements: ipv4 - required: True - ipv4_neighobor: - description: - - IPv4 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_lo: - description: - - IPv4 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: True - ipv4_vpc_peer_lo: - description: - - IPv4 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv4 - required: False - default: '' - ipv6_neighbor: - description: - - IPv6 neighbor address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_lo: - description: - - IPv6 loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - ipv6_vpc_peer_lo: - description: - - IPv6 vpc peer loopback address - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: ipv6 - required: False - default: '' - route_map_tag: - description: - - Route Tag - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: True - default: 12345 - neigh_int_descr: - description: - - Description of the interface - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: str - required: False - default: '' - local_asn: - description: - - Local ASN number - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: int - required: False - default: 12345 - adv_host: - description: - - Flag indicating if the host is to be advertised - - NOTE: This object is applicable only when 'peering_option' is 'ebgp' - type: bool - required: False - default: True - second_arm: - description: - - Details regarding second arm of the route peering - - NOTE: This object is applicable only when 'deploy_mode' is either - 'one_arm_adc' or 'two_arm_adc' - type: dict - required: true - suboptions: - vrf: - description: - - VRF name for the second arm - type: str - required: true - name: - description: - - Network name - type: str - required: true - vlan_id: - description: - - Vlan Id for the second arm - type: int - required: true - profile: - description: - - Profile information for the second arm - type: dict - required: true - suboptions: - ipv4_gw: - description: - - IPV4 gateway information including the mask e.g. 192.168.1.1/24 - type: ipv4 - required: true - ipv6_gw: - description: - - IPV6 gateway information including the mask e.g., 2000:01:01::01/64 - type: ipv6 - required: false - default: "" - vlan_name: - description: - - Vlan name - type: str - required: false - default: "" - int_descr: - description: - - Description of the interface - type: str - required: false - default: "" - tag: - description: - - Route tag information - type: int - required: false - default: 12345 -""" - -EXAMPLES = """ - -States: -This module supports the following states: - -Merged: - Route Peerings defined in the playbook will be merged into the target fabric. - - If the Route Peerings does not exist it will be added. - - If the Route Peerings exists but properties managed by the playbook are different - they will be updated if possible. - - Route peerings that are not specified in the playbook will be untouched. - -Replaced: - Route Peerings defined in the playbook will be replaced in the target fabric. - - If the Route Peerings does not exist it will be added. - - If the Route Peerings exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Route Peerings that are not specified in the playbook will be untouched. - -Overridden: - Route Peerings defined in the playbook will be overridden in the target fabric. - - If the Route Peerings does not exist it will be added. - - If the Route Peerings exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Roue Peerings that are not specified in the playbook will be deleted. - -Deleted: - Route Peerings defined in the playbook will be deleted. - -Query: - Returns the current DCNM state for the route peerings listed in the playbook. - -CREATING ROUTE PEERINGS -======================= - -INTRA-TENANT FIREWALL - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP1 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: IT-VRF-11 # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 101 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2001:db01::1/64 # optional, default is '' - vlan_name: rp1-sn1-inside # optional, default is '' - int_descr: "RP1 SN1 inside interface" # optional, default is '' - tag: 11111 # optional, default is 12345 - next_hop: 192.161.1.100 # mandatory - outside_network: # - vrf: IT-VRF-11 # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 102 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2001:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside # optional, default is '' - int_descr: "RP1 SN1 outside interface" # optionL, default is '' - tag: 11112 # optional, default is 12345 - rev_next_hop: 192.161.2.100 # optional, default is '' - attach: true - deploy: true - -INTER-TENANT FIREWALL with STATIC peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP2 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: static # optional, default is static, choices=[static, ebgp] - inside_network: # - vrf: IT-VRF-21 # mandatory - name: rp2-sn1-inside-net # mandatory - vlan_id: 201 # mandatory - profile: - ipv4_gw: 192.162.1.1/24 # mandatory - ipv6_gw: 2002:db01::1/64 # optional, default is '' - vlan_name: rp2-sn1-inside # optional, default is '' - int_descr: "RP2 SN1 inside interface" # optional, default is '' - static_route: # optional, default is '' - - subnet: 20.20.20.0/24 - next_hop: - - 120.120.120.100 - - 121.121.121.100 - tag: 21111 # optional, default is 12345 - outside_network: # - vrf: IT-VRF-22 # mandatory - name: rp2-sn1-outside-net # mandatory - vlan_id: 202 # mandatory - profile: - ipv4_gw: 192.162.2.1/24 # mandatory - ipv6_gw: 2002:db02::1/64 # optional, default is '' - vlan_name: rp2-sn1-outside # optional, default is '' - int_descr: "RP2 SN1 outside interface" # optional, default is '' - static_route: # optional, default is '' - - subnet: 21.21.21.0/24 - next_hop: - - 122.122.122.100 - - 123.123.123.100 - tag: 22222 # optional, default is 12345 - attach: true - deploy: true - -INTER-TENANT FIREWALL with EBGP peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP3 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - inside_network: - vrf: IT-VRF-31 # mandatory - name: rp3-sn1-inside-net # mandatory - vlan_id: 301 # mandatory - profile: - ipv4_gw: 192.163.1.1/24 # mandatory - ipv6_gw: 2003:db01::1/64 # optional, default is '' - vlan_name: rp3-sn1-inside # optional, default is '' - int_descr: "RP3 SN1 inside interface" # optional, default is '' - tag: 31111 # optional, default is 12345 - ipv4_neighbor: 31.31.31.1 # mandatory - ipv4_lo: 31.31.31.2 # mandatory - ipv4_vpc_peer_lo: 31.31.31.3 # optional, default is '' - ipv6_neighbor: 2003:3131::1 # optional, default is '' - ipv6_lo: 2003:3132::1 # optional, default is '' - ipv6_vpc_peer_lo: 2003:3133::1 # optional, default is '' - route_map_tag: 33111 # optional, default is 12345 ???? - neigh_int_descr: "RP3 SN1 inside interface" # optional, default is '' ???? - local_asn: 65301 # optional, default is '' - adv_host: true # optional, default is false - outside_network: - vrf: IT-VRF-32 # mandatory - name: rp3-sn1-outside-net # mandatory - vlan_id: 302 # mandatory - profile: - ipv4_gw: 192.163.2.1/24 # mandatory - ipv6_gw: 2003:db02::1/64 # optional, default is '' - vlan_name: rp3-sn1-outside # optional, default is '' - int_descr: "RP3 SN1 outside interface" # optional, default is '' - tag: 31112 # optional, default is 12345 - ipv4_neighbor: 131.131.131.1 # mandatory - ipv4_lo: 131.131.131.2 # mandatory - ipv4_vpc_peer_lo: 131.131.131.3 # optional, default is '' - ipv6_neighbor: 2003:8383::1 # optional, default is '' - ipv6_lo: 2003:8384::1:100:1 # optional, default is '' - ipv6_vpc_peer_lo: 2003:8385::1 # optional, default is '' - route_map_tag: 31113 # optional, default is 12345 ???? - neigh_int_descr: "RP3 SN1 outside interface" # optional, default is '' ???? - local_asn: 65302 # optional, default is '' - adv_host: true # optional, default is false - attach: true - deploy: true - -ONEARM ADC with EBGP peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-ADC-RP4 - node_name: IT-SN-2 # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: IT-VRF-41 # mandatory - name: rp4-sn2-first-arm # mandatory - vlan_id: 401 # mandatory - profile: - ipv4_gw: 192.164.1.1/24 # mandatory - ipv6_gw: 2004:db01::1/64 # optional, default is '' - vlan_name: rp4-sn2-first-arm # optional, default is '' - int_descr: "RP4 SN2 first arm intf" # optional, default is '' - tag: 41111 # optional, default is 12345 - ipv4_neighbor: 41.41.41.1 # mandatory - ipv4_lo: 41.41.41.2 # mandatory - ipv4_vpc_peer_lo: 41.41.41.3 # optional, default is '' - ipv6_neighbor: 2004:4141::1 # optional, default is '' - ipv6_lo: 2004:4142::1 # optional, default is '' - ipv6_vpc_peer_lo: 2004:4143::1 # optional, default is '' - route_map_tag: 41112 # optional, default is 12345 - neigh_int_descr: "RP4 SN2 first arm" # optional, default is '' - local_asn: 65401 # optional, default is '' - adv_host: true # optional, default is false - rev_next_hop: 192.164.1.100 # mandatory - attach: true - deploy: true - -TWOARM ADC with EBGP peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-ADC-RP5 - node_name: IT-SN-2 # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: IT-VRF-51 " # mandatory - name: rp5-sn2-first-arm # mandatory - vlan_id: 501 # mandatory - profile: - ipv4_gw: 192.165.1.1/24 # mandatory - ipv6_gw: 2005:db01::1/64 # optional, default is '' - vlan_name: rp5-sn2-first-arm # optional, default is '' - int_descr: "RP5 SN2 first arm intf" # optional, default is '' - tag: 51111 # optional, default is 12345 - ipv4_neighbor: 51.51.51.1 # mandatory - ipv4_lo: 51.51.51.2 # mandatory - ipv4_vpc_peer_lo: 51.51.51.3 # optional, default is '' - ipv6_neighbor: 2005:5151::1 # optional, default is '' - ipv6_lo: 2005:5152::1 # optional, default is '' - ipv6_vpc_peer_lo: 2005:5153::1 # optional, default is '' - route_map_tag: 51115 # optional, default is 12345 - neigh_int_descr: "RP5 SN2 first arm" # optional, default is '' - local_asn: 65501 # optional, default is '' - adv_host: true # optional, default is false - second_arm: - vrf: IT-VRF-52 " # mandatory - name: rp5-sn2-second-arm # mandatory - vlan_id: 502 # mandatory - profile: - ipv4_gw: 192.165.2.1/24 # mandatory - ipv6_gw: 2005:db02::1/64 # optional, default is '' - vlan_name: rp5-sn2-second-arm # optional, default is '' - int_descr: "RP5 SN2 second arm intf" # optional, default is '' - tag: 51112 # optional, default is 12345 - rev_next_hop: 192.165.1.100 # mandatory - attach: true - deploy: true - -ONEARM ADC with STATIC peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-ADC-RP6 - node_name: IT-SN-2 # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: IT-VRF-61 # mandatory - name: rp6-sn2-first-arm # mandatory - vlan_id: 601 # mandatory - profile: - ipv4_gw: 192.166.1.1/24 # mandatory - ipv6_gw: 2006:db01::1/64 # optional, default is '' - vlan_name: rp6-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 61111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 61.61.61.1/24 - next_hop: - - 161.161.161.1 - - 162.162.162.1 - - subnet: 22.0.0.0/24 - next_hop: - - 163.163.163.1 - - 164.164.164.1 - rev_next_hop: 192.166.1.100 # mandatory - attach: true - deploy: true - -TWOARM ADC with STATIC peering - -- name: Create different new service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: - state: merged - fabric: test-fabric - service_fabric: external - config: - - name: IT-ADC-RP7 - node_name: IT-SN-2 # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: IT-VRF-71 # mandatory - name: rp7-sn2-first-arm # mandatory - vlan_id: 701 # mandatory - profile: - ipv4_gw: 192.167.1.1/24 # mandatory - ipv6_gw: 2007:db01::1/64 # optional, default is '' - vlan_name: rp7-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 71111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 71.71.71.1/24 - next_hop: - - 171.171.171.1 - - 172.172.172.1 - second_arm: - vrf: IT-VRF-72 # mandatory - name: rp7-sn2-second-arm # mandatory - vlan_id: 702 # mandatory - profile: - ipv4_gw: 192.167.2.1/24 # mandatory - ipv6_gw: 2007:db02::1/64 # optional, default is '' - vlan_name: rp7-sn2-second-arm # optional, default is '' - int_descr: "RP7 SN2 second arm intf" # optional, default is '' - tag: 71112 # optional, default is 12345 - rev_next_hop: 192.167.1.100 # mandatory - attach: true - deploy: true - -DELETE ROUTE PEERINGS -===================== - -- name: Delete route peerings - cisco.dcnm.dcnm_service_route_peering: - state: deleted - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP1 # mandatory - node_name: IT-SN-1 # mandatory - -OVERRIDE ROUTE PEERINGS -======================= - -- name: Override existing route peerings with new peerings - cisco.dcnm.dcnm_service_route_peering: - state: overridden - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP-OVR1 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: IT-VRF-12 # mandatory - name: rp1-sn1-inside-net-ovr # mandatory - vlan_id: 191 # mandatory - profile: - ipv4_gw: 192.161.91.1/24 # mandatory - ipv6_gw: 2001:db11::1/64 # optional, default is '' - vlan_name: rp1-sn1-inside-ovr # optional, default is '' - int_descr: "RP1 SN1 inside interface ovr" # optional, default is '' - tag: 11191 # optional, default is 12345 - next_hop: 192.161.91.100 # mandatory - outside_network: # - vrf: IT-VRF-12 # mandatory - name: rp1-sn1-outside-net-ovr # mandatory - vlan_id: 192 # mandatory - profile: - ipv4_gw: 192.161.92.1/24 # mandatory - ipv6_gw: 2001:db12::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside-ovr # optional, default is '' - int_descr: "RP1 SN1 outside interface ovr" # optionL, default is '' - tag: 11192 # optional, default is 12345 - rev_next_hop: 192.161.92.100 # optional, default is '' - attach: true - deploy: true - -- name: Override existing route peerings with no new peerings - cisco.dcnm.dcnm_service_route_peering: - state: overridden - fabric: test-fabric - service_fabric: external - attach: true - deploy: true - -- name: Override existing route peerings with just service node names - cisco.dcnm.dcnm_service_route_peering: - state: overridden - fabric: test-fabric - service_fabric: external - config: - - node_name: IT-SN-1 # optional - - node_name: IT-SN-2 # optional - attach: true - deploy: true - -REPLACE ROUTE PEERINGS -====================== - -- name: Replace service route peerings RP1 - cisco.dcnm.dcnm_service_route_peering: &dcnm_srp_rep_13 - state: replaced - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP1 # mandatory - node_name: IT-SN-1 # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: IT-VRF-11 # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 191 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2101:db01::01/64 # optional, default is '' - vlan_name: rp1-sn1-inside-rep # optional, default is '' - int_descr: "RP1 SN1 inside interface - REP" # optional, default is '' - tag: 11101 # optional, default is 12345 - next_hop: 192.161.1.200 # mandatory - outside_network: # - vrf: IT-VRF-11 # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 192 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2101:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside-rep # optional, default is '' - int_descr: "RP1 SN1 outside interface- REP" # optionL, default is '' - tag: 11102 # optional, default is 12345 - rev_next_hop: 192.161.2.200 # optional, default is '' - attach: true - deploy: true - -QUERY ROUTE PEERINGS -==================== - -- name: Query existing route peerings with specific peering names - cisco.dcnm.dcnm_service_route_peering: - state: query - fabric: test-fabric - service_fabric: external - config: - - name: IT-FW-RP1 # optional - node_name: IT-SN-1 # mandatory - - - name: IT-FW-RP2 # optional - node_name: IT-SN-1 # mandatory - - - name: IT-FW-RP3 # optional - node_name: IT-SN-1 # mandatory - - - name: IT-ADC-RP4 # optional - node_name: IT-SN-2 # mandatory - - - name: IT-ADC-RP5 # optional - node_name: IT-SN-2 # mandatory - - - name: IT-ADC-RP6 # optional - node_name: IT-SN-2 # mandatory - - - name: IT-ADC-RP7 # optional - node_name: IT-SN-2 # mandatory - -- name: Query existing route peerings without specific peering names - cisco.dcnm.dcnm_service_route_peering: - state: query - fabric: test-fabric - service_fabric: external - config: - node_name: IT-SN-1 # mandatory - node_name: IT-SN-2 # mandatory - -""" - -import time -import json -import copy - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.cisco.dcnm.plugins.module_utils.network.dcnm.dcnm import ( - dcnm_send, - validate_list_of_dicts, - dcnm_reset_connection, -) - -from datetime import datetime - - -# Route Peering Class object which includes all the required methods and data to configure and maintain Roue peering objects -class DcnmServiceRoutePeering: - def __init__(self, module): - self.debug = False - self.module = module - self.params = module.params - self.fabric = module.params["fabric"] - self.config = copy.deepcopy(module.params.get("config")) - self.check_mode = False - self.srp_info = [] - self.want = [] - self.have = [] - self.diff_create = [] - self.diff_modify = [] - self.diff_delete = [] - self.diff_deploy = [] - self.fd = None - self.changed_dict = [ - {"merged": [], "modified": [], "deleted": [], "deploy": [], "query": []} - ] - self.result = dict(changed=False, diff=[], response=[]) - - def log_msg(self, msg): - - if self.fd is None: - self.fd = open("srp.log", "a+") - if self.fd is not None: - self.fd.write(msg) - self.fd.flush() - - def dcnm_srp_validate_and_build_srp_info( - self, - cfg, - srp_spec, - srp_network_spec, - srp_prof1_spec, - srp_prof2_spec, - net_name1, - net_name2, - ): - - """ - Routine to validate the playbook input and fill up default values for objects not included. It takes specific profiles - to validate the input against. In this csase we validate the playbook against srp_spec which inlcudes common information - srp_network_spec which inlcudes network specific information and profile_specX which inlciudes network profile information. - For route peering we have two networks or arms and hence two profile specs. This routine updates self.srp_info with validated - playbook information by defaulting values not included - - Parameters: - cfg (dict): The config from playbook - srp_spec (dict): Route peering common spec - srp_network_spec (dict): Rourte peering network related config spec - srp_prof1_spec (dict): Route peering profile spec for inside-network/outside-network/first-arm - srp_prof2_spec (dict): Route peering profile spec for second-arm - net_name1 (string): Name of inside-network/first-arm - net_name2 (string): Name of outside-network/second-arm - - Returns: - None - """ - - srp_static_route_spec = dict( - subnet=dict(required=True, type="ipv4"), - next_hop=dict(required=True, type="list"), - ) - - srp_info, invalid_params = validate_list_of_dicts(cfg, srp_spec) - if invalid_params: - if cfg[0].get("name", " ") != " ": - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - else: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - Unknown, " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - self.srp_info.extend(srp_info) - - in_list = [] - out_list = [] - for item in srp_info: - - in_list.append(item[net_name1]) - # Validate inside and outside network dicts from route peering info - in_net, invalid_params = validate_list_of_dicts(in_list, srp_network_spec) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Network/Arm - " - + net_name1 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - in_list.remove(item[net_name1]) - item[net_name1].update(in_net[0]) - - if item.get(net_name2, "") != "": - out_list.append(item[net_name2]) - out_net, invalid_params = validate_list_of_dicts( - out_list, srp_network_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Network/Arm - " - + net_name2 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - out_list.remove(item[net_name2]) - item[net_name2].update(out_net[0]) - - in_list.append(item[net_name1]["profile"]) - # Validate inside and outside network profile dicts from route peering info - in_net_prof, invalid_params = validate_list_of_dicts( - in_list, srp_prof1_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Profile under Network/Arm - " - + net_name1 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - in_list.remove(item[net_name1]["profile"]) - item[net_name1]["profile"].update(in_net_prof[0]) - - if item.get(net_name2, "") != "": - out_list.append(item[net_name2]["profile"]) - out_net_prof, invalid_params = validate_list_of_dicts( - out_list, srp_prof2_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Profile under Network/Arm - " - + net_name2 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - out_list.remove(item[net_name2]["profile"]) - item[net_name2]["profile"].update(out_net_prof[0]) - - # Check if static route information is included under networks/arms. If yes, validate the same - - if item[net_name1]["profile"].get("static_route", "") != "": - - # Static Route is a list of route dicts - for rt in item[net_name1]["profile"]["static_route"]: - in_list.append(rt) - in_net_route, invalid_params = validate_list_of_dicts( - in_list, srp_static_route_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Static Route under Network/Arm - " - + net_name1 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - in_list.remove(rt) - rt.update(in_net_route[0]) - - if item.get(net_name2, "") != "": - if item[net_name2]["profile"].get("static_route", "") != "": - # Static Route is a list of route dicts - for rt in item[net_name2]["profile"]["static_route"]: - out_list.append(rt) - out_net_route, invalid_params = validate_list_of_dicts( - out_list, srp_static_route_spec - ) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Static Route under Network/Arm - " - + net_name2 - + ", under Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - out_list.remove(rt) - rt.update(out_net_route[0]) - - def dcnm_srp_translate_deploy_mode(self, item): - - """ - Routine to translate the deploy_mode string from the playbook format to the payload format. The translated - value is updated in the 'item' object directly - - Parameters: - item (dict) : route peering block whose 'deploy_mode' object need to be translated - - Returns: - None - """ - - trans_dict = { - "intra_tenant_fw": "IntraTenantFW", - "inter_tenant_fw": "InterTenantFW", - "one_arm_adc": "OneArmADC", - "two_arm_adc": "TwoArmADC", - } - - if item["deploy_mode"] not in trans_dict.keys(): - mesg = "Invalid 'deploy_mode' = {}, in playbook, Expected values = {}".format( - item["deploy_mode"], trans_dict.keys() - ) - self.module.fail_json(msg=mesg) - - return trans_dict[item["deploy_mode"]] - - def dcnm_srp_validate_input(self): - - """ - Routine to validate the given playbook input based on the type of peering. - This routine updates self.srp_info with validated playbook information by defaulting values - not included. Since each state has a different config structure, this routine handles the - validation based on the given state - - Parameters: - None - - Returns: - None - """ - - if None is self.config: - return - - # Inputs will vary for Firewall and ADC service nodes and for each state. Make specific checks - # for each case. - - cfg = [] - for item in self.config: - - citem = copy.deepcopy(item) - - cfg.append(citem) - - if self.module.params["state"] == "deleted": - # config for delete state is different. So validate deleted state differently - self.dcnm_srp_validate_delete_state_input(cfg) - elif self.module.params["state"] == "query": - # config for query state is different. So validate query state differently - self.dcnm_srp_validate_query_state_input(cfg) - # For 'overridden' state, we can have full config for a peering or just service node name alone. - # In the formar case go down to 'else' block to validate the full config - elif (self.module.params["state"] == "overridden") and ( - item.get("name", None) is None - ): - # config for overridden state is different. So validate overridden state differently - self.dcnm_srp_validate_overridden_state_input(cfg) - else: - if "deploy_mode" not in item: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + item["name"] - + ", deploy_mode - Required parameter not found" - ) - self.module.fail_json(msg=mesg) - - # Translate the deploy_mode from playbook format to a format that DCNM expects - item["deploy_mode"] = self.dcnm_srp_translate_deploy_mode(item) - citem["deploy_mode"] = item["deploy_mode"] - - if (item["deploy_mode"].lower() == "intratenantfw") or ( - item["deploy_mode"].lower() == "intertenantfw" - ): - self.dcnm_srp_validate_firewall_input( - cfg, item["deploy_mode"].lower() - ) - if (item["deploy_mode"].lower() == "onearmadc") or ( - item["deploy_mode"].lower() == "twoarmadc" - ): - self.dcnm_srp_validate_adc_input(cfg, item["deploy_mode"].lower()) - cfg.remove(citem) - - def dcnm_srp_validate_intra_tenant_firewall_input(self, cfg): - - """ - Routine to validate the playbook input based on Firewall perring type intra-tenant. - This routine updates self.srp_info with validated intra-tenant firewall related playbook - information by defaulting values not included - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_spec = dict( - name=dict(required=True, type="str"), - node_name=dict(required=True, type="str"), - deploy_mode=dict(required=True, type="str"), - inside_network=dict(required=True, type="dict"), - outside_network=dict(required=True, type="dict"), - next_hop=dict(required=True, type="ipv4"), - rev_next_hop=dict(type="ipv4", default=""), - ) - - srp_network_spec = dict( - vrf=dict(required=True, type="str"), - name=dict(required=True, type="str"), - vlan_id=dict(required=True, type="int"), - profile=dict(required=True, type="dict"), - ) - - srp_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - ) - - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_prof_spec, - srp_prof_spec, - "inside_network", - "outside_network", - ) - - def dcnm_srp_validate_inter_tenant_firewall_input(self, cfg): - - """ - Routine to validate the playbook input based on Firewall perring type inter-tenant. - This routine updates self.srp_info with validated inter-tenant firewall related playbook - information by defaulting values not included - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_spec = dict( - name=dict(required=True, type="str"), - node_name=dict(required=True, type="str"), - deploy_mode=dict(required=True, type="str"), - peering_option=dict(type="str", default="static"), - inside_network=dict(required=True, type="dict"), - outside_network=dict(required=True, type="dict"), - ) - - srp_network_spec = dict( - vrf=dict(required=True, type="str"), - name=dict(required=True, type="str"), - vlan_id=dict(required=True, type="int"), - profile=dict(required=True, type="dict"), - ) - - srp_static_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - static_route=dict(type="list", default=""), - ) - - srp_ebgp_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - ipv4_neighbor=dict(required=True, type="ipv4"), - ipv4_lo=dict(required=True, type="ipv4"), - ipv4_vpc_peer_lo=dict(type="ipv4", default=""), - ipv6_neighbor=dict(type="ipv6", default=""), - ipv6_lo=dict(type="ipv6", default=""), - ipv6_vpc_peer_lo=dict(type="ipv6", default=""), - route_map_tag=dict(type="int", default=12345), - neigh_int_descr=dict(type="str", default=""), - local_asn=dict(type="int", default=""), - adv_host=dict(type="bool", default=True), - ) - - if (cfg[0].get("peering_option", "none") == "none") or ( - cfg[0]["peering_option"].lower() == "static" - ): - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_static_prof_spec, - srp_static_prof_spec, - "inside_network", - "outside_network", - ) - elif cfg[0]["peering_option"].lower() == "ebgp": - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_ebgp_prof_spec, - srp_ebgp_prof_spec, - "inside_network", - "outside_network", - ) - - def dcnm_srp_validate_adc_input(self, cfg, deploy_mode): - - """ - Routine to validate the playbook input based on Loadbalance perring type one-arm and two-arm. - This routine updates self.srp_info with validated adc related playbook information by defaulting - values not included - - Parameters: - cfg (dict): The config from playbook - deploy_mode (string): Deployment mode identifying the type of ADC - - Returns: - None - """ - - srp_spec = dict( - name=dict(required=True, type="str"), - node_name=dict(required=True, type="str"), - deploy_mode=dict(required=True, type="str"), - peering_option=dict(type="str", default="static"), - first_arm=dict(required=True, type="dict"), - second_arm=dict(type="dict", default=""), - rev_next_hop=dict(required=True, type="ipv4"), - ) - - srp_network_spec = dict( - vrf=dict(required=True, type="str"), - name=dict(required=True, type="str"), - vlan_id=dict(required=True, type="int"), - profile=dict(required=True, type="dict"), - ) - - srp_static_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - static_route=dict(type="list", default=""), - ) - - srp_ebgp_first_arm_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - ipv4_neighbor=dict(required=True, type="ipv4"), - ipv4_lo=dict(required=True, type="ipv4"), - ipv4_vpc_peer_lo=dict(type="ipv4", default=""), - ipv6_neighbor=dict(type="ipv6", default=""), - ipv6_lo=dict(type="ipv6", default=""), - ipv6_vpc_peer_lo=dict(type="ipv6", default=""), - route_map_tag=dict(type="int", default=12345), - neigh_int_descr=dict(type="str", default=""), - local_asn=dict(type="int", default=""), - adv_host=dict(type="bool", default=True), - ) - - srp_ebgp_second_arm_prof_spec = dict( - ipv4_gw=dict(required=True, type="ipv4_subnet"), - ipv6_gw=dict(type="ipv6_subnet", default=""), - vlan_name=dict(type="str", default=""), - int_descr=dict(type="str", default=""), - tag=dict(type="int", default=12345), - ) - - if (cfg[0].get("peering_option", "none") == "none") or ( - cfg[0]["peering_option"].lower() == "static" - ): - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_static_prof_spec, - srp_static_prof_spec, - "first_arm", - "second_arm", - ) - elif cfg[0]["peering_option"].lower() == "ebgp": - self.dcnm_srp_validate_and_build_srp_info( - cfg, - srp_spec, - srp_network_spec, - srp_ebgp_first_arm_prof_spec, - srp_ebgp_second_arm_prof_spec, - "first_arm", - "second_arm", - ) - - def dcnm_srp_validate_firewall_input(self, cfg, deploy_mode): - - if deploy_mode == "intratenantfw": - self.dcnm_srp_validate_intra_tenant_firewall_input(cfg) - elif deploy_mode == "intertenantfw": - self.dcnm_srp_validate_inter_tenant_firewall_input(cfg) - - def dcnm_srp_validate_delete_state_input(self, cfg): - - """ - Playbook input will be different for differnt states. This routine validates the delete state - input. This routine updates self.srp_info with validated playbook information related to delete - state. - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_delete_spec = dict( - name=dict(required=True, type="str"), - node_name=dict(required=True, type="str"), - ) - - srp_info, invalid_params = validate_list_of_dicts(cfg, srp_delete_spec) - if invalid_params: - if cfg[0].get("name", " ") != " ": - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + cfg[0]["name"] - + ", " - + "".join(invalid_params) - ) - else: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - Unknown, " - + "".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - self.srp_info.extend(srp_info) - - def dcnm_srp_validate_query_state_input(self, cfg): - - """ - Playbook input will be different for differnt states. This routine validates the query state - input. This routine updates self.srp_info with validated playbook information related to query - state. - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_query_spec = dict( - name=dict(type="str", default="None"), - node_name=dict(required=True, type="str"), - ) - - srp_info, invalid_params = validate_list_of_dicts(cfg, srp_query_spec) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - self.srp_info.extend(srp_info) - - def dcnm_srp_validate_overridden_state_input(self, cfg): - - """ - Playbook input will be different for differnt states. This routine validates the overridden state - input. This routine updates self.srp_info with validated playbook information related to overridden - state. - - Parameters: - cfg (dict): The config from playbook - - Returns: - None - """ - - srp_overridden_spec = dict( - name=dict(required=False, type="str", default=""), - node_name=dict(required=False, type="str", default=""), - ) - - srp_info, invalid_params = validate_list_of_dicts(cfg, srp_overridden_spec) - if invalid_params: - mesg = "Invalid parameters in playbook: {}".format( - "while processing Route Peering - " - + cfg[0]["name"] - + ", " - + "\n".join(invalid_params) - ) - self.module.fail_json(msg=mesg) - - self.srp_info.extend(srp_info) - - def dcnm_srp_get_payload_route_info(self, srp, srp_payload): - - """ - This routine builds the route peering payload information from the playbook input - that is related to static of ebgp route information. - - Parameters: - srp (dict): The route peering information from self.want - srp_payload (dict): Route peering information to be filled from the given srp config - - Returns: - None - """ - - in_route_info = {"nvPairs": {}} - - out_route_info = {"nvPairs": {}} - - if (srp["deploy_mode"].lower() == "intratenantfw") or ( - srp["deploy_mode"].lower() == "intertenantfw" - ): - net_name1 = "inside_network" - net_name2 = "outside_network" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - - srp_payload["routes"] = [] - if srp_payload["peeringOption"] == "StaticPeering": - - srp_payload["routes"].append(in_route_info) - srp_payload["routes"][0]["templateName"] = "service_static_route" - - nv = srp_payload["routes"][0]["nvPairs"] - - nv["VRF_NAME"] = srp[net_name1]["vrf"] - srp_payload["routes"][0]["vrfName"] = srp[net_name1]["vrf"] - - # Build Multiroutes object - routes = srp[net_name1]["profile"]["static_route"] - multi_routes = "" - - for rt in routes: - hops = rt["next_hop"] - for nh in hops: - multi_routes += rt["subnet"] + "," + nh + "\n" - - nv["MULTI_ROUTES"] = multi_routes.rstrip("\n") - - if srp_payload["deploymentMode"] == "InterTenantFW": - - srp_payload["routes"].append(out_route_info) - srp_payload["routes"][1]["templateName"] = "service_static_route" - - nv = srp_payload["routes"][1]["nvPairs"] - - nv["VRF_NAME"] = srp[net_name2]["vrf"] - srp_payload["routes"][1]["vrfName"] = srp[net_name2]["vrf"] - - # Build Multiroutes object - routes = srp[net_name2]["profile"]["static_route"] - multi_routes = "" - - for rt in routes: - hops = rt["next_hop"] - for nh in hops: - multi_routes += rt["subnet"] + "," + nh + "\n" - - nv["MULTI_ROUTES"] = multi_routes.rstrip("\n") - - elif srp_payload["peeringOption"] == "EBGPDynamicPeering": - - srp_payload["routes"].append(in_route_info) - srp_payload["routes"][0]["templateName"] = "service_ebgp_route" - - nv = srp_payload["routes"][0]["nvPairs"] - - nv["NEIGHBOR_IP"] = srp[net_name1]["profile"]["ipv4_neighbor"] - nv["LOOPBACK_IP"] = srp[net_name1]["profile"]["ipv4_lo"] - nv["PEER_LOOPBACK_IP"] = srp[net_name1]["profile"]["ipv4_vpc_peer_lo"] - nv["NEIGHBOR_IPV6"] = srp[net_name1]["profile"]["ipv6_neighbor"] - nv["LOOPBACK_IPV6"] = srp[net_name1]["profile"]["ipv6_lo"] - nv["PEER_LOOPBACK_IPV6"] = srp[net_name1]["profile"]["ipv6_vpc_peer_lo"] - nv["ROUTE_MAP_TAG"] = srp[net_name1]["profile"]["route_map_tag"] - nv["DESC"] = srp[net_name1]["profile"]["neigh_int_descr"] - nv["LOCAL_ASN"] = srp[net_name1]["profile"]["local_asn"] - nv["ADVERTISE_HOST_ROUTE"] = srp[net_name1]["profile"]["adv_host"] - nv["ADMIN_STATE"] = True - nv["VRF_NAME"] = srp[net_name1]["vrf"] - - srp_payload["routes"][0]["vrfName"] = srp[net_name1]["vrf"] - - if srp_payload["deploymentMode"] == "InterTenantFW": - - srp_payload["routes"].append(out_route_info) - srp_payload["routes"][1]["templateName"] = "service_ebgp_route" - - nv = srp_payload["routes"][1]["nvPairs"] - - nv["NEIGHBOR_IP"] = srp[net_name2]["profile"]["ipv4_neighbor"] - nv["LOOPBACK_IP"] = srp[net_name2]["profile"]["ipv4_lo"] - nv["PEER_LOOPBACK_IP"] = srp[net_name2]["profile"]["ipv4_vpc_peer_lo"] - nv["NEIGHBOR_IPV6"] = srp[net_name2]["profile"]["ipv6_neighbor"] - nv["LOOPBACK_IPV6"] = srp[net_name2]["profile"]["ipv6_lo"] - nv["PEER_LOOPBACK_IPV6"] = srp[net_name2]["profile"]["ipv6_vpc_peer_lo"] - nv["ROUTE_MAP_TAG"] = srp[net_name2]["profile"]["route_map_tag"] - nv["DESC"] = srp[net_name2]["profile"]["neigh_int_descr"] - nv["LOCAL_ASN"] = srp[net_name2]["profile"]["local_asn"] - nv["ADVERTISE_HOST_ROUTE"] = srp[net_name2]["profile"]["adv_host"] - nv["ADMIN_STATE"] = True - nv["VRF_NAME"] = srp[net_name2]["vrf"] - - srp_payload["routes"][1]["vrfName"] = srp[net_name2]["vrf"] - - def dcnm_srp_get_common_payload(self, srp, deploy_mode): - - """ - This routine builds the common part of the route peering payload. By common we mean information that is common - to both inside and outside networks or one-arm and two-arm adc. - - Parameters: - srp (dict): Route peering information from self.want - deploy_mode (string): Rourte peering deployment mode - - Returns: - srp_payload (dict): Route peering common payload information populated from playbook configuration - """ - - in_network_defaults = { - "templateName": "Service_Network_Universal", - "nvPairs": { - "isLayer2Only": False, - "suppressArp": False, - "enableIR": False, - "trmEnabled": False, - "rtBothAuto": False, - }, - } - - out_network_defaults = { - "templateName": "Service_Network_Universal", - "nvPairs": { - "isLayer2Only": False, - "suppressArp": False, - "enableIR": False, - "trmEnabled": False, - "rtBothAuto": False, - }, - } - - srp_payload = {"serviceNetworks": [], "enabled": self.attach} - - if (deploy_mode == "intratenantfw") or (deploy_mode == "intertenantfw"): - net_name1 = "inside_network" - net_name2 = "outside_network" - networkType1 = "InsideNetworkFW" - networkType2 = "OutsideNetworkFW" - serviceNodeType = "Firewall" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - networkType1 = "ArmOneADC" - networkType2 = "ArmTwoADC" - serviceNodeType = "ADC" - - # Global - srp_payload["peeringName"] = srp["name"] - srp_payload["deploymentMode"] = srp["deploy_mode"] - srp_payload["serviceNodeType"] = serviceNodeType - - # Inside Network - srp_payload["serviceNetworks"].append(in_network_defaults) - - srp_payload["serviceNetworks"][0]["vrfName"] = srp[net_name1]["vrf"] - srp_payload["serviceNetworks"][0]["networkType"] = networkType1 - srp_payload["serviceNetworks"][0]["networkName"] = srp[net_name1]["name"] - srp_payload["serviceNetworks"][0]["vlanId"] = srp[net_name1]["vlan_id"] - - # Inside Network Profile - srp_payload["serviceNetworks"][0]["nvPairs"]["gatewayIpAddress"] = srp[ - net_name1 - ]["profile"]["ipv4_gw"] - srp_payload["serviceNetworks"][0]["nvPairs"]["gatewayIpV6Address"] = srp[ - net_name1 - ]["profile"]["ipv6_gw"] - srp_payload["serviceNetworks"][0]["nvPairs"]["vlanName"] = srp[net_name1][ - "profile" - ]["vlan_name"] - srp_payload["serviceNetworks"][0]["nvPairs"]["intfDescription"] = srp[ - net_name1 - ]["profile"]["int_descr"] - srp_payload["serviceNetworks"][0]["nvPairs"]["tag"] = srp[net_name1]["profile"][ - "tag" - ] - srp_payload["serviceNetworks"][0]["nvPairs"]["vlanId"] = srp[net_name1][ - "vlan_id" - ] - - if deploy_mode != "onearmadc": - - # Outside Network - srp_payload["serviceNetworks"].append(out_network_defaults) - - srp_payload["serviceNetworks"][1]["vrfName"] = srp[net_name2]["vrf"] - srp_payload["serviceNetworks"][1]["networkType"] = networkType2 - srp_payload["serviceNetworks"][1]["networkName"] = srp[net_name2]["name"] - srp_payload["serviceNetworks"][1]["vlanId"] = srp[net_name2]["vlan_id"] - - # Outside Network Profile - srp_payload["serviceNetworks"][1]["nvPairs"]["gatewayIpAddress"] = srp[ - net_name2 - ]["profile"]["ipv4_gw"] - srp_payload["serviceNetworks"][1]["nvPairs"]["gatewayIpV6Address"] = srp[ - net_name2 - ]["profile"]["ipv6_gw"] - srp_payload["serviceNetworks"][1]["nvPairs"]["vlanName"] = srp[net_name2][ - "profile" - ]["vlan_name"] - srp_payload["serviceNetworks"][1]["nvPairs"]["intfDescription"] = srp[ - net_name2 - ]["profile"]["int_descr"] - srp_payload["serviceNetworks"][1]["nvPairs"]["tag"] = srp[net_name2][ - "profile" - ]["tag"] - srp_payload["serviceNetworks"][1]["nvPairs"]["vlanId"] = srp[net_name2][ - "vlan_id" - ] - - # Service Node and Fabric details - srp_payload["serviceNodeName"] = srp["node_name"] - srp_payload["attachedFabricName"] = self.module.params["fabric"] - srp_payload["fabricName"] = self.module.params["service_fabric"] - - return srp_payload - - def dcnm_get_srp_payload(self, srp): - - """ - This routine builds the complete payload step-by-step first by building common part, then other - parts based on the deploy_mode and peering_option. - - Parameters: - srp (dict): Route peering information - - Returns: - self.srp_payuload (dict): SRP payload information populated with appropriate data from playbook config - """ - - deploy_mode = srp["deploy_mode"].lower() - srp_payload = self.dcnm_srp_get_common_payload(srp, deploy_mode) - - # Based on the deployment mode, add the other required objects - if deploy_mode == "intratenantfw": - - srp_payload["peeringOption"] = "None" - # Add NextHop and Reverse NextHop - srp_payload["nextHopIp"] = srp["next_hop"] - srp_payload["reverseNextHopIp"] = srp["rev_next_hop"] - elif deploy_mode == "intertenantfw": - - if srp["peering_option"] == "static": - srp_payload["peeringOption"] = "StaticPeering" - else: - srp_payload["peeringOption"] = "EBGPDynamicPeering" - self.dcnm_srp_get_payload_route_info(srp, srp_payload) - elif deploy_mode == "onearmadc": - - if srp["peering_option"] == "static": - srp_payload["peeringOption"] = "StaticPeering" - else: - srp_payload["peeringOption"] = "EBGPDynamicPeering" - srp_payload["reverseNextHopIp"] = srp["rev_next_hop"] - self.dcnm_srp_get_payload_route_info(srp, srp_payload) - elif deploy_mode == "twoarmadc": - - if srp["peering_option"] == "static": - srp_payload["peeringOption"] = "StaticPeering" - else: - srp_payload["peeringOption"] = "EBGPDynamicPeering" - srp_payload["reverseNextHopIp"] = srp["rev_next_hop"] - self.dcnm_srp_get_payload_route_info(srp, srp_payload) - - return srp_payload - - def dcnm_srp_update_route_info(self, want, have, cfg): - - """ - This routine is invoked after self.want is populated based on playbook info. For merging route peerings - all the information that is not included in the playbook must be left as is and the information which - is included must be updated. This routine checks for playbook info and updates self.want as required - This routine updates self.want with appriopriate route information from playbook and self.have based on - objects included in the playbook. - - Parameters: - cfg (dict): The config from playbook - want (dict): Route peering payload information populated from playbook config - have (dict): Rourte peering information that exists on the DCNM server - - Returns: - None - """ - - if (want["deploymentMode"].lower() == "intratenantfw") or ( - want["deploymentMode"].lower() == "intertenantfw" - ): - net_name1 = "inside_network" - net_name2 = "outside_network" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - - # Check the peeringOption and if not same, just leave 'want' as it is and do not try to compare it with - # 'have' since the fields are completely different - - if want["peeringOption"] != have["peeringOption"]: - return - - # All objects that are not included in the playbook will be copied from have to leave them undisturbed - if cfg.get("peering_option", None) is None: - want["peeringOption"] = have["peeringOption"] - - if want["peeringOption"] == "StaticPeering": - - if cfg.get("vrf", None) is None: - want["routes"][0]["vrfName"] = have["routes"][0]["vrfName"] - - wnv = want["routes"][0]["nvPairs"] - hnv = have["routes"][0]["nvPairs"] - - if cfg.get("vrf", None) is None: - wnv["VRF_NAME"] = hnv["VRF_NAME"] - - if cfg[net_name1]["profile"].get("static_route", None) is None: - wnv["MULTI_ROUTES"] = hnv["MULTI_ROUTES"] - - if want["deploymentMode"] == "InterTenantFW": - - if cfg.get("vrf", None) is None: - want["routes"][1]["vrfName"] = have["routes"][1]["vrfName"] - - wnv = want["routes"][1]["nvPairs"] - hnv = have["routes"][1]["nvPairs"] - - if cfg.get("vrf", None) is None: - wnv["VRF_NAME"] = hnv["VRF_NAME"] - - if cfg[net_name2]["profile"].get("static_route", None) is None: - wnv["MULTI_ROUTES"] = hnv["MULTI_ROUTES"] - - elif want["peeringOption"] == "EBGPDynamicPeering": - - wnv = want["routes"][0]["nvPairs"] - hnv = have["routes"][0]["nvPairs"] - - if cfg[net_name1]["profile"].get("ipv4_neighbor", None) is None: - wnv["NEIGHBOR_IP"] = hnv["NEIGHBOR_IP"] - - if cfg[net_name1]["profile"].get("ipv4_lo", None) is None: - wnv["LOOPBACK_IP"] = hnv["LOOPBACK_IP"] - - if cfg[net_name1]["profile"].get("ipv4_vpc_peer_lo", None) is None: - wnv["PEER_LOOPBACK_IP"] = hnv["PEER_LOOPBACK_IP"] - - if cfg[net_name1]["profile"].get("ipv6_neighbor", None) is None: - wnv["NEIGHBOR_IPV6"] = hnv["NEIGHBOR_IPV6"] - - if cfg[net_name1]["profile"].get("ipv6_lo", None) is None: - wnv["LOOPBACK_IPV6"] = hnv["LOOPBACK_IPV6"] - - if cfg[net_name1]["profile"].get("ipv6_vpc_peer_lo", None) is None: - wnv["PEER_LOOPBACK_IPV6"] = hnv["PEER_LOOPBACK_IPV6"] - - if cfg[net_name1]["profile"].get("route_map_tag", None) is None: - wnv["ROUTE_MAP_TAG"] = hnv["ROUTE_MAP_TAG"] - - if cfg[net_name1]["profile"].get("neigh_int_descr", None) is None: - wnv["DESC"] = hnv["DESC"] - - if cfg[net_name1]["profile"].get("local_asn", None) is None: - wnv["LOCAL_ASN"] = hnv["LOCAL_ASN"] - - if cfg[net_name1]["profile"].get("adv_host", None) is None: - wnv["ADVERTISE_HOST_ROUTE"] = hnv["ADVERTISE_HOST_ROUTE"] - - if cfg.get("vrf", None) is None: - wnv["VRF_NAME"] = hnv["VRF_NAME"] - - if cfg.get("vrf", None) is None: - want["routes"][0]["vrfName"] = have["routes"][0]["vrfName"] - - if want["deploymentMode"] == "InterTenantFW": - - wnv = want["routes"][1]["nvPairs"] - hnv = have["routes"][1]["nvPairs"] - - if cfg[net_name2]["profile"].get("ipv4_neighbor", None) is None: - wnv["NEIGHBOR_IP"] = hnv["NEIGHBOR_IP"] - - if cfg[net_name2]["profile"].get("ipv4_lo", None) is None: - wnv["LOOPBACK_IP"] = hnv["LOOPBACK_IP"] - - if cfg[net_name2]["profile"].get("ipv4_vpc_peer_lo", None) is None: - wnv["PEER_LOOPBACK_IP"] = hnv["PEER_LOOPBACK_IP"] - - if cfg[net_name2]["profile"].get("ipv6_neighbor", None) is None: - wnv["NEIGHBOR_IPV6"] = hnv["NEIGHBOR_IPV6"] - - if cfg[net_name2]["profile"].get("ipv6_lo", None) is None: - wnv["LOOPBACK_IPV6"] = hnv["LOOPBACK_IPV6"] - - if cfg[net_name2]["profile"].get("ipv6_vpc_peer_lo", None) is None: - wnv["PEER_LOOPBACK_IPV6"] = hnv["PEER_LOOPBACK_IPV6"] - - if cfg[net_name2]["profile"].get("route_map_tag", None) is None: - wnv["ROUTE_MAP_TAG"] = hnv["ROUTE_MAP_TAG"] - - if cfg[net_name2]["profile"].get("neigh_int_descr", None) is None: - wnv["DESC"] = hnv["DESC"] - - if cfg[net_name2]["profile"].get("loacl_asn", None) is None: - wnv["LOCAL_ASN"] = hnv["LOCAL_ASN"] - - if cfg[net_name2]["profile"].get("adv_host", None) is None: - wnv["ADVERTISE_HOST_ROUTE"] = hnv["ADVERTISE_HOST_ROUTE"] - - if cfg.get("vrf", None) is None: - wnv["VRF_NAME"] = hnv["VRF_NAME"] - - if cfg.get("vrf", None) is None: - want["routes"][1]["vrfName"] = have["routes"][1]["vrfName"] - - def dcnm_srp_update_common_info(self, want, have, cfg): - - """ - Routine to update the common part of the route peering information in self.want - This routine updates self.want with common information from playbook and self.have based on objects - included in the playbook. - - Parameters: - cfg (dict): The config from playbook - want (dict): Route peering payload information populated from playbook config - have (dict): Rourte peering information that exists on the DCNM server - - Returns: - None - """ - - if (want["deploymentMode"].lower() == "intratenantfw") or ( - want["deploymentMode"].lower() == "intertenantfw" - ): - net_name1 = "inside_network" - net_name2 = "outside_network" - else: - net_name1 = "first_arm" - net_name2 = "second_arm" - - # All objects that are not included in the playbook will be copied from have to leave them undisturbed - # Inside Network - if cfg[net_name1].get("vrf", None) is None: - want["serviceNetworks"][0]["vrfName"] = have["serviceNetworks"][0][ - "vrfName" - ] - - if cfg[net_name1].get("name", None) is None: - want["serviceNetworks"][0]["networkName"] = have["serviceNetworks"][0][ - "networkName" - ] - - if cfg[net_name1].get("vlan_id", None) is None: - want["serviceNetworks"][0]["vlanId"] = have["serviceNetworks"][0]["vlanId"] - - # Inside Network Profile - if cfg[net_name1]["profile"].get("ipv4_gw", None) is None: - want["serviceNetworks"][0]["nvPairs"]["gatewayIpAddress"] = have[ - "serviceNetworks" - ][0]["nvPairs"]["gatewayIpAddress"] - - if cfg[net_name1]["profile"].get("ipv6_gw", None) is None: - want["serviceNetworks"][0]["nvPairs"]["gatewayIpV6Address"] = have[ - "serviceNetworks" - ][0]["nvPairs"]["gatewayIpV6Address"] - - if cfg[net_name1]["profile"].get("vlan_name", None) is None: - want["serviceNetworks"][0]["nvPairs"]["vlanName"] = have["serviceNetworks"][ - 0 - ]["nvPairs"]["vlanName"] - - if cfg[net_name1]["profile"].get("int_descr", None) is None: - hif_desc = have["serviceNetworks"][0]["nvPairs"]["intfDescription"].split( - " " - )[:-1] - want["serviceNetworks"][0]["nvPairs"]["intfDescription"] = " ".join( - hif_desc - ) - - if cfg[net_name1]["profile"].get("tag", None) is None: - want["serviceNetworks"][0]["nvPairs"]["tag"] = have["serviceNetworks"][0][ - "nvPairs" - ]["tag"] - - if cfg[net_name1]["profile"].get("vlan_id", None) is None: - want["serviceNetworks"][0]["nvPairs"]["vlanId"] = have["serviceNetworks"][ - 0 - ]["nvPairs"]["vlanId"] - - if want["deploymentMode"].lower() != "onearmadc": - - # Outside Network - if cfg[net_name2].get("vrf", None) is None: - want["serviceNetworks"][1]["vrfName"] = have["serviceNetworks"][1][ - "vrfName" - ] - - if cfg[net_name2].get("name", None) is None: - want["serviceNetworks"][1]["networkName"] = have["serviceNetworks"][1][ - "networkName" - ] - - if cfg[net_name2].get("vlan_id", None) is None: - want["serviceNetworks"][1]["vlanId"] = have["serviceNetworks"][1][ - "vlanId" - ] - - # Outside Network Profile - if cfg[net_name2]["profile"].get("ipv4_gw", None) is None: - want["serviceNetworks"][1]["nvPairs"]["gatewayIpAddress"] = have[ - "serviceNetworks" - ][1]["nvPairs"]["gatewayIpAddress"] - - if cfg[net_name2]["profile"].get("ipv6_gw", None) is None: - want["serviceNetworks"][1]["nvPairs"]["gatewayIpV6Address"] = have[ - "serviceNetworks" - ][1]["nvPairs"]["gatewayIpV6Address"] - - if cfg[net_name2]["profile"].get("vlan_name", None) is None: - want["serviceNetworks"][1]["nvPairs"]["vlanName"] = have[ - "serviceNetworks" - ][1]["nvPairs"]["vlanName"] - - if cfg[net_name2]["profile"].get("int_descr", None) is None: - hif_desc = have["serviceNetworks"][1]["nvPairs"][ - "intfDescription" - ].split(" ")[:-1] - want["serviceNetworks"][1]["nvPairs"]["intfDescription"] = " ".join( - hif_desc - ) - - if cfg[net_name2]["profile"].get("tag", None) is None: - want["serviceNetworks"][1]["nvPairs"]["tag"] = have["serviceNetworks"][ - 1 - ]["nvPairs"]["tag"] - - if cfg[net_name2]["profile"].get("vlan_id", None) is None: - want["serviceNetworks"][1]["nvPairs"]["vlanId"] = have[ - "serviceNetworks" - ][1]["nvPairs"]["vlanId"] - - # if self.module.params["attach"] is "default, then attach is not given in Playbook - if self.module.params["attach"] == "default": - want["enabled"] = have["enabled"] - - def dcnm_srp_update_want(self): - - """ - Routine to compare want and have and make approriate changes to want. This routine checks the existing - informationm with the config from playbook and populates the payloads in self.want apropriately. - This routine updates self.want with final paylload information after comparing self.want and self.have and - the playbook information. - - Parameters: - None - - Returns: - None - """ - - # only for 'merged' state we need to update the objects that are not included in playbook with - # values from self.have. - - if self.module.params["state"] != "merged": - return - - if self.want == []: - return - - for srp in self.want: - - # Get the matching have to copy values if required - match_have = [ - have - for have in self.have - if ( - (srp["peeringName"] == have["peeringName"]) - and (srp["fabricName"] == have["fabricName"]) - and (srp["serviceNodeName"] == have["serviceNodeName"]) - and (srp["attachedFabricName"] == have["attachedFabricName"]) - ) - ] - if match_have == []: - continue - - # Get the SRP from self.config to check if a particular object is included or not - match_cfg = [ - cfg - for cfg in self.config - if ( - (srp["peeringName"] == cfg["name"]) - and (srp["fabricName"] == self.module.params["service_fabric"]) - and (srp["serviceNodeName"] == cfg["node_name"]) - and (srp["attachedFabricName"] == self.module.params["fabric"]) - ) - ] - if match_cfg == []: - continue - - self.dcnm_srp_update_common_info(srp, match_have[0], match_cfg[0]) - self.dcnm_srp_update_route_info(srp, match_have[0], match_cfg[0]) - - def dcnm_srp_get_want(self): - - """ - This routine updates self.want with the payload information based on the playbook configuration. - - Parameters: - None - - Returns: - None - """ - - if None is self.config: - return - - if not self.srp_info: - return - - # self.srp_info is a list of directories each having config related to a particular srp - for srp_elem in self.srp_info: - # If route peering name is not given, then that means we are handling the case of Playbook - # including just the service node name. In such a casse we don't have to worry about filling want - if srp_elem.get("name", "") == "": - continue - srp_payload = self.dcnm_get_srp_payload(srp_elem) - if srp_payload not in self.want: - self.want.append(srp_payload) - - def dcnm_srp_get_srp_info_with_service_node(self, node_name): - - """ - Routine to get all route peerings based on the Service Node information included in the playbook. - - Parameters: - node_name (string): service node name to fetch the route peerings information from - - Returns: - resp["DATA"] (dict): All route peerings present on the specified service node - """ - - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + self.module.params["service_fabric"] - + "/service-nodes/" - + node_name - + "/peerings/" - + self.module.params["fabric"] - ) - - retries = 0 - while retries < 5: - retries += 1 - resp = dcnm_send(self.module, "GET", path) - - if resp and resp["RETURN_CODE"] != 200: - time.sleep(10) - continue - else: - break - - if resp and (resp["RETURN_CODE"] == 200) and resp["DATA"]: - resp["RETRIES"] = retries - return resp["DATA"] - else: - return [] - - def dcnm_srp_get_service_nodes_from_dcnm(self): - - """ - Routine to get list of all service nodes from DCNM. - - Parameters: - None - - Returns: - resp["DATA"] (dict): All service nodes on the specified fabric - """ - - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/?attached-fabric=" - + self.module.params["fabric"] - ) - - retries = 0 - while retries < 5: - retries += 1 - resp = dcnm_send(self.module, "GET", path) - - if resp and resp["RETURN_CODE"] != 200: - time.sleep(10) - continue - else: - break - - if resp and (resp["RETURN_CODE"] == 200) and resp["DATA"]: - resp["RETRIES"] = retries - return resp["DATA"] - else: - return [] - - def dcnm_srp_get_srp_info_from_dcnm(self, srp, srp_type): - - """ - Routine to get existing Route peering information from DCNM which matches the given SRP. - - Parameters: - srp (dict): Route peering information - srp_type (string): String indicating whether the 'srp' passed is in 'PLAYBOOK' format - or 'PAYLOAD' format - Returns: - resp["DATA"] (dict): SRP informatikon obtained from the DCNM server if it exists - [] otherwise - """ - - if srp_type == "PAYLOAD": - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - ) - else: - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + self.module.params["service_fabric"] - + "/service-nodes/" - + srp["node_name"] - + "/peerings/" - + self.module.params["fabric"] - + "/" - + srp["name"] - ) - - retries = 0 - while retries < 5: - retries += 1 - resp = dcnm_send(self.module, "GET", path) - - if resp and resp["RETURN_CODE"] != 200: - # Check if the error is "ResourceNotFound". In that case we can return without - # retrying. - if resp.get("error", None) is not None: - if resp["error"].get("code") == "ResourceNotFound": - break - time.sleep(10) - continue - else: - break - - if resp and (resp["RETURN_CODE"] == 200) and resp["DATA"]: - resp["RETRIES"] = retries - return resp["DATA"] - else: - return [] - - def dcnm_srp_get_have(self): - - """ - Routine to get exisitng roue peering information from DCNM that matches information in self.want. - This routine updates self.have with all the route peerings that match the given playbook configuration - - Parameters: - None - - Returns: - None - """ - - if self.want == []: - return - - for srp in self.want: - have = self.dcnm_srp_get_srp_info_from_dcnm(srp, "PAYLOAD") - if (have != []) and (have not in self.have): - self.have.append(have) - - def dcnm_srp_compare_common_info(self, want, have): - - """ - Routine to compare common information from want and have to decide if the information from self.want is to - be added to the create list/replace list or not. - - Parameters: - want (dict): SRP Payload information populated using playbook config - have (dict): SRP information existing on the DCNM server - - Returns: - DCNM_SRP_NO_MATCH (string): if information in want and have don't match - DCNM_SRP_MATCH (string): if want and have match - mismatch_reasons (list): A list containing strings identifying which objects did not match or [] - """ - - mismatch_reasons = [] - - if want["deploymentMode"] != have["deploymentMode"]: - mismatch_reasons.append("DCNM_SRP_DM_NO_MATCH") - - # Global - if want["serviceNodeType"] != have["serviceNodeType"]: - mismatch_reasons.append("DCNM_SRP_SNT_NO_MATCH") - - # Inside Network - if ( - want["serviceNetworks"][0]["vrfName"] - != have["serviceNetworks"][0]["vrfName"] - ): - mismatch_reasons.append("DCNM_SRP_IN_VRF_NO_MATCH") - - if ( - want["serviceNetworks"][0]["networkType"] - != have["serviceNetworks"][0]["networkType"] - ): - mismatch_reasons.append("DCNM_SRP_IN_NT_NO_MATCH") - - if ( - want["serviceNetworks"][0]["networkName"] - != have["serviceNetworks"][0]["networkName"] - ): - mismatch_reasons.append("DCNM_SRP_IN_NN_NO_MATCH") - - if want["serviceNetworks"][0]["vlanId"] != have["serviceNetworks"][0]["vlanId"]: - mismatch_reasons.append("DCNM_SRP_IN_VID_NO_MATCH") - - # Inside Network Profile - if ( - want["serviceNetworks"][0]["nvPairs"]["gatewayIpAddress"] - != have["serviceNetworks"][0]["nvPairs"]["gatewayIpAddress"] - ): - mismatch_reasons.append("DCNM_SRP_IN_IPV4GW_NO_MATCH") - if ( - want["serviceNetworks"][0]["nvPairs"]["gatewayIpV6Address"] - != have["serviceNetworks"][0]["nvPairs"]["gatewayIpV6Address"] - ): - mismatch_reasons.append("DCNM_SRP_IN_IPV6GW_NO_MATCH") - if ( - want["serviceNetworks"][0]["nvPairs"]["vlanName"] - != have["serviceNetworks"][0]["nvPairs"]["vlanName"] - ): - mismatch_reasons.append("DCNM_SRP_IN_VNAME_NO_MATCH") - - # When we get the SRP inmformation from have, the intfDescription would have been modified and some meta data added. so ignore the meta data - # when comparing the interface descriptions - if want["serviceNetworks"][0]["nvPairs"]["intfDescription"] != "": - wif_desc = want["serviceNetworks"][0]["nvPairs"]["intfDescription"].split( - " " - ) - else: - wif_desc = [] - hif_desc = have["serviceNetworks"][0]["nvPairs"]["intfDescription"].split(" ")[ - :-1 - ] - if wif_desc != hif_desc: - mismatch_reasons.append("DCNM_SRP_IN_DESCR_NO_MATCH") - if ( - str(want["serviceNetworks"][0]["nvPairs"]["tag"]) - != have["serviceNetworks"][0]["nvPairs"]["tag"] - ): - mismatch_reasons.append("DCNM_SRP_IN_TAG_NO_MATCH") - if ( - str(want["serviceNetworks"][0]["nvPairs"]["vlanId"]) - != have["serviceNetworks"][0]["nvPairs"]["vlanId"] - ): - mismatch_reasons.append("DCNM_SRP_IN_PROF_VID_NO_MATCH") - - if want["deploymentMode"].lower() != "onearmadc": - - # Outside Network - if ( - want["serviceNetworks"][1]["vrfName"] - != have["serviceNetworks"][1]["vrfName"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_VRF_NO_MATCH") - if ( - want["serviceNetworks"][1]["networkType"] - != have["serviceNetworks"][1]["networkType"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_NT_NO_MATCH") - if ( - want["serviceNetworks"][1]["networkName"] - != have["serviceNetworks"][1]["networkName"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_NN_NO_MATCH") - if ( - want["serviceNetworks"][1]["vlanId"] - != have["serviceNetworks"][1]["vlanId"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_VID_NO_MATCH") - - # Outside Network Profile - if ( - want["serviceNetworks"][1]["nvPairs"]["gatewayIpAddress"] - != have["serviceNetworks"][1]["nvPairs"]["gatewayIpAddress"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_IPV4GW_NO_MATCH") - if ( - want["serviceNetworks"][1]["nvPairs"]["gatewayIpV6Address"] - != have["serviceNetworks"][1]["nvPairs"]["gatewayIpV6Address"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_IPV6GW_NO_MATCH") - if ( - want["serviceNetworks"][1]["nvPairs"]["vlanName"] - != have["serviceNetworks"][1]["nvPairs"]["vlanName"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_VNAME_NO_MATCH") - - # When we get the SRP inmformation from have, the intfDescription would have been modified and some meta data added. so ignore the meta data - # when comparing the interface descriptions - if want["serviceNetworks"][1]["nvPairs"]["intfDescription"] != "": - wif_desc = want["serviceNetworks"][1]["nvPairs"][ - "intfDescription" - ].split(" ") - else: - wif_desc = [] - hif_desc = have["serviceNetworks"][1]["nvPairs"]["intfDescription"].split( - " " - )[:-1] - if wif_desc != hif_desc: - mismatch_reasons.append("DCNM_SRP_OUT_DESCR_NO_MATCH") - if ( - str(want["serviceNetworks"][1]["nvPairs"]["tag"]) - != have["serviceNetworks"][1]["nvPairs"]["tag"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_TAG_NO_MATCH") - if ( - str(want["serviceNetworks"][1]["nvPairs"]["vlanId"]) - != have["serviceNetworks"][1]["nvPairs"]["vlanId"] - ): - mismatch_reasons.append("DCNM_SRP_OUT_PROF_VID_NO_MATCH") - - if str(want["enabled"]).lower() != str(have["enabled"]).lower(): - mismatch_reasons.append("DCNM_SRP_ATT_NO_MATCH") - - if mismatch_reasons == []: - return "DCNM_SRP_MATCH", mismatch_reasons - else: - return "DCNM_SRP_NO_MATCH", mismatch_reasons - - def dcnm_srp_compare_multi_routes(self, wmr, hmr): - - """ - Routine to compare MULTIROUTE object of route peerings from self.want and self.have. - - Parameters: - wmr (dict): Multi-Route info object from want - hmr (dict): Multi-Route info object from have - - Returns: - DCNM_MR_NO_MATCH (string): if multi-route objects do not match - DCNM_MR_MATCH (string): if multi-route objects match - """ - - wmrl = wmr.split("\n") - hmrl = hmr.split("\n") - - fwmr = [item.replace(" ", "") for item in wmrl] - fhmr = [item.replace(" ", "") for item in hmrl] - - for rt in fwmr: - if rt not in fhmr: - return "DCNM_MR_NO_MATCH" - return "DCNM_MR_MATCH" - - def dcnm_srp_compare_route_info(self, want, have): - - """ - Routine to compare route objects of route peerings from self.want and self.have. - - Parameters: - want (dict): SRP Payload information populated using playbook config - have (dict): SRP information existing on the DCNM server - - Returns: - DCNM_SRP_MATCH (string): if route information in want and have match - DCNM_SRP_NO_MATCH (string): if route information in want and have do not match - mismatch_reasons (list): A list containing strings indicating which objects did not match - """ - - mismatch_reasons = [] - - if want["peeringOption"] != have["peeringOption"]: - # If peeringOption doesn't match, we cannot compare rest of the fields because they will be - # entirely different. - mismatch_reasons.append("DCNM_SRP_PO_NO_MATCH") - return "DCNM_SRP_NO_MATCH", mismatch_reasons - - if want["peeringOption"] == "StaticPeering": - - if want["routes"][0]["templateName"] != have["routes"][0]["templateName"]: - mismatch_reasons.append("DCNM_SRP_SP_IN_TN_NO_MATCH") - - if want["routes"][0]["vrfName"] != have["routes"][0]["vrfName"]: - mismatch_reasons.append("DCNM_SRP_SP_IN_VRF_NO_MATCH") - - wnv = want["routes"][0]["nvPairs"] - hnv = have["routes"][0]["nvPairs"] - - if wnv["VRF_NAME"] != hnv["VRF_NAME"]: - mismatch_reasons.append("DCNM_SRP_SP_IN_PROF_VRF_NO_MATCH") - - rc = self.dcnm_srp_compare_multi_routes( - wnv["MULTI_ROUTES"], hnv["MULTI_ROUTES"] - ) - - if rc == "DCNM_MR_NO_MATCH": - mismatch_reasons.append("DCNM_SRP_SP_IN_MR_NO_MATCH") - - if want["deploymentMode"] == "InterTenantFW": - - if ( - want["routes"][1]["templateName"] - != have["routes"][1]["templateName"] - ): - mismatch_reasons.append("DCNM_SRP_SP_OUT_TN_NO_MATCH") - - if want["routes"][1]["vrfName"] != have["routes"][1]["vrfName"]: - mismatch_reasons.append("DCNM_SRP_SP_OUT_VRF_NO_MATCH") - - wnv = want["routes"][1]["nvPairs"] - hnv = have["routes"][1]["nvPairs"] - - if wnv["VRF_NAME"] != hnv["VRF_NAME"]: - mismatch_reasons.append("DCNM_SRP_SP_OUT_PROF_VRF_NO_MATCH") - - rc = self.dcnm_srp_compare_multi_routes( - wnv["MULTI_ROUTES"], hnv["MULTI_ROUTES"] - ) - - if rc == "DCNM_MR_NO_MATCH": - mismatch_reasons.append("DCNM_SRP_SP_OUT_MR_NO_MATCH") - - elif want["peeringOption"] == "EBGPDynamicPeering": - - if want["routes"][0]["templateName"] != have["routes"][0]["templateName"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_TN_NO_MATCH") - - wnv = want["routes"][0]["nvPairs"] - hnv = have["routes"][0]["nvPairs"] - - if wnv["NEIGHBOR_IP"] != hnv["NEIGHBOR_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_NIP4_NO_MATCH") - if wnv["LOOPBACK_IP"] != hnv["LOOPBACK_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_LIP4_NO_MATCH") - if wnv["PEER_LOOPBACK_IP"] != hnv["PEER_LOOPBACK_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_PLIP4_NO_MATCH") - if wnv["NEIGHBOR_IPV6"] != hnv["NEIGHBOR_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_NIP6_NO_MATCH") - if wnv["LOOPBACK_IPV6"] != hnv["LOOPBACK_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_LIP6_NO_MATCH") - if wnv["PEER_LOOPBACK_IPV6"] != hnv["PEER_LOOPBACK_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_PLIP6_NO_MATCH") - if str(wnv["ROUTE_MAP_TAG"]) != hnv["ROUTE_MAP_TAG"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_RMT_NO_MATCH") - if wnv["DESC"] != hnv["DESC"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_DESCR_NO_MATCH") - if str(wnv["LOCAL_ASN"]) != hnv["LOCAL_ASN"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_ASN_NO_MATCH") - if str(wnv["ADVERTISE_HOST_ROUTE"]).lower() != hnv["ADVERTISE_HOST_ROUTE"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_ADV_HR_NO_MATCH") - if str(wnv["ADMIN_STATE"]).lower() != hnv["ADMIN_STATE"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_AS_NO_MATCH") - if wnv["VRF_NAME"] != hnv["VRF_NAME"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_PROF_VRF_NO_MATCH") - - if want["routes"][0]["vrfName"] != have["routes"][0]["vrfName"]: - mismatch_reasons.append("DCNM_SRP_EBGP_IN_VRF_NO_MATCH") - - if want["deploymentMode"] == "InterTenantFW": - - if ( - want["routes"][1]["templateName"] - != have["routes"][1]["templateName"] - ): - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_TN_NO_MATCH") - - wnv = want["routes"][1]["nvPairs"] - hnv = have["routes"][1]["nvPairs"] - - if wnv["NEIGHBOR_IP"] != hnv["NEIGHBOR_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_NIP4_NO_MATCH") - if wnv["LOOPBACK_IP"] != hnv["LOOPBACK_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_LIP4_NO_MATCH") - if wnv["PEER_LOOPBACK_IP"] != hnv["PEER_LOOPBACK_IP"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_PLIP4_NO_MATCH") - if wnv["NEIGHBOR_IPV6"] != hnv["NEIGHBOR_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_NIP6_NO_MATCH") - if wnv["LOOPBACK_IPV6"] != hnv["LOOPBACK_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_LIP6_NO_MATCH") - if wnv["PEER_LOOPBACK_IPV6"] != hnv["PEER_LOOPBACK_IPV6"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_PLIP6_NO_MATCH") - if str(wnv["ROUTE_MAP_TAG"]) != hnv["ROUTE_MAP_TAG"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_RMT_NO_MATCH") - if wnv["DESC"] != hnv["DESC"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_DESCR_NO_MATCH") - if str(wnv["LOCAL_ASN"]) != hnv["LOCAL_ASN"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_ASN_NO_MATCH") - if ( - str(wnv["ADVERTISE_HOST_ROUTE"]).lower() - != hnv["ADVERTISE_HOST_ROUTE"] - ): - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_ADV_HR_NO_MATCH") - if str(wnv["ADMIN_STATE"]).lower() != hnv["ADMIN_STATE"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_AS_NO_MATCH") - if wnv["VRF_NAME"] != hnv["VRF_NAME"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_PROF_VRF_NO_MATCH") - - if want["routes"][1]["vrfName"] != have["routes"][1]["vrfName"]: - mismatch_reasons.append("DCNM_SRP_EBGP_OUT_VRF_NO_MATCH") - - if mismatch_reasons == []: - return "DCNM_SRP_MATCH", mismatch_reasons - else: - return "DCNM_SRP_NO_MATCH", mismatch_reasons - - def dcnm_srp_compare_route_peerings(self, srp): - - """ - Routine to compare route peerings from self.want and self.have. Used during merge and replace. - - Parameters: - srp (dict): The SRP payload information - - Returns: - DCNM_SRP_ADD_NEW (string): if the given SRP does not exist - DCNM_SRP_DONT_ADD (string): if given SRP already exist and is exactly the same - DCNM_SRP_MERGE (string): if given SRP already exists but not exactly the same - """ - - found = False - - if self.have == []: - return ("DCNM_SRP_ADD_NEW", None) - - match_have = [ - have - for have in self.have - if ( - (srp["peeringName"] == have["peeringName"]) - and (srp["fabricName"] == have["fabricName"]) - and (srp["serviceNodeName"] == have["serviceNodeName"]) - and (srp["attachedFabricName"] == have["attachedFabricName"]) - ) - ] - for have in match_have: - found = True - - # A matching SRP found. Check if it exactly matches with what is being requested for - rc, reasons = self.dcnm_srp_compare_common_info(srp, have) - - if rc == "DCNM_SRP_MATCH": - rc, reasons = self.dcnm_srp_compare_route_info(srp, have) - - if rc == "DCNM_SRP_MATCH": - return ("DCNM_SRP_DONT_ADD", have) - - if found is True: - # Found a matching route peering, but some of the objects don't match. - # Go ahead and merge the objects into the existing srp - return ("DCNM_SRP_MERGE", have) - else: - return ("DCNM_SRP_ADD_NEW", None) - - def dcnm_srp_get_srp_attachment_status(self, srp): - - """ - Routine to get the attachment/deployment information for a given route peering. This information - is used to implement idempotent operations. Change is deployment state will be treated as a change - in route peering during merge and replace operations. - - Parameters: - srp (dict): Route peering information - - Returns: - attached (bool): a flag indicating is the given SRP is attached - deployed (bool): a flag indicating is the given SRP is deployed - """ - - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - + "/attachments" - ) - - retries = 0 - while retries < 5: - retries += 1 - resp = dcnm_send(self.module, "GET", path) - - if resp and resp["RETURN_CODE"] != 200: - time.sleep(10) - continue - else: - break - - if resp: - resp["RETRIES"] = retries - self.result["response"].append(resp) - - attached = True - deployed = True - if ( - resp - and (resp["RETURN_CODE"] == 200) - and (resp.get("DATA", None) is not None) - ): - - for item in resp["DATA"]: - for attach in item["switchAttaches"]: - # The API will return status for all switches whether the service node is attached to it or not. - # Hence check only entries that are relevant. We can find this by checking for 'portNames' and - # vlanID which will be updated only for those switches to which the service node is attached. We - # can ignore the rest. - if (attach.get("portNames", None) is None) or ( - attach.get("vlanId", 0) == 0 - ): - continue - if attach["lanAttached"] is False: - attached = False - if (attach["attachState"] == "NA") or ( - attach["attachState"] == "PENDING" - ): - deployed = False - return (attached, deployed) - - def dcnm_srp_get_diff_merge(self): - - """ - Routine to get a list of payload information, self.diff_create/self.diff_modify to create new or modify - existing peerings. This routine updates self.diff_merge/self.diff_modify with route peering payloads - that are to created or modified. - - Parameters: - None - - Returns: - None - """ - - if not self.want: - return - - for srp in self.want: - - rc, have = self.dcnm_srp_compare_route_peerings(srp) - - if rc == "DCNM_SRP_ADD_NEW": - # A srp does not exists, create a new one. - if srp not in self.diff_create: - self.changed_dict[0]["merged"].append(srp) - self.diff_create.append(srp) - elif rc == "DCNM_SRP_MERGE": - # A srp exists and it needs to be updated - self.changed_dict[0]["modified"].append(srp) - self.diff_modify.append(srp) - - # Check the 'deploy' flag and decide if this srp is to be deployed - if have is None: - # A new route peering. If attach and deploy are set, attach and deploy - if self.deploy is True: - ditem = {} - ditem["serviceNodeName"] = srp["serviceNodeName"] - ditem["attachedFabricName"] = srp["attachedFabricName"] - ditem["fabricName"] = srp["fabricName"] - ditem["peeringName"] = srp["peeringName"] - self.diff_deploy.append(ditem) - else: - - attached, deployed = self.dcnm_srp_get_srp_attachment_status(srp) - - if self.deploy is True: - # We deploy when self.deploy is True and: - # 1. there are no changes due to this request(rc is DCNM_SRP_DONT_ADD), but the SRP is not deployed - # 2. there are changes due to this request (rc is DCNM_SRP_MERGE) - if ((rc == "DCNM_SRP_DONT_ADD") and (deployed is False)) or ( - rc == "DCNM_SRP_MERGE" - ): - ditem = {} - ditem["serviceNodeName"] = srp["serviceNodeName"] - ditem["attachedFabricName"] = srp["attachedFabricName"] - ditem["fabricName"] = srp["fabricName"] - ditem["peeringName"] = srp["peeringName"] - self.diff_deploy.append(ditem) - - if self.diff_deploy != []: - self.changed_dict[0]["deploy"].extend(self.diff_deploy) - - def dcnm_srp_get_diff_deleted(self): - - """ - Routine to get a list of payload information that will be used to delete route peerings. - This routine updates self.diff_delete with payloads that are used to delete route peerings - from the server. - - Parameters: - None - - Returns: - None - """ - - for srp in self.srp_info: - - # Get the route peering that is to be deleted. - resp = self.dcnm_srp_get_srp_info_from_dcnm(srp, "PLAYBOOK") - - # For deleting route peerings, it must first be detached and then deployed. - if resp != [] and resp not in self.diff_delete: - self.diff_delete.append(resp) - self.changed_dict[0]["deleted"].append(srp) - - def dcnm_srp_get_diff_query(self): - - """ - Routine to get route peering information based on the playbook configuration. - This routine updates self.result with SRPs requested for in the playbook if they exist on - the DCNM server. - - Parameters: - None - - Returns: - None - """ - - for srp in self.srp_info: - - # Query may or may not include the peeringName. Get the SRP info based on whether - # a peeringName is included or not. If a peeringName is not included, then get all - # peerings from the service-node. Otherwise get the specific peering that is requested - - if srp["name"] != "None": - # peeringName included - resp = self.dcnm_srp_get_srp_info_from_dcnm(srp, "PLAYBOOK") - - if resp != []: - self.result["response"].append(resp) - else: - # peeringName not included - resp = self.dcnm_srp_get_srp_info_with_service_node(srp["node_name"]) - - if resp != []: - self.result["response"].extend(resp) - self.changed_dict[0]["query"].append(srp) - - def dcnm_srp_get_diff_overridden(self): - - """ - Routine to build payload information for overridden state. This routine will build delete list, - merge list, replace list etc. based on what is required and what is already existing on the DCNM server. - This routine updates self.diff_merge that contains all route peerings that are to be created afresh and - self.diff_dlete that contains all route peerings that are to be deleted. - - Parameters: - None - - Returns: - None - """ - - # There are 3 cases with overridden state: - # 1. Peering Name and Service Node Name are given - # 2. Only Service Node Name is given - # 3. Neither given - - if self.srp_info == []: - # In this case we need to get all service nodes and all route peerings from those nodes and delete them - serv_nodes = self.dcnm_srp_get_service_nodes_from_dcnm() - else: - serv_nodes = [{"name": d["node_name"]} for d in self.srp_info] - - srp_list = [] - # From each of the service nodes get the list of all route peerings. - for snode in serv_nodes: - srps = self.dcnm_srp_get_srp_info_with_service_node(snode["name"]) - srp_list.extend(srps) - - # Before we add a route peering to self.diff_delete, make sure a matching route peering - # is not included in the current self.want. If it is, then we need not delete the same. We can just update - # the same - - delete_srps = [] - - for srp in srp_list: - match_want = [ - want - for want in self.want - if ( - (srp["peeringName"] == want["peeringName"]) - and (srp["fabricName"] == want["fabricName"]) - and (srp["serviceNodeName"] == want["serviceNodeName"]) - and (srp["attachedFabricName"] == want["attachedFabricName"]) - ) - ] - if match_want == []: - # There is no matching RP in want. The SRP can be deleted - delete_srps.append(srp) - - self.diff_delete.extend(delete_srps) - self.changed_dict[0]["deleted"].extend(delete_srps) - - # Now go and handle SRPs in self.want - self.dcnm_srp_get_diff_merge() - - def dcnm_srp_create_srp(self, srp, command): - - """ - Routine to send create payload to DCNM. - - Parameters: - srp (dict): Route peering information - command (string): REST API command, either POST or PUT - - Returns: - resp (dict): Response from DCNM server - """ - - if command == "POST": - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings" - ) - else: - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - ) - - json_payload = json.dumps(srp) - - resp = dcnm_send(self.module, command, path, json_payload) - return resp - - def dcnm_srp_detach_srp(self, srp): - - """ - Routine to detach SRP from service node. - - Parameters: - srp (dict): Route peering to be detached - - Returns: - resp (dict): Response from DCNM server - """ - - resp = None - - # First detach the route peerings - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - + "/attachments" - ) - - resp = dcnm_send(self.module, "DELETE", path, "") - return resp - - def dcnm_srp_delete_srp(self, srp): - - """ - Routine to delete an SRP from service node. - - Parameters: - srp (dict): Route peering information that is to be deleted - - Returns: - resp (dict): Response from DCNM server - """ - - # Delete the route peering - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - ) - resp = dcnm_send(self.module, "DELETE", path, "") - return resp - - def dcnm_srp_config_save_and_deploy(self): - - """ - Routine to save and deploy configuration for the entire box. - - Parameters: - None - - Returns: - resp (dict): Response from DCNM server - """ - - path = ( - "/rest/control/fabrics/" + self.module.params["fabric"] + "/config-deploy" - ) - - resp = dcnm_send(self.module, "POST", path, "") - return resp - - def dcnm_srp_deploy_srp(self, srp, command): - - """ - Routine to deploy SRP on the service node. - - Parameters: - srp (dict): Route peering information to be deployed - command (string): REST API command which is POST - - Returns: - resp (dict): Response from DCNM server - """ - - path = ( - "/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/" - + srp["fabricName"] - + "/service-nodes/" - + srp["serviceNodeName"] - + "/peerings/" - + srp["attachedFabricName"] - + "/" - + srp["peeringName"] - + "/deployments" - ) - - resp = dcnm_send(self.module, command, path, "") - return resp - - def dcnm_srp_check_unauthorized_error_in_resp(self, resp): - - """ - Routine to check for "unauthorized" errors in which case the conncetion must be reset by logging out and - logging in again. - - Parameters: - resp (dict): Response which has to be checked for "unauthorized error" - - Returns: - rc (string): unauthorized_error, if resp["DATA"]["error"]["code"] is UserUnauthorized - other_error, otherwise - """ - - rc = "other_error" - if resp.get("DATA"): - if resp["DATA"].get("error"): - if resp["DATA"]["error"].get("code") == "UserUnauthorized": - # We have seen "unauthorized error" from DCNM even though the token has been allocated and the connection timeout - # has not happened. As per suggestions from L4-L7 services team we will reset token by logging out and logging in - # again so that a new token is obtained - dcnm_reset_connection(self.module) - rc = "unauthorized_error" - return rc - - def dcnm_srp_send_message_to_dcnm(self): - - """ - Routine to push payloads to DCNM server. This routine implements reqquired error checks and retry mechanisms to handle - transient errors. This routine checks self.diff_create, self.diff_modify, self.diff_delete and self.diff_deploy lists - and push appropriate requests to DCNM. - - Parameters: - None - - Returns: - None - """ - - resp = None - create_flag = False - modify_flag = False - delete_flag = False - deploy_flag = False - - for srp in self.diff_create: - retries = 0 - command = "POST" - while retries < 10: - retries += 1 - resp = self.dcnm_srp_create_srp(srp, command) - if resp.get("RETURN_CODE") == 200: - create_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - self.dcnm_srp_check_unauthorized_error_in_resp(resp) - - # There may be a temporary issue on the server. so we should try again. In case - # of create or modify, the peering may have been created/updated, but the error may - # be due to the attach. So check if the peering is created and if attach flag is set. - # If so then try attaching the peering and do not try to recreate - get_resp = self.dcnm_srp_get_srp_info_from_dcnm(srp, "PAYLOAD") - if get_resp != []: - # Since the peering is already created, use PUT to update the peering again with - # the same payload - command = "PUT" - time.sleep(10) - continue - resp["RETRIES"] = retries - self.result["response"].append(resp) - - for srp in self.diff_modify: - retries = 0 - while retries < 10: - retries += 1 - resp = self.dcnm_srp_create_srp(srp, "PUT") - if resp.get("RETURN_CODE") == 200: - modify_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - resp["RETRIES"] = retries - self.result["response"].append(resp) - - for srp in self.diff_delete: - retries = 0 - while retries < 10: - retries += 1 - resp = self.dcnm_srp_detach_srp(srp) - if (resp is not None) and (resp.get("RETURN_CODE") == 200): - delete_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - if resp is not None: - resp["RETRIES"] = retries - self.result["response"].append(resp) - - # For delete case we have done a detach. do a deploy before actual delete - for srp in self.diff_delete: - retries = 0 - while retries < 10: - retries += 1 - resp = self.dcnm_srp_deploy_srp(srp, "POST") - - if (resp is not None) and (resp.get("RETURN_CODE") == 200): - delete_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - resp["RETRIES"] = retries - self.result["response"].append(resp) - - if delete_flag is True: - time.sleep(40) - - for srp in self.diff_delete: - retries = 0 - deploy_in_prog = False - while retries < 25: - retries += 1 - resp = self.dcnm_srp_delete_srp(srp) - if (resp is not None) and (resp.get("RETURN_CODE") == 200): - delete_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - self.dcnm_srp_check_unauthorized_error_in_resp(resp) - - if retries == 15: - # We failed to delete even after all retries. Try a config save and deploy which - # may pull out of the situation - - resp = self.dcnm_srp_config_save_and_deploy() - self.result["response"].append(resp) - elif deploy_in_prog is False: - # We will require a deploy here. Otherwise we may see delete errors in some cases - # indicating that a deploy operation is still in progress and peering cannot be deleted - resp = self.dcnm_srp_deploy_srp(srp, "POST") - if resp.get("RETURN_CODE") == 200: - deploy_in_prog = True - else: - self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - if resp is not None: - resp["RETRIES"] = retries - self.result["response"].append(resp) - - for srp in self.diff_deploy: - retries = 0 - while retries < 10: - retries += 1 - resp = self.dcnm_srp_deploy_srp(srp, "POST") - if resp.get("RETURN_CODE") == 200: - deploy_flag = True - break - else: - # We sometimes see "UserUnauthorized" errors while transacting with DCNM server. Suggested remedy is to - # logout and login again. We will do the logout from here and expect the login to happen again after this - # from the connection module - self.dcnm_srp_check_unauthorized_error_in_resp(resp) - time.sleep(10) - continue - resp["RETRIES"] = retries - self.result["response"].append(resp) - - self.result["changed"] = ( - create_flag or modify_flag or delete_flag or deploy_flag - ) - - -def main(): - - """ main entry point for module execution - """ - element_spec = dict( - fabric=dict(required=True, type="str"), - service_fabric=dict(required=True, type="str"), - config=dict(required=False, type="list"), - state=dict( - type="str", - default="merged", - choices=["merged", "deleted", "replaced", "query", "overridden"], - ), - deploy=dict(required=False, type="bool", default=True), - attach=dict(required=False, type="str", default="default"), - check_mode=dict(required=False, type="bool", default=False), - debug=dict(required=False, type="bool", default=False), - ) - - module = AnsibleModule(argument_spec=element_spec, supports_check_mode=True) - - dcnm_srp = DcnmServiceRoutePeering(module) - - dcnm_srp.result["StartTime"] = datetime.now().strftime("%H:%M:%S") - - dcnm_srp.deploy = module.params["deploy"] - if (module.params["attach"] == "default") or ( - module.params["attach"].lower() == "true" - ): - dcnm_srp.attach = True - else: - dcnm_srp.attach = False - - dcnm_srp.debug = module.params["debug"] - - state = module.params["state"] - - if not dcnm_srp.config: - if state == "merged" or state == "deleted" or state == "query": - module.fail_json( - msg="'config' element is mandatory for state '{}', given = '{}'".format( - state, dcnm_srp.config - ) - ) - - dcnm_srp.dcnm_srp_validate_input() - - if (module.params["state"] != "query") and (module.params["state"] != "deleted"): - - dcnm_srp.dcnm_srp_get_want() - dcnm_srp.dcnm_srp_get_have() - - # self.want would have defaulted all optional objects not included in playbook. But the way - # these objects are handled is different between 'merged' and 'replaced' states. For 'merged' - # state, objects not included in the playbook must be left as they are and for state 'replaced' - # they must be purged or defaulted. - - dcnm_srp.dcnm_srp_update_want() - - if (module.params["state"] == "merged") or (module.params["state"] == "replaced"): - dcnm_srp.dcnm_srp_get_diff_merge() - - if module.params["state"] == "deleted": - dcnm_srp.dcnm_srp_get_diff_deleted() - - if module.params["state"] == "query": - dcnm_srp.dcnm_srp_get_diff_query() - - if module.params["state"] == "overridden": - dcnm_srp.dcnm_srp_get_diff_overridden() - - dcnm_srp.result["diff"] = dcnm_srp.changed_dict - - if dcnm_srp.diff_create or dcnm_srp.diff_modify or dcnm_srp.diff_delete: - dcnm_srp.result["changed"] = True - - if module.params["check_mode"]: - dcnm_srp.result["changed"] = False - dcnm_srp.result["EndTime"] = datetime.now().strftime("%H:%M:%S") - module.exit_json(**dcnm_srp.result) - - dcnm_srp.dcnm_srp_send_message_to_dcnm() - - dcnm_srp.result["EndTime"] = datetime.now().strftime("%H:%M:%S") - module.exit_json(**dcnm_srp.result) - - -if __name__ == "__main__": - main() diff --git a/tests/integration/targets/dcnm_service_node/defaults/main.yaml b/tests/integration/targets/dcnm_service_node/defaults/main.yaml deleted file mode 100644 index 55a93fc23..000000000 --- a/tests/integration/targets/dcnm_service_node/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/meta/main.yaml b/tests/integration/targets/dcnm_service_node/meta/main.yaml deleted file mode 100644 index 5514b6a40..000000000 --- a/tests/integration/targets/dcnm_service_node/meta/main.yaml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml b/tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml deleted file mode 100644 index 7081e21b6..000000000 --- a/tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: collect dcnm test cases - find: - paths: "{{ role_path }}/tests/dcnm" - patterns: "{{ testcase }}.yaml" - connection: local - register: dcnm_cases - -- set_fact: - test_cases: - files: "{{ dcnm_cases.files }}" - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=httpapi) - include: "{{ test_case_to_run }} ansible_connection=httpapi connection={{ dcnm }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tasks/main.yaml b/tests/integration/targets/dcnm_service_node/tasks/main.yaml deleted file mode 100644 index 78c5fb834..000000000 --- a/tests/integration/targets/dcnm_service_node/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: dcnm.yaml, tags: ['dcnm'] } \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml deleted file mode 100644 index 7066c3c7e..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/deleted.yaml +++ /dev/null @@ -1,344 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: DELETED - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: DELETED - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: DELETED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### DELETED ## -############################################### - -- name: DELETED - Delete Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: DELETED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - Delete Service Node with single switch - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with 2 switches and vPC Interface - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - Delete Service Node - WITHOUT ANY CONFIG ELEMENT - cisco.dcnm.dcnm_service_node: &conf2 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - conf2 - Idempotence - cisco.dcnm.dcnm_service_node: *conf2 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -- name: DELETED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: DELETED - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - Delete Service Node - WITHOUT ANY CONFIG ELEMENT - cisco.dcnm.dcnm_service_node: &conf3 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: DELETED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: DELETED - conf3 - Idempotence - cisco.dcnm.dcnm_service_node: *conf3 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - - 'result.diff|length == 0' - -################################################ -#### CLEAN-UP ## -################################################ - -- name: DELETED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml deleted file mode 100644 index 8ac75ef5f..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/merged.yaml +++ /dev/null @@ -1,768 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: MERGED - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: MERGED - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -############################################### -### MERGED ## -############################################### - -- name: MERGED - Create Service Node with form factor virtual - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with form factor physical - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with type load balancer - cisco.dcnm.dcnm_service_node: &conf2 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: load_balancer - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "ADC"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf2 - Idempotence - cisco.dcnm.dcnm_service_node: *conf2 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with type virtual network function - cisco.dcnm.dcnm_service_node: &conf3 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf3 - Idempotence - cisco.dcnm.dcnm_service_node: *conf3 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with check mode set to true - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - check_mode: true - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - '(result["response"] | length) == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: MERGED - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: &conf4 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf4 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 2 switches and vPC Interface with type load balancer - cisco.dcnm.dcnm_service_node: &conf5 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: load_balancer - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "ADC"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf5 - Idempotence - cisco.dcnm.dcnm_service_node: *conf5 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 2 switches and vPC Interface with type virtual network function - cisco.dcnm.dcnm_service_node: &conf6 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf6 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with default state 'merged'/ without providing state explicitily - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 3 tasks having 3 different types of type and single form factor virtual - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-13 - type: load_balancer - form_factor: virtual - svc_int_name: svc3 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Virtual"' - - 'result.response[1].DATA.interfaceName == "svc2"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "Firewall"' - - 'result.response[1].DATA.name == "SN-12"' - - 'result.response[2].RETURN_CODE == 200' - - 'result.response[2].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[2].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[2].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[2].DATA.formFactor == "Virtual"' - - 'result.response[2].DATA.interfaceName == "svc3"' - - 'result.response[2].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[2].DATA.type == "ADC"' - - 'result.response[2].DATA.name == "SN-13"' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 3 tasks having 3 different types of type and form factor physical - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-12 - type: firewall - form_factor: physical - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - - name: SN-13 - type: load_balancer - form_factor: physical - svc_int_name: svc3 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Physical"' - - 'result.response[1].DATA.interfaceName == "svc2"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "Firewall"' - - 'result.response[1].DATA.name == "SN-12"' - - 'result.response[2].RETURN_CODE == 200' - - 'result.response[2].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[2].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[2].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[2].DATA.formFactor == "Physical"' - - 'result.response[2].DATA.interfaceName == "svc3"' - - 'result.response[2].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[2].DATA.type == "ADC"' - - 'result.response[2].DATA.name == "SN-13"' - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: MERGED - Create Service Node with 2 switches and invalid vpc interface - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc2 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -- name: MERGED - Create Service Node with 2 switches and invalid vpc name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPortchannel12 - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"if two switches are provided, vpc is only interface option" in result.msg' - -- name: MERGED - Create Service Node with 1 switch and valid vpc name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"For 1 switch, vpc is not the interface option" in result.msg' - -- name: MERGED - Create Service Node with more than 2 switch and valid vpc name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch1 }}" - - "{{ ansible_switch2 }}" - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Upto 2 switches only allowed" in result.msg' - -- name: MERGED - Create Service Node without required parameter - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Required parameter not found" in result.msg' - -- name: MERGED - Create Service Node with wrong type - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: karth - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Invalid choice provided" in result.msg' - -- name: MERGED - Create Service Node with wrong formfactor - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: not - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - - '"Invalid choice provided" in result.msg' - -############################################### -### CLEAN-UP ## -############################################### - -- name: MERGED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml deleted file mode 100644 index e28ea2877..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/overridden.yaml +++ /dev/null @@ -1,281 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: OVERRIDDEN - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: OVERRIDDEN - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: OVERRIDDEN - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: OVERRIDDEN - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: OVERRIDDEN - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### OVERRIDDEN ## -############################################### - -- name: OVERRIDDEN - Update service node - delete and create - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: overridden - config: - - name: SN-12 - type: load_balancer - form_factor: physical - svc_int_name: svc12 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].METHOD == "DELETE"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Physical"' - - 'result.response[1].DATA.interfaceName == "svc12"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "ADC"' - - 'result.response[1].DATA.name == "SN-12"' - -- name: OVERRIDDEN - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: OVERRIDDEN - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: OVERRIDDEN - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: OVERRIDDEN - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: OVERRIDDEN - Create 2 Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc11 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: SN-12 - type: load_balancer - form_factor: virtual - svc_int_name: svc12 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch2 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc11"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Virtual"' - - 'result.response[1].DATA.interfaceName == "svc12"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "ADC"' - - 'result.response[1].DATA.name == "SN-12"' - -- name: OVERRIDDEN - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: OVERRIDDEN - Create and Delete new service nodes - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: overridden - config: - - name: SN-13 - type: virtual_network_function - form_factor: virtual - svc_int_name: svc13 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: SN-14 - type: firewall - form_factor: virtual - svc_int_name: svc14 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch2 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].METHOD == "DELETE"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].METHOD == "DELETE"' - - 'result.response[2].RETURN_CODE == 200' - - 'result.response[2].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[2].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[2].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[2].DATA.formFactor == "Virtual"' - - 'result.response[2].DATA.interfaceName == "svc13"' - - 'result.response[2].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[2].DATA.type == "VNF"' - - 'result.response[2].DATA.name == "SN-13"' - - 'result.response[3].RETURN_CODE == 200' - - 'result.response[3].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[3].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[3].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[3].DATA.formFactor == "Virtual"' - - 'result.response[3].DATA.interfaceName == "svc14"' - - 'result.response[3].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[3].DATA.type == "Firewall"' - - 'result.response[3].DATA.name == "SN-14"' - -- name: OVERRIDDEN - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: OVERRIDDEN - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: OVERRIDDEN - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -############################################## -## CLEAN-UP ## -############################################## - -- name: OVERRIDDEN - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml deleted file mode 100644 index 756b3d973..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/query.yaml +++ /dev/null @@ -1,396 +0,0 @@ -############################################## -## SETUP ## -############################################## -- -- name: QUERY - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: QUERY - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: QUERY - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: QUERY - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### QUERY ## -############################################### - -- name: QUERY - Query the Service Node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].MESSAGE == ""' - -- name: QUERY - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: QUERY - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query the - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query without the config element - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: QUERY - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: QUERY - Create Service Node with single/mutiple switch - 2 tasks - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - - 'result.response[1].RETURN_CODE == 200' - - 'result.response[1].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].DATA.formFactor == "Virtual"' - - 'result.response[1].DATA.interfaceName == "svc2"' - - 'result.response[1].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[1].DATA.type == "Firewall"' - - 'result.response[1].DATA.name == "SN-12"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query the - Create Service Node with single/mutiple switch - 2 tasks - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - "{{ ansible_switch1 }}" - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc2 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - - 'result.response[1].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].formFactor == "Virtual"' - - 'result.response[1].interfaceName == "svc2"' - - 'result.response[1].linkTemplateName == "service_link_trunk"' - - 'result.response[1].type == "Firewall"' - - 'result.response[1].name == "SN-12"' - -- name: QUERY - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: QUERY - Query without the config element - 2 tasks - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - -- assert: - that: - - 'result.changed == false' - - 'result.response[0].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].formFactor == "Virtual"' - - 'result.response[0].interfaceName == "svc1"' - - 'result.response[0].linkTemplateName == "service_link_trunk"' - - 'result.response[0].type == "Firewall"' - - 'result.response[0].name == "SN-11"' - - 'result.response[1].attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[1].attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[1].fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[1].formFactor == "Virtual"' - - 'result.response[1].interfaceName == "svc2"' - - 'result.response[1].linkTemplateName == "service_link_trunk"' - - 'result.response[1].type == "Firewall"' - - 'result.response[1].name == "SN-12"' - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: QUERY - Query the non available Service Node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - config: - - name: SN-11111111 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'result.changed == false' - - 'result.response|length == 0' - -############################################### -### CLEAN-UP ## -############################################### - -- name: QUERY - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml b/tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml deleted file mode 100644 index 8f2f95ff6..000000000 --- a/tests/integration/targets/dcnm_service_node/tests/dcnm/replaced.yaml +++ /dev/null @@ -1,421 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: REPLACED - Verify if fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_it_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: REPLACED - Verify if service fabric is deployed. - cisco.dcnm.dcnm_rest: - method: GET - path: /rest/control/fabrics/{{ ansible_ext_fabric }} - register: result - -- assert: - that: - - 'result.response.DATA != None' - -- name: REPLACED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: REPLACED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: REPLACED - Create Service Node with 2 switches and vPC Interface with type firewall - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -############################################### -### REPLACED ## -############################################### - -- name: REPLACED - Replace Service Node with form factor physical - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: REPLACED - conf - Idempotence - cisco.dcnm.dcnm_service_node: *conf - register: result - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with form factor virtual - cisco.dcnm.dcnm_service_node: &conf1 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_vpc1 }}" - switches: - - "{{ ansible_switch4 }}" - - "{{ ansible_switch5 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_vpc1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: REPLACED - conf1 - Idempotence - cisco.dcnm.dcnm_service_node: *conf1 - register: result - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted - -- name: REPLACED - Query fabric state before proceeding - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: query - register: result - - until: - - 'result.response|length == 0' - retries: 10 - delay: 5 - -- name: REPLACED - Create Service Node with single switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Virtual"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with form factor physical - cisco.dcnm.dcnm_service_node: &conf2 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - conf2 - Idempotence - cisco.dcnm.dcnm_service_node: *conf2 - register: result - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with type load balancer - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: load_balancer - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "ADC"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with type virtual network function - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: virtual_network_function - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc1"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "VNF"' - - 'result.response[0].DATA.name == "SN-11"' - -- name: REPLACED - sleep for 20 seconds for DCNM to completely update the state - wait_for: - timeout: 20 - -- name: REPLACED - Replace Service Node with a new creation of service node, since the sn is not created already - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11111111111 - type: firewall - form_factor: physical - svc_int_name: svc11 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == true' - - 'result.response[0].RETURN_CODE == 200' - - 'result.response[0].DATA.attachedFabricName == "{{ ansible_it_fabric }}"' - - 'result.response[0].DATA.attachedSwitchInterfaceName == "{{ ansible_int1 }}"' - - 'result.response[0].DATA.fabricName == "{{ ansible_ext_fabric }}"' - - 'result.response[0].DATA.formFactor == "Physical"' - - 'result.response[0].DATA.interfaceName == "svc11"' - - 'result.response[0].DATA.linkTemplateName == "service_link_trunk"' - - 'result.response[0].DATA.type == "Firewall"' - - 'result.response[0].DATA.name == "SN-11111111111"' - -- name: REPLACED - Replace Service Node with not supported change of already created svc int name - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc111111111 - attach_interface: "{{ ansible_int1 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - Replace Service Node with not supported change of already created attach interface - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc11 - attach_interface: "{{ ansible_int2 }}" - switches: - - "{{ ansible_switch4 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -- name: REPLACED - Replace Service Node with not supported change of already created attached switch - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: replaced - config: - - name: SN-11 - type: firewall - form_factor: physical - svc_int_name: svc11 - attach_interface: "{{ ansible_int2 }}" - switches: - - "{{ ansible_switch5 }}" - register: result - ignore_errors: yes - -- assert: - that: - - 'result.changed == false' - -############################################### -### CLEAN-UP ## -############################################### - -- name: REPLACED - Clean up any existing service node - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_ext_fabric }}" - state: deleted \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_route_peering/defaults/main.yaml b/tests/integration/targets/dcnm_service_route_peering/defaults/main.yaml deleted file mode 100644 index 5f709c5aa..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/defaults/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -testcase: "*" diff --git a/tests/integration/targets/dcnm_service_route_peering/meta/main.yaml b/tests/integration/targets/dcnm_service_route_peering/meta/main.yaml deleted file mode 100644 index f280ef854..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/meta/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - prepare_dcnm_service_route_peering diff --git a/tests/integration/targets/dcnm_service_route_peering/tasks/dcnm.yaml b/tests/integration/targets/dcnm_service_route_peering/tasks/dcnm.yaml deleted file mode 100644 index e54dbdf26..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/tasks/dcnm.yaml +++ /dev/null @@ -1,105 +0,0 @@ ---- -- name: collect dcnm test cases - find: - paths: "{{ role_path }}/tests/dcnm" - patterns: "{{ testcase }}.yaml" - connection: local - register: dcnm_cases - -- set_fact: - test_cases: - files: "{{ dcnm_cases.files }}" - -- name: set test_items - set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" - -- name: run test cases (connection=httpapi) - include: "{{ test_case_to_run }}" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - -- name: Cleanup - Delete Service Nodes - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - state: deleted - config: - - name: "{{ ansible_snode_1 }}" - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_att_intf1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: "{{ ansible_snode_2 }}" - type: load_balancer - form_factor: physical - svc_int_name: svc2 - attach_interface: "{{ ansible_att_intf2 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -- name: Cleanup - sleep for 40 seconds for DCNM to completely update the state - wait_for: - timeout: 40 - -- name: Cleanup - Delete all VRFs - cisco.dcnm.dcnm_vrf: - fabric: "{{ ansible_it_fabric }}" - state: deleted - config: - - vrf_name: "{{ ansible_vrf_11 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_12 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_21 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_22 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_31 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_32 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_41 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_42 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_51 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_52 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_61 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_62 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_71 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_72 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' diff --git a/tests/integration/targets/dcnm_service_route_peering/tasks/main.yaml b/tests/integration/targets/dcnm_service_route_peering/tasks/main.yaml deleted file mode 100644 index 78c5fb834..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- { include: dcnm.yaml, tags: ['dcnm'] } \ No newline at end of file diff --git a/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/.dcnm_service_route_peering_delete.yaml.swp b/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/.dcnm_service_route_peering_delete.yaml.swp deleted file mode 100644 index 59ebb23a019fbc4a1b2c2077ceee9a2e0706f337..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI3OKjXk7{>?t;MG!~oRDaz2_h|uch{RoTT2yclQasjNl8;)QM7UF*^L{oZESBI zw4tZMrIkRv^#Xze^opQWIUsKI%BvKP2sogY18_m2g}+~0@5WAcQzaZ2OTV=}kI$dK znfW~5WHOa|VW>d&WpV_^Lxc>STbvwzX3K_;G(swss;ZSu!^>LkC=`zM4-JkC3k6{` zx34?3=tfsJ{ZB|`Yv>3BBqa0T9>!+70s!V4t%PhzhJ=G*UgIi!7 zEwGhz9gZ6Y?&22b=*5U>+Di1y6&WUtlKfnq;Es+ZQfGD9C>nBwNz}GP!7)T3656N$rIFMI zeG|lL)@*OFJSWk7E+@j6rHt8XzddxXtetU2}Mz)i;Gc1 z*GWu!q^O zQo2U-BSgctqND-RLZ?d@BB9g-l~WXMW{8MuGepo-cQ8ciI|8M#G16T7H8(~AgQgFW zwI3sa2F(ui+lG#4*dyN->KPO40s*q-Jb7;mWA z8MyY_q9*DdYT#+1_l|oB$4^gk6S0TJ1PL_oSVLpN;THw((sB zt|U*{no{q{G`F@XFUa^Pohr-8~kjmh|P)qQ=*sd zvzhENs%oVYv#}MC8m1wzdChULMUaNCKz(sE+&JiflmR$*wWe1kQ6(rlN3}Z3OO9IJAqSSF=R0*>h zZ||h)6$_4Kdu%@G!?v`iMJ>FX8D$l7mcfIf z3VzGf3m)#=*&l_IJrcEK{ke5#@5TQc5esibZ0yDV(cjlEA;!N5D&Psw4t_w4|2B9F z41!yT?QepQ!3;PKc7bb%?Y{$`gA3q8a2}iiWgvjx5$j(Bi=Yo20^Q(Aa1-(T_uv{h z4XQu}lb{H);0EIRtKeJk1-J~(ftSG!@FU*m0x*FACc!A!12zHgeK!Dpa0_q?a0_q? za0~ozEf7p1nu+whl1)T=Ua=tJ3o68-J}<#LAZ2$D_l>uCF?8F+cy0oh{&EO{$CFfN zM%kU-s4SF6lkSWQJNy=WzksjI0Q#;L2RT4DGB?};lb7ZvZkjg5SiA5|0lU)+D8T8aD4C~1f z?aqa1b28R)N~Rqwr$;mIv7j8}I67k%MFCX7dJ19%)$wop`-ThDHNDxlKE3yLpGzIRtL@XSUA?0&oxX15b-!h!-K4dncmN;uU+= 7' - - - name: Query non-existing route peerings - cisco.dcnm.dcnm_service_route_peering: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1-ABS # optional - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP2-ABS # optional - node_name: "{{ ansible_snode_2 }}" # mandatory - state: query - register: result - - - assert: - that: - - 'result.changed == false' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 0' - - '(result["diff"][0]["query"] | length) == 2' - - '(result.response | length) == 0' - -############################################## -## CLEANUP ## -############################################## - - always: - - - - name: Delete all created route peerings - cisco.dcnm.dcnm_service_route_peering: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-ADC-RP4 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP5 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP6 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP7 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - state: deleted - register: result - when: IT_CONTEXT is not defined - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - when: IT_CONTEXT is not defined - diff --git a/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_replace.yaml b/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_replace.yaml deleted file mode 100644 index 898c6ee19..000000000 --- a/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/dcnm_service_route_peering_replace.yaml +++ /dev/null @@ -1,883 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: Remove local log file - local_action: command rm -f srp.log - -- name: Delete route peerings - cisco.dcnm.dcnm_service_route_peering: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-ADC-RP4 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP5 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP6 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP7 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - state: deleted - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - - -- block: - -############################################## -## MERGE ## -############################################## - - - name: Create different non-existing service route peerings including all objects - cisco.dcnm.dcnm_service_route_peering: &dcnm_srp_all - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 101 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2001:db01::1/64 # optional, default is '' - vlan_name: rp1-sn1-inside # optional, default is '' - int_descr: "RP1 SN1 inside interface" # optional, default is '' - tag: 11111 # optional, default is 12345 - next_hop: 192.161.1.100 # mandatory - outside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 102 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2001:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside # optional, default is '' - int_descr: "RP1 SN1 outside interface" # optionL, default is '' - tag: 11112 # optional, default is 12345 - rev_next_hop: 192.161.2.100 # optional, default is '' - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: static # optional, default is static, choices=[static, ebgp] - inside_network: # - vrf: "{{ ansible_vrf_21 }}" # mandatory - name: rp2-sn1-inside-net # mandatory - vlan_id: 201 # mandatory - profile: - ipv4_gw: 192.162.1.1/24 # mandatory - ipv6_gw: 2002:db01::1/64 # optional, default is '' - vlan_name: rp2-sn1-inside # optional, default is '' - int_descr: "RP2 SN1 inside interface" # optional, default is '' - static_route: # optional, default is '' - - subnet: 20.20.20.0/24 - next_hop: - - 120.120.120.100 - - 121.121.121.100 - tag: 21111 # optional, default is 12345 - outside_network: # - vrf: "{{ ansible_vrf_22 }}" # mandatory - name: rp2-sn1-outside-net # mandatory - vlan_id: 202 # mandatory - profile: - ipv4_gw: 192.162.2.1/24 # mandatory - ipv6_gw: 2002:db02::1/64 # optional, default is '' - vlan_name: rp2-sn1-outside # optional, default is '' - int_descr: "RP2 SN1 outside interface" # optional, default is '' - static_route: # optional, default is '' - - subnet: 21.21.21.0/24 - next_hop: - - 122.122.122.100 - - 123.123.123.100 - tag: 22222 # optional, default is 12345 - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - inside_network: - vrf: "{{ ansible_vrf_31 }}" # mandatory - name: rp3-sn1-inside-net # mandatory - vlan_id: 301 # mandatory - profile: - ipv4_gw: 192.163.1.1/24 # mandatory - ipv6_gw: 2003:db01::1/64 # optional, default is '' - vlan_name: rp3-sn1-inside # optional, default is '' - int_descr: "RP3 SN1 inside interface" # optional, default is '' - tag: 31111 # optional, default is 12345 - ipv4_neighbor: 31.31.31.1 # mandatory - ipv4_lo: 31.31.31.2 # mandatory - ipv4_vpc_peer_lo: 31.31.31.3 # optional, default is '' - ipv6_neighbor: 2003:3131::1 # optional, default is '' - ipv6_lo: 2003:3132::1 # optional, default is '' - ipv6_vpc_peer_lo: 2003:3133::1 # optional, default is '' - route_map_tag: 33111 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 inside interface" # optional, default is '' - local_asn: 65301 # optional, default is '' - adv_host: true # optional, default is false - outside_network: - vrf: "{{ ansible_vrf_32 }}" # mandatory - name: rp3-sn1-outside-net # mandatory - vlan_id: 302 # mandatory - profile: - ipv4_gw: 192.163.2.1/24 # mandatory - ipv6_gw: 2003:db02::1/64 # optional, default is '' - vlan_name: rp3-sn1-outside # optional, default is '' - int_descr: "RP3 SN1 outside interface" # optional, default is '' - tag: 31112 # optional, default is 12345 - ipv4_neighbor: 131.131.131.1 # mandatory - ipv4_lo: 131.131.131.2 # mandatory - ipv4_vpc_peer_lo: 131.131.131.3 # optional, default is '' - ipv6_neighbor: 2003:8383::1 # optional, default is '' - ipv6_lo: 2003:8384::1:100:1 # optional, default is '' - ipv6_vpc_peer_lo: 2003:8385::1 # optional, default is '' - route_map_tag: 31113 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 outside interface" # optional, default is '' - local_asn: 65302 # optional, default is '' - adv_host: true # optional, default is false - - - name: IT-ADC-RP4 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_41 }}" # mandatory - name: rp4-sn2-first-arm # mandatory - vlan_id: 401 # mandatory - profile: - ipv4_gw: 192.164.1.1/24 # mandatory - ipv6_gw: 2004:db01::1/64 # optional, default is '' - vlan_name: rp4-sn2-first-arm # optional, default is '' - int_descr: "RP4 SN2 first arm intf" # optional, default is '' - tag: 41111 # optional, default is 12345 - ipv4_neighbor: 41.41.41.1 # mandatory - ipv4_lo: 41.41.41.2 # mandatory - ipv4_vpc_peer_lo: 41.41.41.3 # optional, default is '' - ipv6_neighbor: 2004:4141::1 # optional, default is '' - ipv6_lo: 2004:4142::1 # optional, default is '' - ipv6_vpc_peer_lo: 2004:4143::1 # optional, default is '' - route_map_tag: 41112 # optional, default is 12345 - neigh_int_descr: "RP4 SN2 first arm" # optional, default is '' - local_asn: 65401 # optional, default is '' - adv_host: true # optional, default is false - rev_next_hop: 192.164.1.100 # mandatory - - - name: IT-ADC-RP5 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-first-arm # mandatory - vlan_id: 501 # mandatory - profile: - ipv4_gw: 192.165.1.1/24 # mandatory - ipv6_gw: 2005:db01::1/64 # optional, default is '' - vlan_name: rp5-sn2-first-arm # optional, default is '' - int_descr: "RP5 SN2 first arm intf" # optional, default is '' - tag: 51111 # optional, default is 12345 - ipv4_neighbor: 51.51.51.1 # mandatory - ipv4_lo: 51.51.51.2 # mandatory - ipv4_vpc_peer_lo: 51.51.51.3 # optional, default is '' - ipv6_neighbor: 2005:5151::1 # optional, default is '' - ipv6_lo: 2005:5152::1 # optional, default is '' - ipv6_vpc_peer_lo: 2005:5153::1 # optional, default is '' - route_map_tag: 51115 # optional, default is 12345 - neigh_int_descr: "RP5 SN2 first arm" # optional, default is '' - local_asn: 65501 # optional, default is '' - adv_host: true # optional, default is false - second_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-second-arm # mandatory - vlan_id: 502 # mandatory - profile: - ipv4_gw: 192.165.2.1/24 # mandatory - ipv6_gw: 2005:db02::1/64 # optional, default is '' - vlan_name: rp5-sn2-second-arm # optional, default is '' - int_descr: "RP5 SN2 second arm intf" # optional, default is '' - tag: 51112 # optional, default is 12345 - rev_next_hop: 192.165.1.100 # mandatory - - - name: IT-ADC-RP6 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_61 }}" # mandatory - name: rp6-sn2-first-arm # mandatory - vlan_id: 601 # mandatory - profile: - ipv4_gw: 192.166.1.1/24 # mandatory - ipv6_gw: 2006:db01::1/64 # optional, default is '' - vlan_name: rp6-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 61111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 61.61.61.1/24 - next_hop: - - 161.161.161.1 - - 162.162.162.1 - - subnet: 22.0.0.0/24 - next_hop: - - 163.163.163.1 - - 164.164.164.1 - rev_next_hop: 192.166.1.100 # mandatory - - - name: IT-ADC-RP7 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-first-arm # mandatory - vlan_id: 701 # mandatory - profile: - ipv4_gw: 192.167.1.1/24 # mandatory - ipv6_gw: 2007:db01::1/64 # optional, default is '' - vlan_name: rp7-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 71111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 71.71.71.1/24 - next_hop: - - 171.171.171.1 - - 172.172.172.1 - second_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-second-arm # mandatory - vlan_id: 702 # mandatory - profile: - ipv4_gw: 192.167.2.1/24 # mandatory - ipv6_gw: 2007:db02::1/64 # optional, default is '' - vlan_name: rp7-sn2-second-arm # optional, default is '' - int_descr: "RP7 SN2 second arm intf" # optional, default is '' - tag: 71112 # optional, default is 12345 - rev_next_hop: 192.167.1.100 # mandatory - attach: true - deploy: true - state: replaced - register: result - - - assert: - that: - - 'result.changed == true' - - '(result["diff"][0]["merged"] | length) == 7' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 0' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 7' - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - - - name: Timeout - sleep for 180 seconds for DCNM to completely update the state - wait_for: - timeout: 180 - - -############################################## -## REPLACE RP1-RP3 ## -############################################## - - - name: Replace service route peerings RP1 to RP3 - cisco.dcnm.dcnm_service_route_peering: &dcnm_srp_rep_13 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 191 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2101:db01::01/64 # optional, default is '' - vlan_name: rp1-sn1-inside-rep # optional, default is '' - int_descr: "RP1 SN1 inside interface - REP" # optional, default is '' - tag: 11101 # optional, default is 12345 - next_hop: 192.161.1.200 # mandatory - outside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 192 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2101:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside-rep # optional, default is '' - int_descr: "RP1 SN1 outside interface- REP" # optionL, default is '' - tag: 11102 # optional, default is 12345 - rev_next_hop: 192.161.2.200 # optional, default is '' - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: static # optional, default is static, choices=[static, ebgp] - inside_network: # - vrf: "{{ ansible_vrf_21 }}" # mandatory - name: rp2-sn1-inside-net # mandatory - vlan_id: 291 # mandatory - profile: - ipv4_gw: 192.162.1.1/24 # mandatory - ipv6_gw: 2102:db01::1/64 # optional, default is '' - vlan_name: rp2-sn1-inside-rep # optional, default is '' - int_descr: "RP2 SN1 inside interface - REP" # optional, default is '' - static_route: # optional, default is '' - - subnet: 20.20.90.0/24 - next_hop: - - 120.120.190.100 - - 121.121.191.100 - tag: 21101 # optional, default is 12345 - outside_network: # - vrf: "{{ ansible_vrf_22 }}" # mandatory - name: rp2-sn1-outside-net # mandatory - vlan_id: 292 # mandatory - profile: - ipv4_gw: 192.162.2.1/24 # mandatory - ipv6_gw: 2102:db02::1/64 # optional, default is '' - vlan_name: rp2-sn1-outside-rep # optional, default is '' - int_descr: "RP2 SN1 outside interface - REP" # optional, default is '' - static_route: # optional, default is '' - - subnet: 21.21.29.0/24 - next_hop: - - 122.122.129.100 - - 123.123.129.100 - tag: 22202 # optional, default is 12345 - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - inside_network: - vrf: "{{ ansible_vrf_31 }}" # mandatory - name: rp3-sn1-inside-net # mandatory - vlan_id: 391 # mandatory - profile: - ipv4_gw: 192.163.1.1/24 # mandatory - ipv6_gw: 2103:db01::1/64 # optional, default is '' - vlan_name: rp3-sn1-inside-rep # optional, default is '' - int_descr: "RP3 SN1 inside interface - REP" # optional, default is '' - tag: 31101 # optional, default is 12345 - ipv4_neighbor: 31.31.39.1 # mandatory - ipv4_lo: 31.31.39.2 # mandatory - ipv4_vpc_peer_lo: 31.31.39.3 # optional, default is '' - ipv6_neighbor: 2103:3131::1 # optional, default is '' - ipv6_lo: 2103:3132::1 # optional, default is '' - ipv6_vpc_peer_lo: 2103:3133::1 # optional, default is '' - route_map_tag: 33101 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 inside interface - REP" # optional, default is '' - local_asn: 65391 # optional, default is '' - adv_host: true # optional, default is false - outside_network: - vrf: "{{ ansible_vrf_32 }}" # mandatory - name: rp3-sn1-outside-net # mandatory - vlan_id: 302 # mandatory - profile: - ipv4_gw: 192.163.2.1/24 # mandatory - ipv6_gw: 2103:db02::1/64 # optional, default is '' - vlan_name: rp3-sn1-outside-rep # optional, default is '' - int_descr: "RP3 SN1 outside interface - REP" # optional, default is '' - tag: 31102 # optional, default is 12345 - ipv4_neighbor: 131.131.139.1 # mandatory - ipv4_lo: 131.131.139.2 # mandatory - ipv4_vpc_peer_lo: 131.131.139.3 # optional, default is '' - ipv6_neighbor: 2103:8383::1 # optional, default is '' - ipv6_lo: 2103:8384::1:100:1 # optional, default is '' - ipv6_vpc_peer_lo: 2103:8385::1 # optional, default is '' - route_map_tag: 31103 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 outside interface - REP" # optional, default is '' - local_asn: 65392 # optional, default is '' - adv_host: true # optional, default is false - - - name: IT-ADC-RP4 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_41 }}" # mandatory - name: rp4-sn2-first-arm # mandatory - vlan_id: 401 # mandatory - profile: - ipv4_gw: 192.164.1.1/24 # mandatory - ipv6_gw: 2004:db01::1/64 # optional, default is '' - vlan_name: rp4-sn2-first-arm # optional, default is '' - int_descr: "RP4 SN2 first arm intf" # optional, default is '' - tag: 41111 # optional, default is 12345 - ipv4_neighbor: 41.41.41.1 # mandatory - ipv4_lo: 41.41.41.2 # mandatory - ipv4_vpc_peer_lo: 41.41.41.3 # optional, default is '' - ipv6_neighbor: 2004:4141::1 # optional, default is '' - ipv6_lo: 2004:4142::1 # optional, default is '' - ipv6_vpc_peer_lo: 2004:4143::1 # optional, default is '' - route_map_tag: 41112 # optional, default is 12345 - neigh_int_descr: "RP4 SN2 first arm" # optional, default is '' - local_asn: 65401 # optional, default is '' - adv_host: true # optional, default is false - rev_next_hop: 192.164.1.100 # mandatory - - - name: IT-ADC-RP5 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-first-arm # mandatory - vlan_id: 501 # mandatory - profile: - ipv4_gw: 192.165.1.1/24 # mandatory - ipv6_gw: 2005:db01::1/64 # optional, default is '' - vlan_name: rp5-sn2-first-arm # optional, default is '' - int_descr: "RP5 SN2 first arm intf" # optional, default is '' - tag: 51111 # optional, default is 12345 - ipv4_neighbor: 51.51.51.1 # mandatory - ipv4_lo: 51.51.51.2 # mandatory - ipv4_vpc_peer_lo: 51.51.51.3 # optional, default is '' - ipv6_neighbor: 2005:5151::1 # optional, default is '' - ipv6_lo: 2005:5152::1 # optional, default is '' - ipv6_vpc_peer_lo: 2005:5153::1 # optional, default is '' - route_map_tag: 51115 # optional, default is 12345 - neigh_int_descr: "RP5 SN2 first arm" # optional, default is '' - local_asn: 65501 # optional, default is '' - adv_host: true # optional, default is false - second_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-second-arm # mandatory - vlan_id: 502 # mandatory - profile: - ipv4_gw: 192.165.2.1/24 # mandatory - ipv6_gw: 2005:db02::1/64 # optional, default is '' - vlan_name: rp5-sn2-second-arm # optional, default is '' - int_descr: "RP5 SN2 second arm intf" # optional, default is '' - tag: 51112 # optional, default is 12345 - rev_next_hop: 192.165.1.100 # mandatory - - - name: IT-ADC-RP6 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_61 }}" # mandatory - name: rp6-sn2-first-arm # mandatory - vlan_id: 601 # mandatory - profile: - ipv4_gw: 192.166.1.1/24 # mandatory - ipv6_gw: 2006:db01::1/64 # optional, default is '' - vlan_name: rp6-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 61111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 61.61.61.1/24 - next_hop: - - 161.161.161.1 - - 162.162.162.1 - - subnet: 22.0.0.0/24 - next_hop: - - 163.163.163.1 - - 164.164.164.1 - rev_next_hop: 192.166.1.100 # mandatory - - - name: IT-ADC-RP7 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-first-arm # mandatory - vlan_id: 701 # mandatory - profile: - ipv4_gw: 192.167.1.1/24 # mandatory - ipv6_gw: 2007:db01::1/64 # optional, default is '' - vlan_name: rp7-sn2-first-arm # optional, default is '' - int_descr: "RP6 SN2 first arm intf" # optional, default is '' - tag: 71111 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 71.71.71.1/24 - next_hop: - - 171.171.171.1 - - 172.172.172.1 - second_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-second-arm # mandatory - vlan_id: 702 # mandatory - profile: - ipv4_gw: 192.167.2.1/24 # mandatory - ipv6_gw: 2007:db02::1/64 # optional, default is '' - vlan_name: rp7-sn2-second-arm # optional, default is '' - int_descr: "RP7 SN2 second arm intf" # optional, default is '' - tag: 71112 # optional, default is 12345 - rev_next_hop: 192.167.1.100 # mandatory - attach: true - deploy: true - state: replaced - register: result - - - assert: - that: - - 'result.changed == true' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 3' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 3' - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - - - name: Timeout - sleep for 240 seconds for DCNM to completely update the state - wait_for: - timeout: 240 - - - - name: Replace service route peerings RP1 to RP3 - Idempotence - cisco.dcnm.dcnm_service_route_peering: *dcnm_srp_rep_13 - register: result - - - assert: - that: - - 'result.changed == false' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 0' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 0' - - -############################################## -## REPLACE RP4-RP7 ## -############################################## - - - name: Replace service route peerings RP4 to RP7 - cisco.dcnm.dcnm_service_route_peering: &dcnm_srp_rep_47 - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: intra_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - inside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-inside-net # mandatory - vlan_id: 191 # mandatory - profile: - ipv4_gw: 192.161.1.1/24 # mandatory - ipv6_gw: 2101:db01::01/64 # optional, default is '' - vlan_name: rp1-sn1-inside-rep # optional, default is '' - int_descr: "RP1 SN1 inside interface - REP" # optional, default is '' - tag: 11101 # optional, default is 12345 - next_hop: 192.161.1.200 # mandatory - outside_network: # - vrf: "{{ ansible_vrf_11 }}" # mandatory - name: rp1-sn1-outside-net # mandatory - vlan_id: 192 # mandatory - profile: - ipv4_gw: 192.161.2.1/24 # mandatory - ipv6_gw: 2101:db02::1/64 # optional, default is '' - vlan_name: rp1-sn1-outside-rep # optional, default is '' - int_descr: "RP1 SN1 outside interface- REP" # optionL, default is '' - tag: 11102 # optional, default is 12345 - rev_next_hop: 192.161.2.200 # optional, default is '' - - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: static # optional, default is static, choices=[static, ebgp] - inside_network: # - vrf: "{{ ansible_vrf_21 }}" # mandatory - name: rp2-sn1-inside-net # mandatory - vlan_id: 291 # mandatory - profile: - ipv4_gw: 192.162.1.1/24 # mandatory - ipv6_gw: 2102:db01::1/64 # optional, default is '' - vlan_name: rp2-sn1-inside-rep # optional, default is '' - int_descr: "RP2 SN1 inside interface - REP" # optional, default is '' - static_route: # optional, default is '' - - subnet: 20.20.90.0/24 - next_hop: - - 120.120.190.100 - - 121.121.191.100 - tag: 21101 # optional, default is 12345 - outside_network: # - vrf: "{{ ansible_vrf_22 }}" # mandatory - name: rp2-sn1-outside-net # mandatory - vlan_id: 292 # mandatory - profile: - ipv4_gw: 192.162.2.1/24 # mandatory - ipv6_gw: 2102:db02::1/64 # optional, default is '' - vlan_name: rp2-sn1-outside-rep # optional, default is '' - int_descr: "RP2 SN1 outside interface - REP" # optional, default is '' - static_route: # optional, default is '' - - subnet: 21.21.29.0/24 - next_hop: - - 122.122.129.100 - - 123.123.129.100 - tag: 22202 # optional, default is 12345 - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - deploy_mode: inter_tenant_fw # mandatory, choices=[intra_tenant_fw, inter_tenant_fw] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - inside_network: - vrf: "{{ ansible_vrf_31 }}" # mandatory - name: rp3-sn1-inside-net # mandatory - vlan_id: 391 # mandatory - profile: - ipv4_gw: 192.163.1.1/24 # mandatory - ipv6_gw: 2103:db01::1/64 # optional, default is '' - vlan_name: rp3-sn1-inside-rep # optional, default is '' - int_descr: "RP3 SN1 inside interface - REP" # optional, default is '' - tag: 31101 # optional, default is 12345 - ipv4_neighbor: 31.31.39.1 # mandatory - ipv4_lo: 31.31.39.2 # mandatory - ipv4_vpc_peer_lo: 31.31.39.3 # optional, default is '' - ipv6_neighbor: 2103:3131::1 # optional, default is '' - ipv6_lo: 2103:3132::1 # optional, default is '' - ipv6_vpc_peer_lo: 2103:3133::1 # optional, default is '' - route_map_tag: 33101 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 inside interface - REP" # optional, default is '' - local_asn: 65391 # optional, default is '' - adv_host: true # optional, default is false - outside_network: - vrf: "{{ ansible_vrf_32 }}" # mandatory - name: rp3-sn1-outside-net # mandatory - vlan_id: 302 # mandatory - profile: - ipv4_gw: 192.163.2.1/24 # mandatory - ipv6_gw: 2103:db02::1/64 # optional, default is '' - vlan_name: rp3-sn1-outside-rep # optional, default is '' - int_descr: "RP3 SN1 outside interface - REP" # optional, default is '' - tag: 31102 # optional, default is 12345 - ipv4_neighbor: 131.131.139.1 # mandatory - ipv4_lo: 131.131.139.2 # mandatory - ipv4_vpc_peer_lo: 131.131.139.3 # optional, default is '' - ipv6_neighbor: 2103:8383::1 # optional, default is '' - ipv6_lo: 2103:8384::1:100:1 # optional, default is '' - ipv6_vpc_peer_lo: 2103:8385::1 # optional, default is '' - route_map_tag: 31103 # optional, default is 12345 - neigh_int_descr: "RP3 SN1 outside interface - REP" # optional, default is '' - local_asn: 65392 # optional, default is '' - adv_host: true # optional, default is false - - - name: IT-ADC-RP4 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_41 }}" # mandatory - name: rp4-sn2-first-arm # mandatory - vlan_id: 491 # mandatory - profile: - ipv4_gw: 192.164.1.1/24 # mandatory - ipv6_gw: 2104:db01::1/64 # optional, default is '' - vlan_name: rp4-sn2-first-arm-rep # optional, default is '' - int_descr: "RP4 SN2 first arm intf - REP" # optional, default is '' - tag: 41101 # optional, default is 12345 - ipv4_neighbor: 41.41.49.1 # mandatory - ipv4_lo: 41.41.49.2 # mandatory - ipv4_vpc_peer_lo: 41.41.49.3 # optional, default is '' - ipv6_neighbor: 2104:4141::1 # optional, default is '' - ipv6_lo: 2104:4142::1 # optional, default is '' - ipv6_vpc_peer_lo: 2104:4143::1 # optional, default is '' - route_map_tag: 41102 # optional, default is 12345 - neigh_int_descr: "RP4 SN2 first arm - REP" # optional, default is '' - local_asn: 65491 # optional, default is '' - adv_host: true # optional, default is false - rev_next_hop: 192.164.1.200 # mandatory - - - name: IT-ADC-RP5 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: ebgp # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-first-arm # mandatory - vlan_id: 591 # mandatory - profile: - ipv4_gw: 192.165.1.1/24 # mandatory - ipv6_gw: 2105:db01::1/64 # optional, default is '' - vlan_name: rp5-sn2-first-arm-rep # optional, default is '' - int_descr: "RP5 SN2 first arm intf - REP" # optional, default is '' - tag: 51101 # optional, default is 12345 - ipv4_neighbor: 51.51.59.1 # mandatory - ipv4_lo: 51.51.59.2 # mandatory - ipv4_vpc_peer_lo: 51.51.51.3 # optional, default is '' - ipv6_neighbor: 2105:5151::1 # optional, default is '' - ipv6_lo: 2105:5152::1 # optional, default is '' - ipv6_vpc_peer_lo: 2105:5153::1 # optional, default is '' - route_map_tag: 51105 # optional, default is 12345 - neigh_int_descr: "RP5 SN2 first arm - REP" # optional, default is '' - local_asn: 65591 # optional, default is '' - adv_host: true # optional, default is false - second_arm: - vrf: "{{ ansible_vrf_51 }}" # mandatory - name: rp5-sn2-second-arm # mandatory - vlan_id: 592 # mandatory - profile: - ipv4_gw: 192.165.2.1/24 # mandatory - ipv6_gw: 2105:db02::1/64 # optional, default is '' - vlan_name: rp5-sn2-second-arm-rep # optional, default is '' - int_descr: "RP5 SN2 second arm intf - REP" # optional, default is '' - tag: 51102 # optional, default is 12345 - rev_next_hop: 192.165.1.200 # mandatory - - - name: IT-ADC-RP6 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: one_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_61 }}" # mandatory - name: rp6-sn2-first-arm # mandatory - vlan_id: 691 # mandatory - profile: - ipv4_gw: 192.166.1.1/24 # mandatory - ipv6_gw: 2106:db01::1/64 # optional, default is '' - vlan_name: rp6-sn2-first-arm-rep # optional, default is '' - int_descr: "RP6 SN2 first arm intf - REP" # optional, default is '' - tag: 61101 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 61.61.69.1/24 - next_hop: - - 161.161.169.1 - - 162.162.169.1 - - subnet: 29.0.0.0/24 - next_hop: - - 163.163.169.1 - - 164.164.169.1 - rev_next_hop: 192.166.1.200 # mandatory - - - name: IT-ADC-RP7 - node_name: "{{ ansible_snode_2 }}" # mandatory - deploy_mode: two_arm_adc # mandatory, choices=[one_arm_adc, two_arm_adc] - peering_option: static # optional, default is static, choices=[static, ebgp] - first_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-first-arm # mandatory - vlan_id: 791 # mandatory - profile: - ipv4_gw: 192.167.1.1/24 # mandatory - ipv6_gw: 2107:db01::1/64 # optional, default is '' - vlan_name: rp7-sn2-first-arm-rep # optional, default is '' - int_descr: "RP6 SN2 first arm intf - REP" # optional, default is '' - tag: 71101 # optional, default is 12345 - static_route: # optional, default is '' - - subnet: 71.71.79.1/24 - next_hop: - - 171.171.179.1 - - 172.172.179.1 - second_arm: - vrf: "{{ ansible_vrf_71 }}" # mandatory - name: rp7-sn2-second-arm # mandatory - vlan_id: 792 # mandatory - profile: - ipv4_gw: 192.167.2.1/24 # mandatory - ipv6_gw: 2107:db02::1/64 # optional, default is '' - vlan_name: rp7-sn2-second-arm-rep # optional, default is '' - int_descr: "RP7 SN2 second arm intf - REP" # optional, default is '' - tag: 71102 # optional, default is 12345 - rev_next_hop: 192.167.1.200 # mandatory - attach: true - deploy: true - state: replaced - register: result - - - assert: - that: - - 'result.changed == true' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 4' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 4' - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - - - name: Timeout - sleep for 240 seconds for DCNM to completely update the state - wait_for: - timeout: 240 - - - - name: Replace service route peerings RP4 to RP7 - Idempotence - cisco.dcnm.dcnm_service_route_peering: *dcnm_srp_rep_47 - register: result - - - assert: - that: - - 'result.changed == false' - - '(result["diff"][0]["merged"] | length) == 0' - - '(result["diff"][0]["deleted"] | length) == 0' - - '(result["diff"][0]["modified"] | length) == 0' - - '(result["diff"][0]["query"] | length) == 0' - - '(result["diff"][0]["deploy"] | length) == 0' - -############################################## -## CLEANUP ## -############################################## - - always: - - - - name: Delete all created route peerings - cisco.dcnm.dcnm_service_route_peering: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - config: - - name: IT-FW-RP1 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP2 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-FW-RP3 # mandatory - node_name: "{{ ansible_snode_1 }}" # mandatory - - - name: IT-ADC-RP4 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP5 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP6 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - - name: IT-ADC-RP7 # mandatory - node_name: "{{ ansible_snode_2 }}" # mandatory - - state: deleted - register: result - when: IT_CONTEXT is not defined - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - when: IT_CONTEXT is not defined - diff --git a/tests/integration/targets/prepare_dcnm_service_route_peering/tasks/main.yaml b/tests/integration/targets/prepare_dcnm_service_route_peering/tasks/main.yaml deleted file mode 100644 index e430965fd..000000000 --- a/tests/integration/targets/prepare_dcnm_service_route_peering/tasks/main.yaml +++ /dev/null @@ -1,184 +0,0 @@ -############################################## -## SETUP ## -############################################## - -- name: Initialize the setup - Delete Service Nodes - cisco.dcnm.dcnm_service_node: &conf - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - state: deleted - config: - - name: "{{ ansible_snode_1 }}" - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_att_intf1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: "{{ ansible_snode_2 }}" - type: load_balancer - form_factor: physical - svc_int_name: svc2 - attach_interface: "{{ ansible_att_intf2 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -- name: Initialize the setup - Delete VRFs - cisco.dcnm.dcnm_vrf: - fabric: "{{ ansible_it_fabric }}" - state: deleted - config: - - vrf_name: "{{ ansible_vrf_11 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_12 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_21 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_22 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_31 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_32 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_41 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_42 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_51 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_52 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_61 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_62 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_71 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_72 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - register: result - -- assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -- name: Initialize the setup - sleep for 10 seconds for DCNM to completely update the state - wait_for: - timeout: 10 - -- block: - -############################################## -## MERGE VRFs ## -############################################## - - - name: Initialize the setup - Create all VRFs - cisco.dcnm.dcnm_vrf: - fabric: "{{ ansible_it_fabric }}" - state: merged - config: - - vrf_name: "{{ ansible_vrf_11 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_12 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_21 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_22 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_31 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_32 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_41 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_42 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_51 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_52 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_61 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_62 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_71 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - - vrf_name: "{{ ansible_vrf_72 }}" - attach: - - ip_address: "{{ ansible_switch1 }}" - register: result - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -############################################## -## MERGE SERVICE NODES ## -############################################## - - - name: Initialize the setup - Create all Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: "{{ ansible_it_fabric }}" - service_fabric: "{{ ansible_it_service_fabric }}" - state: merged - config: - - name: "{{ ansible_snode_1 }}" - type: firewall - form_factor: physical - svc_int_name: svc1 - attach_interface: "{{ ansible_att_intf1 }}" - switches: - - "{{ ansible_switch1 }}" - - name: "{{ ansible_snode_2 }}" - type: load_balancer - form_factor: physical - svc_int_name: svc2 - attach_interface: "{{ ansible_att_intf2 }}" - switches: - - "{{ ansible_switch1 }}" - register: result - - - assert: - that: - - 'item["RETURN_CODE"] == 200' - loop: '{{ result.response }}' - -- name: Initialize the setup - sleep for 180 seconds for DCNM to completely update the state - wait_for: - timeout: 180 - diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_service_node.json b/tests/unit/modules/dcnm/fixtures/dcnm_service_node.json deleted file mode 100644 index bb2f81728..000000000 --- a/tests/unit/modules/dcnm/fixtures/dcnm_service_node.json +++ /dev/null @@ -1,612 +0,0 @@ -{ - "mock_ip_sn" : { - "10.10.10.224": "XYZKSJHSMK1", - "10.10.10.225": "XYZKSJHSMK2", - "10.10.10.226": "XYZKSJHSMK3", - "10.10.10.227": "XYZKSJHSMK4", - "10.10.10.228": "XYZKSJHSMK5" - }, - - "playbook_config" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_replace_new" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_replace_new1" : [ - { - "name": "SN-11", - "type": "load_balancer", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_new_config" : [ - { - "name": "SN-12", - "type": "load_balancer", - "form_factor": "virtual", - "svc_int_name": "svc12", - "attach_interface": "Ethernet1/12", - "switches": "10.10.10.225" - } - ], - - "playbook_over_config" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "scv1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_name" : [ - { - "name": "SN-11" - } - ], - - "playbook_config_virtual" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "virtual", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_load" : [ - { - "name": "SN-11", - "type": "load_balancer", - "form_factor": "virtual", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_vnf" : [ - { - "name": "SN-11", - "type": "virtual_network_function", - "form_factor": "virtual", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_vpc" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPC1", - "switches": ["10.10.10.224", "10.10.10.225"] - } - ], - - "playbook_config_invalid_vpc" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPortchannel12", - "switches": ["10.10.10.224", "10.10.10.225"] - } - ], - - "playbook_config_more_switch" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPC1", - "switches": ["10.10.10.224", "10.10.10.225", "10.10.10.226"] - } - ], - - "playbook_config_noparams" : [ - { - "name": "", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_no_type" : [ - { - "name": "SN-11", - "type": "karth", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_no_ff" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "babu", - "svc_int_name": "svc1", - "attach_interface": "Ethernet1/1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_no_vpc" : [ - { - "name": "SN-11", - "type": "firewall", - "form_factor": "physical", - "svc_int_name": "svc1", - "attach_interface": "vPC1", - "switches": "10.10.10.224" - } - ], - - "playbook_config_query" : [ - { - "switches": "10.10.10.224" - } - ], - - "mock_sn_1_object": { - "ERROR": "", - "RETURN_CODE": 200, - "MESSAGE":"", - "DATA": [ - { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "svc1", - "lastUpdated": 1611748269292, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-141180", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "DEST_FABRIC_NAME": "external", - "DEST_SWITCH_NAME": "SN-11", - "IS_METASWITCH": "false", - "LINK_UUID": "LINK-UUID-141180", - "MTU": "jumbo", - "POLICY_DESC": "", - "POLICY_ID": "POLICY-141190", - "PORTTYPE_FAST_ENABLED": "true", - "PRIORITY": "500", - "SOURCE_FABRIC_NAME": "test_fabric", - "SOURCE_SWITCH_NAME": "dt-n9k1", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - ] - }, - - "mock_sn_merge_1_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_2_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_3_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "AVB", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_4_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "VNF", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_5_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "vPC1", - "attachedSwitchSn": "XYZKSJHSMK1, XYZKSJHSMK2", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_merge_6_success": { - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/2", - "attachedSwitchSn": "XYZKSJHSMK2", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv12", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-12", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "ADC", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_replace_1_success": { - "MESSAGE": "", - "METHOD": "PUT", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv11", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_replace_2_success": { - "MESSAGE": "", - "METHOD": "PUT", - "RETURN_CODE": 200, - "DATA": { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Virtual", - "interfaceName": "scv11", - "lastUpdated": 1612515571015, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-287550", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "MTU": "jumbo", - "PORTTYPE_FAST_ENABLED": "true", - "SPEED": "Auto" - }, - "type": "ADC", - "vpcSwitchesAttached": false - } - }, - - "mock_sn_have_success": { - "MESSAGE": "", - "METHOD": "GET", - "RETURN_CODE": 200, - "DATA": [ - { - "attachedFabricName": "test_fabric", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "XYZKSJHSMK1", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612604671520, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-304470", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "DEST_FABRIC_NAME": "external", - "DEST_IF_NAME": "scv1", - "DEST_SERIAL_NUMBER": "SN-11-external", - "DEST_SWITCH_NAME": "SN-11", - "IS_METASWITCH": "true", - "LINK_UUID": "LINK-UUID-304470", - "MTU": "jumbo", - "POLICY_DESC": "", - "POLICY_ID": "POLICY-304480", - "PORTTYPE_FAST_ENABLED": "true", - "PRIORITY": "500", - "SOURCE_FABRIC_NAME": "test_fabric", - "SOURCE_IF_NAME": "Ethernet1/1", - "SOURCE_SERIAL_NUMBER": "XYZKSJHSMK1", - "SOURCE_SWITCH_NAME": "XYZKSJHSMK1", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - } - ] - }, - - "mock_sn_query_success": { - "attachedFabricName": "Fabric1", - "attachedSwitchInterfaceName": "Ethernet1/1", - "attachedSwitchSn": "SAL1812NTBP", - "fabricName": "external", - "formFactor": "Physical", - "interfaceName": "scv1", - "lastUpdated": 1612606479781, - "linkTemplateName": "service_link_trunk", - "linkUuid": "LINK-UUID-304710", - "name": "SN-11", - "nvPairs": { - "ADMIN_STATE": "true", - "ALLOWED_VLANS": "none", - "BPDUGUARD_ENABLED": "no", - "DEST_FABRIC_NAME": "external", - "DEST_IF_NAME": "scv1", - "DEST_SERIAL_NUMBER": "SN-11-external", - "DEST_SWITCH_NAME": "SN-11", - "IS_METASWITCH": "true", - "LINK_UUID": "LINK-UUID-304710", - "MTU": "jumbo", - "POLICY_DESC": "", - "POLICY_ID": "POLICY-304720", - "PORTTYPE_FAST_ENABLED": "true", - "PRIORITY": "500", - "SOURCE_FABRIC_NAME": "Fabric1", - "SOURCE_IF_NAME": "Ethernet1/1", - "SOURCE_SERIAL_NUMBER": "SAL1812NTBP", - "SOURCE_SWITCH_NAME": "SAL1812NTBP", - "SPEED": "Auto" - }, - "type": "Firewall", - "vpcSwitchesAttached": false - }, - - "blank_data": { - "DATA": [], - "MESSAGE": "", - "METHOD": "POST", - "RETURN_CODE": 200 - }, - "blank_get_data": { - "DATA": [], - "MESSAGE": "", - "METHOD": "GET", - "RETURN_CODE": 200 - }, - - "blank_data_null": { - "DATA": [], - "MESSAGE": "", - "METHOD": "", - "RETURN_CODE": 0 - }, - - - "get_have_failure": { - "DATA": "Invalid JSON response: Invalid Fabric: demo-fabric-123", - "ERROR": "Not Found", - "METHOD": "GET", - "RETURN_CODE": 404, - "MESSAGE": "OK" - }, - "error1": { - "DATA": "None", - "ERROR": "There is an error", - "METHOD": "POST", - "RETURN_CODE": 400, - "MESSAGE": "OK" - }, - - "sn_delete_success_resp": { - "DATA": {}, - "ERROR": "", - "METHOD": "DELETE", - "RETURN_CODE": 200, - "MESSAGE": "" - }, - "sn_query_success_resp": { - "DATA": {}, - "ERROR": "", - "METHOD": "POST", - "RETURN_CODE": 200, - "MESSAGE": "" - }, - - "sn_inv_data": { - "10.10.10.224":{ - "ipAddress": "10.10.10.224", - "logicalName": "dt-n9k1", - "serialNumber": "XYZKSJHSMK1", - "switchRole": "leaf" - }, - "10.10.10.225":{ - "ipAddress": "10.10.10.225", - "logicalName": "dt-n9k2", - "serialNumber": "XYZKSJHSMK2", - "switchRole": "leaf" - }, - "10.10.10.226":{ - "ipAddress": "10.10.10.226", - "logicalName": "dt-n9k3", - "serialNumber": "XYZKSJHSMK3", - "switchRole": "leaf" - }, - "10.10.10.227":{ - "ipAddress": "10.10.10.227", - "logicalName": "dt-n9k4", - "serialNumber": "XYZKSJHSMK4", - "switchRole": "border spine" - }, - "10.10.10.228":{ - "ipAddress": "10.10.10.228", - "logicalName": "dt-n9k5", - "serialNumber": "XYZKSJHSMK5", - "switchRole": "border" - } - } -} \ No newline at end of file diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_srp_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_srp_configs.json deleted file mode 100644 index a8c9127c4..000000000 --- a/tests/unit/modules/dcnm/fixtures/dcnm_srp_configs.json +++ /dev/null @@ -1,1672 +0,0 @@ -{ - "delete_rp1_rp7_config": [ - { - "name": "IT-FW-RP1", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP2", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP3", - "node_name": "IT-SN-1" - }, - { - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2" - } - ], - - "delete_no_mand_elems": [ - { - "name": "IT-FW-RP1", - "node_name": "IT-SN-1" - }], - - "merge_rp1_rp7_config" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface - change", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2001:0901::01/64" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface - change", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2001:0902::1/64" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.100" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface - change", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2002:0901::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.120.100", - "121.121.121.100" - ], - "subnet": "20.20.20.0/24" - } - ] - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface - change", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2002:0902::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.122.100", - "123.123.123.100" - ], - "subnet": "21.21.21.0/24" - } - ] - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface - change", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1", - "ipv4_vpc_peer_lo": "31.31.31.3", - "ipv6_gw": "2003:0901::1/64", - "ipv6_lo": "2003:3932::01", - "ipv6_neighbor": "2003:3931::1", - "ipv6_vpc_peer_lo": "2003:3933::01", - "local_asn": 65301, - "neigh_int_descr": "RP3 SN1 inside interface - change", - "route_map_tag": 33111 - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface - change", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1", - "ipv4_vpc_peer_lo": "131.131.131.3", - "ipv6_gw": "2003:0902::1/64", - "ipv6_lo": "2003:8984::1:100:1", - "ipv6_neighbor": "2003:8983::1", - "ipv6_vpc_peer_lo": "2003:8985::1", - "local_asn": 65302, - "neigh_int_descr": "RP3 SN1 outside interface - change", - "route_map_tag": 31113 - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf - change", - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1", - "ipv4_vpc_peer_lo": "41.41.41.3", - "ipv6_gw": "2004:0901::1/64", - "ipv6_lo": "2004:4942::1", - "ipv6_neighbor": "2004:4941::1", - "ipv6_vpc_peer_lo": "2004:4943::1", - "local_asn": 65401, - "neigh_int_descr": "RP4 SN2 first arm - change", - "route_map_tag": 41112 - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP5 SN2 first arm intf - change", - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.51.2", - "ipv4_neighbor": "51.51.51.1", - "ipv4_vpc_peer_lo": "51.51.51.3", - "ipv6_gw": "2005:0901::1/64", - "ipv6_lo": "2005:5952::1", - "ipv6_neighbor": "2005:5951::1", - "ipv6_vpc_peer_lo": "2005:5953::1", - "local_asn": 65501, - "neigh_int_descr": "RP5 SN2 first arm - change", - "route_map_tag": 51115 - }, - "vlan_id": 501, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.100", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "int_descr": "RP5 SN2 second arm intf - change", - "ipv4_gw": "192.165.2.1/24", - "ipv6_gw": "2005:0902::1/64" - }, - "vlan_id": 502, - "vrf": "IT_VRF_51" - } - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - change", - "ipv4_gw": "192.166.1.1/24", - "ipv6_gw": "2006:0901::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.161.1", - "162.162.162.1" - ], - "subnet": "61.61.61.1/24" - }, - { - "next_hop": [ - "163.163.163.1", - "164.164.164.1" - ], - "subnet": "22.0.0.0/24" - } - ] - }, - "vlan_id": 601, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp7-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - change", - "ipv4_gw": "192.167.1.1/24", - "ipv6_gw": "2007:0901::1/64", - "static_route": [ - { - "next_hop": [ - "171.171.171.1", - "172.172.172.1" - ], - "subnet": "71.71.71.1/24" - } - ] - }, - "vlan_id": 701, - "vrf": "IT_VRF_71" - }, - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.167.1.100", - "second_arm": { - "name": "rp7-sn2-second-arm", - "profile": { - "int_descr": "RP7 SN2 second arm intf - change", - "ipv4_gw": "192.167.2.1/24", - "ipv6_gw": "2007:0902::1/64" - }, - "vlan_id": 702, - "vrf": "IT_VRF_71" - } - } - ], - "create_rp1_rp3_rp5_config" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2001:0101::01/64", - "tag": 11111, - "vlan_name": "rp1-sn1-inside" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2001:0102::1/64", - "tag": 11112, - "vlan_name": "rp1-sn1-outside" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.100" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1", - "ipv4_vpc_peer_lo": "31.31.31.3", - "ipv6_gw": "2003:0101::1/64", - "ipv6_lo": "2003:3132::01", - "ipv6_neighbor": "2003:3131::1", - "ipv6_vpc_peer_lo": "2003:3133::01", - "local_asn": 65301, - "neigh_int_descr": "RP3 SN1 inside interface", - "route_map_tag": 33111, - "tag": 31111, - "vlan_name": "rp3-sn1-inside" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1", - "ipv4_vpc_peer_lo": "131.131.131.3", - "ipv6_gw": "2003:0102::1/64", - "ipv6_lo": "2003:8384::1:100:1", - "ipv6_neighbor": "2003:8383::1", - "ipv6_vpc_peer_lo": "2003:8385::1", - "local_asn": 65302, - "neigh_int_descr": "RP3 SN1 outside interface", - "route_map_tag": 31113, - "tag": 31112, - "vlan_name": "rp3-sn1-outside" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP5 SN2 first arm intf", - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.51.2", - "ipv4_neighbor": "51.51.51.1", - "ipv4_vpc_peer_lo": "51.51.51.3", - "ipv6_gw": "2005:0101::1/64", - "ipv6_lo": "2005:5152::1", - "ipv6_neighbor": "2005:5151::1", - "ipv6_vpc_peer_lo": "2005:5153::1", - "local_asn": 65501, - "neigh_int_descr": "RP5 SN2 first arm", - "route_map_tag": 51115, - "tag": 51111, - "vlan_name": "rp5-sn2-first-arm" - }, - "vlan_id": 501, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.100", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "int_descr": "RP5 SN2 second arm intf", - "ipv4_gw": "192.165.2.1/24", - "ipv6_gw": "2005:0102::1/64", - "tag": 51112, - "vlan_name": "rp5-sn2-second-arm" - }, - "vlan_id": 502, - "vrf": "IT_VRF_51" - } - } - ], - "update_rp2_rp4_config" : [ - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface - upd", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2002:0109::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.129.100", - "121.121.121.100" - ], - "subnet": "20.20.20.0/24" - } - ], - "tag": 21111, - "vlan_name": "rp2-sn1-inside" - }, - "vlan_id": 209, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface - upd", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2002:0102::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.122.100", - "123.123.123.100" - ], - "subnet": "21.21.21.0/24" - } - ], - "tag": 22222, - "vlan_name": "rp2-sn1-outside - upd" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf - upd", - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1", - "ipv4_vpc_peer_lo": "41.41.41.3", - "ipv6_gw": "2004:0101::1/64", - "ipv6_lo": "2004:4142::1", - "ipv6_neighbor": "2004:4141::1", - "ipv6_vpc_peer_lo": "2004:4143::1", - "local_asn": 65401, - "neigh_int_descr": "RP4 SN2 first arm - upd", - "route_map_tag": 41119, - "tag": 41119, - "vlan_name": "rp4-sn2-first-arm-upd" - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - } - ], - "create_rp1_rp7_config" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2001:0101::01/64", - "tag": 11111, - "vlan_name": "rp1-sn1-inside" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2001:0102::1/64", - "tag": 11112, - "vlan_name": "rp1-sn1-outside" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.100" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2002:0101::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.120.100", - "121.121.121.100" - ], - "subnet": "20.20.20.0/24" - } - ], - "tag": 21111, - "vlan_name": "rp2-sn1-inside" - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2002:0102::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.122.100", - "123.123.123.100" - ], - "subnet": "21.21.21.0/24" - } - ], - "tag": 22222, - "vlan_name": "rp2-sn1-outside" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1", - "ipv4_vpc_peer_lo": "31.31.31.3", - "ipv6_gw": "2003:0101::1/64", - "ipv6_lo": "2003:3132::01", - "ipv6_neighbor": "2003:3131::1", - "ipv6_vpc_peer_lo": "2003:3133::01", - "local_asn": 65301, - "neigh_int_descr": "RP3 SN1 inside interface", - "route_map_tag": 33111, - "tag": 31111, - "vlan_name": "rp3-sn1-inside" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1", - "ipv4_vpc_peer_lo": "131.131.131.3", - "ipv6_gw": "2003:0102::1/64", - "ipv6_lo": "2003:8384::1:100:1", - "ipv6_neighbor": "2003:8383::1", - "ipv6_vpc_peer_lo": "2003:8385::1", - "local_asn": 65302, - "neigh_int_descr": "RP3 SN1 outside interface", - "route_map_tag": 31113, - "tag": 31112, - "vlan_name": "rp3-sn1-outside" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf", - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1", - "ipv4_vpc_peer_lo": "41.41.41.3", - "ipv6_gw": "2004:0101::1/64", - "ipv6_lo": "2004:4142::1", - "ipv6_neighbor": "2004:4141::1", - "ipv6_vpc_peer_lo": "2004:4143::1", - "local_asn": 65401, - "neigh_int_descr": "RP4 SN2 first arm", - "route_map_tag": 41112, - "tag": 41111, - "vlan_name": "rp4-sn2-first-arm" - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP5 SN2 first arm intf", - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.51.2", - "ipv4_neighbor": "51.51.51.1", - "ipv4_vpc_peer_lo": "51.51.51.3", - "ipv6_gw": "2005:0101::1/64", - "ipv6_lo": "2005:5152::1", - "ipv6_neighbor": "2005:5151::1", - "ipv6_vpc_peer_lo": "2005:5153::1", - "local_asn": 65501, - "neigh_int_descr": "RP5 SN2 first arm", - "route_map_tag": 51115, - "tag": 51111, - "vlan_name": "rp5-sn2-first-arm" - }, - "vlan_id": 501, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.100", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "int_descr": "RP5 SN2 second arm intf", - "ipv4_gw": "192.165.2.1/24", - "ipv6_gw": "2005:0102::1/64", - "tag": 51112, - "vlan_name": "rp5-sn2-second-arm" - }, - "vlan_id": 502, - "vrf": "IT_VRF_51" - } - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf", - "ipv4_gw": "192.166.1.1/24", - "ipv6_gw": "2006:0101::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.161.1", - "162.162.162.1" - ], - "subnet": "61.61.61.1/24" - }, - { - "next_hop": [ - "163.163.163.1", - "164.164.164.1" - ], - "subnet": "22.0.0.0/24" - } - ], - "tag": 61111, - "vlan_name": "rp6-sn2-first-arm" - }, - "vlan_id": 601, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp7-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf", - "ipv4_gw": "192.167.1.1/24", - "ipv6_gw": "2007:0101::1/64", - "static_route": [ - { - "next_hop": [ - "171.171.171.1", - "172.172.172.1" - ], - "subnet": "71.71.71.1/24" - } - ], - "tag": 71111, - "vlan_name": "rp7-sn2-first-arm" - }, - "vlan_id": 701, - "vrf": "IT_VRF_71" - }, - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.167.1.100", - "second_arm": { - "name": "rp7-sn2-second-arm", - "profile": { - "int_descr": "RP7 SN2 second arm intf", - "ipv4_gw": "192.167.2.1/24", - "ipv6_gw": "2007:0102::1/64", - "tag": 71112, - "vlan_name": "rp7-sn2-second-arm" - }, - "vlan_id": 702, - "vrf": "IT_VRF_71" - } - } - ], - "create_no_intra_fw_mand_elems" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "ipv4_gw": "192.161.1.1/24" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "ipv4_gw": "192.161.2.1/24" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - } - }], - "create_no_inter_fw_mand_elems" : [ - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }], - - "create_no_adc_mand_elems" : [ - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1" - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - }], - - "create_rp1_rp7_config_no_opt_elems" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "ipv4_gw": "192.161.1.1/24" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "ipv4_gw": "192.161.2.1/24" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - } - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "ipv4_gw": "192.162.1.1/24" - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "ipv4_gw": "192.162.2.1/24" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - } - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.41.2", - "ipv4_neighbor": "41.41.41.1" - }, - "vlan_id": 401, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.51.2", - "ipv4_neighbor": "51.51.51.1" - }, - "vlan_id": 501, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.100", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "ipv4_gw": "192.165.2.1/24" - }, - "vlan_id": 502, - "vrf": "IT_VRF_51" - } - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "ipv4_gw": "192.166.1.1/24" - }, - "vlan_id": 601, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "rev_next_hop": "192.166.1.100" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp7-sn2-first-arm", - "profile": { - "ipv4_gw": "192.167.1.1/24" - }, - "vlan_id": 701, - "vrf": "IT_VRF_71" - }, - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2", - "rev_next_hop": "192.167.1.100", - "second_arm": { - "name": "rp7-sn2-second-arm", - "profile": { - "ipv4_gw": "192.167.2.1/24" - }, - "vlan_id": 702, - "vrf": "IT_VRF_71" - } - } - ], - - "query_no_mand_elems": [ - { - "name": "IT-FW-RP1-ABS", - "node_name": "IT-SN-1" - }], - - "config_query_non_exist": [ - { - "name": "IT-FW-RP1-ABS", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP2-ABS", - "node_name": "IT-SN-2" - } - ], - - "config_query_with_node": [ - { - "node_name": "IT-SN-1" - }, - { - "node_name": "IT-SN-2" - } - ], - - "config_query_with_peername": [ - { - "name": "IT-FW-RP1", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP2", - "node_name": "IT-SN-1" - }, - { - "name": "IT-FW-RP3", - "node_name": "IT-SN-1" - }, - { - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2" - }, - { - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2" - } - ], - - "replace_rp1_to_rp3_no_opt_elems" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "ipv4_gw": "192.161.1.1/24" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "ipv4_gw": "192.161.2.1/24" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - } - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "ipv4_gw": "192.162.1.1/24" - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "ipv4_gw": "192.162.2.1/24" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - } - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }], - - "replace_rp1_rp3_no_change" : [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2001:0101::01/64", - "tag": 11111, - "vlan_name": "rp1-sn1-inside" - }, - "vlan_id": 101, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2001:0102::1/64", - "tag": 11112, - "vlan_name": "rp1-sn1-outside" - }, - "vlan_id": 102, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.100" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2002:0101::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.120.100", - "121.121.121.100" - ], - "subnet": "20.20.20.0/24" - } - ], - "tag": 21111, - "vlan_name": "rp2-sn1-inside" - }, - "vlan_id": 201, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2002:0102::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.122.100", - "123.123.123.100" - ], - "subnet": "21.21.21.0/24" - } - ], - "tag": 22222, - "vlan_name": "rp2-sn1-outside" - }, - "vlan_id": 202, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.31.2", - "ipv4_neighbor": "31.31.31.1", - "ipv4_vpc_peer_lo": "31.31.31.3", - "ipv6_gw": "2003:0101::1/64", - "ipv6_lo": "2003:3132::01", - "ipv6_neighbor": "2003:3131::1", - "ipv6_vpc_peer_lo": "2003:3133::01", - "local_asn": 65301, - "neigh_int_descr": "RP3 SN1 inside interface", - "route_map_tag": 33111, - "tag": 31111, - "vlan_name": "rp3-sn1-inside" - }, - "vlan_id": 301, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.131.2", - "ipv4_neighbor": "131.131.131.1", - "ipv4_vpc_peer_lo": "131.131.131.3", - "ipv6_gw": "2003:0102::1/64", - "ipv6_lo": "2003:8384::1:100:1", - "ipv6_neighbor": "2003:8383::1", - "ipv6_vpc_peer_lo": "2003:8385::1", - "local_asn": 65302, - "neigh_int_descr": "RP3 SN1 outside interface", - "route_map_tag": 31113, - "tag": 31112, - "vlan_name": "rp3-sn1-outside" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - }], - "replace_rp1_to_rp3": [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net", - "profile": { - "int_descr": "RP1 SN1 inside interface - REP", - "ipv4_gw": "192.161.1.1/24", - "ipv6_gw": "2101:0101::01/64", - "tag": 11101, - "vlan_name": "rp1-sn1-inside-rep" - }, - "vlan_id": 191, - "vrf": "IT_VRF_11" - }, - "name": "IT-FW-RP1", - "next_hop": "192.161.1.200", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net", - "profile": { - "int_descr": "RP1 SN1 outside interface- REP", - "ipv4_gw": "192.161.2.1/24", - "ipv6_gw": "2101:0102::1/64", - "tag": 11102, - "vlan_name": "rp1-sn1-outside-rep" - }, - "vlan_id": 192, - "vrf": "IT_VRF_11" - }, - "rev_next_hop": "192.161.2.200" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp2-sn1-inside-net", - "profile": { - "int_descr": "RP2 SN1 inside interface - REP", - "ipv4_gw": "192.162.1.1/24", - "ipv6_gw": "2102:0101::1/64", - "static_route": [ - { - "next_hop": [ - "120.120.190.100", - "121.121.191.100" - ], - "subnet": "20.20.90.0/24" - } - ], - "tag": 21101, - "vlan_name": "rp2-sn1-inside-rep" - }, - "vlan_id": 291, - "vrf": "IT_VRF_21" - }, - "name": "IT-FW-RP2", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp2-sn1-outside-net", - "profile": { - "int_descr": "RP2 SN1 outside interface - REP", - "ipv4_gw": "192.162.2.1/24", - "ipv6_gw": "2102:0102::1/64", - "static_route": [ - { - "next_hop": [ - "122.122.129.100", - "123.123.129.100" - ], - "subnet": "21.21.29.0/24" - } - ], - "tag": 22202, - "vlan_name": "rp2-sn1-outside-rep" - }, - "vlan_id": 292, - "vrf": "IT_VRF_22" - }, - "peering_option": "static" - }, - { - "deploy_mode": "inter_tenant_fw", - "inside_network": { - "name": "rp3-sn1-inside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 inside interface - REP", - "ipv4_gw": "192.163.1.1/24", - "ipv4_lo": "31.31.39.2", - "ipv4_neighbor": "31.31.39.1", - "ipv4_vpc_peer_lo": "31.31.39.3", - "ipv6_gw": "2103:0101::1/64", - "ipv6_lo": "2103:3132::01", - "ipv6_neighbor": "2103:3131::1", - "ipv6_vpc_peer_lo": "2103:3133::01", - "local_asn": 65391, - "neigh_int_descr": "RP3 SN1 inside interface - REP", - "route_map_tag": 33101, - "tag": 31101, - "vlan_name": "rp3-sn1-inside-rep" - }, - "vlan_id": 391, - "vrf": "IT_VRF_31" - }, - "name": "IT-FW-RP3", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp3-sn1-outside-net", - "profile": { - "adv_host": true, - "int_descr": "RP3 SN1 outside interface - REP", - "ipv4_gw": "192.163.2.1/24", - "ipv4_lo": "131.131.139.2", - "ipv4_neighbor": "131.131.139.1", - "ipv4_vpc_peer_lo": "131.131.139.3", - "ipv6_gw": "2103:0102::1/64", - "ipv6_lo": "2103:8384::1:100:1", - "ipv6_neighbor": "2103:8383::1", - "ipv6_vpc_peer_lo": "2103:8385::1", - "local_asn": 65392, - "neigh_int_descr": "RP3 SN1 outside interface - REP", - "route_map_tag": 31103, - "tag": 31102, - "vlan_name": "rp3-sn1-outside-rep" - }, - "vlan_id": 302, - "vrf": "IT_VRF_32" - }, - "peering_option": "ebgp" - } - ], - - "replace_rp4_to_rp7": [ - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf - REP", - "ipv4_gw": "192.164.1.1/24", - "ipv4_lo": "41.41.49.2", - "ipv4_neighbor": "41.41.49.1", - "ipv4_vpc_peer_lo": "41.41.49.3", - "ipv6_gw": "2104:0101::1/64", - "ipv6_lo": "2104:4142::1", - "ipv6_neighbor": "2104:4141::1", - "ipv6_vpc_peer_lo": "2104:4143::1", - "local_asn": 65491, - "neigh_int_descr": "RP4 SN2 first arm - REP", - "route_map_tag": 41102, - "tag": 41101, - "vlan_name": "rp4-sn2-first-arm-rep" - }, - "vlan_id": 491, - "vrf": "IT_VRF_41" - }, - "name": "IT-ADC-RP4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.1.200" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp5-sn2-first-arm", - "profile": { - "adv_host": true, - "int_descr": "RP5 SN2 first arm intf - REP", - "ipv4_gw": "192.165.1.1/24", - "ipv4_lo": "51.51.59.2", - "ipv4_neighbor": "51.51.59.1", - "ipv4_vpc_peer_lo": "51.51.51.3", - "ipv6_gw": "2105:0101::1/64", - "ipv6_lo": "2105:5152::1", - "ipv6_neighbor": "2105:5151::1", - "ipv6_vpc_peer_lo": "2105:5153::1", - "local_asn": 65591, - "neigh_int_descr": "RP5 SN2 first arm - REP", - "route_map_tag": 51105, - "tag": 51101, - "vlan_name": "rp5-sn2-first-arm-rep" - }, - "vlan_id": 591, - "vrf": "IT_VRF_51" - }, - "name": "IT-ADC-RP5", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.165.1.200", - "second_arm": { - "name": "rp5-sn2-second-arm", - "profile": { - "int_descr": "RP5 SN2 second arm intf - REP", - "ipv4_gw": "192.165.2.1/24", - "ipv6_gw": "2105:0102::1/64", - "tag": 51102, - "vlan_name": "rp5-sn2-second-arm-rep" - }, - "vlan_id": 592, - "vrf": "IT_VRF_51" - } - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - REP", - "ipv4_gw": "192.166.1.1/24", - "ipv6_gw": "2106:0101::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.169.1", - "162.162.169.1" - ], - "subnet": "61.61.69.1/24" - }, - { - "next_hop": [ - "163.163.169.1", - "164.164.169.1" - ], - "subnet": "29.0.0.0/24" - } - ], - "tag": 61101, - "vlan_name": "rp6-sn2-first-arm-rep" - }, - "vlan_id": 691, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.1.200" - }, - { - "deploy_mode": "two_arm_adc", - "first_arm": { - "name": "rp7-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - REP", - "ipv4_gw": "192.167.1.1/24", - "ipv6_gw": "2107:0101::1/64", - "static_route": [ - { - "next_hop": [ - "171.171.179.1", - "172.172.179.1" - ], - "subnet": "71.71.79.1/24" - } - ], - "tag": 71101, - "vlan_name": "rp7-sn2-first-arm-rep" - }, - "vlan_id": 791, - "vrf": "IT_VRF_71" - }, - "name": "IT-ADC-RP7", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.167.1.200", - "second_arm": { - "name": "rp7-sn2-second-arm", - "profile": { - "int_descr": "RP7 SN2 second arm intf - REP", - "ipv4_gw": "192.167.2.1/24", - "ipv6_gw": "2107:0102::1/64", - "tag": 71102, - "vlan_name": "rp7-sn2-second-arm-rep" - }, - "vlan_id": 792, - "vrf": "IT_VRF_71" - } - } - ], - "override_with_no_config" : [], - "override_with_snodes": [ - { - "node_name": "IT-SN-1" - }, - { - "node_name": "IT-SN-2" - } - ], - "override_with_existing_peering": [ - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf", - "ipv4_gw": "192.166.1.1/24", - "ipv6_gw": "2006:0101::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.161.1", - "162.162.162.1" - ], - "subnet": "61.61.61.1/24" - }, - { - "next_hop": [ - "163.163.163.1", - "164.164.164.1" - ], - "subnet": "22.0.0.0/24" - } - ], - "tag": 61111, - "vlan_name": "rp6-sn2-first-arm" - }, - "vlan_id": 601, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.1.100" - } - ], - "override_with_existing_peering_updated": [ - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp6-sn2-first-arm", - "profile": { - "int_descr": "RP6 SN2 first arm intf - ovr", - "ipv4_gw": "192.166.9.1/24", - "ipv6_gw": "2006:0109::1/64", - "static_route": [ - { - "next_hop": [ - "161.161.169.1", - "162.162.169.1" - ], - "subnet": "61.61.69.1/24" - }, - { - "next_hop": [ - "163.163.169.1", - "164.164.169.1" - ], - "subnet": "29.0.0.0/24" - } - ], - "tag": 61111, - "vlan_name": "rp6-sn2-first-arm" - }, - "vlan_id": 609, - "vrf": "IT_VRF_61" - }, - "name": "IT-ADC-RP6", - "node_name": "IT-SN-2", - "peering_option": "static", - "rev_next_hop": "192.166.9.100" - } - ], - "override_with_new_peerings": [ - { - "deploy_mode": "intra_tenant_fw", - "inside_network": { - "name": "rp1-sn1-inside-net-ovr", - "profile": { - "int_descr": "RP1 SN1 inside interface ovr", - "ipv4_gw": "192.161.91.1/24", - "ipv6_gw": "2001:0901::01/64", - "tag": 11191, - "vlan_name": "rp1-sn1-inside-ovr" - }, - "vlan_id": 191, - "vrf": "IT_VRF_12" - }, - "name": "IT-FW-RP-OVR1", - "next_hop": "192.161.91.100", - "node_name": "IT-SN-1", - "outside_network": { - "name": "rp1-sn1-outside-net-ovr", - "profile": { - "int_descr": "RP1 SN1 outside interface ovr", - "ipv4_gw": "192.161.92.1/24", - "ipv6_gw": "2001:0902::1/64", - "tag": 11192, - "vlan_name": "rp1-sn1-outside-ovr" - }, - "vlan_id": 192, - "vrf": "IT_VRF_12" - }, - "rev_next_hop": "192.161.92.100" - }, - { - "deploy_mode": "one_arm_adc", - "first_arm": { - "name": "rp4-sn2-first-arm-ovr", - "profile": { - "adv_host": true, - "int_descr": "RP4 SN2 first arm intf ovr", - "ipv4_gw": "192.164.91.1/24", - "ipv4_lo": "49.49.49.2", - "ipv4_neighbor": "49.49.49.1", - "ipv4_vpc_peer_lo": "49.49.49.3", - "ipv6_gw": "2004:0901:01::1/64", - "ipv6_lo": "2004:4942::1", - "ipv6_neighbor": "2004:4941::1", - "ipv6_vpc_peer_lo": "2004:4943::1", - "local_asn": 65491, - "neigh_int_descr": "RP4 SN2 first arm ovr", - "route_map_tag": 41192, - "tag": 41191, - "vlan_name": "rp3-sn1-first-arm-ovr" - }, - "vlan_id": 491, - "vrf": "IT_VRF_42" - }, - "name": "IT-ADC-RP-OVR4", - "node_name": "IT-SN-2", - "peering_option": "ebgp", - "rev_next_hop": "192.164.91.100" - } - ] -} diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_srp_payloads.json b/tests/unit/modules/dcnm/fixtures/dcnm_srp_payloads.json deleted file mode 100644 index c4efe6c16..000000000 --- a/tests/unit/modules/dcnm/fixtures/dcnm_srp_payloads.json +++ /dev/null @@ -1,3084 +0,0 @@ -{ - "create_rp7_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 400 - }, - - "create_rp4_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 400 - }, - - "det_rp1_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1/attachments", - "RETURN_CODE": 400 - }, - - "deploy_rp4_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4/deployments", - "RETURN_CODE": 400 - }, - - "delete_rp7_resp_unauth_err": - { - "DATA": { - "error": { - "code": "UserUnauthorized", - "detail": "User is not authenticated, or not authorized to access the requested resources. " - } - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7", - "RETURN_CODE": 400 - }, - - "create_rp1_resp" : - { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "IntraTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504100184, - "nextHopIp": "192.161.1.100", - "peeringName": "IT-FW-RP1", - "peeringOption": "None", - "reverseNextHopIp": "192.161.2.100", - "routes": [], - "serviceNetworks": [ - { - "networkName": "rp1-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.161.1.1/24", - "gatewayIpV6Address": "2001:0101::01/64", - "intfDescription": "RP1 SN1 inside interface fw:inside:external:IT-SN-1:external-intf:IT-FW-RP1", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp1-sn1-inside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30005", - "suppressArp": "false", - "tag": "11111", - "trmEnabled": "false", - "vlanId": "101", - "vlanName": "rp1-sn1-inside", - "vrfName": "IT_VRF_11" - }, - "templateName": "Service_Network_Universal", - "vlanId": 101, - "vrfName": "IT_VRF_11" - }, - { - "networkName": "rp1-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.161.2.1/24", - "gatewayIpV6Address": "2001:0102::1/64", - "intfDescription": "RP1 SN1 outside interface fw:outside:external:IT-SN-1:external-intf:IT-FW-RP1", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp1-sn1-outside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30006", - "suppressArp": "false", - "tag": "11112", - "trmEnabled": "false", - "vlanId": "102", - "vlanName": "rp1-sn1-outside", - "vrfName": "IT_VRF_11" - }, - "templateName": "Service_Network_Universal", - "vlanId": 102, - "vrfName": "IT_VRF_11" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings", - "RETURN_CODE": 200 - }, - "create_rp2_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "InterTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504107408, - "peeringName": "IT-FW-RP2", - "peeringOption": "StaticPeering", - "routes": [ - { - "nvPairs": { - "MULTI_ROUTES": "20.20.20.0/24,120.120.120.100\n20.20.20.0/24,121.121.121.100", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_21" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_21" - }, - { - "nvPairs": { - "MULTI_ROUTES": "21.21.21.0/24,122.122.122.100\n21.21.21.0/24,123.123.123.100", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_22" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_22" - } - ], - "serviceNetworks": [ - { - "networkName": "rp2-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.162.1.1/24", - "gatewayIpV6Address": "2002:0101::1/64", - "intfDescription": "RP2 SN1 inside interface fw:inside:external:IT-SN-1:external-intf:IT-FW-RP2", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp2-sn1-inside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30007", - "suppressArp": "false", - "tag": "21111", - "trmEnabled": "false", - "vlanId": "201", - "vlanName": "rp2-sn1-inside", - "vrfName": "IT_VRF_21" - }, - "templateName": "Service_Network_Universal", - "vlanId": 201, - "vrfName": "IT_VRF_21" - }, - { - "networkName": "rp2-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.162.2.1/24", - "gatewayIpV6Address": "2002:0102::1/64", - "intfDescription": "RP2 SN1 outside interface fw:outside:external:IT-SN-1:external-intf:IT-FW-RP2", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp2-sn1-outside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30008", - "suppressArp": "false", - "tag": "22222", - "trmEnabled": "false", - "vlanId": "202", - "vlanName": "rp2-sn1-outside", - "vrfName": "IT_VRF_22" - }, - "templateName": "Service_Network_Universal", - "vlanId": 202, - "vrfName": "IT_VRF_22" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings", - "RETURN_CODE": 200 - }, - "create_rp3_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "InterTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504115514, - "peeringName": "IT-FW-RP3", - "peeringOption": "EBGPDynamicPeering", - "routes": [ - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP3 SN1 inside interface", - "LOCAL_ASN": "65301", - "LOOPBACK_IP": "31.31.31.2", - "LOOPBACK_IPV6": "2003:3132::01", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "31.31.31.1", - "NEIGHBOR_IPV6": "2003:3131::1", - "PEER_LOOPBACK_IP": "31.31.31.3", - "PEER_LOOPBACK_IPV6": "2003:3133::01", - "ROUTE_MAP_TAG": "33111", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_31" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_31" - }, - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP3 SN1 outside interface", - "LOCAL_ASN": "65302", - "LOOPBACK_IP": "131.131.131.2", - "LOOPBACK_IPV6": "2003:8384::1:100:1", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "131.131.131.1", - "NEIGHBOR_IPV6": "2003:8383::1", - "PEER_LOOPBACK_IP": "131.131.131.3", - "PEER_LOOPBACK_IPV6": "2003:8385::1", - "ROUTE_MAP_TAG": "31113", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_32" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_32" - } - ], - "serviceNetworks": [ - { - "networkName": "rp3-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.163.1.1/24", - "gatewayIpV6Address": "2003:0101::1/64", - "intfDescription": "RP3 SN1 inside interface fw:inside:external:IT-SN-1:external-intf:IT-FW-RP3", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp3-sn1-inside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30009", - "suppressArp": "false", - "tag": "31111", - "trmEnabled": "false", - "vlanId": "301", - "vlanName": "rp3-sn1-inside", - "vrfName": "IT_VRF_31" - }, - "templateName": "Service_Network_Universal", - "vlanId": 301, - "vrfName": "IT_VRF_31" - }, - { - "networkName": "rp3-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.163.2.1/24", - "gatewayIpV6Address": "2003:0102::1/64", - "intfDescription": "RP3 SN1 outside interface fw:outside:external:IT-SN-1:external-intf:IT-FW-RP3", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp3-sn1-outside-net", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30010", - "suppressArp": "false", - "tag": "31112", - "trmEnabled": "false", - "vlanId": "302", - "vlanName": "rp3-sn1-outside", - "vrfName": "IT_VRF_32" - }, - "templateName": "Service_Network_Universal", - "vlanId": 302, - "vrfName": "IT_VRF_32" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings", - "RETURN_CODE": 200 - }, - "create_rp4_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "OneArmADC", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504123921, - "nextHopIp": "", - "peeringName": "IT-ADC-RP4", - "peeringOption": "EBGPDynamicPeering", - "reverseNextHopIp": "192.164.1.100", - "routes": [ - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP4 SN2 first arm", - "LOCAL_ASN": "65401", - "LOOPBACK_IP": "41.41.41.2", - "LOOPBACK_IPV6": "2004:4142::1", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "41.41.41.1", - "NEIGHBOR_IPV6": "2004:4141::1", - "PEER_LOOPBACK_IP": "41.41.41.3", - "PEER_LOOPBACK_IPV6": "2004:4143::1", - "ROUTE_MAP_TAG": "41112", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_41" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_41" - } - ], - "serviceNetworks": [ - { - "networkName": "rp4-sn1-first-arm", - "networkType": "ArmOneADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.164.1.1/24", - "gatewayIpV6Address": "2004:0101::1/64", - "intfDescription": "RP4 SN1 first arm intf lb:one:external:IT-SN-2:external-intf:IT-ADC-RP4", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp4-sn1-first-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30011", - "suppressArp": "false", - "tag": "41111", - "trmEnabled": "false", - "vlanId": "401", - "vlanName": "rp3-sn1-first-arm", - "vrfName": "IT_VRF_41" - }, - "templateName": "Service_Network_Universal", - "vlanId": 401, - "vrfName": "IT_VRF_41" - } - ], - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 200 - }, - "create_rp5_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "TwoArmADC", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504131111, - "nextHopIp": "", - "peeringName": "IT-ADC-RP5", - "peeringOption": "EBGPDynamicPeering", - "reverseNextHopIp": "192.165.1.100", - "routes": [ - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP5 SN2 first arm", - "LOCAL_ASN": "65501", - "LOOPBACK_IP": "51.51.51.2", - "LOOPBACK_IPV6": "2005:5152::1", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "51.51.51.1", - "NEIGHBOR_IPV6": "2005:5151::1", - "PEER_LOOPBACK_IP": "51.51.51.3", - "PEER_LOOPBACK_IPV6": "2005:5153::1", - "ROUTE_MAP_TAG": "51115", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_51" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_51" - } - ], - "serviceNetworks": [ - { - "networkName": "rp5-sn2-first-arm", - "networkType": "ArmOneADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.165.1.1/24", - "gatewayIpV6Address": "2005:0101::1/64", - "intfDescription": "RP5 SN2 first arm intf lb:one:external:IT-SN-2:external-intf:IT-ADC-RP5", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp5-sn2-first-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30012", - "suppressArp": "false", - "tag": "51111", - "trmEnabled": "false", - "vlanId": "501", - "vlanName": "rp5-sn2-first-arm", - "vrfName": "IT_VRF_51" - }, - "templateName": "Service_Network_Universal", - "vlanId": 501, - "vrfName": "IT_VRF_51" - }, - { - "networkName": "rp5-sn2-second-arm", - "networkType": "ArmTwoADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.165.2.1/24", - "gatewayIpV6Address": "2005:0102::1/64", - "intfDescription": "RP5 SN2 second arm intf lb:two:external:IT-SN-2:external-intf:IT-ADC-RP5", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp5-sn2-second-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30013", - "suppressArp": "false", - "tag": "51112", - "trmEnabled": "false", - "vlanId": "502", - "vlanName": "rp5-sn2-second-arm", - "vrfName": "IT_VRF_51" - }, - "templateName": "Service_Network_Universal", - "vlanId": 502, - "vrfName": "IT_VRF_51" - } - ], - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 200 - }, - "create_rp6_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "OneArmADC", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504137242, - "nextHopIp": "", - "peeringName": "IT-ADC-RP6", - "peeringOption": "StaticPeering", - "reverseNextHopIp": "192.166.1.100", - "routes": [ - { - "nvPairs": { - "MULTI_ROUTES": "61.61.61.1/24,161.161.161.1\n61.61.61.1/24,162.162.162.1\n22.0.0.0/24,163.163.163.1\n22.0.0.0/24,164.164.164.1", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_61" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_61" - } - ], - "serviceNetworks": [ - { - "networkName": "rp6-sn2-first-arm", - "networkType": "ArmOneADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.166.1.1/24", - "gatewayIpV6Address": "2006:0101::1/64", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf:IT-ADC-RP6", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp6-sn2-first-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30014", - "suppressArp": "false", - "tag": "61111", - "trmEnabled": "false", - "vlanId": "601", - "vlanName": "rp6-sn2-first-arm", - "vrfName": "IT_VRF_61" - }, - "templateName": "Service_Network_Universal", - "vlanId": 601, - "vrfName": "IT_VRF_61" - } - ], - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 200 - }, - "create_rp7_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "TwoArmADC", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612504143911, - "nextHopIp": "", - "peeringName": "IT-ADC-RP7", - "peeringOption": "StaticPeering", - "reverseNextHopIp": "192.167.1.100", - "routes": [ - { - "nvPairs": { - "MULTI_ROUTES": "71.71.71.1/24,171.171.171.1\n71.71.71.1/24,172.172.172.1", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_71" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_71" - } - ], - "serviceNetworks": [ - { - "networkName": "rp7-sn2-first-arm", - "networkType": "ArmOneADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.167.1.1/24", - "gatewayIpV6Address": "2007:0101::1/64", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf:IT-ADC-RP7", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp7-sn2-first-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30015", - "suppressArp": "false", - "tag": "71111", - "trmEnabled": "false", - "vlanId": "701", - "vlanName": "rp7-sn2-first-arm", - "vrfName": "IT_VRF_71" - }, - "templateName": "Service_Network_Universal", - "vlanId": 701, - "vrfName": "IT_VRF_71" - }, - { - "networkName": "rp7-sn2-second-arm", - "networkType": "ArmTwoADC", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.167.2.1/24", - "gatewayIpV6Address": "2007:0102::1/64", - "intfDescription": "RP7 SN2 second arm intf lb:two:external:IT-SN-2:external-intf:IT-ADC-RP7", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "networkName": "rp7-sn2-second-arm", - "nveId": "1", - "rtBothAuto": "false", - "segmentId": "30016", - "suppressArp": "false", - "tag": "71112", - "trmEnabled": "false", - "vlanId": "702", - "vlanName": "rp7-sn2-second-arm", - "vrfName": "IT_VRF_71" - }, - "templateName": "Service_Network_Universal", - "vlanId": 702, - "vrfName": "IT_VRF_71" - } - ], - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC" - }, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings", - "RETURN_CODE": 200 - }, - - "deploy_rp1_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp2_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp3_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp4_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp5_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp6_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6/deployments", - "RETURN_CODE": 200 - }, - "deploy_rp7_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7/deployments", - "RETURN_CODE": 200 - }, - - "attach_rp1_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1/attachments", - "RETURN_CODE": 200 - }, - "attach_rp2_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2/attachments", - "RETURN_CODE": 200 - }, - "attach_rp3_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3/attachments", - "RETURN_CODE": 200 - }, - "attach_rp4_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4/attachments", - "RETURN_CODE": 200 - }, - "attach_rp5_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5/attachments", - "RETURN_CODE": 200 - }, - "attach_rp6_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6/attachments", - "RETURN_CODE": 200 - }, - "attach_rp7_resp" : { - "DATA": [{ - "switchAttaches": [ - { - "switchName": "dt-n9k2-1", - "switchSerialNumber": "SAL1819S6K3", - "switchIp": "10.122.84.175", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - }, - { - "switchName": "dt-n9k1", - "switchSerialNumber": "SAL1820SDPP", - "switchIp": "10.122.84.174", - "portNames": "Ethernet1/1", - "vlanId": 3000, - "attachState": "DEPLOYED", - "lanAttached": true - } - ] - }], - "MESSAGE": "", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7/attachments", - "RETURN_CODE": 200 - }, - "config_deploy_resp" : { - "DATA": { - "status": "Config deployment has been triggered" - }, - "MESSAGE": "OK", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/rest/control/fabrics/mmudigon/config-deploy", - "RETURN_CODE": 200 - }, - "detach_rp1_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1/attachments", - "RETURN_CODE": 200 - }, - "detach_rp2_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2/attachments", - "RETURN_CODE": 200 - }, - "detach_rp3_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3/attachments", - "RETURN_CODE": 200 - }, - "detach_rp4_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4/attachments", - "RETURN_CODE": 200 - }, - "detach_rp5_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5/attachments", - "RETURN_CODE": 200 - }, - "detach_rp6_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6/attachments", - "RETURN_CODE": 200 - }, - "detach_rp7_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7/attachments", - "RETURN_CODE": 200 - }, - "config_deploy_resp" : { - "DATA": { - "status": "Config deployment has been triggered" - }, - "MESSAGE": "OK", - "METHOD": "POST", - "REQUEST_PATH": "https://10.122.197.6:443/rest/control/fabrics/mmudigon/config-deploy", - "RETURN_CODE": 200 - }, - "delete_rp1_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1", - "RETURN_CODE": 200 - }, - "delete_rp2_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2", - "RETURN_CODE": 200 - }, - "delete_rp3_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3", - "RETURN_CODE": 200 - }, - "delete_rp4_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4", - "RETURN_CODE": 200 - }, - "delete_rp5_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5", - "RETURN_CODE": 200 - }, - "delete_rp6_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6", - "RETURN_CODE": 200 - }, - "delete_rp7_resp" : { - "DATA": {}, - "MESSAGE": "", - "METHOD": "DELETE", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7", - "RETURN_CODE": 200 - }, - - "have_it_sn1_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon", - "RETURN_CODE": 200, - "DATA": [{ - "peeringName": "IT-FW-RP1", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "None", - "deploymentMode": "IntraTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_11", - "networkName": "rp1-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 101, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "101", - "gatewayIpAddress": "192.161.1.1/24", - "networkName": "rp1-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp1-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP1 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "segmentId": "30005", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2001:0101::01/64", - "dhcpServerAddr2": "", - "tag": "11111", - "nveId": "1", - "vrfName": "IT_VRF_11" - } - }, - { - "vrfName": "IT_VRF_11", - "networkName": "rp1-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 102, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "102", - "gatewayIpAddress": "192.161.2.1/24", - "networkName": "rp1-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp1-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP1 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "segmentId": "30006", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2001:0102::1/64", - "dhcpServerAddr2": "", - "tag": "11112", - "nveId": "1", - "vrfName": "IT_VRF_11" - } - } - ], - "routes": [ - - ], - "nextHopIp": "192.161.1.100", - "reverseNextHopIp": "192.161.2.100", - "enabled": "True", - "lastUpdated": 1612867982779, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Network", - "resourceName": "rp1-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp1-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-FW-RP2", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "StaticPeering", - "deploymentMode": "InterTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_21", - "networkName": "rp2-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 201, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "201", - "gatewayIpAddress": "192.162.1.1/24", - "networkName": "rp2-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp2-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP2 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "segmentId": "30009", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2002:0101::1/64", - "dhcpServerAddr2": "", - "tag": "21111", - "nveId": "1", - "vrfName": "IT_VRF_21" - } - }, - { - "vrfName": "IT_VRF_22", - "networkName": "rp2-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 202, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "202", - "gatewayIpAddress": "192.162.2.1/24", - "networkName": "rp2-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp2-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP2 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "segmentId": "30010", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2002:0102::1/64", - "dhcpServerAddr2": "", - "tag": "22222", - "nveId": "1", - "vrfName": "IT_VRF_22" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_21", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_21", - "MULTI_ROUTES": "20.20.20.0/24,120.120.120.100\n20.20.20.0/24,121.121.121.100", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - }, - { - "vrfName": "IT_VRF_22", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_22", - "MULTI_ROUTES": "21.21.21.0/24,122.122.122.100\n21.21.21.0/24,123.123.123.100", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "enabled": "True", - "lastUpdated": 1612867989552, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_21~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Policy", - "resourceName": "IT_VRF_22~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp2-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp2-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-FW-RP3", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "InterTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_31", - "networkName": "rp3-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 301, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "301", - "gatewayIpAddress": "192.163.1.1/24", - "networkName": "rp3-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp3-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP3 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "segmentId": "30011", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2003:0101::1/64", - "dhcpServerAddr2": "", - "tag": "31111", - "nveId": "1", - "vrfName": "IT_VRF_31" - } - }, - { - "vrfName": "IT_VRF_32", - "networkName": "rp3-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 302, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "302", - "gatewayIpAddress": "192.163.2.1/24", - "networkName": "rp3-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp3-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP3 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "segmentId": "30012", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2003:0102::1/64", - "dhcpServerAddr2": "", - "tag": "31112", - "nveId": "1", - "vrfName": "IT_VRF_32" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_31", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "31.31.31.1", - "LOOPBACK_IP": "31.31.31.2", - "PEER_LOOPBACK_IP": "31.31.31.3", - "NEIGHBOR_IPV6": "2003:3131::1", - "LOOPBACK_IPV6": "2003:3132::01", - "PEER_LOOPBACK_IPV6": "2003:3133::01", - "ROUTE_MAP_TAG": "33111", - "DESC": "RP3 SN1 inside interface", - "LOCAL_ASN": "65301", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_31", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - }, - { - "vrfName": "IT_VRF_32", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "131.131.131.1", - "LOOPBACK_IP": "131.131.131.2", - "PEER_LOOPBACK_IP": "131.131.131.3", - "NEIGHBOR_IPV6": "2003:8383::1", - "LOOPBACK_IPV6": "2003:8384::1:100:1", - "PEER_LOOPBACK_IPV6": "2003:8385::1", - "ROUTE_MAP_TAG": "31113", - "DESC": "RP3 SN1 outside interface", - "LOCAL_ASN": "65302", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_32", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "enabled": "True", - "lastUpdated": 1612867999301, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_31~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Policy", - "resourceName": "IT_VRF_32~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp3-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp3-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - ] - }, - - "have_it_sn2_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon", - "RETURN_CODE": 200, - "DATA" : [ - { - "peeringName": "IT-ADC-RP4", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "OneArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_41", - "networkName": "rp4-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 401, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "401", - "gatewayIpAddress": "192.164.1.1/24", - "networkName": "rp4-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp4-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP4 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP4", - "segmentId": "30013", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2004:0101::1/64", - "dhcpServerAddr2": "", - "tag": "41111", - "nveId": "1", - "vrfName": "IT_VRF_41" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_41", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "41.41.41.1", - "LOOPBACK_IP": "41.41.41.2", - "PEER_LOOPBACK_IP": "41.41.41.3", - "NEIGHBOR_IPV6": "2004:4141::1", - "LOOPBACK_IPV6": "2004:4142::1", - "PEER_LOOPBACK_IPV6": "2004:4143::1", - "ROUTE_MAP_TAG": "41112", - "DESC": "RP4 SN2 first arm", - "LOCAL_ASN": "65401", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_41", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.164.1.100", - "enabled": "True", - "lastUpdated": 1612868008195, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_41~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp4-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-ADC-RP5", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "TwoArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_51", - "networkName": "rp5-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 501, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "501", - "gatewayIpAddress": "192.165.1.1/24", - "enableL3OnBorder": "false", - "vlanName": "rp5-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP5 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP5", - "segmentId": "30007", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2005:0101::1/64", - "dhcpServerAddr2": "", - "tag": "51111", - "nveId": "1", - "vrfName": "IT_VRF_51" - } - }, - { - "vrfName": "IT_VRF_51", - "networkName": "rp5-sn2-second-arm", - "networkType": "ArmTwoADC", - "vlanId": 502, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "502", - "gatewayIpAddress": "192.165.2.1/24", - "enableL3OnBorder": "false", - "vlanName": "rp5-sn2-second-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP5 SN2 second arm intf lb:two:external:IT-SN-2:external-intf-2:IT-ADC-RP5", - "segmentId": "30008", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2005:0102::1/64", - "dhcpServerAddr2": "", - "tag": "51112", - "nveId": "1", - "vrfName": "IT_VRF_51" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_51", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "51.51.51.1", - "LOOPBACK_IP": "51.51.51.2", - "PEER_LOOPBACK_IP": "51.51.51.3", - "NEIGHBOR_IPV6": "2005:5151::1", - "LOOPBACK_IPV6": "2005:5152::1", - "PEER_LOOPBACK_IPV6": "2005:5153::1", - "ROUTE_MAP_TAG": "51115", - "DESC": "RP5 SN2 first arm", - "LOCAL_ASN": "65501", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_51", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.165.1.100", - "enabled": "True", - "lastUpdated": 1612868017158, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_51~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp5-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp5-sn2-second-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-ADC-RP6", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "StaticPeering", - "deploymentMode": "OneArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_61", - "networkName": "rp6-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 601, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "601", - "gatewayIpAddress": "192.166.1.1/24", - "networkName": "rp6-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp6-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP6", - "segmentId": "30014", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2006:0101::1/64", - "dhcpServerAddr2": "", - "tag": "61111", - "nveId": "1", - "vrfName": "IT_VRF_61" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_61", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_61", - "MULTI_ROUTES": "61.61.61.1/24,161.161.161.1\n61.61.61.1/24,162.162.162.1\n22.0.0.0/24,163.163.163.1\n22.0.0.0/24,164.164.164.1", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.166.1.100", - "enabled": "True", - "lastUpdated": 1612868027172, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_61~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp6-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - }, - { - "peeringName": "IT-ADC-RP7", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "StaticPeering", - "deploymentMode": "TwoArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_71", - "networkName": "rp7-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 701, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "701", - "gatewayIpAddress": "192.167.1.1/24", - "networkName": "rp7-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp7-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP7", - "segmentId": "30015", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2007:0101::1/64", - "dhcpServerAddr2": "", - "tag": "71111", - "nveId": "1", - "vrfName": "IT_VRF_71" - } - }, - { - "vrfName": "IT_VRF_71", - "networkName": "rp7-sn2-second-arm", - "networkType": "ArmTwoADC", - "vlanId": 702, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "702", - "gatewayIpAddress": "192.167.2.1/24", - "networkName": "rp7-sn2-second-arm", - "enableL3OnBorder": "false", - "vlanName": "rp7-sn2-second-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP7 SN2 second arm intf lb:two:external:IT-SN-2:external-intf-2:IT-ADC-RP7", - "segmentId": "30016", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2007:0102::1/64", - "dhcpServerAddr2": "", - "tag": "71112", - "nveId": "1", - "vrfName": "IT_VRF_71" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_71", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_71", - "MULTI_ROUTES": "71.71.71.1/24,171.171.171.1\n71.71.71.1/24,172.172.172.1", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.167.1.100", - "enabled": "True", - "lastUpdated": 1612868035280, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_71~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp7-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp7-sn2-second-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - ] - }, - - "have_rp1_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-ADC-RP1", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-FW-RP1", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "None", - "deploymentMode": "IntraTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_11", - "networkName": "rp1-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 101, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "101", - "gatewayIpAddress": "192.161.1.1/24", - "networkName": "rp1-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp1-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP1 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "segmentId": "30005", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2001:0101::01/64", - "dhcpServerAddr2": "", - "tag": "11111", - "nveId": "1", - "vrfName": "IT_VRF_11" - } - }, - { - "vrfName": "IT_VRF_11", - "networkName": "rp1-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 102, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "102", - "gatewayIpAddress": "192.161.2.1/24", - "networkName": "rp1-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp1-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP1 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "segmentId": "30006", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2001:0102::1/64", - "dhcpServerAddr2": "", - "tag": "11112", - "nveId": "1", - "vrfName": "IT_VRF_11" - } - } - ], - "routes": [ - - ], - "nextHopIp": "192.161.1.100", - "reverseNextHopIp": "192.161.2.100", - "enabled": "True", - "lastUpdated": 1612867982779, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Network", - "resourceName": "rp1-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp1-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp2_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-ADC-RP2", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-FW-RP2", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "StaticPeering", - "deploymentMode": "InterTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_21", - "networkName": "rp2-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 201, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "201", - "gatewayIpAddress": "192.162.1.1/24", - "networkName": "rp2-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp2-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP2 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "segmentId": "30009", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2002:0101::1/64", - "dhcpServerAddr2": "", - "tag": "21111", - "nveId": "1", - "vrfName": "IT_VRF_21" - } - }, - { - "vrfName": "IT_VRF_22", - "networkName": "rp2-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 202, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "202", - "gatewayIpAddress": "192.162.2.1/24", - "networkName": "rp2-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp2-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP2 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "segmentId": "30010", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2002:0102::1/64", - "dhcpServerAddr2": "", - "tag": "22222", - "nveId": "1", - "vrfName": "IT_VRF_22" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_21", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_21", - "MULTI_ROUTES": "20.20.20.0/24,120.120.120.100\n20.20.20.0/24,121.121.121.100", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - }, - { - "vrfName": "IT_VRF_22", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_22", - "MULTI_ROUTES": "21.21.21.0/24,122.122.122.100\n21.21.21.0/24,123.123.123.100", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "enabled": "True", - "lastUpdated": 1612867989552, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_21~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Policy", - "resourceName": "IT_VRF_22~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp2-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp2-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp3_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-ADC-RP3", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-FW-RP3", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "InterTenantFW", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_31", - "networkName": "rp3-sn1-inside-net", - "networkType": "InsideNetworkFW", - "vlanId": 301, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "301", - "gatewayIpAddress": "192.163.1.1/24", - "networkName": "rp3-sn1-inside-net", - "enableL3OnBorder": "false", - "vlanName": "rp3-sn1-inside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP3 SN1 inside interface fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "segmentId": "30011", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2003:0101::1/64", - "dhcpServerAddr2": "", - "tag": "31111", - "nveId": "1", - "vrfName": "IT_VRF_31" - } - }, - { - "vrfName": "IT_VRF_32", - "networkName": "rp3-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "vlanId": 302, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "302", - "gatewayIpAddress": "192.163.2.1/24", - "networkName": "rp3-sn1-outside-net", - "enableL3OnBorder": "false", - "vlanName": "rp3-sn1-outside", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP3 SN1 outside interface fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "segmentId": "30012", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2003:0102::1/64", - "dhcpServerAddr2": "", - "tag": "31112", - "nveId": "1", - "vrfName": "IT_VRF_32" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_31", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "31.31.31.1", - "LOOPBACK_IP": "31.31.31.2", - "PEER_LOOPBACK_IP": "31.31.31.3", - "NEIGHBOR_IPV6": "2003:3131::1", - "LOOPBACK_IPV6": "2003:3132::01", - "PEER_LOOPBACK_IPV6": "2003:3133::01", - "ROUTE_MAP_TAG": "33111", - "DESC": "RP3 SN1 inside interface", - "LOCAL_ASN": "65301", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_31", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - }, - { - "vrfName": "IT_VRF_32", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "131.131.131.1", - "LOOPBACK_IP": "131.131.131.2", - "PEER_LOOPBACK_IP": "131.131.131.3", - "NEIGHBOR_IPV6": "2003:8383::1", - "LOOPBACK_IPV6": "2003:8384::1:100:1", - "PEER_LOOPBACK_IPV6": "2003:8385::1", - "ROUTE_MAP_TAG": "31113", - "DESC": "RP3 SN1 outside interface", - "LOCAL_ASN": "65302", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_32", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "enabled": "True", - "lastUpdated": 1612867999301, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_31~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Policy", - "resourceName": "IT_VRF_32~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp3-sn1-inside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp3-sn1-outside-net", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp4_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP4", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-ADC-RP4", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "OneArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_41", - "networkName": "rp4-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 401, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "401", - "gatewayIpAddress": "192.164.1.1/24", - "networkName": "rp4-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp4-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP4 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP4", - "segmentId": "30013", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2004:0101::1/64", - "dhcpServerAddr2": "", - "tag": "41111", - "nveId": "1", - "vrfName": "IT_VRF_41" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_41", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "41.41.41.1", - "LOOPBACK_IP": "41.41.41.2", - "PEER_LOOPBACK_IP": "41.41.41.3", - "NEIGHBOR_IPV6": "2004:4141::1", - "LOOPBACK_IPV6": "2004:4142::1", - "PEER_LOOPBACK_IPV6": "2004:4143::1", - "ROUTE_MAP_TAG": "41112", - "DESC": "RP4 SN2 first arm", - "LOCAL_ASN": "65401", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_41", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.164.1.100", - "enabled": "True", - "lastUpdated": 1612868008195, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_41~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp4-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp5_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP5", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-ADC-RP5", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "EBGPDynamicPeering", - "deploymentMode": "TwoArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_51", - "networkName": "rp5-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 501, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "501", - "gatewayIpAddress": "192.165.1.1/24", - "enableL3OnBorder": "false", - "vlanName": "rp5-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP5 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP5", - "segmentId": "30007", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2005:0101::1/64", - "dhcpServerAddr2": "", - "tag": "51111", - "nveId": "1", - "vrfName": "IT_VRF_51" - } - }, - { - "vrfName": "IT_VRF_51", - "networkName": "rp5-sn2-second-arm", - "networkType": "ArmTwoADC", - "vlanId": 502, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "502", - "gatewayIpAddress": "192.165.2.1/24", - "enableL3OnBorder": "false", - "vlanName": "rp5-sn2-second-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP5 SN2 second arm intf lb:two:external:IT-SN-2:external-intf-2:IT-ADC-RP5", - "segmentId": "30008", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2005:0102::1/64", - "dhcpServerAddr2": "", - "tag": "51112", - "nveId": "1", - "vrfName": "IT_VRF_51" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_51", - "templateName": "service_ebgp_route", - "nvPairs": { - "NEIGHBOR_IP": "51.51.51.1", - "LOOPBACK_IP": "51.51.51.2", - "PEER_LOOPBACK_IP": "51.51.51.3", - "NEIGHBOR_IPV6": "2005:5151::1", - "LOOPBACK_IPV6": "2005:5152::1", - "PEER_LOOPBACK_IPV6": "2005:5153::1", - "ROUTE_MAP_TAG": "51115", - "DESC": "RP5 SN2 first arm", - "LOCAL_ASN": "65501", - "ADVERTISE_HOST_ROUTE": "true", - "ADMIN_STATE": "true", - "VRF_NAME": "IT_VRF_51", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.165.1.100", - "enabled": "True", - "lastUpdated": 1612868017158, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_51~service_ebgp_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp5-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp5-sn2-second-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp6_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP6", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-ADC-RP6", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "StaticPeering", - "deploymentMode": "OneArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_61", - "networkName": "rp6-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 601, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "601", - "gatewayIpAddress": "192.166.1.1/24", - "networkName": "rp6-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp6-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP6", - "segmentId": "30014", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2006:0101::1/64", - "dhcpServerAddr2": "", - "tag": "61111", - "nveId": "1", - "vrfName": "IT_VRF_61" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_61", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_61", - "MULTI_ROUTES": "61.61.61.1/24,161.161.161.1\n61.61.61.1/24,162.162.162.1\n22.0.0.0/24,163.163.163.1\n22.0.0.0/24,164.164.164.1", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.166.1.100", - "enabled": "True", - "lastUpdated": 1612868027172, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_61~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp6-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - "have_rp7_resp": { - "MESSAGE": "", - "METHOD": "GET", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-2/peerings/mmudigon/IT-ADC-RP7", - "RETURN_CODE": 200, - "DATA": { - "peeringName": "IT-ADC-RP7", - "fabricName": "external", - "attachedFabricName": "mmudigon", - "serviceNodeName": "IT-SN-2", - "serviceNodeType": "ADC", - "peeringOption": "StaticPeering", - "deploymentMode": "TwoArmADC", - "serviceNetworks": [ - { - "vrfName": "IT_VRF_71", - "networkName": "rp7-sn2-first-arm", - "networkType": "ArmOneADC", - "vlanId": 701, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "701", - "gatewayIpAddress": "192.167.1.1/24", - "networkName": "rp7-sn2-first-arm", - "enableL3OnBorder": "false", - "vlanName": "rp7-sn2-first-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP6 SN2 first arm intf lb:one:external:IT-SN-2:external-intf-2:IT-ADC-RP7", - "segmentId": "30015", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2007:0101::1/64", - "dhcpServerAddr2": "", - "tag": "71111", - "nveId": "1", - "vrfName": "IT_VRF_71" - } - }, - { - "vrfName": "IT_VRF_71", - "networkName": "rp7-sn2-second-arm", - "networkType": "ArmTwoADC", - "vlanId": 702, - "templateName": "Service_Network_Universal", - "nvPairs": { - "suppressArp": "false", - "loopbackId": "", - "vlanId": "702", - "gatewayIpAddress": "192.167.2.1/24", - "networkName": "rp7-sn2-second-arm", - "enableL3OnBorder": "false", - "vlanName": "rp7-sn2-second-arm", - "enableIR": "false", - "rtBothAuto": "false", - "isLayer2Only": "false", - "intfDescription": "RP7 SN2 second arm intf lb:two:external:IT-SN-2:external-intf-2:IT-ADC-RP7", - "segmentId": "30016", - "mcastGroup": "239.1.1.0", - "dhcpServerAddr3": "", - "trmEnabled": "false", - "gatewayIpV6Address": "2007:0102::1/64", - "dhcpServerAddr2": "", - "tag": "71112", - "nveId": "1", - "vrfName": "IT_VRF_71" - } - } - ], - "routes": [ - { - "vrfName": "IT_VRF_71", - "templateName": "service_static_route", - "nvPairs": { - "VRF_NAME": "IT_VRF_71", - "MULTI_ROUTES": "71.71.71.1/24,171.171.171.1\n71.71.71.1/24,172.172.172.1", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "NEIGHBOR_ASN": "1500" - } - } - ], - "nextHopIp": "", - "reverseNextHopIp": "192.167.1.100", - "enabled": "True", - "lastUpdated": 1612868035280, - "status": "In-Sync", - "statusDetails": [ - { - "resourceType": "Policy", - "resourceName": "IT_VRF_71~service_static_route", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp7-sn2-first-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - }, - { - "resourceType": "Network", - "resourceName": "rp7-sn2-second-arm", - "fabricName": "mmudigon", - "switchStatuses": [ - { - "switchSerialNumber": "SAL1819S6K3", - "status": "In-Sync", - "updatedBy": "config-compliance", - "updatedTime": 1612868242683 - } - ] - } - ] - } - }, - - "replaced_rp1_resp" : { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "IntraTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612942460116, - "nextHopIp": "192.161.1.200", - "peeringName": "IT-FW-RP1", - "peeringOption": "None", - "reverseNextHopIp": "192.161.2.200", - "routes": [], - "serviceNetworks": [ - { - "networkName": "rp1-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.161.1.1/24", - "gatewayIpV6Address": "2101:0101::01/64", - "intfDescription": "RP1 SN1 inside interface - REP fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "11101", - "trmEnabled": "false", - "vlanId": "191", - "vlanName": "rp1-sn1-inside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 191, - "vrfName": "IT_VRF_11" - }, - { - "networkName": "rp1-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.161.2.1/24", - "gatewayIpV6Address": "2101:0102::1/64", - "intfDescription": "RP1 SN1 outside interface- REP fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP1", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "11102", - "trmEnabled": "false", - "vlanId": "192", - "vlanName": "rp1-sn1-outside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 192, - "vrfName": "IT_VRF_11" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "PUT", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP1", - "RETURN_CODE": 200 - }, - "replaced_rp2_resp": { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "InterTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612942469457, - "peeringName": "IT-FW-RP2", - "peeringOption": "StaticPeering", - "routes": [ - { - "nvPairs": { - "MULTI_ROUTES": "20.20.90.0/24,120.120.190.100\n20.20.90.0/24,121.121.191.100", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_21" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_21" - }, - { - "nvPairs": { - "MULTI_ROUTES": "21.21.29.0/24,122.122.129.100\n21.21.29.0/24,123.123.129.100", - "NEIGHBOR_ASN": "1500", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_22" - }, - "templateName": "service_static_route", - "vrfName": "IT_VRF_22" - } - ], - "serviceNetworks": [ - { - "networkName": "rp2-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.162.1.1/24", - "gatewayIpV6Address": "2102:0101::1/64", - "intfDescription": "RP2 SN1 inside interface - REP fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "21101", - "trmEnabled": "false", - "vlanId": "291", - "vlanName": "rp2-sn1-inside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 291, - "vrfName": "IT_VRF_21" - }, - { - "networkName": "rp2-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.162.2.1/24", - "gatewayIpV6Address": "2102:0102::1/64", - "intfDescription": "RP2 SN1 outside interface - REP fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP2", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "22202", - "trmEnabled": "false", - "vlanId": "292", - "vlanName": "rp2-sn1-outside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 292, - "vrfName": "IT_VRF_22" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "PUT", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP2", - "RETURN_CODE": 200 - }, - - "replaced_rp3_resp": { - "DATA": { - "attachedFabricName": "mmudigon", - "deploymentMode": "InterTenantFW", - "enabled": true, - "fabricName": "external", - "lastUpdated": 1612942479141, - "peeringName": "IT-FW-RP3", - "peeringOption": "EBGPDynamicPeering", - "routes": [ - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP3 SN1 inside interface - REP", - "LOCAL_ASN": "65391", - "LOOPBACK_IP": "31.31.39.2", - "LOOPBACK_IPV6": "2103:3132::01", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "31.31.39.1", - "NEIGHBOR_IPV6": "2103:3131::1", - "PEER_LOOPBACK_IP": "31.31.39.3", - "PEER_LOOPBACK_IPV6": "2103:3133::01", - "ROUTE_MAP_TAG": "33101", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_31" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_31" - }, - { - "nvPairs": { - "ADMIN_STATE": "true", - "ADVERTISE_HOST_ROUTE": "true", - "DESC": "RP3 SN1 outside interface - REP", - "LOCAL_ASN": "65392", - "LOOPBACK_IP": "131.131.139.2", - "LOOPBACK_IPV6": "2103:8384::1:100:1", - "NEIGHBOR_ASN": "1500", - "NEIGHBOR_IP": "131.131.139.1", - "NEIGHBOR_IPV6": "2103:8383::1", - "PEER_LOOPBACK_IP": "131.131.139.3", - "PEER_LOOPBACK_IPV6": "2103:8385::1", - "ROUTE_MAP_TAG": "31103", - "SERVICE_LEAF_SWITCH": "SAL1819S6K3", - "VRF_NAME": "IT_VRF_32" - }, - "templateName": "service_ebgp_route", - "vrfName": "IT_VRF_32" - } - ], - "serviceNetworks": [ - { - "networkName": "rp3-sn1-inside-net", - "networkType": "InsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.163.1.1/24", - "gatewayIpV6Address": "2103:0101::1/64", - "intfDescription": "RP3 SN1 inside interface - REP fw:inside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "31101", - "trmEnabled": "false", - "vlanId": "391", - "vlanName": "rp3-sn1-inside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 391, - "vrfName": "IT_VRF_31" - }, - { - "networkName": "rp3-sn1-outside-net", - "networkType": "OutsideNetworkFW", - "nvPairs": { - "enableIR": "false", - "enableL3OnBorder": "false", - "gatewayIpAddress": "192.163.2.1/24", - "gatewayIpV6Address": "2103:0102::1/64", - "intfDescription": "RP3 SN1 outside interface - REP fw:outside:external:IT-SN-1:external-intf-1:IT-FW-RP3", - "isLayer2Only": "false", - "mcastGroup": "239.1.1.0", - "rtBothAuto": "false", - "suppressArp": "false", - "tag": "31102", - "trmEnabled": "false", - "vlanId": "302", - "vlanName": "rp3-sn1-outside-rep" - }, - "templateName": "Service_Network_Universal", - "vlanId": 302, - "vrfName": "IT_VRF_32" - } - ], - "serviceNodeName": "IT-SN-1", - "serviceNodeType": "Firewall" - }, - "MESSAGE": "", - "METHOD": "PUT", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/fabrics/external/service-nodes/IT-SN-1/peerings/mmudigon/IT-FW-RP3", - "RETURN_CODE": 200 - }, - - "serv_nodes_resp" : { - "MESSAGE": "", - "METHOD": "PUT", - "REQUEST_PATH": "https://10.122.197.6:443/appcenter/Cisco/elasticservice/elasticservice-api/?atached-fabric=mmudigon", - "RETURN_CODE": 200, - "DATA" :[ - { - "name" : "IT-SN-1" - }, - { - "name" : "IT-SN-2" - } - ] - } -} - diff --git a/tests/unit/modules/dcnm/test_dcnm_service_node.py b/tests/unit/modules/dcnm/test_dcnm_service_node.py deleted file mode 100644 index 94aff6f2e..000000000 --- a/tests/unit/modules/dcnm/test_dcnm_service_node.py +++ /dev/null @@ -1,499 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2021 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from ansible_collections.ansible.netcommon.tests.unit.compat.mock import patch - -from ansible_collections.cisco.dcnm.plugins.modules import dcnm_service_node -from .dcnm_module import TestDcnmModule, set_module_args, loadPlaybookData - -import json, copy - -__copyright__ = "Copyright (c) 2021 Cisco and/or its affiliates." -__author__ = "Karthik Babu Harichandra Babu" - -class TestDcnmServiceNodeModule(TestDcnmModule): - - module = dcnm_service_node - - test_data = loadPlaybookData('dcnm_service_node') - - SUCCESS_RETURN_CODE = 200 - - mock_ip_sn = test_data.get('mock_ip_sn') - sn_inv_data = test_data.get('sn_inv_data') - playbook_config = test_data.get('playbook_config') - playbook_config_replace_new = test_data.get('playbook_config_replace_new') - playbook_config_replace_new1 = test_data.get('playbook_config_replace_new1') - playbook_new_config = test_data.get('playbook_new_config') - playbook_config_virtual = test_data.get('playbook_config_virtual') - playbook_config_load = test_data.get('playbook_config_load') - playbook_config_vnf = test_data.get('playbook_config_vnf') - playbook_config_vpc = test_data.get('playbook_config_vpc') - playbook_config_invalid_vpc = test_data.get('playbook_config_invalid_vpc') - playbook_config_no_params = test_data.get('playbook_config_no_params') - playbook_config_no_type = test_data.get('playbook_config_no_type') - playbook_config_no_ff = test_data.get('playbook_config_no_ff') - playbook_config_no_vpc = test_data.get('playbook_config_no_vpc') - playbook_config_more_switch = test_data.get('playbook_config_more_switch') - playbook_config_name = test_data.get('playbook_config_name') - playbook_over_config = test_data.get('playbook_over_config') - playbook_config_query = test_data.get('playbook_config_query') - get_have_failure = test_data.get('get_have_failure') - blank_data = test_data.get('blank_data') - blank_data_null = test_data.get('blank_data_null') - blank_get_data = test_data.get('blank_get_data') - error1 = test_data.get('error1') - sn_delete_success_resp = test_data.get('sn_delete_success_resp') - sn_query_success_resp = test_data.get('sn_query_success_resp') - - def init_data(self): - # Some of the mock data is re-initialized after each test as previous test might have altered portions - # of the mock data. - - self.mock_sn_1_object = copy.deepcopy(self.test_data.get('mock_sn_1_object')) - self.mock_sn_merge_1_success = copy.deepcopy(self.test_data.get('mock_sn_merge_1_success')) - self.mock_sn_merge_2_success = copy.deepcopy(self.test_data.get('mock_sn_merge_2_success')) - self.mock_sn_merge_3_success = copy.deepcopy(self.test_data.get('mock_sn_merge_3_success')) - self.mock_sn_merge_4_success = copy.deepcopy(self.test_data.get('mock_sn_merge_4_success')) - self.mock_sn_merge_5_success = copy.deepcopy(self.test_data.get('mock_sn_merge_5_success')) - self.mock_sn_merge_6_success = copy.deepcopy(self.test_data.get('mock_sn_merge_6_success')) - self.mock_sn_replace_1_success = copy.deepcopy(self.test_data.get('mock_sn_replace_1_success')) - self.mock_sn_replace_2_success = copy.deepcopy(self.test_data.get('mock_sn_replace_2_success')) - self.mock_sn_have_success = copy.deepcopy(self.test_data.get('mock_sn_have_success')) - self.mock_sn_query_success = copy.deepcopy(self.test_data.get('mock_sn_query_success')) - - def setUp(self): - super(TestDcnmServiceNodeModule, self).setUp() - - self.mock_dcnm_ip_sn = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_node.get_fabric_inventory_details') - self.run_dcnm_ip_sn = self.mock_dcnm_ip_sn.start() - - self.mock_dcnm_send = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_node.dcnm_send') - self.run_dcnm_send = self.mock_dcnm_send.start() - - def tearDown(self): - super(TestDcnmServiceNodeModule, self).tearDown() - self.mock_dcnm_send.stop() - self.mock_dcnm_ip_sn.stop() - - def load_fixtures(self, response=None, device=''): - - if 'sn_blank_fabric' in self._testMethodName: - self.run_dcnm_ip_sn.side_effect = [{}] - else: - self.run_dcnm_ip_sn.side_effect = [self.sn_inv_data] - - if 'get_have_failure' in self._testMethodName: - self.run_dcnm_send.side_effect = [self.get_have_failure] - - elif '_check_mode' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_get_data] - - elif '_merged_one' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_1_success] - - elif '_merged_two' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_2_success] - - elif '_merged_three' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_3_success] - - elif '_merged_four' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_4_success] - - elif '_merged_five' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_5_success] - - elif 'error1' in self._testMethodName: - self.run_dcnm_send.side_effect = [self.blank_data, self.error1, self.blank_data] - - elif '_merged_invalid_vpc' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_params' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_type' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_ff' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_more_switch' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif '_merged_no_vpc' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif 'delete_std' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.sn_delete_success_resp] - - elif 'delete_all' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.sn_delete_success_resp] - - elif 'query_no' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.sn_query_success_resp] - - elif 'query_on' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success,self.mock_sn_have_success] - - elif 'query_without_config' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success,self.mock_sn_have_success] - - elif 'query_withonly_name' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success,self.mock_sn_have_success] - - elif 'query_invalid_param' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [] - - elif 'query_null' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data_null] - - elif 'override_with_additions' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.blank_data, self.mock_sn_merge_1_success] - - elif 'override_with_deletions' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.sn_delete_success_resp, self.mock_sn_merge_6_success] - - elif 'override_without_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success] - - elif 'replace_with_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.mock_sn_replace_1_success] - - elif 'replace_with_type_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success, self.mock_sn_replace_2_success] - - elif 'replace_without_changes' in self._testMethodName: - self.init_data() - self.run_dcnm_send.side_effect = [self.mock_sn_have_success] - - else: - pass - - def test_dcnm_sn_blank_fabric(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric test_fabric missing on DCNM or does not have any switches') - - def test_dcnm_sn_get_have_failure(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric test_fabric not present on DCNM') - - def test_dcnm_sn_check_mode(self): - set_module_args(dict(check_mode=True, state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertFalse(result.get('response')) - - def test_dcnm_sn_merged_one(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_two(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_virtual)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_three(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_load)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'AVB') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_four(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_vnf)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'VNF') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_merged_five(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_vpc)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'vPC1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_error1(self): - set_module_args(dict(state='merged', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result['msg']['RETURN_CODE'], 400) - self.assertEqual(result['msg']['ERROR'], 'There is an error') - - def test_dcnm_sn_merged_invalid_vpc(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_invalid_vpc)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric: test_fabric - if two switches are provided, vpc is only interface option') - - def test_dcnm_sn_merged_more_switch(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_more_switch)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric: test_fabric - Upto 2 switches only allowed') - - def test_dcnm_sn_merged_no_params(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_params)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'config: element is mandatory for this state merged') - - def test_dcnm_sn_merged_no_type(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_type)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Invalid parameters in playbook: karth : Invalid choice provided') - - def test_dcnm_sn_merged_no_ff(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_ff)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Invalid parameters in playbook: babu : Invalid choice provided') - - def test_dcnm_sn_merged_no_vpc(self): - set_module_args(dict(state='merged', - fabric='test_fabric', - service_fabric='external', config=self.playbook_config_no_vpc)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Fabric: test_fabric - For 1 switch, vpc is not the interface option') - - def test_dcnm_sn_delete_std(self): - set_module_args(dict(state='deleted', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'DELETE') - - def test_dcnm_sn_delete_all(self): - set_module_args(dict(state='deleted', fabric='test_fabric', - service_fabric='external', config=[])) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'DELETE') - - def test_dcnm_sn_query_no(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result.get('response'), []) - - def test_dcnm_sn_query_on(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result['response'][0]['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['fabricName'], 'external') - self.assertEqual(result['response'][0]['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['name'], 'SN-11') - self.assertEqual(result['response'][0]['type'], 'Firewall') - - def test_dcnm_sn_query_without_config(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=[])) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result['response'][0]['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['fabricName'], 'external') - self.assertEqual(result['response'][0]['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['name'], 'SN-11') - self.assertEqual(result['response'][0]['type'], 'Firewall') - - def test_dcnm_sn_query_withonly_name(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_name)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertEqual(result['response'][0]['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['fabricName'], 'external') - self.assertEqual(result['response'][0]['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['name'], 'SN-11') - self.assertEqual(result['response'][0]['type'], 'Firewall') - - def test_dcnm_sn_query_invalid_param(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_query)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Invalid parameters in playbook: name : Required parameter not found') - - def test_dcnm_sn_query_null(self): - set_module_args(dict(state='query', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=False, failed=True) - self.assertEqual(result.get('msg'), 'Unable to Service Node under fabric: test_fabric') - - def test_dcnm_sn_override_with_additions(self): - set_module_args(dict(state='overridden', fabric='test_fabric', - service_fabric='external', config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Physical') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv1') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_override_with_deletions(self): - set_module_args(dict(state='overridden', fabric='test_fabric', - service_fabric='external', config=self.playbook_new_config)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'DELETE') - self.assertEqual(result['response'][1]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][1]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/2') - self.assertEqual(result['response'][1]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][1]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][1]['DATA']['interfaceName'], 'scv12') - self.assertEqual(result['response'][1]['DATA']['name'], 'SN-12') - self.assertEqual(result['response'][1]['DATA']['type'], 'ADC') - self.assertEqual(result['response'][1]['RETURN_CODE'], 200) - - def test_dcnm_sn_override_without_changes(self): - set_module_args(dict(state='overridden', fabric='test_fabric', - service_fabric='external', config=self.playbook_over_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertFalse(result.get('response')) - - def test_dcnm_sn_replace_with_changes(self): - set_module_args(dict(state='replaced', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_replace_new)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'PUT') - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv11') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'Firewall') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_replace_with_type_changes(self): - set_module_args(dict(state='replaced', fabric='test_fabric', - service_fabric='external', config=self.playbook_config_replace_new1)) - result = self.execute_module(changed=True, failed=False) - self.assertEqual(result['response'][0]['RETURN_CODE'], self.SUCCESS_RETURN_CODE) - self.assertEqual(result['response'][0]['METHOD'], 'PUT') - self.assertEqual(result['response'][0]['DATA']['attachedFabricName'], 'test_fabric') - self.assertEqual(result['response'][0]['DATA']['attachedSwitchInterfaceName'], 'Ethernet1/1') - self.assertEqual(result['response'][0]['DATA']['fabricName'], 'external') - self.assertEqual(result['response'][0]['DATA']['formFactor'], 'Virtual') - self.assertEqual(result['response'][0]['DATA']['interfaceName'], 'scv11') - self.assertEqual(result['response'][0]['DATA']['name'], 'SN-11') - self.assertEqual(result['response'][0]['DATA']['type'], 'ADC') - self.assertEqual(result['response'][0]['RETURN_CODE'], 200) - - def test_dcnm_sn_replace_without_changes(self): - set_module_args(dict(state='replaced', fabric='test_fabric', - service_fabric='external', config=self.playbook_over_config)) - result = self.execute_module(changed=False, failed=False) - self.assertFalse(result.get('diff')) - self.assertFalse(result.get('response')) diff --git a/tests/unit/modules/dcnm/test_dcnm_service_route_peering.py b/tests/unit/modules/dcnm/test_dcnm_service_route_peering.py deleted file mode 100644 index 80d8582f5..000000000 --- a/tests/unit/modules/dcnm/test_dcnm_service_route_peering.py +++ /dev/null @@ -1,1839 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2020 Cisco and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -from ansible_collections.ansible.netcommon.tests.unit.compat.mock import patch - -from ansible_collections.cisco.dcnm.plugins.modules import dcnm_service_route_peering -from .dcnm_module import TestDcnmModule, set_module_args, loadPlaybookData - -import json, copy - -class TestDcnmServiceRoutePeeringModule(TestDcnmModule): - - module = dcnm_service_route_peering - fd = None - - def init_data(self): - self.fd = None - - def log_msg (self, msg): - - if (self.fd is None): - self.fd = open("srp-ut.log", "w+") - self.fd.write (msg) - - def setUp(self): - - super(TestDcnmServiceRoutePeeringModule, self).setUp() - - self.mock_dcnm_send = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_route_peering.dcnm_send') - self.run_dcnm_send = self.mock_dcnm_send.start() - - self.mock_dcnm_reset_connection = patch('ansible_collections.cisco.dcnm.plugins.modules.dcnm_service_route_peering.dcnm_reset_connection') - self.run_dcnm_reset_connection = self.mock_dcnm_reset_connection.start() - def tearDown(self): - - super(TestDcnmServiceRoutePeeringModule, self).tearDown() - self.mock_dcnm_send.stop() - self.mock_dcnm_reset_connection.stop() - -#################################### FIXTURES ############################ - - def load_srp_fixtures (self): - - if ('test_dcnm_srp_merged_new' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - deploy_rp4_resp_unauth_err = self.payloads_data.get('deploy_rp4_resp_unauth_err') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp_unauth_err, deploy_rp4_resp, - deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merged_new_no_opt_elems' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merged_existing_no_opt_elems' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - att_rp4_status = self.payloads_data.get('attach_rp4_resp') - att_rp5_status = self.payloads_data.get('attach_rp5_resp') - att_rp6_status = self.payloads_data.get('attach_rp6_resp') - att_rp7_status = self.payloads_data.get('attach_rp7_resp') - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - att_rp1_status, att_rp2_status, att_rp3_status, - att_rp4_status, att_rp5_status, att_rp6_status, - att_rp7_status, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merged_new_check_mode' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp] - - - if ('test_dcnm_srp_merged_new_unauth_error' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - create_rp7_resp_unauth_err = self.payloads_data.get('create_rp7_resp_unauth_err') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp_unauth_err, have_rp7_resp, create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_config_without_state' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - - deploy_rp7_resp] - if ('test_dcnm_srp_merge_no_deploy' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merge_deploy_false' == self._testMethodName): - - have_rp1_resp = [] - have_rp2_resp = [] - have_rp3_resp = [] - have_rp4_resp = [] - have_rp5_resp = [] - have_rp6_resp = [] - have_rp7_resp = [] - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp5_resp = self.payloads_data.get('create_rp5_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - create_rp4_resp, create_rp5_resp, create_rp6_resp, - create_rp7_resp] - - - if ('test_dcnm_srp_merged_existing' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - att_rp4_status = self.payloads_data.get('attach_rp4_resp') - att_rp5_status = self.payloads_data.get('attach_rp5_resp') - att_rp6_status = self.payloads_data.get('attach_rp6_resp') - att_rp7_status = self.payloads_data.get('attach_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - att_rp1_status, att_rp2_status, att_rp3_status, - att_rp4_status, att_rp5_status, att_rp6_status, - att_rp7_status] - - if ('test_dcnm_srp_merged_existing_and_non_existing' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - att_rp5_status = self.payloads_data.get('attach_rp5_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - create_rp7_resp = self.payloads_data.get('create_rp7_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, [], have_rp3_resp, - [], have_rp5_resp, [], [], - att_rp1_status, att_rp3_status, - att_rp5_status, - create_rp2_resp, create_rp4_resp, create_rp6_resp, - create_rp7_resp, - deploy_rp2_resp, deploy_rp4_resp, deploy_rp6_resp, - deploy_rp7_resp] - - if ('test_dcnm_srp_merged_update_existing' == self._testMethodName): - - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp4_status = self.payloads_data.get('attach_rp4_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - - self.run_dcnm_send.side_effect = [have_rp2_resp, have_rp4_resp, - att_rp2_status, att_rp4_status, - create_rp2_resp, create_rp4_resp, - deploy_rp2_resp, deploy_rp4_resp] - - if ('test_dcnm_srp_merged_update_existing_unauth_err' == self._testMethodName): - - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp4_status = self.payloads_data.get('attach_rp4_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp4_resp = self.payloads_data.get('create_rp4_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - - create_rp4_resp_unauth_err = self.payloads_data.get('create_rp4_resp_unauth_err') - - self.run_dcnm_send.side_effect = [have_rp2_resp, have_rp4_resp, - att_rp2_status, att_rp4_status, - create_rp2_resp, - create_rp4_resp_unauth_err, - create_rp4_resp, - deploy_rp2_resp, deploy_rp4_resp] - - if ('test_dcnm_srp_delete_existing' == self._testMethodName): - - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp] - - if ('test_dcnm_srp_delete_existing_unauth_err' == self._testMethodName): - - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - det_rp1_resp_unauth_err = self.payloads_data.get('det_rp1_resp_unauth_err') - deploy_rp4_resp_unauth_err = self.payloads_data.get('deploy_rp4_resp_unauth_err') - delete_rp7_resp_unauth_err = self.payloads_data.get('delete_rp7_resp_unauth_err') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp, - det_rp1_resp_unauth_err, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp_unauth_err, deploy_rp4_resp, - deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp_unauth_err, deploy_rp7_resp, delete_rp7_resp] - - if ('test_dcnm_srp_delete_existing_and_non_existing' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [have_rp1_resp, [], have_rp3_resp, - [], [], have_rp6_resp, - have_rp7_resp, - det_rp1_resp, det_rp3_resp, - det_rp6_resp, det_rp7_resp, - deploy_rp1_resp, deploy_rp3_resp, - deploy_rp6_resp, deploy_rp7_resp, - delete_rp1_resp, delete_rp3_resp, - delete_rp6_resp, delete_rp7_resp] - - if ('test_dcnm_srp_delete_non_existing' == self._testMethodName): - - self.run_dcnm_send.side_effect = [[], [], [], [], [], [], []] - - if ('test_dcnm_srp_replace_rp1_to_rp3_non_existing' == self._testMethodName): - - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - - self.run_dcnm_send.side_effect = [[], [], [], - create_rp1_resp, create_rp2_resp, create_rp3_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp] - - if ('test_dcnm_srp_replace_rp1_to_rp3_existing' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - create_rp3_resp = self.payloads_data.get('create_rp3_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - att_rp1_status, att_rp2_status, att_rp3_status, - create_rp1_resp, create_rp2_resp, create_rp3_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp] - - if ('test_dcnm_srp_replace_rp1_to_rp3_existing_no_change' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - att_rp1_status = self.payloads_data.get('attach_rp1_resp') - att_rp2_status = self.payloads_data.get('attach_rp2_resp') - att_rp3_status = self.payloads_data.get('attach_rp3_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - att_rp1_status, att_rp2_status, att_rp3_status] - - if ('test_dcnm_srp_override_rp1_rp7_with_new_peerings' == self._testMethodName): - - have_it_sn1_resp = self.payloads_data.get('have_it_sn1_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - create_rp1_resp = self.payloads_data.get('create_rp1_resp') - create_rp2_resp = self.payloads_data.get('create_rp2_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [[], [], - have_it_sn1_resp, have_it_sn2_resp, - create_rp1_resp, create_rp2_resp, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp, deploy_rp1_resp, deploy_rp2_resp - ] - - if ('test_dcnm_srp_override_with_existing_peering' == self._testMethodName): - - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - att_rp6_status = self.payloads_data.get('attach_rp6_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [have_rp6_resp, - have_it_sn2_resp, att_rp6_status, - det_rp4_resp, det_rp5_resp, - det_rp7_resp, - deploy_rp4_resp, deploy_rp5_resp, - deploy_rp7_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp7_resp - ] - - if ('test_dcnm_srp_override_with_existing_peering_updated' == self._testMethodName): - - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - create_rp6_resp = self.payloads_data.get('create_rp6_resp') - att_rp6_status = self.payloads_data.get('attach_rp6_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp6_resp, - have_it_sn2_resp, att_rp6_status, - create_rp6_resp, - det_rp4_resp, det_rp5_resp, - det_rp7_resp, - deploy_rp4_resp, deploy_rp5_resp, - deploy_rp7_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp7_resp, - deploy_rp6_resp - ] - - if ('test_dcnm_srp_override_with_service_nodes_alone' == self._testMethodName): - - have_it_sn1_resp = self.payloads_data.get('have_it_sn1_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [have_it_sn1_resp, have_it_sn2_resp, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp - ] - - if ('test_dcnm_srp_override_with_no_config' == self._testMethodName): - - serv_nodes_resp = self.payloads_data.get('serv_nodes_resp') - have_it_sn1_resp = self.payloads_data.get('have_it_sn1_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - det_rp1_resp = self.payloads_data.get('detach_rp1_resp') - det_rp2_resp = self.payloads_data.get('detach_rp2_resp') - det_rp3_resp = self.payloads_data.get('detach_rp3_resp') - det_rp4_resp = self.payloads_data.get('detach_rp4_resp') - det_rp5_resp = self.payloads_data.get('detach_rp5_resp') - det_rp6_resp = self.payloads_data.get('detach_rp6_resp') - det_rp7_resp = self.payloads_data.get('detach_rp7_resp') - delete_rp1_resp = self.payloads_data.get('delete_rp1_resp') - delete_rp2_resp = self.payloads_data.get('delete_rp2_resp') - delete_rp3_resp = self.payloads_data.get('delete_rp3_resp') - delete_rp4_resp = self.payloads_data.get('delete_rp4_resp') - delete_rp5_resp = self.payloads_data.get('delete_rp5_resp') - delete_rp6_resp = self.payloads_data.get('delete_rp6_resp') - delete_rp7_resp = self.payloads_data.get('delete_rp7_resp') - deploy_rp1_resp = self.payloads_data.get('deploy_rp1_resp') - deploy_rp2_resp = self.payloads_data.get('deploy_rp2_resp') - deploy_rp3_resp = self.payloads_data.get('deploy_rp3_resp') - deploy_rp4_resp = self.payloads_data.get('deploy_rp4_resp') - deploy_rp5_resp = self.payloads_data.get('deploy_rp5_resp') - deploy_rp6_resp = self.payloads_data.get('deploy_rp6_resp') - deploy_rp7_resp = self.payloads_data.get('deploy_rp7_resp') - - - self.run_dcnm_send.side_effect = [serv_nodes_resp, - have_it_sn1_resp, have_it_sn2_resp, - det_rp1_resp, det_rp2_resp, - det_rp3_resp, det_rp4_resp, - det_rp5_resp, det_rp6_resp, - det_rp7_resp, - deploy_rp1_resp, deploy_rp2_resp, deploy_rp3_resp, - deploy_rp4_resp, deploy_rp5_resp, deploy_rp6_resp, - deploy_rp7_resp, - delete_rp1_resp, delete_rp2_resp, delete_rp3_resp, - delete_rp4_resp, delete_rp5_resp, delete_rp6_resp, - delete_rp7_resp - ] - - if ('test_dcnm_srp_query_non_existing' == self._testMethodName): - - self.run_dcnm_send.side_effect = [[],[]] - - if ('test_dcnm_srp_query_with_service_nodes' == self._testMethodName): - - have_it_sn1_resp = self.payloads_data.get('have_it_sn1_resp') - have_it_sn2_resp = self.payloads_data.get('have_it_sn2_resp') - - self.run_dcnm_send.side_effect = [have_it_sn1_resp, have_it_sn2_resp] - - if ('test_dcnm_srp_query_with_peer_names' == self._testMethodName): - - have_rp1_resp = self.payloads_data.get('have_rp1_resp') - have_rp2_resp = self.payloads_data.get('have_rp2_resp') - have_rp3_resp = self.payloads_data.get('have_rp3_resp') - have_rp4_resp = self.payloads_data.get('have_rp4_resp') - have_rp5_resp = self.payloads_data.get('have_rp5_resp') - have_rp6_resp = self.payloads_data.get('have_rp6_resp') - have_rp7_resp = self.payloads_data.get('have_rp7_resp') - - self.run_dcnm_send.side_effect = [have_rp1_resp, have_rp2_resp, have_rp3_resp, - have_rp4_resp, have_rp5_resp, have_rp6_resp, - have_rp7_resp] - - - def load_fixtures(self, response=None, device=''): - - # Load srp related side-effects - self.load_srp_fixtures () - -#################################### FIXTURES END ############################ -#################################### TEST-CASES ############################## - - def test_dcnm_srp_merged_new (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_new_no_opt_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config_no_opt_elems') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_existing_no_opt_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config_no_opt_elems') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_new_no_intra_fw_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_no_intra_fw_mand_elems') - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - ## No Deploy Mode object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("deploy_mode") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('deploy_mode - Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No name object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("name") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("next_hop") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('next_hop : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No node_name object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("node_name") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('node_name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - nets = ["inside_network", "outside_network"] - - for net in nets: - ## No Inside Name object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net].pop("name") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No Inside Profile IPV4GW object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net]["profile"].pop("ipv4_gw") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('ipv4_gw : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No Inside vlan_id object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net].pop("vlan_id") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('vlan_id : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No Inside vrf object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net].pop("vrf") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('vrf : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - def test_dcnm_srp_merged_new_no_inter_fw_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_no_inter_fw_mand_elems') - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - nets = ["inside_network", "outside_network"] - - for net in nets: - - ## No Inside ipv4_lo object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net]["profile"].pop("ipv4_lo") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('ipv4_lo : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No Inside ipv4_neighbor object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0][net]["profile"].pop("ipv4_neighbor") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('ipv4_neighbor : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - def test_dcnm_srp_merged_new_no_adc_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_no_adc_mand_elems') - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - ## No rev_next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("rev_next_hop") - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('rev_next_hop : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - - def test_dcnm_srp_merged_new_check_mode (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - check_mode=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - def test_dcnm_srp_merged_new_unauth_error (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_config_without_state (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merge_no_deploy (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 7) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merge_deploy_false (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=False, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 7) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_wrong_state(self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='wrong_state', - attach=True, - deploy=False, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = None - try: - result = self.execute_module(changed=False, failed=False) - except: - self.assertEqual (result, None) - - def test_dcnm_srp_merged_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_existing_and_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('create_rp1_rp7_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 4) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 4) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_update_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('update_rp2_rp4_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 2) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 2) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_merged_update_existing_unauth_err (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('update_rp2_rp4_config') - - set_module_args(dict(state='merged', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 2) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 2) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_rp1_rp7_config') - - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_existing_unauth_err (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_rp1_rp7_config') - - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_existing_and_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_rp1_rp7_config') - - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 4) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_rp1_rp7_config') - - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_delete_no_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('delete_no_mand_elems') - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - ## No rev_next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("name") - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - ## No rev_next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("node_name") - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('node_name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - - def test_dcnm_srp_replace_rp1_to_rp3_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('replace_rp1_to_rp3') - - set_module_args(dict(state='replaced', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 3) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 3) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_replace_rp1_to_rp3_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('replace_rp1_to_rp3') - - set_module_args(dict(state='replaced', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 3) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 3) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_replace_rp1_to_rp3_existing_no_change (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('replace_rp1_to_rp3_no_change') - - set_module_args(dict(state='replaced', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_override_rp1_rp7_with_new_peerings (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_new_peerings') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 2) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 2) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_override_with_existing_peering (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_existing_peering') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 3) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - - def test_dcnm_srp_override_with_existing_peering_updated (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_existing_peering_updated') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 3) - self.assertEqual(len(result["diff"][0]["modified"]) , 1) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 1) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_override_with_service_nodes_alone (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_snodes') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_override_with_no_config (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('override_with_no_config') - - set_module_args(dict(state='overridden', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=True, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 7) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 0) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - # Validate create and deploy responses - for resp in result["response"]: - self.assertEqual(resp["RETURN_CODE"], 200) - - def test_dcnm_srp_query_non_existing (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('config_query_non_exist') - - set_module_args(dict(state='query', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 2) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - def test_dcnm_srp_query_with_service_nodes (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('config_query_with_node') - - set_module_args(dict(state='query', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 2) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - self.assertEqual(len(result["response"]) , 7) - - def test_dcnm_srp_query_with_peer_names (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('config_query_with_peername') - - set_module_args(dict(state='query', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - self.assertEqual(len(result["diff"][0]["merged"]) , 0) - self.assertEqual(len(result["diff"][0]["deleted"]) , 0) - self.assertEqual(len(result["diff"][0]["modified"]) , 0) - self.assertEqual(len(result["diff"][0]["query"]) , 7) - self.assertEqual(len(result["diff"][0]["deploy"]) , 0) - - self.assertEqual(len(result["response"]) , 7) - - def test_dcnm_srp_query_no_mand_elems (self): - - # load the json from playbooks - self.config_data = loadPlaybookData('dcnm_srp_configs') - self.payloads_data = loadPlaybookData('dcnm_srp_payloads') - - # load required config data - self.playbook_config = self.config_data.get('query_no_mand_elems') - - set_module_args(dict(state='query', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=self.playbook_config)) - result = self.execute_module(changed=False, failed=False) - - # From here we will remove one mandatory element from the config and check if that - # is detected and errored out - - ## No rev_next_hop object - cfg_no_dm = copy.deepcopy(self.playbook_config) - cfg_no_dm[0].pop("node_name") - set_module_args(dict(state='deleted', - attach=True, - deploy=True, - fabric='mmudigon', - service_fabric='external', - config=cfg_no_dm)) - result = None - try: - result = self.execute_module(changed=True, failed=False) - except Exception as e: - self.assertEqual(('node_name : Required parameter not found' in (str(e))), True) - self.assertEqual (result, None) - From 90755f2350bf2e04831f969ae81d37b9131467f3 Mon Sep 17 00:00:00 2001 From: Praveen Ramoorthy Date: Thu, 15 Jul 2021 19:51:05 +0530 Subject: [PATCH 14/71] Remove docs for unsupported modules --- README.md | 1 - docs/cisco.dcnm.dcnm_service_node_module.rst | 403 ------------------- 2 files changed, 404 deletions(-) delete mode 100644 docs/cisco.dcnm.dcnm_service_node_module.rst diff --git a/README.md b/README.md index 83c818418..bd6be1909 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ Name | Description [cisco.dcnm.dcnm_network](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_network_module.rst)|Add and remove Networks from a DCNM managed VXLAN fabric. [cisco.dcnm.dcnm_policy](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_policy_module.rst)|DCNM Ansible Module for managing policies. [cisco.dcnm.dcnm_rest](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_rest_module.rst)|Send REST API requests to DCNM controller. -[cisco.dcnm.dcnm_service_node](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_service_node_module.rst)|Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric. [cisco.dcnm.dcnm_template](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_template_module.rst)|DCNM Ansible Module for managing templates. [cisco.dcnm.dcnm_vrf](https://github.com/CiscoDevNet/ansible-dcnm/blob/main/docs/cisco.dcnm.dcnm_vrf_module.rst)|Add and remove VRFs from a DCNM managed VXLAN fabric. diff --git a/docs/cisco.dcnm.dcnm_service_node_module.rst b/docs/cisco.dcnm.dcnm_service_node_module.rst deleted file mode 100644 index ad0520735..000000000 --- a/docs/cisco.dcnm.dcnm_service_node_module.rst +++ /dev/null @@ -1,403 +0,0 @@ -.. _cisco.dcnm.dcnm_service_node_module: - - -**************************** -cisco.dcnm.dcnm_service_node -**************************** - -**Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric.** - - -Version added: 0.9.0 - -.. contents:: - :local: - :depth: 1 - - -Synopsis --------- -- Create/Modify/Delete service node based on type and attached interfaces from a DCNM managed VXLAN fabric. - - - - -Parameters ----------- - -.. raw:: html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterChoices/DefaultsComments
-
- config - -
- list - / elements=dictionary - / required -
-
- -
List of details of service nodes being managed
-
-
- attach_interface - -
- string - / required -
-
- -
List of switch interfaces where the service node will be attached
-
-
- form_factor - -
- string - / required -
-
- Default:
"physical"
-
-
Name of the form factor of the service node
-
-
- name - -
- string - / required -
-
- -
Name of service node
-
-
- svc_int_name - -
- string - / required -
-
- -
Name of the service interface
-
-
- switches - -
- list - / required -
-
- -
IP address of the switch where service node will be added/deleted
-
-
- type - -
- string - / required -
-
- Default:
"firewall"
-
-
Name of the service node type
-
-
- fabric - -
- string - / required -
-
- -
Name of attached easy fabric to which service node is attached
-
-
- service_fabric - -
- string - / required -
-
- -
Name of external fabric where the service node is located
-
-
- state - -
- string -
-
-
    Choices: -
  • merged ←
  • -
  • replaced
  • -
  • overridden
  • -
  • deleted
  • -
  • query
  • -
-
-
The state of DCNM after module completion.
-
-
- - - - -Examples --------- - -.. code-block:: yaml+jinja - - This module supports the following states: - - Merged: - Service Nodes defined in the playbook will be merged into the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Service Nodes that are not specified in the playbook will be untouched. - - Replaced: - Service Nodes defined in the playbook will be replaced in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be untouched. - - Overridden: - Service Node defined in the playbook will be overridden in the service fabric. - - If the service node does not exist it will be added. - - If the service node exists but properties managed by the playbook are different - they will be updated if possible. - - Properties that can be managed by the module but are not specified - in the playbook will be deleted or defaulted if possible. - - Service Nodes that are not specified in the playbook will be deleted. - - Deleted: - Service Node defined in the playbook will be deleted. - If no Service Nodes are provided in the playbook, all service node present on that DCNM fabric will be deleted. - - Query: - Returns the current DCNM state for the service node listed in the playbook. - - - name: Merge Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: merged - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - - - name: Replace Service Nodes form factor/type parameter - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: replaced - config: - - name: SN-11 - type: firewall - # Replace can only modify the form factor - # form_factor: virtual # the virtual will be changed to new physical - # form_factor: physical - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Nothing will be replaced in the below service node as there is no change - # Dont touch this if its present on DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - - - name: Override Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: overridden - config: - # Create this service node - - name: SN-13 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-11 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: Ethernet1/1 - # switches: - # - 192.168.1.224 - # Delete this service node from the DCNM - # - name: SN-12 - # type: firewall - # form_factor: virtual - # svc_int_name: svc1 - # attach_interface: vPC1 - # switches: # up to two switches, if two switches are provided, vpc is only option - # - 192.168.1.224 - # - 192.168.1.225 - - - name: Delete selected Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - - - name: Delete all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: deleted - - - name: Query Service Nodes state for SN-11 and SN-12 - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query - config: - - name: SN-11 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: Ethernet1/1 - switches: - - 192.168.1.224 - - name: SN-12 - type: firewall - form_factor: virtual - svc_int_name: svc1 - attach_interface: vPC1 - switches: # up to two switches, if two switches are provided, vpc is only option - - 192.168.1.224 - - 192.168.1.225 - - - name: Query all the Service Nodes - cisco.dcnm.dcnm_service_node: - fabric: Fabric1 - service_fabric: external - state: query - - - - -Status ------- - - -Authors -~~~~~~~ - -- Karthik Babu Harichandra Babu From da7678fda6d105d0b4f5b88b43e2ebdb08b411f0 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Wed, 6 Oct 2021 18:40:50 -0400 Subject: [PATCH 15/71] Add plain text support for dcnm_rest module (#96) * Add support for plan text payloads * Update doc * Remove NDFC referencs * Update json validation code --- plugins/modules/dcnm_rest.py | 61 +++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/plugins/modules/dcnm_rest.py b/plugins/modules/dcnm_rest.py index 74e8a742d..f0b796e75 100644 --- a/plugins/modules/dcnm_rest.py +++ b/plugins/modules/dcnm_rest.py @@ -1,6 +1,6 @@ #!/usr/bin/python # -# Copyright (c) 2020 Cisco and/or its affiliates. +# Copyright (c) 2020-2021 Cisco and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -33,9 +33,12 @@ description: - 'REST API Path Endpoint' required: yes - json_data: + type: str + data: description: - - 'Additional JSON data to include with the REST API call' + - 'Additional data in JSON or TEXT to include with the REST API call' + aliases: + - json_data required: no author: - Mike Wiebe (@mikewiebe) @@ -52,6 +55,24 @@ dcnm_rest: method: GET path: /rest/control/fabrics + +- name: Set deployment to false in lanAttachList for vrf + dcnm_rest: + method: POST + path: /rest/top-down/fabrics/fabric1/vrfs/attachments + json_data: '[{"vrfName":"sales66_vrf1","lanAttachList":[{"fabric":"fabric1","vrfName":"sales66_vrf1","serialNumber":"FDO21392QKM","vlan":2000,"freeformConfig":"","deployment":false,"extensionValues":"","instanceValues":"{\"loopbackId\":\"\",\"loopbackIpAddress\":\"\",\"loopbackIpV6Address\":\"\"}"}]}]' + +# Read payload data from file and validate a template +- set_fact: + data: "{{ lookup('file', 'validate_payload') }}" + +- name: Validate a template + cisco.dcnm.dcnm_rest: + method: POST + path: /fm/fmrest/config/templates/validate + json_data: "{{ data }}" + register: result + ''' RETURN = ''' @@ -61,8 +82,13 @@ elements: dict ''' +import json +from json.decoder import JSONDecodeError from ansible.module_utils.connection import Connection from ansible.module_utils.basic import AnsibleModule +from ansible_collections.cisco.dcnm.plugins.module_utils.network.dcnm.dcnm import ( + dcnm_send, +) def main(): @@ -70,7 +96,7 @@ def main(): argument_spec = dict( method=dict(required=True, choices=['GET', 'POST', 'PUT', 'DELETE']), path=dict(required=True, type='str'), - json_data=dict(type='raw', required=False, default=None)) + data=dict(type='raw', required=False, default=None, aliases=["json_data"])) # seed the result dict result = dict( @@ -85,16 +111,23 @@ def main(): method = module.params['method'] path = module.params['path'] - json_data = {} - if module.params['json_data'] is not None: - json_data = module.params['json_data'] - - conn = Connection(module._socket_path) - result['response'] = conn.send_request(method, path, json_data) - - res = result['response'] - if res and res['RETURN_CODE'] >= 400: - module.fail_json(msg=res) + for key in ['json_data', 'data']: + data = module.params.get(key) + if data is not None: + break + if data is None: + data = "{}" + + # Determine if this is valid JSON or not + try: + json.loads(data) + result['response'] = dcnm_send(module, method, path, data) + except json.JSONDecodeError: + # Resend data as text since it's not valid JSON + result['response'] = dcnm_send(module, method, path, data, "text") + + if result['response']['RETURN_CODE'] >= 400: + module.fail_json(msg=result['response']) module.exit_json(**result) From e4674821df7c3bb8443f87276b5c6fc23fc16288 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Wed, 6 Oct 2021 18:57:30 -0400 Subject: [PATCH 16/71] Update galaxy.yml --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index bb5abc210..84bd4a4d9 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dcnm -version: 1.2.0 +version: 1.2.1 readme: README.md authors: - Shrishail Kariyappanavar From b668d3d3e57666fc7d281d7d29c2b55dd7d584b2 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Wed, 6 Oct 2021 18:59:06 -0400 Subject: [PATCH 17/71] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52c5ce8b7..fa99ddff4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [1.2.1] - 2021-10 + +### Added + +Added support for plain text payloads to `dcnm_rest` module + ## [1.2.0] - 2021-07 ### Added @@ -95,6 +101,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[1.2.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.0...1.2.1 [1.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.1.1...1.2.0 [1.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.1.0...1.1.1 [1.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.0.0...1.1.0 From 9fdb35370480fd7f0cbb9681474f37edaf8ba8ec Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Wed, 6 Oct 2021 19:01:15 -0400 Subject: [PATCH 18/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f426c730..113b12f35 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 1.2.0 + version: 1.2.1 ``` ## Using this collection From d66b6e1716fd17aa41e45f12afba9bd4029df3a1 Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Thu, 14 Oct 2021 12:52:44 -0400 Subject: [PATCH 19/71] Fix error code handling --- plugins/httpapi/dcnm.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/plugins/httpapi/dcnm.py b/plugins/httpapi/dcnm.py index 192ba8f94..4e090c3f7 100644 --- a/plugins/httpapi/dcnm.py +++ b/plugins/httpapi/dcnm.py @@ -63,22 +63,29 @@ def login(self, username, password): try: response, response_data = self.connection.send(path, data, method=method, headers=self.headers, force_basic_auth=True) + vrd = self._verify_response(response, method, path, response_data) + if vrd['RETURN_CODE'] != 200: + raise ConnectionError(vrd) + response_value = self._get_response_value(response_data) self.connection._auth = {'Dcnm-Token': self._response_to_json(response_value)['Dcnm-Token']} except Exception as e: msg = 'Error on attempt to connect and authenticate with DCNM controller: {}'.format(e) - raise ConnectionError(self._return_info(None, method, path, msg)) + raise ConnectionError(msg) def logout(self): method = 'POST' path = '/rest/logout' try: - response, response_data = self.connection.send(path, self.connection._auth['Dcnm-Token'], method=method, headers=self.headers, force_basic_auth=True) + vrd = response, response_data = self.connection.send(path, self.connection._auth['Dcnm-Token'], method=method, headers=self.headers, force_basic_auth=True) + if vrd['RETURN_CODE'] != 200: + raise ConnectionError(vrd) + except Exception as e: msg = 'Error on attempt to logout from DCNM controller: {}'.format(e) - raise ConnectionError(self._return_info(None, method, path, msg)) + raise ConnectionError(msg) self._verify_response(response, method, path, response_data) @@ -152,11 +159,11 @@ def _verify_response(self, response, method, path, rdata): rc = response.getcode() path = response.geturl() msg = response.msg - if rc >= 200 and rc <= 299: + # This function calls self._return_info to pass the response + # data back in a structured dictionary format. + # A ConnectionError is generated if the return code is unknown. + if rc >= 200 and rc <= 600: return self._return_info(rc, method, path, msg, jrd) - if rc >= 400: - # Add future error code processing here - pass else: msg = 'Unknown RETURN_CODE: {}'.format(rc) raise ConnectionError(self._return_info(rc, method, path, msg, jrd)) From 43500ed2c7a85742d080fcf7b97b1c950d5a5fde Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Tue, 19 Oct 2021 17:50:22 -0400 Subject: [PATCH 20/71] Update version to 1.2.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 84bd4a4d9..98be0a0e4 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dcnm -version: 1.2.1 +version: 1.2.2 readme: README.md authors: - Shrishail Kariyappanavar From 4e495d8a876a78548689b77af49a3904c3e4a341 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 22 Oct 2021 10:17:28 -0400 Subject: [PATCH 21/71] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa99ddff4..16f4a46da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [1.2.2] - 2021-10-21 + +### Added + +Fixed error code handling that was causing an error during authentication + ## [1.2.1] - 2021-10 ### Added @@ -101,6 +107,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[1.2.2]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.1...1.2.2 [1.2.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.0...1.2.1 [1.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.1.1...1.2.0 [1.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.1.0...1.1.1 From c3f86090c1b5309f8bd5c0f94f22b88d8caf438a Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 22 Oct 2021 10:18:00 -0400 Subject: [PATCH 22/71] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16f4a46da..184e15d1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [1.2.2] - 2021-10-21 -### Added +### Fixed Fixed error code handling that was causing an error during authentication From e353057c8e65246e1b470a6b19f7cd8861e48bbd Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 22 Oct 2021 10:19:18 -0400 Subject: [PATCH 23/71] Update runtime.yml --- meta/runtime.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta/runtime.yml b/meta/runtime.yml index 43c0b33ea..56a669973 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -3,7 +3,7 @@ # will redirect to a common action plugin called cisco.dcnm.dcnm # #--- -#requires_ansible: '>=2.9.10,<2.11' +requires_ansible: '>=2.9.10,<2.11' #plugin_routing: # action: # dcnm_inventory: From 768a5ee544d6785274fdb229d891d573706f8640 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 22 Oct 2021 10:22:22 -0400 Subject: [PATCH 24/71] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 113b12f35..ec77d089e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules to help automate common day 2 operations for VXLAN EVPN fabrics. -This collection is intended for use with `DCNM Release 11.4(1)` or later. +This collection is intended for use with `DCNM Release 11.4(x)` release versions. ## Ansible version compatibility @@ -54,7 +54,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 1.2.1 + version: 1.2.2 ``` ## Using this collection @@ -173,7 +173,7 @@ We welcome community contributions to this collection. If you find problems, ple ## Licensing -Copyright (c) 2020 Cisco and/or its affiliates. +Copyright (c) 2020-2021 Cisco and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From fe9da0aaa7db5cf3eef9c944f7b8555174712fda Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Fri, 22 Oct 2021 10:24:45 -0400 Subject: [PATCH 25/71] Update docs --- docs/cisco.dcnm.dcnm_rest_module.rst | 24 +++++++++++++++++++++--- docs/cisco.dcnm.dcnm_vrf_module.rst | 4 ++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/docs/cisco.dcnm.dcnm_rest_module.rst b/docs/cisco.dcnm.dcnm_rest_module.rst index 50ee420a7..5dd1608d5 100644 --- a/docs/cisco.dcnm.dcnm_rest_module.rst +++ b/docs/cisco.dcnm.dcnm_rest_module.rst @@ -36,7 +36,7 @@ Parameters
- json_data + data
- @@ -45,7 +45,8 @@ Parameters -
Additional JSON data to include with the REST API call
+
Additional data in JSON or TEXT to include with the REST API call
+

aliases: json_data
@@ -76,7 +77,7 @@ Parameters path
- - + string / required
@@ -108,6 +109,23 @@ Examples method: GET path: /rest/control/fabrics + - name: Set deployment to false in lanAttachList for vrf + dcnm_rest: + method: POST + path: /rest/top-down/fabrics/fabric1/vrfs/attachments + json_data: '[{"vrfName":"sales66_vrf1","lanAttachList":[{"fabric":"fabric1","vrfName":"sales66_vrf1","serialNumber":"FDO21392QKM","vlan":2000,"freeformConfig":"","deployment":false,"extensionValues":"","instanceValues":"{"loopbackId":"","loopbackIpAddress":"","loopbackIpV6Address":""}"}]}]' + + # Read payload data from file and validate a template + - set_fact: + data: "{{ lookup('file', 'validate_payload') }}" + + - name: Validate a template + cisco.dcnm.dcnm_rest: + method: POST + path: /fm/fmrest/config/templates/validate + json_data: "{{ data }}" + register: result + Return Values diff --git a/docs/cisco.dcnm.dcnm_vrf_module.rst b/docs/cisco.dcnm.dcnm_vrf_module.rst index 9f137e239..8ee7e6429 100644 --- a/docs/cisco.dcnm.dcnm_vrf_module.rst +++ b/docs/cisco.dcnm.dcnm_vrf_module.rst @@ -521,8 +521,8 @@ Examples - ip_address: 192.168.1.224 - ip_address: 192.168.1.225 vrf_lite: - # All parameters under vrf_lite except peer_vrf are optional and - # will be supplied by DCNM when omitted in the playbook + # All parameters under vrf_lite except peer_vrf are optional and + # will be supplied by DCNM when omitted in the playbook - peer_vrf: test_vrf_1 # peer_vrf is mandatory interface: Ethernet1/16 # optional ipv4_addr: 10.33.0.2/30 # optional From 8b6524e702a2b8a0abf81aa4c046ad35f203fef2 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Tue, 16 Nov 2021 10:16:08 -0500 Subject: [PATCH 26/71] Change skipResourceCheck to False --- plugins/modules/dcnm_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/dcnm_interface.py b/plugins/modules/dcnm_interface.py index 70f9d424f..b88a7ebc4 100644 --- a/plugins/modules/dcnm_interface.py +++ b/plugins/modules/dcnm_interface.py @@ -1748,7 +1748,7 @@ def dcnm_get_intf_payload(self, delem, sw): } } ], - "skipResourceCheck": str(True).lower() + "skipResourceCheck": str(False).lower() } # Each interface type will have a different profile name. Set that based on the interface type and use that From ffe72d6e908b9a6cb578cb8b02a49d621c5aefbd Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Tue, 16 Nov 2021 13:47:37 -0500 Subject: [PATCH 27/71] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 184e15d1a..cc6b207fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [1.2.3] - 2021-11-16 + +### Fixed + +Fixed a problem with `dcnm_interface` module where VPCID resource was not being created and then reserved properly + ## [1.2.2] - 2021-10-21 ### Fixed @@ -107,6 +113,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[1.2.3]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.2...1.2.3 [1.2.2]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.1...1.2.2 [1.2.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.0...1.2.1 [1.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.1.1...1.2.0 From 249ec2ee2a720a62e7eb4b218517b292d0ebdae0 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Tue, 16 Nov 2021 13:48:33 -0500 Subject: [PATCH 28/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ec77d089e..5fdadd772 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 1.2.2 + version: 1.2.3 ``` ## Using this collection From f2af87d9e12fcdd76aee6a8ee3bd6ceee368b572 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Tue, 16 Nov 2021 13:49:08 -0500 Subject: [PATCH 29/71] Update galaxy.yml --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 98be0a0e4..8675345bd 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dcnm -version: 1.2.2 +version: 1.2.3 readme: README.md authors: - Shrishail Kariyappanavar From a7de8a969bb00bac2af2843f6e6add87997e51fc Mon Sep 17 00:00:00 2001 From: mikewiebe Date: Fri, 3 Dec 2021 16:50:16 -0500 Subject: [PATCH 30/71] Add dhcp_loopback_id parameter support --- plugins/modules/dcnm_network.py | 57 ++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/plugins/modules/dcnm_network.py b/plugins/modules/dcnm_network.py index 616352eee..96a458729 100644 --- a/plugins/modules/dcnm_network.py +++ b/plugins/modules/dcnm_network.py @@ -1,6 +1,6 @@ #!/usr/bin/python # -# Copyright (c) 2020 Cisco and/or its affiliates. +# Copyright (c) 2020-2021 Cisco and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -144,6 +144,11 @@ description: 'VRF ID of third DHCP server' type: str required: false + dhcp_loopback_id: + description: 'Loopback ID for DHCP Relay interface' + type: int + note: Configured ID value should be in range 0-1023 + required: false attach: description: 'List of network attachment details' type: list @@ -561,6 +566,7 @@ def diff_for_create(self, want, have): dhcp1_vrf_changed = False dhcp2_vrf_changed = False dhcp3_vrf_changed = False + dhcp_loopback_changed = False if want.get('networkId') and want['networkId'] != have['networkId']: self.module.fail_json(msg="networkId can not be updated on existing network: {}". @@ -601,6 +607,8 @@ def diff_for_create(self, want, have): dhcp2_vrf_have = json_to_dict_have.get('vrfDhcp2', "") dhcp3_vrf_want = json_to_dict_want.get('vrfDhcp3', "") dhcp3_vrf_have = json_to_dict_have.get('vrfDhcp3', "") + dhcp_loopback_want = json_to_dict_want.get('loopbackId', "") + dhcp_loopback_have = json_to_dict_have.get('loopbackId', "") if vlanId_have != "": vlanId_have = int(vlanId_have) tag_want = json_to_dict_want.get('tag', "") @@ -628,7 +636,8 @@ def diff_for_create(self, want, have): mtu_have != mtu_want or arpsup_have != arpsup_want or \ dhcp1_ip_have != dhcp1_ip_want or dhcp2_ip_have != dhcp2_ip_want or \ dhcp3_ip_have != dhcp3_ip_want or dhcp1_vrf_have != dhcp1_vrf_want or \ - dhcp2_vrf_have != dhcp2_vrf_want or dhcp3_vrf_have != dhcp3_vrf_want: + dhcp2_vrf_have != dhcp2_vrf_want or dhcp3_vrf_have != dhcp3_vrf_want or \ + dhcp_loopback_have != dhcp_loopback_want: # The network updates with missing networkId will have to use existing # networkId from the instance of the same network on DCNM. @@ -661,6 +670,8 @@ def diff_for_create(self, want, have): dhcp2_vrf_changed = True if dhcp3_vrf_have != dhcp3_vrf_want: dhcp3_vrf_changed = True + if dhcp_loopback_have != dhcp_loopback_want: + dhcp_loopback_changed = True want.update({'networkId': have['networkId']}) create = want @@ -705,13 +716,15 @@ def diff_for_create(self, want, have): dhcp2_vrf_changed = True if dhcp3_vrf_have != dhcp3_vrf_want: dhcp3_vrf_changed = True + if dhcp_loopback_have != dhcp_loopback_want: + dhcp_loopback_changed = True want.update({'networkId': have['networkId']}) create = want return create, gw_changed, tg_changed, warn_msg, l2only_changed, vn_changed, \ - intdesc_changed, mtu_changed, arpsup_changed, dhcp1_ip_changed, dhcp2_ip_changed, \ - dhcp3_ip_changed, dhcp1_vrf_changed, dhcp2_vrf_changed, dhcp3_vrf_changed + intdesc_changed, mtu_changed, arpsup_changed, dhcp1_ip_changed, dhcp2_ip_changed, \ + dhcp3_ip_changed, dhcp1_vrf_changed, dhcp2_vrf_changed, dhcp3_vrf_changed, dhcp_loopback_changed def update_create_params(self, net): @@ -755,7 +768,8 @@ def update_create_params(self, net): 'dhcpServerAddr3': net.get('dhcp_srvr3_ip', ""), 'vrfDhcp': net.get('dhcp_srvr1_vrf', ""), 'vrfDhcp2': net.get('dhcp_srvr2_vrf', ""), - 'vrfDhcp3': net.get('dhcp_srvr3_vrf', "") + 'vrfDhcp3': net.get('dhcp_srvr3_vrf', ""), + 'loopbackId': net.get('dhcp_loopback_id', "") } if template_conf['vlanId'] is None: @@ -774,6 +788,8 @@ def update_create_params(self, net): template_conf['vrfDhcp2'] = "" if template_conf['vrfDhcp3'] is None: template_conf['vrfDhcp3'] = "" + if template_conf['loopbackId'] is None: + template_conf['loopbackId'] = "" net_upd.update({'networkTemplateConfig': json.dumps(template_conf)}) @@ -849,7 +865,8 @@ def get_have(self): 'dhcpServerAddr3': json_to_dict.get('dhcpServerAddr3', ""), 'vrfDhcp': json_to_dict.get('vrfDhcp', ""), 'vrfDhcp2': json_to_dict.get('vrfDhcp2', ""), - 'vrfDhcp3': json_to_dict.get('vrfDhcp3', "") + 'vrfDhcp3': json_to_dict.get('vrfDhcp3', ""), + 'loopbackId': json_to_dict.get('loopbackId', "") } net.update({'networkTemplateConfig': json.dumps(t_conf)}) @@ -882,7 +899,8 @@ def get_have(self): 'dhcpServerAddr3': json_to_dict.get('dhcpServerAddr3', ""), 'vrfDhcp': json_to_dict.get('vrfDhcp', ""), 'vrfDhcp2': json_to_dict.get('vrfDhcp2', ""), - 'vrfDhcp3': json_to_dict.get('vrfDhcp3', "") + 'vrfDhcp3': json_to_dict.get('vrfDhcp3', ""), + 'loopbackId': json_to_dict.get('loopbackId', "") } l2net.update({'networkTemplateConfig': json.dumps(t_conf)}) @@ -1244,6 +1262,7 @@ def get_diff_merge(self, replace=False): dhcp1_vrf_changed = {} dhcp2_vrf_changed = {} dhcp3_vrf_changed = {} + dhcp_loopback_changed = {} for want_c in self.want_create: found = False @@ -1253,7 +1272,7 @@ def get_diff_merge(self, replace=False): found = True diff, gw_chg, tg_chg, warn_msg, l2only_chg, vn_chg, idesc_chg, mtu_chg, \ arpsup_chg, dhcp1_ip_chg, dhcp2_ip_chg, dhcp3_ip_chg, dhcp1_vrf_chg, \ - dhcp2_vrf_chg, dhcp3_vrf_chg = self.diff_for_create(want_c, have_c) + dhcp2_vrf_chg, dhcp3_vrf_chg, dhcp_loopbk_chg = self.diff_for_create(want_c, have_c) gw_changed.update({want_c['networkName']: gw_chg}) tg_changed.update({want_c['networkName']: tg_chg}) l2only_changed.update({want_c['networkName']: l2only_chg}) @@ -1267,6 +1286,7 @@ def get_diff_merge(self, replace=False): dhcp1_vrf_changed.update({want_c['networkName']: dhcp1_vrf_chg}) dhcp2_vrf_changed.update({want_c['networkName']: dhcp2_vrf_chg}) dhcp3_vrf_changed.update({want_c['networkName']: dhcp3_vrf_chg}) + dhcp_loopback_changed.update({want_c['networkName']: dhcp_loopbk_chg}) if diff: diff_create_update.append(diff) break @@ -1349,7 +1369,8 @@ def get_diff_merge(self, replace=False): dhcp3_ip_changed.get(want_a['networkName'], False) or \ dhcp1_vrf_changed.get(want_a['networkName'], False) or \ dhcp2_vrf_changed.get(want_a['networkName'], False) or \ - dhcp3_vrf_changed.get(want_a['networkName'], False): + dhcp3_vrf_changed.get(want_a['networkName'], False) or \ + dhcp_loopback_changed.get(want_a['networkName'], False): dep_net = want_a['networkName'] if not found and want_a.get('lanAttachList'): @@ -1422,6 +1443,7 @@ def format_diff(self): found_c.update({'dhcp_srvr1_vrf': json_to_dict.get('vrfDhcp', "")}) found_c.update({'dhcp_srvr2_vrf': json_to_dict.get('vrfDhcp2', "")}) found_c.update({'dhcp_srvr3_vrf': json_to_dict.get('vrfDhcp3', "")}) + found_c.update({'dhcp_loopback_id': json_to_dict.get('loopbackId', "")}) found_c.update({'attach': []}) del found_c['fabric'] @@ -1564,7 +1586,7 @@ def get_diff_query(self): # fetch the attachment for the network path = '/rest/top-down/fabrics/{}/networks/attachments?network-names={}'. \ - format(self.fabric, net['networkName']) + format(self.fabric, net['networkName']) net_attach_objects = dcnm_send(self.module, method, path) if not net_attach_objects['DATA']: @@ -1718,7 +1740,8 @@ def push_to_remote(self, is_rollback=False): 'dhcpServerAddr3': json_to_dict.get('dhcpServerAddr3', ""), 'vrfDhcp': json_to_dict.get('vrfDhcp', ""), 'vrfDhcp2': json_to_dict.get('vrfDhcp2', ""), - 'vrfDhcp3': json_to_dict.get('vrfDhcp3', "") + 'vrfDhcp3': json_to_dict.get('vrfDhcp3', ""), + 'loopbackId': json_to_dict.get('loopbackId', "") } net.update({'networkTemplateConfig': json.dumps(t_conf)}) @@ -1775,7 +1798,6 @@ def push_to_remote(self, is_rollback=False): self.failure(resp) def validate_input(self): - """Parse the playbook values, validate to param specs.""" state = self.params['state'] @@ -1803,7 +1825,8 @@ def validate_input(self): dhcp_srvr3_ip=dict(type='ipv4', default=""), dhcp_srvr1_vrf=dict(type='str', length_max=32), dhcp_srvr2_vrf=dict(type='str', length_max=32), - dhcp_srvr3_vrf=dict(type='str', length_max=32) + dhcp_srvr3_vrf=dict(type='str', length_max=32), + dhcp_loopback_id=dict(type='int', range_min=0, range_max=1023) ) att_spec = dict( ip_address=dict(required=True, type='str'), @@ -1854,7 +1877,8 @@ def validate_input(self): dhcp_srvr3_ip=dict(type='ipv4', default=""), dhcp_srvr1_vrf=dict(type='str', length_max=32), dhcp_srvr2_vrf=dict(type='str', length_max=32), - dhcp_srvr3_vrf=dict(type='str', length_max=32) + dhcp_srvr3_vrf=dict(type='str', length_max=32), + dhcp_loopback_id=dict(type='int', range_min=0, range_max=1023) ) att_spec = dict( ip_address=dict(required=True, type='str'), @@ -2052,10 +2076,12 @@ def dcnm_update_network_information(self, want, have, cfg): if cfg.get("dhcp_srvr3_vrf", None) is None: json_to_dict_want["vrfDhcp3"] = json_to_dict_have["vrfDhcp3"] + if cfg.get("dhcp_loopback_id", None) is None: + json_to_dict_want["loopbackId"] = json_to_dict_have["loopbackId"] + want.update({'networkTemplateConfig': json.dumps(json_to_dict_want)}) def update_want(self): - """ Routine to compare want and have and make approriate changes to want. This routine checks the existing information with the config from playbook and populates the payloads in self.want apropriately. @@ -2108,7 +2134,6 @@ def update_want(self): def main(): - """ main entry point for module execution """ From 5a2e625501d3451e5b569bccbfb33de0f3e117c6 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 3 Dec 2021 17:16:25 -0500 Subject: [PATCH 31/71] Update version to 1.2.4 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 8675345bd..4db9139db 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dcnm -version: 1.2.3 +version: 1.2.4 readme: README.md authors: - Shrishail Kariyappanavar From 2431cc318d0043f98647d363e70b0a32f867963d Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 3 Dec 2021 17:17:30 -0500 Subject: [PATCH 32/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5fdadd772..3c44ee3b7 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 1.2.3 + version: 1.2.4 ``` ## Using this collection From 3ba0c279438b140ed90e2951bcd208c8368c6466 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 3 Dec 2021 17:23:22 -0500 Subject: [PATCH 33/71] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc6b207fc..eb145e7a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [1.2.4] - 2021-12-03 + +### Added + +* Added support for configuring the loopback ID for DHCP Relay interface. +* The feature is configured using the `dhcp_loopback_id` parameter in the `dcnm_network` module + ## [1.2.3] - 2021-11-16 ### Fixed @@ -113,6 +120,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[1.2.4]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.3...1.2.4 [1.2.3]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.2...1.2.3 [1.2.2]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.1...1.2.2 [1.2.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.0...1.2.1 From c6efbddf6401d8bf548d413784ee93e2ff999809 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Mon, 13 Dec 2021 21:26:04 +0530 Subject: [PATCH 34/71] Update CHANGELOG.md --- CHANGELOG.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b650ba263..9f5a06b45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,9 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [2.0.0] - 2021-12-13 -## Added +### Added * Nexus Dashboard Fabric Controller (NDFC) support for all collection modules * The following new modules are included in this release From 963c2da68b887142ff263d7d1aae492890e97a17 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Mon, 13 Dec 2021 22:55:58 +0530 Subject: [PATCH 35/71] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f5a06b45..ffe29e0b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,8 @@ Added support for plain text payloads to `dcnm_rest` module ## [1.2.0] - 2021-07 +### Added + * cisco.dcnm.dcnm_network: * New parameter `is_l2only:` * New parameter `vlan_name:` From 82b998a875fb98896ec62e89f71ef59f2b1afb6f Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Tue, 19 Jul 2022 19:52:49 +0530 Subject: [PATCH 36/71] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 691e00a2c..a7e69cc05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [2.1.0] - 2022-07-19 ### Added From 475b18b5911675f3f90749333e78d32c0a45455d Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Thu, 18 Aug 2022 11:56:37 -0400 Subject: [PATCH 37/71] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d34ffd146..d741ba258 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [2.1.1] - 2022-08-18 ### Fixed From c5f89420ee190ce48d299cca13433ce6615ba193 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Thu, 18 Aug 2022 11:57:57 -0400 Subject: [PATCH 38/71] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95d0aa60f..d741ba258 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [2.1.1] - 2022-08-18 + +### Fixed + +* Changed the deploy mechanism of policy module for delete state. + ## [2.1.0] - 2022-07-19 ### Added @@ -170,6 +176,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[2.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.1.0...2.1.1 [2.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.0.1...2.1.0 [2.0.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.0.0...2.0.1 [2.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.4...2.0.0 From 0c08fe2a0054908bfcbda65671ebc9332e199047 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Fri, 14 Oct 2022 15:03:06 +0530 Subject: [PATCH 39/71] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 661059006..61f7680ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [2.2.0] - 2022-10-14 ### Added From 6180e5511bc2813ee7498f40151f04833d4fc6f4 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Fri, 14 Oct 2022 15:06:27 +0530 Subject: [PATCH 40/71] Update CHANGELOG.md --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d741ba258..61f7680ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [2.2.0] - 2022-10-14 + +### Added + +* The following new modules are included in this release + * `dcnm_links` - Module for managing dcnm links + +### Fixed + +* https://github.com/CiscoDevNet/ansible-dcnm/issues/155 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/169 + ## [2.1.1] - 2022-08-18 ### Fixed @@ -176,6 +188,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[2.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.1.1...2.2.0 [2.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.1.0...2.1.1 [2.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.0.1...2.1.0 [2.0.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.0.0...2.0.1 From 8396e6d1de23219dc4b5687e9e0bad7dd4d51705 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 17 Nov 2022 16:56:32 +0530 Subject: [PATCH 41/71] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0d138151..6051e1283 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [2.4.0] - 2022-11-17 ### Added From 5d18dd5f8a7ef3db57d5d9ce6c79867f60732010 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 17 Nov 2022 17:02:19 +0530 Subject: [PATCH 42/71] Update CHANGELOG.md --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68923f66d..6051e1283 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [2.4.0] - 2022-11-17 + +### Added + +* POAP support in `dcnm_inventory` module +* SVI interface support in `dcnm_interface` module + +### Fixed + +* Fix for a problem where networks cannot be deleted when detach/undeploy fails and network is in an out of sync state. +* Fix default value for `multicast_group_address` property in `dcnm_network` + ## [2.3.0] - 2022-10-28 ### Added @@ -194,6 +206,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[2.4.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.3.0...2.4.0 [2.3.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.2.0...2.3.0 [2.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.1.1...2.2.0 [2.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.1.0...2.1.1 From 0c58b03b3e9b8da76b0216a0b71d6e2d63c6c6c8 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Wed, 22 Feb 2023 12:52:48 +0530 Subject: [PATCH 43/71] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 836aad645..b41c138a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [3.0.0] - 2023-02-22 ### Added From c7ba57770099e8002e75e9b474786ed60ed76aa2 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Wed, 22 Feb 2023 13:02:39 +0530 Subject: [PATCH 44/71] Update CHANGELOG.md --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6051e1283..b41c138a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [3.0.0] - 2023-02-22 + +### Added + +* RMA support in `dcnm_inventory` module + +### Fixed + +* https://github.com/CiscoDevNet/ansible-dcnm/issues/168 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/140 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/157 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/192 + ## [2.4.0] - 2022-11-17 ### Added @@ -206,6 +219,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[3.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.4.0...3.0.0 [2.4.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.3.0...2.4.0 [2.3.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.2.0...2.3.0 [2.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.1.1...2.2.0 From 3f405244d597c3ab4b394f58498f52857b9c1e05 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Tue, 14 Mar 2023 20:17:20 +0530 Subject: [PATCH 45/71] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1e1f22ec..8338f9fd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [3.1.0] - 2023-03-14 ### Added From 976260c89fd7e908049a7781e347523716b0f272 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Tue, 14 Mar 2023 20:20:04 +0530 Subject: [PATCH 46/71] Update CHANGELOG.md --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b41c138a9..8338f9fd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [3.1.0] - 2023-03-14 + +### Added + +* Support for all config parameters in network module +* Support for all config parameters in vrf module + +### Fixed + +* https://github.com/CiscoDevNet/ansible-dcnm/issues/197 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/194 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/185 + ## [3.0.0] - 2023-02-22 ### Added @@ -219,6 +232,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[3.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.0.0...3.1.0 [3.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.4.0...3.0.0 [2.4.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.3.0...2.4.0 [2.3.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.2.0...2.3.0 From 28fc9ceda281fe3673b7566317a15957b9fa1476 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 17 Mar 2023 12:46:20 -0400 Subject: [PATCH 47/71] netcommon dependency to restrict no later then 4.1.0 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index d3696ba51..c60ebe9ee 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -13,5 +13,5 @@ description: Ansible collection for the Cisco Nexus® Dashboard Fabric Controlle license: Apache-2.0 tags: [cisco, ndfc, dcnm, nxos, networking, vxlan] dependencies: - "ansible.netcommon": ">=2.6.1" + "ansible.netcommon": ">=2.6.1,<=4.1.0" repository: https://github.com/CiscoDevNet/ansible-dcnm From b6931f2e515645653aa9c809dff0f97ada16e919 Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 17 Mar 2023 12:51:30 -0400 Subject: [PATCH 48/71] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8338f9fd0..ef3519224 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [3.1.1] - 2023-03-17 + +### Fixed + +* Restrict installs of netcommon to versions `>=2.6.1,<=4.1.0` due to issue: https://github.com/CiscoDevNet/ansible-dcnm/issues/209 + ## [3.1.0] - 2023-03-14 ### Added @@ -232,6 +238,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[3.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.0...3.1.1 [3.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.0.0...3.1.0 [3.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.4.0...3.0.0 [2.4.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.3.0...2.4.0 From 6a3d0dd223735518b75f2974de878f5e69d8232b Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 17 Mar 2023 12:52:16 -0400 Subject: [PATCH 49/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 611c814c1..134b7898e 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 3.1.0 + version: 3.1.1 ``` ## Using this collection From 60286195c2ca8963dcdd9e0e1e5db322f57f80cd Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Fri, 17 Mar 2023 12:57:16 -0400 Subject: [PATCH 50/71] Update galaxy.yml --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index c60ebe9ee..e30a30c03 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dcnm -version: 3.1.0 +version: 3.1.1 readme: README.md authors: - Shrishail Kariyappanavar From 99ae2751bf90ba05c279b17f9d25fb685ce698ee Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:51:56 +0530 Subject: [PATCH 51/71] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8a5901b2..3f9b2aacf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [3.2.0] - 2023-04-20 ### Added From 37d3ffca926b8ad027d2f96b7d2a3fa0244f0032 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:57:51 +0530 Subject: [PATCH 52/71] Update galaxy.yml --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index e30a30c03..9bca57617 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dcnm -version: 3.1.1 +version: 3.2.0 readme: README.md authors: - Shrishail Kariyappanavar From 337617954e26fac8db5bb7391a07977607753ba0 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:59:36 +0530 Subject: [PATCH 53/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 134b7898e..2d42709e3 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 3.1.1 + version: 3.2.0 ``` ## Using this collection From aa2eace913680d37dc33e5bb07b86893961c6468 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 20 Apr 2023 20:01:50 +0530 Subject: [PATCH 54/71] Update CHANGELOG.md --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef3519224..3f9b2aacf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [3.2.0] - 2023-04-20 + +### Added + +* Support for fex interfaces in interface module + +### Fixed + +* https://github.com/CiscoDevNet/ansible-dcnm/issues/212 + ## [3.1.1] - 2023-03-17 ### Fixed @@ -238,6 +248,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[3.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.1...3.2.0 [3.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.0...3.1.1 [3.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.0.0...3.1.0 [3.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.4.0...3.0.0 From cfddcdd51737a7cdf4fa7c83c0d64866e4a815f9 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Tue, 23 May 2023 12:16:53 +0530 Subject: [PATCH 55/71] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7b4c57c5..bc15fc867 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [3.3.0] - 2023-05-23 ### Added From b0a089b3d821743f3b3b495d8bcde82b528241b7 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Tue, 23 May 2023 12:34:00 +0530 Subject: [PATCH 56/71] Update CHANGELOG.md --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f9b2aacf..bc15fc867 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [3.3.0] - 2023-05-23 + +### Added + +* Support to configure muliple interfaces for vrf_lite on a vrf +* Added support for more switch roles in inventory module. + +### Fixed + +* https://github.com/CiscoDevNet/ansible-dcnm/issues/204 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/205 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/206 +* Removed the restriction on netcommon version supported by DCNM collection. The restriction was introduced as fix for https://github.com/CiscoDevNet/ansible-dcnm/issues/209. Netcommon versions `>=2.6.1` is supported. + ## [3.2.0] - 2023-04-20 ### Added @@ -248,6 +262,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[3.3.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.2.0...3.3.0 [3.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.1...3.2.0 [3.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.0...3.1.1 [3.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.0.0...3.1.0 From ac4f5086212de1f800db863db72bf12f76461c44 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 13 Jul 2023 22:04:15 +0530 Subject: [PATCH 57/71] Update CHANGELOG.md --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc15fc867..c0eb5551e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [3.3.1] - 2023-07-13 + +### Fixed + +* https://github.com/CiscoDevNet/ansible-dcnm/issues/230 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/231 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/232 +* https://github.com/CiscoDevNet/ansible-dcnm/issues/197 + ## [3.3.0] - 2023-05-23 ### Added @@ -262,6 +271,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[3.3.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.0...3.3.1 [3.3.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.2.0...3.3.0 [3.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.1...3.2.0 [3.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.0...3.1.1 From 2f427365996b583f07c6f2d5d32f6fd9d5384d40 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 13 Jul 2023 22:16:28 +0530 Subject: [PATCH 58/71] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0eb5551e..aa9515a31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). * https://github.com/CiscoDevNet/ansible-dcnm/issues/231 * https://github.com/CiscoDevNet/ansible-dcnm/issues/232 * https://github.com/CiscoDevNet/ansible-dcnm/issues/197 - + ## [3.3.0] - 2023-05-23 ### Added From ccca6c34dec8ae8140085bded737db8d89a6e87e Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 13 Jul 2023 22:23:49 +0530 Subject: [PATCH 59/71] Update CHANGELOG.md --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f36533c78..aa9515a31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased - ## [3.3.1] - 2023-07-13 ### Fixed From a2854870b18a1566201183c23c9ef56e7f55285a Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Wed, 16 Aug 2023 19:14:54 +0530 Subject: [PATCH 60/71] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7400ae713..0fa765297 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed * Fix for deploy flag behaviour in inferface module. Config will not be deployed to switches if deploy flag is set to false. When deploy flag is set to true in task and if any of the switch in that task is not manageable or the fabric in task is read-only, then an error is returned without making any changes in the NDFC corresponding to that task. - + ## [3.3.1] - 2023-07-13 ### Fixed From 917ed0bda12d66479c5e01790ceb9e63f0f230d5 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Wed, 16 Aug 2023 19:17:49 +0530 Subject: [PATCH 61/71] Update CHANGELOG.md --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa9515a31..b58024b66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [3.4.0] - 2023-08-16 + +### Added + +* Support for save and deploy options in `dcnm_inventory` module. +* Support for `discovery_username` and `discovery_password` in `dcnm_inventory` module. +* Support for login domain in connection plugin. + +### Fixed + +* Fix for deploy flag behaviour in inferface module. Config will not be deployed to switches if deploy flag is set to false. When deploy flag is set to true in task and if any of the switch in that task is not manageable or the fabric in task is read-only, then an error is returned without making any changes in the NDFC corresponding to that task. + ## [3.3.1] - 2023-07-13 ### Fixed @@ -271,6 +283,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[3.4.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.1...3.4.0 [3.3.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.0...3.3.1 [3.3.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.2.0...3.3.0 [3.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.1...3.2.0 From 57cd010c28dc661d59e2a0c62d812a427f384c5e Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Thu, 17 Aug 2023 16:27:25 -0400 Subject: [PATCH 62/71] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7400ae713..fdd94f3dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [3.4.1] - 2023-08-17 + +There is no functional difference between collection version `3.4.0` and collection version `3.4.1`. This version is only being published as a hotfix to resolve a problem where the wrong +version was inadvertently published to Ansible galaxy. + ## [3.4.0] - 2023-08-16 ### Added @@ -283,6 +288,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules * cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. * cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +[3.4.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.4.0...3.4.1 [3.4.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.1...3.4.0 [3.3.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.0...3.3.1 [3.3.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.2.0...3.3.0 From dd344211fd3edda24eb6c6b701aea9b31edb8e6c Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Thu, 17 Aug 2023 16:27:51 -0400 Subject: [PATCH 63/71] Update galaxy.yml --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 29fe357c6..0f7e738b2 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dcnm -version: 3.4.0 +version: 3.4.1 readme: README.md authors: - Shrishail Kariyappanavar From 42f8cce026c98eb23ce2f2d23fffff92f89ff97b Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Thu, 17 Aug 2023 16:29:43 -0400 Subject: [PATCH 64/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a66c75b7..cce359d23 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 3.4.0 + version: 3.4.1 ``` ## Using this collection From 0267bad139c1a6f196e48ecdee6f0430f592007a Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Mon, 11 Sep 2023 20:03:24 +0530 Subject: [PATCH 65/71] Update galaxy.yml --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 0f7e738b2..8eeff39c0 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dcnm -version: 3.4.1 +version: 3.4.2 readme: README.md authors: - Shrishail Kariyappanavar From 4776f4a56bbeeb5cf38955e55e6628ac17e9f996 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Mon, 11 Sep 2023 20:04:38 +0530 Subject: [PATCH 66/71] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cce359d23..de60f7c1a 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ You can also include it in a `requirements.yml` file and install it with `ansibl --- collections: - name: cisco.dcnm - version: 3.4.1 + version: 3.4.2 ``` ## Using this collection From 5d4ebdedd7c5007bffd3c02accef1aecfd3aab6a Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Mon, 11 Sep 2023 22:31:31 +0530 Subject: [PATCH 67/71] Delete CHANGELOG.md --- CHANGELOG.md | 313 --------------------------------------------------- 1 file changed, 313 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 56538448f..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,313 +0,0 @@ -# Change Log -All notable changes to this project will be documented in this file. -This project adheres to [Semantic Versioning](http://semver.org/). - -## [3.4.1] - 2023-08-17 - -There is no functional difference between collection version `3.4.0` and collection version `3.4.1`. This version is only being published as a hotfix to resolve a problem where the wrong -version was inadvertently published to Ansible galaxy. - -## [3.4.0] - 2023-08-16 - -### Added - -* Support for save and deploy options in `dcnm_inventory` module. -* Support for `discovery_username` and `discovery_password` in `dcnm_inventory` module. -* Support for login domain in connection plugin. - -### Fixed - -* Fix for deploy flag behaviour in inferface module. Config will not be deployed to switches if deploy flag is set to false. When deploy flag is set to true in task and if any of the switch in that task is not manageable or the fabric in task is read-only, then an error is returned without making any changes in the NDFC corresponding to that task. - -## [3.3.1] - 2023-07-13 - -### Fixed - -* https://github.com/CiscoDevNet/ansible-dcnm/issues/230 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/231 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/232 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/197 - -## [3.3.0] - 2023-05-23 - -### Added - -* Support to configure multiple interfaces for vrf_lite on a vrf -* Added support for more switch roles in inventory module. - -### Fixed - -* https://github.com/CiscoDevNet/ansible-dcnm/issues/204 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/205 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/206 -* Removed the restriction on netcommon version supported by DCNM collection. The restriction was introduced as fix for https://github.com/CiscoDevNet/ansible-dcnm/issues/209. Netcommon versions `>=2.6.1` is supported. - -## [3.2.0] - 2023-04-20 - -### Added - -* Support for fex interfaces in interface module - -### Fixed - -* https://github.com/CiscoDevNet/ansible-dcnm/issues/212 - -## [3.1.1] - 2023-03-17 - -### Fixed - -* Restrict installs of netcommon to versions `>=2.6.1,<=4.1.0` due to issue: https://github.com/CiscoDevNet/ansible-dcnm/issues/209 - -## [3.1.0] - 2023-03-14 - -### Added - -* Support for all config parameters in network module -* Support for all config parameters in vrf module - -### Fixed - -* https://github.com/CiscoDevNet/ansible-dcnm/issues/197 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/194 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/185 - -## [3.0.0] - 2023-02-22 - -### Added - -* RMA support in `dcnm_inventory` module - -### Fixed - -* https://github.com/CiscoDevNet/ansible-dcnm/issues/168 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/140 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/157 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/192 - -## [2.4.0] - 2022-11-17 - -### Added - -* POAP support in `dcnm_inventory` module -* SVI interface support in `dcnm_interface` module - -### Fixed - -* Fix for a problem where networks cannot be deleted when detach/undeploy fails and network is in an out of sync state. -* Fix default value for `multicast_group_address` property in `dcnm_network` - -## [2.3.0] - 2022-10-28 - -### Added - -* Added the ability to configure the `multicast_group_address` to the `dcnm_network` module - -## [2.2.0] - 2022-10-14 - -### Added - -* The following new modules are included in this release - * `dcnm_links` - Module for managing dcnm links - -### Fixed - -* https://github.com/CiscoDevNet/ansible-dcnm/issues/155 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/169 - -## [2.1.1] - 2022-08-18 - -### Fixed - -* Changed the deploy mechanism of policy module for delete state. - -## [2.1.0] - 2022-07-19 - -### Added - -* The following new modules are included in this release - * `dcnm_resource_manager` - Module for managing dcnm resources. - [Reference Info](https://www.cisco.com/c/en/us/td/docs/dcn/ndfc/121x/configuration/fabric-controller/cisco-ndfc-fabric-controller-configuration-guide-121x/lan-fabrics.html#task_fsg_sn4_zqb) - -### Fixed - -* https://github.com/CiscoDevNet/ansible-dcnm/issues/151 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/143 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/141 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/139 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/137 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/134 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/112 -* Fixed Restapi used in version detection mechanism in module utils. -* Fixed Restapi used in various modules to support the latest api's. -* Fixed deploy knob behavior for vrf and network module to align with GUI functionality. -* Fixed idempotence issue in interface module. -* Fixed diff generation issue for network deletion with NDFC. - -### Deprecated - -* Deploy knob for individual attachments in vrf and network modules has been marked for deprecation. - -## [2.0.1] - 2022-01-28 - -Fixed httpapi plugin issue preventing connections to latest version of NDFC (Version: `12.0.2f`) - -## [2.0.0] - 2021-12-13 - -### Added - -* Nexus Dashboard Fabric Controller (NDFC) support for all collection modules -* The following new modules are included in this release - * `dcnm_service_route_peering` - Module for managing dcnm service route peering - * `dcnm_service_policy` - Module for managing dcnm service policy - * `dcnm_service_node` - Module for managing dcnm service nodes -* New parameter `check_deploy` in `dcnm_interface` -* [Performance improvement of `dcnm_inventory` module](https://github.com/CiscoDevNet/ansible-dcnm/pull/98) - -### Fixed - -* https://github.com/CiscoDevNet/ansible-dcnm/issues/101 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/87 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/86 -* Fix `dcnm_policy` module configuration deploy issues - -## [1.2.4] - 2021-12-03 - -### Added - -* Added support for configuring the loopback ID for DHCP Relay interface. -* The feature is configured using the `dhcp_loopback_id` parameter in the `dcnm_network` module - -## [1.2.3] - 2021-11-16 - -### Fixed - -Fixed a problem with `dcnm_interface` module where VPCID resource was not being created and then reserved properly - -## [1.2.2] - 2021-10-21 - -### Fixed - -Fixed error code handling that was causing an error during authentication - -## [1.2.1] - 2021-10 - -### Added - -Added support for plain text payloads to `dcnm_rest` module - -## [1.2.0] - 2021-07 - -### Added - -* cisco.dcnm.dcnm_network: - * New parameter `is_l2only:` - * New parameter `vlan_name:` - * New parameter `int_desc:` - * New parameter `mtu_l3intf:` - * New parameter `arp_suppress:` - * New parameter `dhcp_srvr1_ip:` - * New parameter `dhcp_srvr1_vrf:` - * New parameter `dhcp_srvr2_ip:` - * New parameter `dhcp_srvr2_vrf:` - * New parameter `dhcp_srvr3_ip:` - * New parameter `dhcp_srvr3_vrf:` - -## [1.1.1] - 2021-05 - -### Fixed - -* https://github.com/CiscoDevNet/ansible-dcnm/issues/66 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/65 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/63 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/62 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/60 -* https://github.com/CiscoDevNet/ansible-dcnm/issues/57 - -## [1.1.0] - 2021-04 - -### Added - -* The following new modules are included in this release - * `dcnm_policy` - Module for managing dcnm policies - * `dcnm_template` - Module for managing dcnm templates - -* The `dcnm_vrf` and `dcnm_network` modules have been extended to support multisite fabrics - -### Fixed - -* Bug fixes -* Support for DCNM `11.5(1)` release - -## [1.0.0] - 2020-09 - -### Added - -* cisco.dcnm.dcnm_network: - * New parameter `routing_tag:` - -### Changed - -* cisco.dcnm.dcnm_network: - * The `vlan_id:` parameter must be configured under the `config:` block instead of the `attach:` block. - * A warning will be generated informing the user to move the `vlan_id:` under the `config:` block. - * If the user does not specify the `vlan_id` it will be auto generated by DCNM. -* cisco.dcnm_dcnm_interface: - * The various `profile_*:` parameters have now been modified to just `profile:`. - * The playbook with the old `profile_*:` names will still be accepted but a warning message will be generated to change the playbook. - * When specifying switches for a `vpc` interface type the switches should be a flat yaml list instead of a nested yaml list. Both formats will still be accepted. - - Proper Format: - ``` - switch: # provide switches of vPC pair - - "{{ ansible_switch1 }}" - - "{{ ansible_switch2 }}" - ``` - Incorrect Format: - ``` - switch: # provide switches of vPC pair - - ["{{ ansible_switch1 }}", - "{{ ansible_switch2 }}"] - ``` - -### Fixed - -* cisco.dcnm.dcnm_rest: - * Module will return a failure now if the return code from DCNM is `400` or greater. - -## 0.9.0 - 2020-07 - -- Initial release of the Ansible DCNM collection, supporting DCNM release 11.4 - -### Added - -The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules to help automate common day 2 operations for VXLAN EVPN fabrics. - -* cisco.dcnm.dcnm_rest - Send REST API requests to DCNM controller. -* cisco.dcnm.dcnm_inventory - Add and remove Switches from a DCNM managed VXLAN fabric. -* cisco.dcnm.dcnm_vrf - Add and remove VRFs from a DCNM managed VXLAN fabric. -* cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. -* cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. - -[3.4.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.4.0...3.4.1 -[3.4.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.1...3.4.0 -[3.3.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.0...3.3.1 -[3.3.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.2.0...3.3.0 -[3.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.1...3.2.0 -[3.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.1.0...3.1.1 -[3.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.0.0...3.1.0 -[3.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.4.0...3.0.0 -[2.4.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.3.0...2.4.0 -[2.3.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.2.0...2.3.0 -[2.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.1.1...2.2.0 -[2.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.1.0...2.1.1 -[2.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.0.1...2.1.0 -[2.0.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/2.0.0...2.0.1 -[2.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.4...2.0.0 -[1.2.4]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.3...1.2.4 -[1.2.3]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.2...1.2.3 -[1.2.2]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.1...1.2.2 -[1.2.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.2.0...1.2.1 -[1.2.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.1.1...1.2.0 -[1.1.1]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.1.0...1.1.1 -[1.1.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/1.0.0...1.1.0 -[1.0.0]: https://github.com/CiscoDevNet/ansible-dcnm/compare/0.9.0...1.0.0 From a9bb07a2a755f140c9043841fd90889adfdd5132 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Mon, 11 Sep 2023 22:34:59 +0530 Subject: [PATCH 68/71] Update CHANGELOG.rst --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7be5bc120..153858776 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -428,6 +428,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules - cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. - cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +.. _3.4.2: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.4.1...3.4.2 .. _3.4.1: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.4.0...3.4.1 .. _3.4.0: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.1...3.4.0 .. _3.3.1: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.0...3.3.1 From 660d2337f728d68c2ef1176b5029e1b37ae3a360 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Mon, 11 Sep 2023 23:53:00 +0530 Subject: [PATCH 69/71] Update CHANGELOG.rst --- CHANGELOG.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 153858776..08f94740d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,7 +15,14 @@ This project adheres to `Semantic Versioning `_. Added ----- - +- Support for following parameters in ``dcnm_links`` module + - ``mpls_fabric`` + - ``peer1_sr_mpls_index`` + - ``peer2_sr_mpls_index`` + - ``global_block_range`` + - ``dci_routing_proto`` + - ``ospf_area_id`` + - ``dci_routing_tag`` - Support for ``ext_vxlan_mpls_overlay_setup`` and ``ext_vxlan_mpls_underlay_setup`` templates in ``dcnm_links`` module - Support for ``secondary_ipv4_addr`` for loopback interfaces in ``dcnm_interface`` module - Support for fabric and mpls loopback interfaces in ``dcnm_interface`` module From 1b7c4bb95fe77cdba864db32a85b459a64a4a021 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Mon, 11 Sep 2023 23:57:33 +0530 Subject: [PATCH 70/71] Update CHANGELOG.rst --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 08f94740d..9d364fe6e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,7 @@ This project adheres to `Semantic Versioning `_. Added ----- + - Support for following parameters in ``dcnm_links`` module - ``mpls_fabric`` - ``peer1_sr_mpls_index`` From 8c26b556a4465cbf78424ce32c7b7212693c0f5f Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 26 Oct 2023 19:05:23 +0530 Subject: [PATCH 71/71] Update CHANGELOG.rst --- CHANGELOG.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9d364fe6e..cb0eac532 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,16 @@ This project adheres to `Semantic Versioning `_. .. contents:: ``Release Versions`` +`3.4.3`_ +===================== + +**Release Date:** ``2023-10-26`` + +Added +----- + +- Support to attach network to TOR switches paired with leaf and its interfaces + `3.4.2`_ ===================== @@ -436,6 +446,7 @@ The Ansible Cisco Data Center Network Manager (DCNM) collection includes modules - cisco.dcnm.dcnm_network - Add and remove Networks from a DCNM managed VXLAN fabric. - cisco.dcnm.dcnm_interface - DCNM Ansible Module for managing interfaces. +.. _3.4.3: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.4.2...3.4.3 .. _3.4.2: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.4.1...3.4.2 .. _3.4.1: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.4.0...3.4.1 .. _3.4.0: https://github.com/CiscoDevNet/ansible-dcnm/compare/3.3.1...3.4.0