From d70af72609668f0796dc847987f8074786319f40 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 15 Jun 2023 19:16:12 +0530 Subject: [PATCH 1/7] Fix default mcast group address in network module (#224) * Fix default mcast group address in network module * IT case for network creation in ingress multiplication enabled fabric * IT case for network creation in ingress multiplication enabled fabric --- plugins/modules/dcnm_network.py | 15 +- .../ingress_replication_networks.yaml | 134 ++++++++++++++++++ 2 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 tests/integration/targets/dcnm_network/tests/dcnm/self-contained-tests/ingress_replication_networks.yaml diff --git a/plugins/modules/dcnm_network.py b/plugins/modules/dcnm_network.py index 6c33c50aa..5a9649118 100644 --- a/plugins/modules/dcnm_network.py +++ b/plugins/modules/dcnm_network.py @@ -2453,7 +2453,12 @@ def validate_input(self): if state == "query": - if self.dcnm_version > 11: + # If ingress replication is enabled multicast group address should be set to "" as default. + # If ingress replication is not enabled, the default value for multicast group address + # is different for DCNM and NDFC. + if self.fabric_det.get("replicationMode") == "Ingress": + mcast_group_addr = "" + elif self.dcnm_version > 11: mcast_group_addr = "239.1.1.1" else: mcast_group_addr = "239.1.1.0" @@ -2533,8 +2538,12 @@ def validate_input(self): else: - # The default value for multicast group address is different for DCNM and NDFC. - if self.dcnm_version > 11: + # If ingress replication is enabled multicast group address should be set to "" as default. + # If ingress replication is not enabled, the default value for multicast group address + # is different for DCNM and NDFC. + if self.fabric_det.get("replicationMode") == "Ingress": + mcast_group_addr = "" + elif self.dcnm_version > 11: mcast_group_addr = "239.1.1.1" else: mcast_group_addr = "239.1.1.0" diff --git a/tests/integration/targets/dcnm_network/tests/dcnm/self-contained-tests/ingress_replication_networks.yaml b/tests/integration/targets/dcnm_network/tests/dcnm/self-contained-tests/ingress_replication_networks.yaml new file mode 100644 index 000000000..334decde9 --- /dev/null +++ b/tests/integration/targets/dcnm_network/tests/dcnm/self-contained-tests/ingress_replication_networks.yaml @@ -0,0 +1,134 @@ +############################################## +## SETUP ## +############################################## +- block: + - set_fact: + rest_path: "/rest/control/fabrics/{{ test_ing_fabric }}" + when: controller_version == "11" + + - set_fact: + rest_path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ test_ing_fabric }}" + when: controller_version >= "12" + + - name: ING_REP - Verify if fabric - Fabric1 is deployed. + cisco.dcnm.dcnm_rest: + method: GET + path: "{{ rest_path }}" + register: result + + - assert: + that: + - 'result.response.DATA != None' + + - name: ING_REP - Remove all existing networks to start with a clean state + cisco.dcnm.dcnm_network: + fabric: "{{ test_ing_fabric }}" + state: deleted + + - name: ING_REP - Create vrfs required for this test and remove all other vrfs + cisco.dcnm.dcnm_vrf: + fabric: "{{ test_ing_fabric }}" + state: overridden + config: + - vrf_name: Tenant-1 + vrf_id: 9008012 + vlan_id: 501 + attach: + - ip_address: "{{ ansible_ing_switch1 }}" + deploy: true + +############################################## +## MERGED ## +############################################## + + - name: ING_REP - Create New Network with Deploy + cisco.dcnm.dcnm_network: + fabric: "{{ test_ing_fabric }}" + state: merged + config: + - net_name: ansible-net15 + vrf_name: Tenant-1 + net_id: 7005 + net_template: Default_Network_Universal + net_extension_template: Default_Network_Extension_Universal + vlan_id: 1500 + gw_ip_subnet: '192.168.30.1/24' + deploy: True + register: result + + - name: Query fabric for creation of Network Object + cisco.dcnm.dcnm_network: + fabric: "{{ test_ing_fabric }}" + state: query + register: query_result + until: + - "query_result.response[0].parent.displayName is search('ansible-net15')" + - "query_result.response[0].parent.networkId is search('7005')" + - "query_result.response[0].parent.vrf is search('Tenant-1')" + retries: 5 + delay: 2 + + - assert: + that: + - 'result.changed == true' + - 'result.response[0].RETURN_CODE == 200' + - 'result.diff[0].attach|length == 0' + - 'result.diff[0].net_name == "ansible-net15"' + - 'result.diff[0].net_id == 7005' + - 'result.diff[0].vrf_name == "Tenant-1"' + + - name: ING_REP - setup - Clean up any existing networks + cisco.dcnm.dcnm_network: + fabric: "{{ test_ing_fabric }}" + state: deleted + + - name: MERGED - Create New Network with Attach and global deploy + cisco.dcnm.dcnm_network: + fabric: "{{ test_ing_fabric }}" + state: merged + config: + - net_name: ansible-net16 + vrf_name: Tenant-1 + net_id: 7005 + net_template: Default_Network_Universal + net_extension_template: Default_Network_Extension_Universal + vlan_id: 1500 + gw_ip_subnet: '192.168.30.1/24' + attach: + - ip_address: "{{ ansible_ing_switch1 }}" + ports: ["{{ ansible_ing_sw1_int1 }}", "{{ ansible_ing_sw1_int2 }}"] + deploy: True + register: result + + - name: Query fabric state until networkStatus transitions to DEPLOYED state + cisco.dcnm.dcnm_network: + fabric: "{{ test_ing_fabric }}" + state: query + register: query_result + until: + - "query_result.response[0].parent.networkStatus is search('DEPLOYED|PENDING')" + retries: 30 + delay: 2 + + - assert: + that: + - 'result.changed == true' + - 'result.response[0].RETURN_CODE == 200' + - 'result.response[1].RETURN_CODE == 200' + - 'result.response[2].RETURN_CODE == 200' + - '(result.response[1].DATA|dict2items)[0].value == "SUCCESS"' + - 'result.diff[0].attach[0].deploy == true' + - '"{{ ansible_switch1 }}" in result.diff[0].attach[0].ip_address' + - 'result.diff[0].net_name == "ansible-net16"' + - 'result.diff[0].net_id == 7005' + - 'result.diff[0].vrf_name == "Tenant-1"' + +############################################## +## CLEAN-UP ## +############################################## + + - name: MERGED - setup - remove any networks + cisco.dcnm.dcnm_network: + fabric: "{{ test_fabric }}" + state: deleted + when: test_ing_fabric is defined From ade82a83d61503f95f40c60eaaec6c86f01d436d Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 13 Jul 2023 21:19:39 +0530 Subject: [PATCH 2/7] Fix to network and vrf modules to manage deploy flag (#233) * Changes to network and vrf modules due to manage deploy flag * Review comment changes --- docs/cisco.dcnm.dcnm_network_module.rst | 12 ---- docs/cisco.dcnm.dcnm_vrf_module.rst | 8 --- plugins/modules/dcnm_network.py | 62 +++++++++++----- plugins/modules/dcnm_vrf.py | 70 +++++++++---------- .../dcnm_network/tests/dcnm/deleted.yaml | 17 ++--- .../dcnm_network/tests/dcnm/merged.yaml | 32 ++------- .../dcnm_network/tests/dcnm/overridden.yaml | 18 ++--- .../dcnm_network/tests/dcnm/query.yaml | 8 +-- .../dcnm_network/tests/dcnm/replaced.yaml | 25 +++---- 9 files changed, 106 insertions(+), 146 deletions(-) diff --git a/docs/cisco.dcnm.dcnm_network_module.rst b/docs/cisco.dcnm.dcnm_network_module.rst index 749f8acf9..de22372e0 100644 --- a/docs/cisco.dcnm.dcnm_network_module.rst +++ b/docs/cisco.dcnm.dcnm_network_module.rst @@ -804,10 +804,8 @@ Examples attach: - ip_address: 192.168.1.224 ports: [Ethernet1/13, Ethernet1/14] - deploy: true - ip_address: 192.168.1.225 ports: [Ethernet1/13, Ethernet1/14] - deploy: true deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 @@ -819,10 +817,8 @@ Examples attach: - ip_address: 192.168.1.224 ports: [Ethernet1/11, Ethernet1/12] - deploy: true - ip_address: 192.168.1.225 ports: [Ethernet1/11, Ethernet1/12] - deploy: true deploy: false - name: Replace networks @@ -842,11 +838,9 @@ Examples # Replace the ports with new ports # ports: [Ethernet1/13, Ethernet1/14] ports: [Ethernet1/16, Ethernet1/17] - deploy: true # Delete this attachment # - ip_address: 192.168.1.225 # ports: [Ethernet1/13, Ethernet1/14] - # deploy: true deploy: true # Dont touch this if its present on DCNM # - net_name: ansible-net12 @@ -859,10 +853,8 @@ Examples # attach: # - ip_address: 192.168.1.224 # ports: [Ethernet1/11, Ethernet1/12] - # deploy: true # - ip_address: 192.168.1.225 # ports: [Ethernet1/11, Ethernet1/12] - # deploy: true # deploy: false - name: Override networks @@ -882,11 +874,9 @@ Examples # Replace the ports with new ports # ports: [Ethernet1/13, Ethernet1/14] ports: [Ethernet1/16, Ethernet1/17] - deploy: true # Delete this attachment # - ip_address: 192.168.1.225 # ports: [Ethernet1/13, Ethernet1/14] - # deploy: true deploy: true # Delete this network # - net_name: ansible-net12 @@ -899,10 +889,8 @@ Examples # attach: # - ip_address: 192.168.1.224 # ports: [Ethernet1/11, Ethernet1/12] - # deploy: true # - ip_address: 192.168.1.225 # ports: [Ethernet1/11, Ethernet1/12] - # deploy: true # deploy: false - name: Delete selected networks diff --git a/docs/cisco.dcnm.dcnm_vrf_module.rst b/docs/cisco.dcnm.dcnm_vrf_module.rst index 97ef5928c..3bc912cd0 100644 --- a/docs/cisco.dcnm.dcnm_vrf_module.rst +++ b/docs/cisco.dcnm.dcnm_vrf_module.rst @@ -1071,9 +1071,7 @@ Examples service_vrf_template: null attach: - ip_address: 192.168.1.224 - deploy: true - ip_address: 192.168.1.225 - deploy: false - vrf_name: ansible-vrf-r2 vrf_id: 9008012 vrf_template: Default_VRF_Universal @@ -1128,13 +1126,10 @@ Examples service_vrf_template: null attach: - ip_address: 192.168.1.224 - deploy: true # Delete this attachment # - ip_address: 192.168.1.225 - # deploy: true # Create the following attachment - ip_address: 192.168.1.226 - deploy: true # Dont touch this if its present on DCNM # - vrf_name: ansible-vrf-r2 # vrf_id: 9008012 @@ -1158,13 +1153,10 @@ Examples service_vrf_template: null attach: - ip_address: 192.168.1.224 - deploy: true # Delete this attachment # - ip_address: 192.168.1.225 - # deploy: true # Create the following attachment - ip_address: 192.168.1.226 - deploy: true # Delete this vrf # - vrf_name: ansible-vrf-r2 # vrf_id: 9008012 diff --git a/plugins/modules/dcnm_network.py b/plugins/modules/dcnm_network.py index 5a9649118..c0e995e7e 100644 --- a/plugins/modules/dcnm_network.py +++ b/plugins/modules/dcnm_network.py @@ -319,10 +319,8 @@ attach: - ip_address: 192.168.1.224 ports: [Ethernet1/13, Ethernet1/14] - deploy: true - ip_address: 192.168.1.225 ports: [Ethernet1/13, Ethernet1/14] - deploy: true deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 @@ -334,10 +332,8 @@ attach: - ip_address: 192.168.1.224 ports: [Ethernet1/11, Ethernet1/12] - deploy: true - ip_address: 192.168.1.225 ports: [Ethernet1/11, Ethernet1/12] - deploy: true deploy: false - name: Replace networks @@ -357,11 +353,9 @@ # Replace the ports with new ports # ports: [Ethernet1/13, Ethernet1/14] ports: [Ethernet1/16, Ethernet1/17] - deploy: true # Delete this attachment # - ip_address: 192.168.1.225 # ports: [Ethernet1/13, Ethernet1/14] - # deploy: true deploy: true # Dont touch this if its present on DCNM # - net_name: ansible-net12 @@ -374,10 +368,8 @@ # attach: # - ip_address: 192.168.1.224 # ports: [Ethernet1/11, Ethernet1/12] - # deploy: true # - ip_address: 192.168.1.225 # ports: [Ethernet1/11, Ethernet1/12] - # deploy: true # deploy: false - name: Override networks @@ -397,11 +389,9 @@ # Replace the ports with new ports # ports: [Ethernet1/13, Ethernet1/14] ports: [Ethernet1/16, Ethernet1/17] - deploy: true # Delete this attachment # - ip_address: 192.168.1.225 # ports: [Ethernet1/13, Ethernet1/14] - # deploy: true deploy: true # Delete this network # - net_name: ansible-net12 @@ -414,10 +404,8 @@ # attach: # - ip_address: 192.168.1.224 # ports: [Ethernet1/11, Ethernet1/12] - # deploy: true # - ip_address: 192.168.1.225 # ports: [Ethernet1/11, Ethernet1/12] - # deploy: true # deploy: false - name: Delete selected networks @@ -613,6 +601,8 @@ def diff_for_attach_deploy(self, want_a, have_a, replace=False): del want["isAttached"] attach_list.append(want) + if bool(want["is_deploy"]): + dep_net = True continue @@ -625,6 +615,8 @@ def diff_for_attach_deploy(self, want_a, have_a, replace=False): ) del want["isAttached"] attach_list.append(want) + if bool(want["is_deploy"]): + dep_net = True continue if bool(have["isAttached"]) is not bool(want["isAttached"]): @@ -635,21 +627,34 @@ def diff_for_attach_deploy(self, want_a, have_a, replace=False): del have["isAttached"] have.update({"deployment": False}) attach_list.append(have) + if bool(want["is_deploy"]): + dep_net = True continue del want["isAttached"] + want.update({"deployment": True}) attach_list.append(want) + if bool(want["is_deploy"]): + dep_net = True continue if bool(have["deployment"]) is not bool(want["deployment"]): # We hit this section when attachment is successful, but, deployment is stuck in PENDING or # OUT-OF-SYNC. In such cases, we just add the object to deploy list only. have['deployment'] # is set to False when deployment is PENDING or OUT-OF-SYNC - ref - get_have() - dep_net = True + if bool(want["is_deploy"]): + dep_net = True + + if bool(want["is_deploy"]) is not bool(have["is_deploy"]): + if bool(want["is_deploy"]): + dep_net = True if not found: if bool(want["isAttached"]): del want["isAttached"] + want["deployment"] = True attach_list.append(want) + if bool(want["is_deploy"]): + dep_net = True for attach in attach_list[:]: for ip, ser in self.ip_sn.items(): @@ -671,6 +676,7 @@ def diff_for_attach_deploy(self, want_a, have_a, replace=False): havtoattach = copy.deepcopy(hav) havtoattach.update({"switchPorts": ""}) del havtoattach["isAttached"] + havtoattach["deployment"] = True attach_list.append(havtoattach) break @@ -713,11 +719,15 @@ def update_attach_params(self, attach, net_name, deploy): attach.update({"vlan": 0}) attach.update({"dot1QVlan": 0}) attach.update({"untagged": False}) - attach.update({"deployment": deploy}) + # This flag is not to be confused for deploy of attachment. + # "deployment" should be set True for attaching an attachment + # and set to False for detaching an attachment + attach.update({"deployment": True}) attach.update({"isAttached": True}) attach.update({"extensionValues": ""}) attach.update({"instanceValues": ""}) attach.update({"freeformConfig": ""}) + attach.update({"is_deploy": deploy}) if "deploy" in attach: del attach["deploy"] del attach["ports"] @@ -1384,7 +1394,7 @@ def get_have(self): attach.update({"fabric": self.fabric}) attach.update({"vlan": vlan}) attach.update({"serialNumber": sn}) - attach.update({"deployment": deployed}) + attach.update({"deployment": deploy}) attach.update({"extensionValues": ""}) attach.update({"instanceValues": ""}) attach.update({"freeformConfig": ""}) @@ -1393,6 +1403,7 @@ def get_have(self): attach.update({"detachSwitchPorts": ""}) attach.update({"switchPorts": ports}) attach.update({"untagged": False}) + attach.update({"is_deploy": deployed}) if dep_net: dep_networks.append(dep_net) @@ -1428,7 +1439,7 @@ def get_want(self): if not net.get("attach"): continue for attach in net["attach"]: - deploy = net_deploy if "deploy" not in attach else attach["deploy"] + deploy = net_deploy networks.append( self.update_attach_params(attach, net["net_name"], deploy) ) @@ -1912,7 +1923,8 @@ def get_diff_merge(self, replace=False): del base["lanAttachList"] base.update({"lanAttachList": diff}) diff_attach.append(base) - dep_net = want_a["networkName"] + if net: + dep_net = want_a["networkName"] else: if ( net @@ -1957,9 +1969,12 @@ def get_diff_merge(self, replace=False): del base["lanAttachList"] base.update({"lanAttachList": atch_list}) diff_attach.append(base) - if bool(attach["deployment"]): + if bool(attach["is_deploy"]): dep_net = want_a["networkName"] + for atch in atch_list: + atch["deployment"] = True + if dep_net: all_nets.append(dep_net) @@ -2278,6 +2293,10 @@ def push_to_remote(self, is_rollback=False): # Update the fabric name to specific fabric which the switches are part of. self.update_ms_fabric(self.diff_detach) + for d_a in self.diff_detach: + for v_a in d_a["lanAttachList"]: + del v_a["is_deploy"] + resp = dcnm_send( self.module, method, detach_path, json.dumps(self.diff_detach) ) @@ -2406,6 +2425,10 @@ def push_to_remote(self, is_rollback=False): # Update the fabric name to specific fabric which the switches are part of. self.update_ms_fabric(self.diff_attach) + for d_a in self.diff_attach: + for v_a in d_a["lanAttachList"]: + del v_a["is_deploy"] + for attempt in range(0, 50): resp = dcnm_send( self.module, method, attach_path, json.dumps(self.diff_attach) @@ -2553,7 +2576,7 @@ def validate_input(self): net_id=dict(type="int", range_max=16777214), vrf_name=dict(type="str", length_max=32), attach=dict(type="list"), - deploy=dict(type="bool"), + deploy=dict(type="bool", default=True), gw_ip_subnet=dict(type="ipv4_subnet", default=""), vlan_id=dict(type="int", range_max=4094), routing_tag=dict(type="int", default=12345, range_max=4294967295), @@ -2605,6 +2628,7 @@ def validate_input(self): ) net["attach"] = valid_att for attach in net["attach"]: + attach["deploy"] = net["deploy"] if attach.get("ports"): attach["ports"] = [port.capitalize() for port in attach["ports"]] invalid_params.extend(invalid_att) diff --git a/plugins/modules/dcnm_vrf.py b/plugins/modules/dcnm_vrf.py index 3198a593c..c1428dbc3 100644 --- a/plugins/modules/dcnm_vrf.py +++ b/plugins/modules/dcnm_vrf.py @@ -420,9 +420,7 @@ service_vrf_template: null attach: - ip_address: 192.168.1.224 - deploy: true - ip_address: 192.168.1.225 - deploy: false - vrf_name: ansible-vrf-r2 vrf_id: 9008012 vrf_template: Default_VRF_Universal @@ -477,13 +475,10 @@ service_vrf_template: null attach: - ip_address: 192.168.1.224 - deploy: true # Delete this attachment # - ip_address: 192.168.1.225 - # deploy: true # Create the following attachment - ip_address: 192.168.1.226 - deploy: true # Dont touch this if its present on DCNM # - vrf_name: ansible-vrf-r2 # vrf_id: 9008012 @@ -507,13 +502,10 @@ service_vrf_template: null attach: - ip_address: 192.168.1.224 - deploy: true # Delete this attachment # - ip_address: 192.168.1.225 - # deploy: true # Create the following attachment - ip_address: 192.168.1.226 - deploy: true # Delete this vrf # - vrf_name: ansible-vrf-r2 # vrf_id: 9008012 @@ -756,18 +748,21 @@ def diff_for_attach_deploy(self, want_a, have_a, replace=False): else: found = True - # When the attachment is to be detached and undeployed, ignore any changes - # to the attach section in the want(i.e in the playbook). if want.get("isAttached") is not None: if bool(have["isAttached"]) is not bool( want["isAttached"] ): del want["isAttached"] + want["deployment"] = True attach_list.append(want) + if bool(want["is_deploy"]): + dep_vrf = True continue - if bool(have["deployment"]) is not bool(want["deployment"]): - dep_vrf = True + if ((bool(want["deployment"]) is not bool(have["deployment"])) or + (bool(want["is_deploy"]) is not bool(have["is_deploy"]))): + if bool(want["is_deploy"]): + dep_vrf = True if found: break @@ -778,7 +773,10 @@ def diff_for_attach_deploy(self, want_a, have_a, replace=False): if not found: if bool(want["isAttached"]): del want["isAttached"] + want["deployment"] = True attach_list.append(want) + if bool(want["is_deploy"]): + dep_vrf = True return attach_list, dep_vrf @@ -898,9 +896,13 @@ def update_attach_params(self, attach, vrf_name, deploy, vlanId): attach.update({"fabric": self.fabric}) attach.update({"vrfName": vrf_name}) attach.update({"vlan": vlanId}) - attach.update({"deployment": deploy}) + # This flag is not to be confused for deploy of attachment. + # "deployment" should be set True for attaching an attachment + # and set to False for detaching an attachment + attach.update({"deployment": True}) attach.update({"isAttached": True}) attach.update({"serialNumber": serial}) + attach.update({"is_deploy": deploy}) if vrf_ext: attach.update({"extensionValues": json.dumps(ext_values).replace(" ", "")}) attach.update( @@ -1295,11 +1297,12 @@ def get_have(self): attach.update({"fabric": self.fabric}) attach.update({"vlan": vlan}) attach.update({"serialNumber": sn}) - attach.update({"deployment": deployed}) + attach.update({"deployment": deploy}) attach.update({"extensionValues": ""}) attach.update({"instanceValues": ""}) attach.update({"freeformConfig": ""}) attach.update({"isAttached": attach_state}) + attach.update({"is_deploy": deployed}) """ Get the VRF LITE extension template and update it to the attach['extensionvalues']""" @@ -1418,7 +1421,7 @@ def get_want(self): if not vrf.get("attach"): continue for attach in vrf["attach"]: - deploy = vrf_deploy if "deploy" not in attach else attach["deploy"] + deploy = vrf_deploy vrfs.append( self.update_attach_params(attach, vrf["vrf_name"], deploy, vlanId) ) @@ -1801,7 +1804,8 @@ def get_diff_merge(self, replace=False): base.update({"lanAttachList": diff}) diff_attach.append(base) - dep_vrf = want_a["vrfName"] + if vrf: + dep_vrf = want_a["vrfName"] else: if vrf or conf_changed.get(want_a["vrfName"], False): dep_vrf = want_a["vrfName"] @@ -1817,20 +1821,19 @@ def get_diff_merge(self, replace=False): del base["lanAttachList"] base.update({"lanAttachList": atch_list}) diff_attach.append(base) - if bool(attach["deployment"]): + if bool(attach["is_deploy"]): dep_vrf = want_a["vrfName"] + for atch in atch_list: + atch["deployment"] = True + if dep_vrf: all_vrfs += dep_vrf + "," if all_vrfs: diff_deploy.update({"vrfNames": all_vrfs[:-1]}) - if vrf_found and not attach_found: - self.diff_create = [] - else: - self.diff_create = diff_create - + self.diff_create = diff_create self.diff_create_update = diff_create_update self.diff_attach = diff_attach self.diff_deploy = diff_deploy @@ -1918,7 +1921,7 @@ def format_diff(self): del found_c["serviceVrfTemplate"] del found_c["vrfTemplateConfig"] - if diff_deploy: + if diff_deploy and found_c["vrf_name"] in diff_deploy: diff_deploy.remove(found_c["vrf_name"]) if not found_a: diff.append(found_c) @@ -2131,6 +2134,11 @@ def push_to_remote(self, is_rollback=False): for node in elem["lanAttachList"]: node["fabric"] = self.sn_fab[node["serialNumber"]] + for d_a in self.diff_detach: + for v_a in d_a["lanAttachList"]: + if "is_deploy" in v_a.keys(): + del v_a["is_deploy"] + resp = dcnm_send( self.module, method, detach_path, json.dumps(self.diff_detach) ) @@ -2253,6 +2261,8 @@ def push_to_remote(self, is_rollback=False): for d_a in self.diff_attach: for v_a in d_a["lanAttachList"]: v_a.update(vlan=0) + if "is_deploy" in v_a.keys(): + del v_a["is_deploy"] if v_a.get("vrf_lite"): for ip, ser in self.ip_sn.items(): if ser == v_a["serialNumber"]: @@ -2396,7 +2406,7 @@ def push_to_remote(self, is_rollback=False): del v_a["vrf_lite"] else: - if v_a.get("vrf_lite", None) is not None: + if "vrf_lite" in v_a.keys(): del v_a["vrf_lite"] path = self.paths["GET_VRF"].format(self.fabric) @@ -2561,18 +2571,8 @@ def validate_input(self): ) for vrf in valid_vrf: if vrf.get("attach"): - # The deploy setting provided in the user parameters - # has the following behavior: - # (1) By default deploy is true - # (2) The global 'deploy' option for the vrf applies to - # any attachments that don't have the 'deploy' - # option explicity set. for entry in vrf.get("attach"): - if "deploy" not in entry.keys() and "deploy" in vrf: - # This attach entry does not have a deploy key - # but the vrf global deploy flag is set so set - # it to the global 'deploy' value - entry["deploy"] = vrf["deploy"] + entry["deploy"] = vrf["deploy"] valid_att, invalid_att = validate_list_of_dicts( vrf["attach"], att_spec ) diff --git a/tests/integration/targets/dcnm_network/tests/dcnm/deleted.yaml b/tests/integration/targets/dcnm_network/tests/dcnm/deleted.yaml index 80a516fa5..fb4479b16 100644 --- a/tests/integration/targets/dcnm_network/tests/dcnm/deleted.yaml +++ b/tests/integration/targets/dcnm_network/tests/dcnm/deleted.yaml @@ -40,11 +40,9 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -133,7 +131,6 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -144,8 +141,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - assert: @@ -270,7 +266,7 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true + deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -281,8 +277,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -378,7 +373,6 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: True deploy: True register: result @@ -492,7 +486,7 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: True + deploy: True - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7010 @@ -515,7 +509,6 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int1 }}", "{{ ansible_sw2_int2 }}"] - deploy: True deploy: True register: result diff --git a/tests/integration/targets/dcnm_network/tests/dcnm/merged.yaml b/tests/integration/targets/dcnm_network/tests/dcnm/merged.yaml index 1cdb14032..5350cde0a 100644 --- a/tests/integration/targets/dcnm_network/tests/dcnm/merged.yaml +++ b/tests/integration/targets/dcnm_network/tests/dcnm/merged.yaml @@ -157,7 +157,7 @@ fabric: "{{ test_fabric }}" state: deleted -- name: MERGED - Create New Network with Attach specific deploy and no global deploy +- name: MERGED - Create New Network with no deploy cisco.dcnm.dcnm_network: &conf fabric: "{{ test_fabric }}" state: merged @@ -172,11 +172,10 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: True deploy: False register: result -- name: Query fabric state until networkStatus transitions to DEPLOYED state +- name: Query fabric state until networkStatus transitions to PENDING state cisco.dcnm.dcnm_network: fabric: "{{ test_fabric }}" state: query @@ -191,7 +190,6 @@ - 'result.changed == true' - 'result.response[0].RETURN_CODE == 200' - 'result.response[1].RETURN_CODE == 200' - - 'result.response[2].RETURN_CODE == 200' - '(result.response[1].DATA|dict2items)[0].value == "SUCCESS"' - 'result.diff[0].attach[0].deploy == true' - '"{{ ansible_switch1 }}" in result.diff[0].attach[0].ip_address' @@ -228,7 +226,7 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true + deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -239,7 +237,6 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true deploy: false register: result @@ -303,11 +300,9 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: True register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -364,10 +359,8 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int3 }}", "{{ ansible_sw2_int4 }}"] - deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -378,11 +371,9 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int3 }}", "{{ ansible_sw1_int4 }}"] - deploy: true - deploy: false + deploy: True register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -448,11 +439,9 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -511,7 +500,6 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: True deploy: True register: result @@ -590,7 +578,6 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: True deploy: True register: result @@ -847,7 +834,6 @@ attach: - ip_address: ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true deploy: false register: result ignore_errors: yes @@ -872,7 +858,6 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: - deploy: true deploy: false register: result ignore_errors: yes @@ -968,11 +953,6 @@ - 'result.changed == false' - '"Invalid parameters in playbook: DHCP server IP should be specified along with DHCP server VRF" in result.msg' -- name: MERGED - setup - Clean up any existing network - cisco.dcnm.dcnm_network: - fabric: "{{ test_fabric }}" - state: deleted - ############################################## ## CLEAN-UP ## ############################################## diff --git a/tests/integration/targets/dcnm_network/tests/dcnm/overridden.yaml b/tests/integration/targets/dcnm_network/tests/dcnm/overridden.yaml index d4350bab5..d228bac08 100644 --- a/tests/integration/targets/dcnm_network/tests/dcnm/overridden.yaml +++ b/tests/integration/targets/dcnm_network/tests/dcnm/overridden.yaml @@ -40,10 +40,9 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int3 }}", "{{ ansible_sw2_int4 }}"] - deploy: true + deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -54,8 +53,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -110,9 +108,8 @@ # Replace the ports with new ports # ports: [Ethernet1/1, Ethernet1/2] ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int4 }}"] - deploy: true + deploy: true # delete the second network - deploy: false register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -189,10 +186,9 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int3 }}", "{{ ansible_sw2_int4 }}"] - deploy: true + deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -212,8 +208,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -277,8 +272,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state diff --git a/tests/integration/targets/dcnm_network/tests/dcnm/query.yaml b/tests/integration/targets/dcnm_network/tests/dcnm/query.yaml index 36f765540..d84064fac 100644 --- a/tests/integration/targets/dcnm_network/tests/dcnm/query.yaml +++ b/tests/integration/targets/dcnm_network/tests/dcnm/query.yaml @@ -45,7 +45,7 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true + deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -56,8 +56,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int1 }}", "{{ ansible_sw2_int2 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -260,7 +259,7 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: True + deploy: True - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7010 @@ -280,7 +279,6 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int1 }}", "{{ ansible_sw2_int2 }}"] - deploy: True deploy: True register: result diff --git a/tests/integration/targets/dcnm_network/tests/dcnm/replaced.yaml b/tests/integration/targets/dcnm_network/tests/dcnm/replaced.yaml index 8a7600d05..2fe7017fd 100644 --- a/tests/integration/targets/dcnm_network/tests/dcnm/replaced.yaml +++ b/tests/integration/targets/dcnm_network/tests/dcnm/replaced.yaml @@ -40,10 +40,8 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int3 }}", "{{ ansible_sw2_int4 }}"] - deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -54,8 +52,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -135,7 +132,7 @@ - '(result.response[0].DATA|dict2items)[1].value == "SUCCESS"' - '(result.response[0].DATA|dict2items)[2].value == "SUCCESS"' - 'result.diff[0].attach[0].deploy == false' - - 'result.diff[0].attach[1].deploy == false' + - 'result.diff[1].attach[1].deploy == false' - '"{{ ansible_switch1 }}" or "{{ ansible_switch2 }}" in result.diff[1].attach[0].ip_address' - '"{{ ansible_switch2 }}" or "{{ ansible_switch1 }}" in result.diff[1].attach[1].ip_address' - '"ansible-net13" or "ansible-net12" in result.diff[1].net_name' @@ -167,10 +164,9 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int3 }}", "{{ ansible_sw2_int4 }}"] - deploy: true + deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -181,8 +177,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -251,10 +246,9 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int3 }}", "{{ ansible_sw2_int4 }}"] - deploy: true + deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -274,8 +268,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state @@ -415,10 +408,9 @@ attach: - ip_address: "{{ ansible_switch1 }}" ports: ["{{ ansible_sw1_int1 }}", "{{ ansible_sw1_int2 }}"] - deploy: true - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int3 }}", "{{ ansible_sw2_int4 }}"] - deploy: true + deploy: true - net_name: ansible-net12 vrf_name: Tenant-2 net_id: 7002 @@ -438,8 +430,7 @@ attach: - ip_address: "{{ ansible_switch2 }}" ports: ["{{ ansible_sw2_int5 }}", "{{ ansible_sw2_int6 }}"] - deploy: true - deploy: false + deploy: true register: result - name: Query fabric state until networkStatus transitions to DEPLOYED state From c59ec1229ef13b1c6628e95ebb9c7f33a30c4e58 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 13 Jul 2023 21:36:08 +0530 Subject: [PATCH 3/7] Update CHANGELOG.md --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7b4c57c5..c31f1adbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +## [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 @@ -264,6 +273,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 0534797d3b7a2b29e244cf38842883195023fb3b Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 13 Jul 2023 21:37:12 +0530 Subject: [PATCH 4/7] Update galaxy.yml --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index dad67956f..b615fa7bd 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dcnm -version: 3.3.0 +version: 3.3.1 readme: README.md authors: - Shrishail Kariyappanavar From 056f0abd0df1cf92dc7878fb7d3f3295c41e0a71 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 13 Jul 2023 21:39:28 +0530 Subject: [PATCH 5/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a64831ed6..18b603582 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.3.0 + version: 3.3.1 ``` ## Using this collection From 7f7cdaf98c3126fe1e286741a6f0252c863327e9 Mon Sep 17 00:00:00 2001 From: praveenramoorthy <62758226+praveenramoorthy@users.noreply.github.com> Date: Thu, 13 Jul 2023 22:22:57 +0530 Subject: [PATCH 6/7] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c31f1adbd..f36533c78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,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 7/7] 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