From 11d52752bb87599df1a2d55fb359a9f37faad692 Mon Sep 17 00:00:00 2001
From: mmudigon <62759545+mmudigon@users.noreply.github.com>
Date: Mon, 24 Jul 2023 06:12:41 +0530
Subject: [PATCH 01/11] Fix to check for deploy flag during delete operation
(#225)
* Fix to check for deploy flag during delete operation
* Added more details to global deploy flag under documentation
* Corrected errors in docuemntation
---
docs/cisco.dcnm.dcnm_interface_module.rst | 22 +
plugins/modules/dcnm_interface.py | 410 ++++++++++++-----
plugins/modules/dcnm_policy.py | 7 +-
.../targets/dcnm_interface/tasks/dcnm.yaml | 4 +-
.../tests/dcnm/dcnm_delete_deploy.yaml | 229 ++++++++++
.../tests/dcnm/dcnm_delete_diff_options.yaml | 6 +-
.../tests/dcnm/dcnm_intf_misc.yaml | 196 ++++++++
.../targets/prepare_dcnm_intf/tasks/main.yaml | 21 +-
.../fixtures/dcnm_intf_aa_fex_configs.json | 36 +-
.../fixtures/dcnm_intf_bunched_configs.json | 42 +-
.../dcnm/fixtures/dcnm_intf_eth_configs.json | 42 +-
.../fixtures/dcnm_intf_have_all_payloads.json | 73 ++-
.../dcnm/fixtures/dcnm_intf_lo_configs.json | 43 +-
.../fixtures/dcnm_intf_mixed_configs.json | 42 +-
.../fixtures/dcnm_intf_multi_configs.json | 40 +-
.../dcnm_intf_multi_intf_configs.json | 40 +-
.../dcnm/fixtures/dcnm_intf_pc_configs.json | 88 +++-
.../fixtures/dcnm_intf_query_configs.json | 39 +-
.../fixtures/dcnm_intf_st_fex_configs.json | 35 +-
.../fixtures/dcnm_intf_subint_configs.json | 39 +-
.../dcnm/fixtures/dcnm_intf_svi_configs.json | 39 +-
.../dcnm/fixtures/dcnm_intf_vpc_configs.json | 39 +-
tests/unit/modules/dcnm/test_dcnm_intf.py | 419 ++++++++++++++++++
23 files changed, 1747 insertions(+), 204 deletions(-)
create mode 100644 tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_delete_deploy.yaml
create mode 100644 tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_intf_misc.yaml
diff --git a/docs/cisco.dcnm.dcnm_interface_module.rst b/docs/cisco.dcnm.dcnm_interface_module.rst
index 31e64b72e..516375426 100644
--- a/docs/cisco.dcnm.dcnm_interface_module.rst
+++ b/docs/cisco.dcnm.dcnm_interface_module.rst
@@ -2431,6 +2431,28 @@ Parameters
+
diff --git a/plugins/modules/dcnm_interface.py b/plugins/modules/dcnm_interface.py
index b06ef4952..f3bc919fb 100644
--- a/plugins/modules/dcnm_interface.py
+++ b/plugins/modules/dcnm_interface.py
@@ -48,13 +48,19 @@
description:
- The required state of the configuration after module completion.
type: str
- choices:
- - merged
- - replaced
- - overridden
- - deleted
- - query
+ choices: ['merged', 'replaced', 'overridden', 'deleted', 'query']
default: merged
+ deploy:
+ description:
+ - Flag indicating if the configuration must be pushed to the switch. This flag is used to decide the deploy behavior in
+ 'deleted' and 'overridden' states as mentioned below
+ - In 'overridden' state this flag will be used to deploy deleted interfaces.
+ - In 'deleted' state this flag will be used to deploy deleted interfaces when a specific 'config' block is not
+ included.
+ - The 'deploy' flags included with individual interface configuration elements under the 'config' block will take precedence
+ over this global flag.
+ type: bool
+ default: true
config:
description:
- A dictionary of interface operations
@@ -1584,6 +1590,7 @@ class DcnmIntf:
"GLOBAL_IF_DEPLOY": "/rest/globalInterface/deploy",
"INTERFACE": "/rest/interface",
"IF_MARK_DELETE": "/rest/interface/markdelete",
+ "FABRIC_ACCESS_MODE": "/rest/control/fabrics/{}/accessmode",
},
12: {
"VPC_SNO": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/interface/vpcpair_serial_number?serial_number={}",
@@ -1593,6 +1600,7 @@ class DcnmIntf:
"GLOBAL_IF_DEPLOY": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/globalInterface/deploy",
"INTERFACE": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/interface",
"IF_MARK_DELETE": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/interface/markdelete",
+ "FABRIC_ACCESS_MODE": "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{}/accessmode",
},
}
@@ -1617,6 +1625,10 @@ def __init__(self, module):
self.log_verbosity = 0
self.fd = None
self.vpc_ip_sn = {}
+ self.ip_sn = {}
+ self.hn_sn = {}
+ self.monitoring = []
+
self.changed_dict = [
{
"merged": [],
@@ -1626,15 +1638,14 @@ def __init__(self, module):
"deploy": [],
"query": [],
"debugs": [],
+ "delete_deploy": [],
}
]
self.dcnm_version = dcnm_version_supported(self.module)
- 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.inventory_data = {}
+
self.paths = self.dcnm_intf_paths[self.dcnm_version]
self.dcnm_intf_facts = {
@@ -1780,6 +1791,28 @@ def log_msg(self, msg):
self.fd.write("\n")
self.fd.flush()
+ def dcnm_intf_dump_have_all(self):
+
+ lhave_all = []
+ for have in self.have_all:
+ lhave_all.append(
+ {
+ "COMPLIANCE": have["complianceStatus"],
+ "FABRIC": have["fabricName"],
+ "IF_NAME": have["ifName"],
+ "IF_TYPE": have["ifType"],
+ "IP": have["ipAddress"],
+ "SNO": have["serialNo"],
+ "SYS NAME": have["sysName"],
+ "DELETABLE": have["deletable"],
+ "MARKED DELETE": have["markDeleted"],
+ "ALIAS": have["alias"],
+ "IS PHYSICAL": have["isPhysical"],
+ "UNDERLAY POLICIES": have["underlayPolicies"],
+ }
+ )
+ self.log_msg(f"HAVE ALL = {lhave_all}")
+
# New Interfaces
def dcnm_intf_get_if_name(self, name, if_type):
@@ -1823,12 +1856,9 @@ def dcnm_intf_get_vpc_serial_number(self, sw):
# messing up the incoming config make a copy of it.
def dcnm_intf_copy_config(self):
- if None is self.config:
- return
-
for cfg in self.config:
- if None is cfg.get("switch", None):
+ if cfg.get("switch", None) is None:
continue
for sw in cfg["switch"]:
@@ -1856,6 +1886,7 @@ def dcnm_intf_copy_config(self):
c[ck]["sno"] = self.vpc_ip_sn[sw]
else:
c[ck]["sno"] = self.ip_sn[sw]
+
ifname, port_id = self.dcnm_intf_get_if_name(
c["name"], c["type"]
)
@@ -2324,6 +2355,7 @@ def dcnm_intf_validate_delete_state_input(self, cfg):
del_spec = dict(
name=dict(required=False, type="str"),
switch=dict(required=False, type="list", elements="str"),
+ deploy=dict(required=False, type="bool", default=True),
)
self.dcnm_intf_validate_interface_input(cfg, del_spec, None)
@@ -2350,9 +2382,6 @@ def dcnm_intf_validate_overridden_state_input(self, cfg):
def dcnm_intf_validate_input(self):
"""Parse the playbook values, validate to param specs."""
- if None is self.config:
- return
-
# Inputs will vary for each type of interface and for each state. Make specific checks
# for each case.
@@ -3145,14 +3174,13 @@ def dcnm_intf_merge_intf_info(self, intf_info, if_head):
def dcnm_intf_get_want(self):
- if None is self.config:
+ if self.config == []:
return
- if not self.intf_info:
+ if self.intf_info == []:
return
# self.intf_info is a list of directories each having config related to a particular interface
-
for delem in self.intf_info:
if any("profile" in key for key in delem):
for sw in delem["switch"]:
@@ -3171,9 +3199,22 @@ def dcnm_intf_get_intf_info(self, ifName, serialNumber, ifType):
sno = serialNumber
path = self.paths["IF_WITH_SNO_IFNAME"].format(sno, ifName)
- resp = dcnm_send(self.module, "GET", path)
- if "DATA" in resp and resp["DATA"]:
+ retry_count = 0
+ while retry_count < 3:
+ retry_count += 1
+ resp = dcnm_send(self.module, "GET", path)
+
+ if resp == [] or resp["RETURN_CODE"] == 200:
+ break
+ time.sleep(1)
+
+ if (
+ resp
+ and "DATA" in resp
+ and resp["DATA"]
+ and resp["RETURN_CODE"] == 200
+ ):
return resp["DATA"][0]
else:
return []
@@ -3191,7 +3232,7 @@ def dcnm_intf_get_have_all_with_sno(self, sno):
path = self.paths["IF_DETAIL_WITH_SNO"].format(sno)
resp = dcnm_send(self.module, "GET", path)
- if "DATA" in resp and resp["DATA"]:
+ if resp and "DATA" in resp and resp["DATA"]:
self.have_all.extend(resp["DATA"])
def dcnm_intf_get_have_all(self, sw):
@@ -3223,7 +3264,7 @@ def dcnm_intf_get_have(self):
for intf in elem["interfaces"]:
# For each interface present here, get the information that is already available
# in DCNM. Based on this information, we will create the required payloads to be sent
- # to the DCNM controller based on the requested
+ # to the DCNM controller.
# Fetch the information from DCNM w.r.t to the interafce that we have in self.want
intf_payload = self.dcnm_intf_get_intf_info_from_dcnm(intf)
@@ -3552,7 +3593,7 @@ def dcnm_intf_compare_want_and_have(self, state):
intf_changed = True
# if deploy flag is set to True, add the information so that this interface will be deployed
- if str(deploy) == "True":
+ if str(deploy).lower() == "true":
# Add to diff_deploy,
# 1. if intf_changed is True
# 2. if intf_changed is Flase, then if 'complianceStatus is
@@ -3714,7 +3755,7 @@ def dcnm_intf_process_config(self, cfg):
processed = []
- if None is cfg.get("switch", None):
+ if cfg.get("switch", None) is None:
return
for sw in cfg["switch"]:
@@ -3734,15 +3775,18 @@ def dcnm_intf_process_config(self, cfg):
def dcnm_intf_get_diff_overridden(self, cfg):
+ deploy = False
self.diff_create = []
self.diff_delete = [[], [], [], [], [], [], [], []]
self.diff_delete_deploy = [[], [], [], [], [], [], [], []]
self.diff_deploy = []
self.diff_replace = []
- if (cfg is not None) and (cfg != []):
- self.dcnm_intf_process_config(cfg)
- elif [] == cfg:
+ # If no config is included, delete/default all interfaces
+ if cfg == []:
+ # Since there is no 'config' block, then the 'deploy' flag at top level will be
+ # used to determine the deploy behaviour
+ deploy = self.module.params["deploy"]
for address in self.ip_sn.keys():
# the given switch may be part of a VPC pair. In that case we
# need to get interface information using one switch which returns interfaces
@@ -3752,9 +3796,17 @@ def dcnm_intf_get_diff_overridden(self, cfg):
for d in self.have_all
):
self.dcnm_intf_get_have_all(address)
- elif self.config:
- # compute have_all for every switch
- for config in self.config:
+ else:
+ # compute have_all for every switch included in 'cfg'.
+ # 'deploy' flag will be picked from 'cfg' in case of state 'deleted' and from
+ # top level in case of state 'overridden'
+
+ if self.module.params["state"] == "overridden":
+ deploy = self.module.params["deploy"]
+ if self.module.params["state"] == "deleted":
+ # NOTE: in case of state 'deleted' 'cfg' will have a single entry only.
+ deploy = cfg[0].get("deploy")
+ for config in cfg:
self.dcnm_intf_process_config(config)
del_list = []
@@ -3771,6 +3823,8 @@ def dcnm_intf_get_diff_overridden(self, cfg):
(str(have["isPhysical"]).lower() != "none")
and (str(have["isPhysical"]).lower() == "true")
):
+ if have["alias"] != "" and have["deleteReason"] is not None:
+ continue
if str(have["deletable"]).lower() == "false":
# Add this 'have to a deferred list. We will process this list once we have processed all the 'haves'
@@ -3787,7 +3841,6 @@ def dcnm_intf_get_diff_overridden(self, cfg):
intf = self.dcnm_intf_get_intf_info(
have["ifName"], have["serialNo"], have["ifType"]
)
-
if intf == []:
# In case of LANClassic fabrics, a GET on policy details for Ethernet interfaces will return [] since
# these interfaces dont have any policies configured by default. In that case there is nothing to be done
@@ -3798,7 +3851,6 @@ def dcnm_intf_get_diff_overridden(self, cfg):
== "DCNM_INTF_MATCH"
):
continue
-
if uelem is not None:
# Before defaulting ethernet interfaces, check if they are
# member of any port-channel. If so, do not default that
@@ -3817,7 +3869,6 @@ def dcnm_intf_get_diff_overridden(self, cfg):
self.changed_dict[0]["deploy"].append(
copy.deepcopy(delem)
)
-
# Sub-interafces are returned as INTERFACE_ETHERNET in have_all. So do an
# additional check to see if it is physical. If not assume it to be sub-interface
# for now. We will have to re-visit this check if there are additional non-physical
@@ -3840,12 +3891,18 @@ def dcnm_intf_get_diff_overridden(self, cfg):
)
):
- # Certain interfaces cannot be deleted, so check before deleting.
- if str(have["deletable"]).lower() == "true":
-
+ # Certain interfaces cannot be deleted, so check before deleting. But if the interface has been marked for delete,
+ # we still go in and check if need to deploy.
+ if (
+ str(have["deletable"]).lower() == "true"
+ or str(have["markDeleted"]).lower() == "true"
+ ):
# Port-channel which are created as part of VPC peer link should not be deleted
if have["ifType"] == "INTERFACE_PORT_CHANNEL":
- if have["alias"] == '"vpc-peer-link"':
+ if (
+ have["alias"] is not None
+ and "vpc-peer-link" in have["alias"]
+ ):
continue
# Interfaces sometimes take time to get deleted from DCNM. Such interfaces will have
@@ -3872,7 +3929,6 @@ def dcnm_intf_get_diff_overridden(self, cfg):
and (fabric == d["interfaces"][0]["fabricName"])
)
]
-
if not match_want:
delem = {}
@@ -3883,19 +3939,23 @@ def dcnm_intf_get_diff_overridden(self, cfg):
delem["serialNumber"] = sno
delem["fabricName"] = fabric
- self.diff_delete[
- self.int_index[have["ifType"]]
- ].append(delem)
-
- # For INTERFACE_VLAN the "mode" argument is not set in have_all.
- # if have["mode"] is not None or have["ifType"] == "INTERFACE_VLAN":
- self.diff_delete_deploy[
- self.int_index[have["ifType"]]
- ].append(delem)
- self.changed_dict[0]["deleted"].append(
- copy.deepcopy(delem)
- )
- del_list.append(have)
+ # have_all will include interfaces which are marked for DELETE too. Do not delete them again.
+ if str(have["markDeleted"]).lower() == "false":
+ self.diff_delete[
+ self.int_index[have["ifType"]]
+ ].append(delem)
+ self.changed_dict[0]["deleted"].append(
+ copy.deepcopy(delem)
+ )
+ del_list.append(have)
+
+ if str(deploy).lower() == "true":
+ self.diff_delete_deploy[
+ self.int_index[have["ifType"]]
+ ].append(delem)
+ self.changed_dict[0]["delete_deploy"].append(
+ copy.deepcopy(delem)
+ )
for intf in defer_list:
# Check if the 'source' for the ethernet interface is one of the interfaces that is already deleted.
@@ -3939,26 +3999,10 @@ def dcnm_intf_get_diff_deleted(self):
self.diff_deploy = []
self.diff_replace = []
- if (None is self.config) or (self.config is []):
- # If no config is specified, then it means we need to delete or
- # reset all interfaces in the fabric.
-
- # Get the IP addresses from ip_sn. For every IP, get all interfaces
- # and delete/reset all
-
- for address in self.ip_sn.keys():
- # the given switch may be part of a VPC pair. In that case we
- # need to get interface information using one switch which returns interfaces
- # from both the switches
- if not any(
- d.get("serialNo", None) == self.ip_sn[address]
- for d in self.have_all
- ):
- self.dcnm_intf_get_have_all(address)
-
+ if self.config == []:
# Now that we have all the interface information we can run override
# and delete or reset interfaces.
- self.dcnm_intf_get_diff_overridden(None)
+ self.dcnm_intf_get_diff_overridden(self.config)
elif self.config:
for cfg in self.config:
if cfg.get("name", None) is not None:
@@ -3975,6 +4019,7 @@ def dcnm_intf_get_diff_deleted(self):
switches = cfg["switch"]
for sw in switches:
+
intf = {}
delem = {}
@@ -4086,15 +4131,70 @@ def dcnm_intf_get_diff_deleted(self):
self.diff_delete[
self.int_index[if_type]
].append(delem)
- if "monitor" not in intf_payload["policy"]:
- self.diff_delete_deploy[
- self.int_index[if_type]
- ].append(delem)
self.changed_dict[0]["deleted"].append(
copy.deepcopy(delem)
)
+
+ if "monitor" not in intf_payload["policy"]:
+ if (
+ str(cfg.get("deploy", "true")).lower()
+ == "true"
+ ):
+ self.diff_delete_deploy[
+ self.int_index[if_type]
+ ].append(delem)
+ self.changed_dict[0][
+ "delete_deploy"
+ ].append(copy.deepcopy(delem))
+ else:
+ # Get Interface details which will include even interfaces that are marked for delete.
+ if sw not in have_all:
+ have_all.append(sw)
+ self.dcnm_intf_get_have_all(sw)
+
+ # Get the matching interface from have_all
+ match_have = [
+ have
+ for have in self.have_all
+ if (
+ (
+ intf["ifName"].lower()
+ == have["ifName"].lower()
+ )
+ and (
+ intf["serialNumber"]
+ == have["serialNo"]
+ )
+ )
+ ]
+
+ if match_have:
+ # Matching interface found. Check 'complianceStatus' and deploy if necessary
+ if (
+ match_have[0]["complianceStatus"]
+ == "In-Sync"
+ ) or (
+ match_have[0]["complianceStatus"]
+ == "Pending"
+ ):
+ if (
+ str(
+ cfg.get("deploy", "true")
+ ).lower()
+ == "true"
+ ):
+ delem["ifName"] = if_name
+ delem["serialNumber"] = intf[
+ "serialNumber"
+ ]
+ self.diff_delete_deploy[
+ self.int_index[if_type]
+ ].append(delem)
+ self.changed_dict[0][
+ "delete_deploy"
+ ].append(copy.deepcopy(delem))
else:
- self.dcnm_intf_get_diff_overridden(cfg)
+ self.dcnm_intf_get_diff_overridden([cfg])
def dcnm_extract_if_name(self, cfg):
@@ -4284,6 +4384,7 @@ def dcnm_intf_check_deployment_status(self, deploy_list):
)
]
if match_have:
+
if match_have[0]["complianceStatus"] == "In-Sync":
break
@@ -4328,6 +4429,7 @@ def dcnm_intf_send_message_to_dcnm(self):
changed = False
delete = False
+ delete_deploy = False
create = False
deploy = False
replace = False
@@ -4387,9 +4489,6 @@ def dcnm_intf_send_message_to_dcnm(self):
resp = None
- # In 11.4 version of DCNM, sometimes interfaces don't get deleted
- # completely, but only marked for deletion. They get removed only after a
- # deploy. So we will do a deploy on the deleted elements
path = self.paths["GLOBAL_IF_DEPLOY"]
index = -1
for delem in self.diff_delete_deploy:
@@ -4408,11 +4507,17 @@ def dcnm_intf_send_message_to_dcnm(self):
else:
deploy_failed = True
for item in resp["DATA"]:
- if "No Commands to execute" not in item["message"]:
+ if (
+ "No Commands to execute" not in item["message"]
+ and "In-Sync" not in item["message"]
+ ):
deploy_failed = True
if deploy_failed is False:
resp["RETURN_CODE"] = 200
resp["MESSAGE"] = "OK"
+ delete_deploy = True
+ else:
+ delete_deploy = True
self.result["response"].append(resp)
resp = None
@@ -4422,6 +4527,7 @@ def dcnm_intf_send_message_to_dcnm(self):
json_payload = json.dumps(payload)
resp = dcnm_send(self.module, "PUT", path, json_payload)
+
self.result["response"].append(resp)
if (resp.get("MESSAGE") != "OK") or (
@@ -4439,6 +4545,7 @@ def dcnm_intf_send_message_to_dcnm(self):
json_payload = json.dumps(payload)
resp = dcnm_send(self.module, "POST", path, json_payload)
+
self.result["response"].append(resp)
if (resp.get("MESSAGE") != "OK") or (
@@ -4498,38 +4605,109 @@ def dcnm_intf_send_message_to_dcnm(self):
if (self.module.params["state"] == "overridden") or (
self.module.params["state"] == "deleted"
):
- self.result["changed"] = delete or create or deploy
+ self.result["changed"] = (
+ delete or create or deploy or delete_deploy
+ )
else:
- if delete or create or replace or deploy:
+ if delete or create or replace or deploy or delete_deploy:
self.result["changed"] = True
else:
self.result["changed"] = False
- def dcnm_translate_switch_info(self, config, ip_sn, hn_sn):
+ def dcnm_intf_update_inventory_data(self):
- if None is config:
- return
+ """
+ Routine to update inventory data for all fabrics included in the playbook. This routine
+ also updates ip_sn, sn_hn and hn_sn objetcs from the updated inventory data.
- for cfg in config:
+ Parameters:
+ None
- index = 0
+ Returns:
+ None
+ """
- if None is cfg.get("switch", None):
- continue
- for sw_elem in cfg["switch"]:
- addr_info = dcnm_get_ip_addr_info(
- self.module, sw_elem, ip_sn, hn_sn
+ inv_data = get_fabric_inventory_details(self.module, self.fabric)
+ self.inventory_data.update(inv_data)
+
+ if self.module.params["state"] != "query":
+
+ # Get all switches which are managable. Changes must be avoided to all switches which are not part of this list
+ managable_ip = [
+ (key, self.inventory_data[key]["serialNumber"])
+ for key in self.inventory_data
+ if str(self.inventory_data[key]["managable"]).lower() == "true"
+ ]
+ managable_hosts = [
+ (
+ self.inventory_data[key]["logicalName"],
+ self.inventory_data[key]["serialNumber"],
)
- cfg["switch"][index] = addr_info
- index = index + 1
+ for key in self.inventory_data
+ if str(self.inventory_data[key]["managable"]).lower() == "true"
+ ]
+
+ managable = dict(managable_ip + managable_hosts)
+
+ # Get all switches which are managable. Deploy must be avoided to all switches which are not part of this list
+ ronly_sw_list = []
+ for cfg in self.config:
+ # Check if there are any switches which are not managable in the config.
+ if cfg.get("switch", None) is not None:
+ for sw in cfg["switch"]:
+ if sw not in managable:
+ if sw not in ronly_sw_list:
+ ronly_sw_list.append(sw)
+
+ # Deploy must be avoided to fabrics which are in monitoring mode
+ path = self.paths["FABRIC_ACCESS_MODE"].format(self.fabric)
+ resp = dcnm_send(self.module, "GET", path)
- # Check if the VPC serial number information is already present. If not fetch that
+ if resp and resp["RETURN_CODE"] == 200:
+ if str(resp["DATA"]["readonly"]).lower() == "true":
+ self.monitoring.append(self.fabric)
- if self.vpc_ip_sn.get(addr_info, None) is None:
- sno = self.dcnm_intf_get_vpc_serial_number(addr_info)
- if "~" in sno:
- # This switch is part of VPC pair. Populate the VPC serial number DB
- self.vpc_ip_sn[addr_info] = sno
+ # Check if source fabric is in monitoring mode. If so return an error, since fabrics in monitoring mode do not allow
+ # create/modify/delete and deploy operations.
+ if self.fabric in self.monitoring:
+ self.module.fail_json(
+ msg="Error: Source Fabric '{0}' is in Monitoring mode, No changes are allowed on the fabric\n".format(
+ self.fabric
+ )
+ )
+
+ if ronly_sw_list:
+ self.module.fail_json(
+ msg="Error: Switches {0} are not managable in Fabric '{1}', No changes are allowed on these switches\n".format(
+ ronly_sw_list, self.fabric
+ )
+ )
+
+ # Based on the updated inventory_data, update ip_sn, hn_sn and sn_hn objects
+ self.ip_sn, self.hn_sn = get_ip_sn_dict(self.inventory_data)
+
+ def dcnm_translate_playbook_info(self, config, ip_sn, hn_sn):
+
+ for cfg in config:
+ index = 0
+ if cfg.get("switch", None) is None:
+ continue
+ for sw_elem in cfg["switch"][:]:
+ if sw_elem in self.ip_sn or sw_elem in self.hn_sn:
+ addr_info = dcnm_get_ip_addr_info(
+ self.module, sw_elem, ip_sn, hn_sn
+ )
+ cfg["switch"][index] = addr_info
+
+ # Check if the VPC serial number information is already present. If not fetch that
+ if self.vpc_ip_sn.get(addr_info, None) is None:
+ sno = self.dcnm_intf_get_vpc_serial_number(addr_info)
+ if "~" in sno:
+ # This switch is part of VPC pair. Populate the VPC serial number DB
+ self.vpc_ip_sn[addr_info] = sno
+ else:
+ cfg["switch"].remove(sw_elem)
+ index = index + 1
def main():
@@ -4537,7 +4715,8 @@ def main():
"""main entry point for module execution"""
element_spec = dict(
fabric=dict(required=True, type="str"),
- config=dict(required=False, type="list", elements="dict"),
+ config=dict(required=False, type="list", elements="dict", default=[]),
+ deploy=dict(required=False, type="bool", default=True),
state=dict(
type="str",
default="merged",
@@ -4552,6 +4731,17 @@ def main():
dcnm_intf = DcnmIntf(module)
+ state = module.params["state"]
+ if not dcnm_intf.config:
+ if state == "merged" or state == "replaced" or state == "query":
+ module.fail_json(
+ msg="'config' element is mandatory for state '{0}', given = '{1}'".format(
+ state, dcnm_intf.config
+ )
+ )
+
+ dcnm_intf.dcnm_intf_update_inventory_data()
+
if not dcnm_intf.ip_sn:
dcnm_intf.result[
"msg"
@@ -4564,16 +4754,7 @@ def main():
)
)
- state = module.params["state"]
- if not dcnm_intf.config:
- if state == "merged" or state == "replaced" or state == "query":
- module.fail_json(
- msg="'config' element is mandatory for state '{0}', given = '{1}'".format(
- state, dcnm_intf.config
- )
- )
-
- dcnm_intf.dcnm_translate_switch_info(
+ dcnm_intf.dcnm_translate_playbook_info(
dcnm_intf.config, dcnm_intf.ip_sn, dcnm_intf.hn_sn
)
@@ -4595,10 +4776,7 @@ def main():
dcnm_intf.dcnm_intf_get_diff_replaced()
if module.params["state"] == "overridden":
- if dcnm_intf.config is None:
- dcnm_intf.dcnm_intf_get_diff_overridden([])
- else:
- dcnm_intf.dcnm_intf_get_diff_overridden(None)
+ dcnm_intf.dcnm_intf_get_diff_overridden(dcnm_intf.config)
if module.params["state"] == "deleted":
dcnm_intf.dcnm_intf_get_diff_deleted()
@@ -4620,6 +4798,7 @@ def main():
or dcnm_intf.diff_delete[dcnm_intf.int_index["INTERFACE_VLAN"]]
or dcnm_intf.diff_delete[dcnm_intf.int_index["STRAIGHT_TROUGH_FEX"]]
or dcnm_intf.diff_delete[dcnm_intf.int_index["AA_FEX"]]
+ or dcnm_intf.diff_delete_deploy
):
dcnm_intf.result["changed"] = True
else:
@@ -4630,7 +4809,6 @@ def main():
module.exit_json(**dcnm_intf.result)
dcnm_intf.dcnm_intf_send_message_to_dcnm()
-
module.exit_json(**dcnm_intf.result)
diff --git a/plugins/modules/dcnm_policy.py b/plugins/modules/dcnm_policy.py
index 121b0af2e..9bdd101a6 100644
--- a/plugins/modules/dcnm_policy.py
+++ b/plugins/modules/dcnm_policy.py
@@ -1112,9 +1112,10 @@ def dcnm_policy_send_message_to_dcnm(self):
and (resp.get("DATA", None) is not None)
):
if resp["DATA"].get("successList", None) is not None:
- if "is created successfully" in resp["DATA"][
- "successList"
- ][0].get("message"):
+ if (
+ resp["DATA"]["successList"][0].get("status").lower()
+ == "success"
+ ):
policy_id = re.findall(
r"POLICY-\d+",
resp["DATA"]["successList"][0].get("message"),
diff --git a/tests/integration/targets/dcnm_interface/tasks/dcnm.yaml b/tests/integration/targets/dcnm_interface/tasks/dcnm.yaml
index e42041ea1..fe857e700 100644
--- a/tests/integration/targets/dcnm_interface/tasks/dcnm.yaml
+++ b/tests/integration/targets/dcnm_interface/tasks/dcnm.yaml
@@ -19,13 +19,14 @@
loop_control:
loop_var: test_case_to_run
-- name: Final Cleanup - delete feature_interface_vlan and hsrp policies that we created during init
+- name: Final Cleanup - delete my_lacp my_interface_vlan and my_hsrp policies that we created during init
cisco.dcnm.dcnm_policy:
fabric: "{{ ansible_it_fabric }}"
state: deleted # only choose form [merged, deleted, query]
config:
- name: my_interface_vlan
- name: my_hsrp
+ - name: my_lacp
- switch:
- ip: "{{ ansible_switch1 }}"
- ip: "{{ ansible_switch2 }}"
@@ -42,6 +43,7 @@
config:
- name: my_interface_vlan
- name: my_hsrp
+ - name: my_lacp
register: result
- assert:
diff --git a/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_delete_deploy.yaml b/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_delete_deploy.yaml
new file mode 100644
index 000000000..783195442
--- /dev/null
+++ b/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_delete_deploy.yaml
@@ -0,0 +1,229 @@
+##############################################
+## SETUP ##
+##############################################
+
+- name: Remove local log file
+ local_action: command rm -f dcnm_intf.log
+
+- name: Put the fabric to default state
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ fabric: "{{ ansible_it_fabric }}"
+ state: overridden # only choose form [merged, replaced, deleted, overridden, query]
+ register: result
+
+- assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+- block:
+
+##############################################
+## MERGE ##
+##############################################
+ - name: Create interfaces to check deploy cases during delete
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ fabric: "{{ ansible_it_fabric }}"
+ state: merged # only choose form [merged, replaced, deleted, overridden, query]
+ config:
+ - name: po333 # should be of the form po
+ type: pc # choose from this list [pc, vpc, sub_int, lo, eth, svi]
+ switch:
+ - "{{ ansible_switch1 }}" # provide the switch information where the config is to be deployed
+ deploy: true # choose from [true, false]
+ profile:
+ mode: trunk # choose from [trunk, access, l3, monitor]
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == true'
+ - '(result["diff"][0]["merged"] | length) == 1'
+ - '(result["diff"][0]["deleted"] | length) == 0'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 1'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## DELETE ##
+##############################################
+
+ - name: Delete interfaces with global deploy as false
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ deploy: false
+ fabric: "{{ ansible_it_fabric }}"
+ state: deleted # only choose form [merged, replaced, deleted, overridden,query]
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == true'
+ - '(result["diff"][0]["merged"] | length) == 0'
+ - '(result["diff"][0]["deleted"] | length) == 1'
+ - '(result["diff"][0]["delete_deploy"] | length) == 0'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 0'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## DELETE ##
+##############################################
+
+ - name: Delete interfaces again, global deploy as true
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ deploy: true
+ fabric: "{{ ansible_it_fabric }}"
+ state: deleted # only choose form [merged, replaced, deleted, overridden,query]
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == true'
+ - '(result["diff"][0]["merged"] | length) == 0'
+ - '(result["diff"][0]["deleted"] | length) == 0'
+ - '(result["diff"][0]["delete_deploy"] | length) == 1'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 0'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## DELETE ##
+##############################################
+
+ - name: Delete interfaces - Idempotence
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ deploy: true
+ fabric: "{{ ansible_it_fabric }}"
+ state: deleted # only choose form [merged, replaced, deleted, overridden,query]
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == false'
+ - '(result["diff"][0]["merged"] | length) == 0'
+ - '(result["diff"][0]["deleted"] | length) == 0'
+ - '(result["diff"][0]["delete_deploy"] | length) == 0'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 0'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## MERGE ##
+##############################################
+ - name: Create interfaces to check deploy cases during delete inlcuding config block
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ fabric: "{{ ansible_it_fabric }}"
+ state: merged # only choose form [merged, replaced, deleted, overridden, query]
+ config:
+ - name: po334 # should be of the form po
+ type: pc # choose from this list [pc, vpc, sub_int, lo, eth, svi]
+ switch:
+ - "{{ ansible_switch1 }}" # provide the switch information where the config is to be deployed
+ deploy: true # choose from [true, false]
+ profile:
+ mode: trunk # choose from [trunk, access, l3, monitor]
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == true'
+ - '(result["diff"][0]["merged"] | length) == 1'
+ - '(result["diff"][0]["deleted"] | length) == 0'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 1'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## DELETE ##
+##############################################
+
+ - name: Delete interfaces - global deploy as true and deploy in config block as false
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ deploy: true
+ fabric: "{{ ansible_it_fabric }}"
+ state: deleted # only choose form [merged, replaced, deleted, overridden,query]
+ config:
+ - name: po334 # should be of the form po
+ switch:
+ - "{{ ansible_switch1 }}" # provide the switch information where the config is to be deployed
+ deploy: false # choose from [true, false]
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == true'
+ - '(result["diff"][0]["merged"] | length) == 0'
+ - '(result["diff"][0]["deleted"] | length) == 1'
+ - '(result["diff"][0]["delete_deploy"] | length) == 0'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 0'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## DELETE ##
+##############################################
+
+ - name: Delete interfaces - global deploy as false and deploy in config block as true
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ deploy: false
+ fabric: "{{ ansible_it_fabric }}"
+ state: deleted # only choose form [merged, replaced, deleted, overridden,query]
+ config:
+ - name: po334 # should be of the form po
+ switch:
+ - "{{ ansible_switch1 }}" # provide the switch information where the config is to be deployed
+ deploy: true # choose from [true, false]
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == true'
+ - '(result["diff"][0]["merged"] | length) == 0'
+ - '(result["diff"][0]["deleted"] | length) == 0'
+ - '(result["diff"][0]["delete_deploy"] | length) == 1'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 0'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
diff --git a/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_delete_diff_options.yaml b/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_delete_diff_options.yaml
index 86d26a8d6..ddd1ce1e1 100644
--- a/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_delete_diff_options.yaml
+++ b/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_delete_diff_options.yaml
@@ -158,7 +158,7 @@
mode: lo # choose from [lo]
ipv4_addr: 193.168.2.1 # ipv4 address for the loopback interface
- - name: vpc100 # should be of the form vpc
+ - name: vpc101 # should be of the form vpc
type: vpc # choose from this list [pc, vpc, sub_int, lo, eth, svi]
switch: # provide switches of vPC pair
- "{{ ansible_switch1 }}"
@@ -265,7 +265,7 @@
mode: lo # choose from [lo]
ipv4_addr: 193.168.2.1 # ipv4 address for the loopback interface
- - name: vpc100 # should be of the form vpc
+ - name: vpc102 # should be of the form vpc
type: vpc # choose from this list [pc, vpc, sub_int, lo, eth, svi]
switch: # provide switches of vPC pair
- "{{ ansible_switch1 }}"
@@ -323,7 +323,7 @@
- name: lo100 # should be of the form lo
switch:
- "{{ ansible_switch1 }}" # provide the switch where to deploy the config
- - name: vpc100 # should be of the form vpc
+ - name: vpc102 # should be of the form vpc
switch:
- "{{ ansible_switch1 }}"
- "{{ ansible_switch2 }}" # provide the switch where to deploy the config
diff --git a/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_intf_misc.yaml b/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_intf_misc.yaml
new file mode 100644
index 000000000..f9674527b
--- /dev/null
+++ b/tests/integration/targets/dcnm_interface/tests/dcnm/dcnm_intf_misc.yaml
@@ -0,0 +1,196 @@
+##############################################
+## SETUP ##
+##############################################
+
+- name: Remove local log file
+ local_action: command rm -f dcnm_intf.log
+
+- name: Put the fabric to default state
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ fabric: "{{ ansible_it_fabric }}"
+ state: overridden # only choose form [merged, replaced, deleted, overridden, query]
+ register: result
+
+- assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+- block:
+
+##############################################
+## MERGE ##
+##############################################
+
+ - name: Create interfaces to check delete with deploy and no deploy
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ fabric: "{{ ansible_it_fabric }}"
+ state: merged # only choose form [merged, replaced, deleted, overridden, query]
+ config:
+ - name: po300 # should be of the form po
+ type: pc # choose from this list [pc, vpc, sub_int, lo, eth, svi]
+ switch:
+ - "{{ ansible_switch1 }}" # provide the switch information where the config is to be deployed
+ deploy: true # choose from [true, false]
+ profile:
+ mode: trunk # choose from [trunk, access, l3, monitor]
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == true'
+ - '(result["diff"][0]["merged"] | length) == 1'
+ - '(result["diff"][0]["deleted"] | length) == 0'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 1'
+ - '(result["diff"][0]["delete_deploy"] | length) == 0'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## DELETE ##
+##############################################
+
+ - name: Delete interface with deploy set to False
+ cisco.dcnm.dcnm_interface:
+ fabric: "{{ ansible_it_fabric }}"
+ state: deleted # only choose form [merged, replaced, deleted, overridden, query]
+ config:
+ - name: po300 # should be of the form po
+ deploy: false
+ switch:
+ - "{{ ansible_switch1 }}" # provide the switch information where the config is to be deployed
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == true'
+ - '(result["diff"][0]["merged"] | length) == 0'
+ - '(result["diff"][0]["deleted"] | length) == 1'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 0'
+ - '(result["diff"][0]["delete_deploy"] | length) == 0'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## DELETE ##
+##############################################
+
+ - name: Delete interface (already marked deleted) with deploy set to True
+ cisco.dcnm.dcnm_interface:
+ fabric: "{{ ansible_it_fabric }}"
+ check_deploy: True
+ state: deleted # only choose form [merged, replaced, deleted, overridden, query]
+ config:
+ - name: po300 # should be of the form po
+ switch:
+ - "{{ ansible_switch1 }}" # provide the switch information where the config is to be deployed
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == true'
+ - '(result["diff"][0]["merged"] | length) == 0'
+ - '(result["diff"][0]["deleted"] | length) == 0'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 0'
+ - '(result["diff"][0]["delete_deploy"] | length) == 1'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## DELETE ##
+##############################################
+
+ - name: Delete interface again (already deployed) with deploy set to True
+ cisco.dcnm.dcnm_interface:
+ fabric: "{{ ansible_it_fabric }}"
+ check_deploy: True
+ state: deleted # only choose form [merged, replaced, deleted, overridden, query]
+ config:
+ - name: po300 # should be of the form po
+ switch:
+ - "{{ ansible_switch1 }}" # provide the switch information where the config is to be deployed
+ register: result
+
+ - assert:
+ that:
+ - 'result.changed == false'
+ - '(result["diff"][0]["merged"] | length) == 0'
+ - '(result["diff"][0]["deleted"] | length) == 0'
+ - '(result["diff"][0]["replaced"] | length) == 0'
+ - '(result["diff"][0]["overridden"] | length) == 0'
+ - '(result["diff"][0]["deploy"] | length) == 0'
+ - '(result["diff"][0]["delete_deploy"] | length) == 0'
+
+ - assert:
+ that:
+ - 'item["RETURN_CODE"] == 200'
+ loop: '{{ result.response }}'
+
+##############################################
+## MERGE ##
+##############################################
+
+ - name: Create interfaces with src fabric in monitoring mode
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ fabric: "{{ ansible_ext_fabric }}"
+ state: merged # only choose form [merged, replaced, deleted, overridden, query]
+ config:
+ - name: po300 # should be of the form po
+ type: pc # choose from this list [pc, vpc, sub_int, lo, eth, svi]
+ switch:
+ - "{{ ansible_switch1 }}" # provide the switch information where the config is to be deployed
+ deploy: true # choose from [true, false]
+ profile:
+ mode: trunk # choose from [trunk, access, l3, monitor]
+ register: result
+ ignore_errors: yes
+
+ - assert:
+ that:
+ - '("Monitoring mode" in result["msg"])'
+ - '("No changes are allowed on the fabric" in result["msg"])'
+ - '("{{ ansible_ext_fabric }}" in result["msg"])'
+
+##############################################
+## MERGE ##
+##############################################
+
+ - name: Create interface on a switch that is not 'managable'.
+ cisco.dcnm.dcnm_interface:
+ check_deploy: True
+ fabric: "mmudigon-unnumbered"
+ state: merged # only choose form [merged, replaced, deleted, overridden, query]
+ config:
+ - name: po300 # should be of the form po
+ type: pc # choose from this list [pc, vpc, sub_int, lo, eth, svi]
+ switch:
+ - "n9kv-test-sw2" # provide the switch information where the config is to be deployed
+ deploy: true # choose from [true, false]
+ profile:
+ mode: trunk # choose from [trunk, access, l3, monitor]
+ register: result
+ ignore_errors: yes
+
+ - assert:
+ that:
+ - '("are not managable in Fabric" in result["msg"])'
+ - '("No changes are allowed on these switches" in result["msg"])'
+ - '("n9kv-test-sw2" in result["msg"])'
diff --git a/tests/integration/targets/prepare_dcnm_intf/tasks/main.yaml b/tests/integration/targets/prepare_dcnm_intf/tasks/main.yaml
index ee4e24460..3ccdbbe13 100644
--- a/tests/integration/targets/prepare_dcnm_intf/tasks/main.yaml
+++ b/tests/integration/targets/prepare_dcnm_intf/tasks/main.yaml
@@ -1,9 +1,19 @@
# SVI interfaces require interface-vlan and hsrp features to be enabled
- - name: Create templates for interface-vlan and hsrp features
+ - name: Create templates for lacp, interface-vlan and hsrp features
cisco.dcnm.dcnm_template:
state: merged # only choose form [merged, deleted, query]
config:
+ - name: my_lacp
+ tags: "lacp"
+ description: "internal template for enabling LACP feature"
+ content: |
+ ##
+ ##template content
+
+ feature lacp
+
+ ##
- name: my_interface_vlan
tags: "interface_vlan"
description: "internal template for enabling interface-vlan feature"
@@ -26,8 +36,8 @@
##
register: result
-# Create the policy to deploy interface-vlan and hsrp features on the switches
- - name: Create interface-vlan and hsrp policies
+# Create the policy to deploy lacp, interface-vlan and hsrp features on the switches
+ - name: Create lacp, interface-vlan and hsrp policies
cisco.dcnm.dcnm_policy:
fabric: "{{ ansible_it_fabric }}"
config:
@@ -37,10 +47,13 @@
- name: my_hsrp # This must be a valid template name
create_additional_policy: false # Do not create a policy if it already exists
priority: 101
+ - name: my_lacp # This must be a valid template name
+ create_additional_policy: false # Do not create a policy if it already exists
+ priority: 101
- switch:
- ip: "{{ ansible_switch1 }}"
- ip: "{{ ansible_switch2 }}"
deploy: true
state: merged
- register: result
\ No newline at end of file
+ register: result
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_aa_fex_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_aa_fex_configs.json
index 2b36b8467..de72c114c 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_aa_fex_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_aa_fex_configs.json
@@ -1,12 +1,28 @@
{
"mock_fab_inv_data": {
"192.168.1.108": {
- "isVpcConfigured": "True",
- "vpcDomain": 1
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
},
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
}
},
@@ -20,6 +36,20 @@
"192.168.1.109" : "FOX1821H035~SAL1819SAN8"
},
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
+ }
+ },
+
"mock_vpc_resp" : {
"MESSAGE": "OK",
"REQUEST_PATH": "https://10.122.197.6:443/rest/interface/vpcpair_serial_number?serial_number=FOX1821H035",
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_bunched_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_bunched_configs.json
index b23f02abf..d54461084 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_bunched_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_bunched_configs.json
@@ -1,15 +1,31 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
}
- },
+ },
"mock_ip_sn" : {
"192.168.1.109": "FOX1821H035",
@@ -31,6 +47,20 @@
"192.168.1.109" : "FOX1821H035~SAL1819SAN8"
},
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
+ }
+ },
+
"mock_succ_resp" : {
"DATA": {},
"MESSAGE": "OK",
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_eth_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_eth_configs.json
index e807e9d8b..df177a308 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_eth_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_eth_configs.json
@@ -1,14 +1,30 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
}
- },
+ },
"mock_ip_sn" : {
"192.168.1.109": "FOX1821H035",
@@ -30,6 +46,20 @@
"METHOD": "GET"
},
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
+ }
+ },
+
"mock_succ_resp" : {
"DATA": {},
"MESSAGE": "OK",
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_have_all_payloads.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_have_all_payloads.json
index a6eb86147..e4ae9211b 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_have_all_payloads.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_have_all_payloads.json
@@ -15,6 +15,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -39,6 +40,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -63,6 +65,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -88,6 +91,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -112,6 +116,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -125,14 +130,14 @@
}
]
}
- ],
- "RETURN_CODE": 200,
- "METHOD": "GET"
+ ],
+ "RETURN_CODE": 200,
+ "METHOD": "GET"
},
- "deployed_payloads" :
- {
- "MESSAGE": "OK",
+ "deployed_payloads" :
+ {
+ "MESSAGE": "OK",
"REQUEST_PATH": "https://10.122.197.6:443/rest/interface?serialNumber=SAL1819SAN8",
"DATA": [
{
@@ -864,11 +869,45 @@
],
"RETURN_CODE": 200,
"METHOD": "GET"
- },
+ },
- "payloads" :
- {
- "MESSAGE": "OK",
+ "deleted_intf_payloads" :
+ {
+ "MESSAGE": "OK",
+ "REQUEST_PATH": "https://10.122.197.6:443/rest/interface?serialNumber=SAL1819SAN8",
+ "DATA": [
+ {
+ "ifName": "port-channel999",
+ "mode": "pc",
+ "serialNo": "SAL1819SAN8",
+ "fabricName": "test_fabric",
+ "ifType": "INTERFACE_PORT_CHANNEL",
+ "isPhysical": "False",
+ "deletable": "True",
+ "markDeleted": "True",
+ "alias": "",
+ "deleteReason": null,
+ "complianceStatus": "In-Sync",
+ "underlayPolicies": [
+ {
+ "source" : ""
+ }
+ ],
+ "interfaces": [
+ {
+ "nvPairs": {
+ }
+ }
+ ]
+ }
+ ],
+ "RETURN_CODE": 200,
+ "METHOD": "GET"
+ },
+
+ "payloads" :
+ {
+ "MESSAGE": "OK",
"REQUEST_PATH": "https://10.122.197.6:443/rest/interface?serialNumber=SAL1819SAN8",
"DATA": [
{
@@ -881,6 +920,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -904,6 +944,7 @@
"deletable": "False",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -927,6 +968,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -950,6 +992,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -973,6 +1016,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -996,6 +1040,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -1019,6 +1064,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -1042,6 +1088,7 @@
"deletable": "False",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -1065,6 +1112,7 @@
"deletable": "False",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -1088,6 +1136,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -1111,6 +1160,7 @@
"deletable": "True",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -1134,6 +1184,7 @@
"deletable": "False",
"markDeleted": "False",
"alias": "",
+ "deleteReason": null,
"complianceStatus": "In-Sync",
"underlayPolicies": [
{
@@ -1150,6 +1201,6 @@
],
"RETURN_CODE": 200,
"METHOD": "GET"
- }
+ }
}
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_lo_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_lo_configs.json
index 745c7af93..6ba28cf15 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_lo_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_lo_configs.json
@@ -1,15 +1,30 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
}
- },
-
+ },
"mock_ip_sn" : {
"192.168.1.109": "FOX1821H035",
"192.168.1.108": "SAL1819SAN8"
@@ -20,6 +35,20 @@
"192.168.1.109" : "FOX1821H035~SAL1819SAN8"
},
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
+ }
+ },
+
"mock_vpc_resp" : {
"MESSAGE": "OK",
"REQUEST_PATH": "https://10.122.197.6:443/rest/interface/vpcpair_serial_number?serial_number=FOX1821H035",
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_mixed_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_mixed_configs.json
index b84ed755e..e391c78a9 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_mixed_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_mixed_configs.json
@@ -1,20 +1,50 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
}
- },
+ },
"mock_ip_sn" : {
"192.168.1.109": "FOX1821H035",
"192.168.1.108": "SAL1819SAN8"
},
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
+ }
+ },
+
"mock_vpc_resp" : {
"MESSAGE": "OK",
"REQUEST_PATH": "https://10.122.197.6:443/rest/interface/vpcpair_serial_number?serial_number=FOX1821H035",
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_multi_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_multi_configs.json
index 96208d42c..eb1501551 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_multi_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_multi_configs.json
@@ -1,12 +1,42 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
+ }
+ },
+
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
}
},
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_multi_intf_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_multi_intf_configs.json
index 8555beefb..c80b7d293 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_multi_intf_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_multi_intf_configs.json
@@ -1,12 +1,42 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
+ }
+ },
+
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
}
},
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_pc_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_pc_configs.json
index 52c91a16c..add47f751 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_pc_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_pc_configs.json
@@ -1,12 +1,41 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
+ }
+ },
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
}
},
@@ -135,6 +164,37 @@
"deploy": "False"
}],
+ "pc_unmanagable_merged_config" : [
+ {
+ "switch": [
+ "n9kv-1"
+ ],
+ "profile": {
+ "description": "port channel acting as trunk",
+ "bpdu_guard": "True",
+ "sno": "SAL1819SAN8",
+ "mtu": "jumbo",
+ "pc_mode": "on",
+ "mode": "trunk",
+ "members": [
+ "e1/9"
+ ],
+ "port_type_fast": "True",
+ "policy": "int_port_channel_trunk_host_11_1",
+ "admin_state": "True",
+ "allowed_vlans": "none",
+ "cmds": [
+ "no shutdown"
+ ],
+ "ifname": "Port-channel300",
+ "fabric": "test_fabric"
+ },
+ "type": "pc",
+ "name": "po300",
+ "deploy": "True"
+ }
+ ],
+
"pc_merged_config" : [
{
"switch": [
@@ -237,6 +297,24 @@
"deploy": "True"
}],
+ "pc_deleted_config_deploy" : [
+ {
+ "switch": [
+ "192.168.1.108"
+ ],
+ "name": "po999",
+ "deploy": "True"
+ }],
+
+ "pc_deleted_config_no_deploy" : [
+ {
+ "switch": [
+ "192.168.1.108"
+ ],
+ "name": "po300",
+ "deploy": "False"
+ }],
+
"pc_deleted_config" : [
{
"switch": [
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_query_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_query_configs.json
index 98f35e6fa..47ba4841e 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_query_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_query_configs.json
@@ -1,12 +1,41 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
+ }
+ },
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
}
},
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_st_fex_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_st_fex_configs.json
index d44e78fb1..179632827 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_st_fex_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_st_fex_configs.json
@@ -1,14 +1,43 @@
{
"mock_fab_inv_data": {
"192.168.1.108": {
- "isVpcConfigured": "True",
- "vpcDomain": 1
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
},
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
}
},
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
+ }
+ },
"mock_ip_sn" : {
"192.168.1.109": "FOX1821H035",
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_subint_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_subint_configs.json
index 4f9cb9186..36a279eec 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_subint_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_subint_configs.json
@@ -1,12 +1,41 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
+ }
+ },
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
}
},
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_svi_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_svi_configs.json
index 33d92d86d..9921e8a78 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_svi_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_svi_configs.json
@@ -1,12 +1,41 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
+ }
+ },
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
}
},
diff --git a/tests/unit/modules/dcnm/fixtures/dcnm_intf_vpc_configs.json b/tests/unit/modules/dcnm/fixtures/dcnm_intf_vpc_configs.json
index 789fe548a..920a94cae 100644
--- a/tests/unit/modules/dcnm/fixtures/dcnm_intf_vpc_configs.json
+++ b/tests/unit/modules/dcnm/fixtures/dcnm_intf_vpc_configs.json
@@ -1,12 +1,41 @@
{
- "mock_fab_inv_data": {
- "192.168.1.108": {
+ "mock_fab_inv_data": {
+ "192.168.1.108": {
+ "logicalName": "n9kv-108",
+ "serialNumber": "SAL1819SAN8",
"isVpcConfigured": "True",
- "vpcDomain": 1
- },
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
"192.168.1.109": {
+ "logicalName": "n9kv-109",
+ "serialNumber": "FOX1821H035",
+ "isVpcConfigured": "True",
+ "vpcDomain": 1,
+ "switchRoleEnum": "Leaf",
+ "managable": "True"
+ },
+ "10.69.69.1": {
+ "logicalName": "n9kv-1",
+ "serialNumber": "TEST-SNO-1",
"isVpcConfigured": "True",
- "vpcDomain": 1
+ "vpcDomain": 1,
+ "switchRoleEnum": "None",
+ "managable": "False"
+ }
+ },
+ "mock_monitor_true_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "True"
+ }
+ },
+
+ "mock_monitor_false_resp": {
+ "RETURN_CODE": 200,
+ "DATA":{
+ "readonly": "False"
}
},
diff --git a/tests/unit/modules/dcnm/test_dcnm_intf.py b/tests/unit/modules/dcnm/test_dcnm_intf.py
index 5a719f555..6ceb0bb17 100644
--- a/tests/unit/modules/dcnm/test_dcnm_intf.py
+++ b/tests/unit/modules/dcnm/test_dcnm_intf.py
@@ -96,6 +96,7 @@ def load_multi_intf_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf,
@@ -137,6 +138,7 @@ def load_multi_intf_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf,
@@ -180,6 +182,7 @@ def load_missing_intf_elems_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf1,
@@ -223,6 +226,7 @@ def load_mixed_intf_elems_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf,
@@ -271,6 +275,7 @@ def load_bunched_intf_elems_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf1,
@@ -315,6 +320,7 @@ def load_missing_members_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_intf,
@@ -345,6 +351,7 @@ def load_type_missing_fixtures(self):
"payloads"
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf,
self.playbook_mock_succ_resp,
@@ -372,6 +379,7 @@ def load_missing_state_fixtures(self):
"payloads"
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf,
playbook_have_all_data,
@@ -433,6 +441,13 @@ def load_query_state_fixtures(self):
self.playbook_mock_succ_resp,
]
+ def load_intf_misc_fixtures(self):
+
+ if "test_dcnm_intf_merge_fabric_monitoring" in self._testMethodName:
+ self.run_dcnm_send.side_effect = [self.mock_monitor_true_resp]
+ if "test_dcnm_intf_merge_unmanagable_switch" in self._testMethodName:
+ self.run_dcnm_send.side_effect = [self.mock_monitor_false_resp]
+
# -------------------------- SVI-FIXTURES --------------------------
def load_svi_fixtures(self):
@@ -445,6 +460,7 @@ def load_svi_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_svi_intf1,
playbook_have_all_data,
@@ -461,6 +477,7 @@ def load_svi_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_svi_intf1,
playbook_have_all_data,
@@ -478,6 +495,7 @@ def load_svi_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_svi_intf1,
self.playbook_mock_succ_resp,
@@ -492,8 +510,10 @@ def load_svi_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_svi_intf1,
+ playbook_svi_intf1,
]
if "_svi_replaced_existing" in self._testMethodName:
playbook_svi_intf1 = self.payloads_data.get("svi_merged_payloads")
@@ -502,6 +522,7 @@ def load_svi_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_svi_intf1,
playbook_have_all_data,
@@ -518,6 +539,7 @@ def load_svi_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_svi_intf1,
playbook_have_all_data,
@@ -552,6 +574,7 @@ def load_aa_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_aa_fex_intf1,
playbook_have_all_data,
@@ -567,6 +590,7 @@ def load_aa_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_aa_fex_intf1,
playbook_have_all_data,
@@ -582,6 +606,7 @@ def load_aa_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_aa_fex_intf1,
playbook_have_all_data,
@@ -599,6 +624,7 @@ def load_aa_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_aa_fex_intf1,
@@ -620,6 +646,7 @@ def load_aa_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_aa_fex_intf1,
self.playbook_mock_succ_resp,
@@ -634,8 +661,10 @@ def load_aa_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_aa_fex_intf1,
+ playbook_aa_fex_intf1,
]
if "_aa_fex_replaced_existing" in self._testMethodName:
@@ -645,6 +674,7 @@ def load_aa_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_aa_fex_intf1,
playbook_have_all_data,
@@ -661,6 +691,7 @@ def load_aa_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_aa_fex_intf1,
playbook_have_all_data,
@@ -691,6 +722,7 @@ def load_aa_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_aa_fex_intf1,
playbook_have_all_data,
@@ -725,6 +757,7 @@ def load_st_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_st_fex_intf1,
playbook_have_all_data,
@@ -740,6 +773,7 @@ def load_st_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_st_fex_intf1,
playbook_have_all_data,
@@ -755,6 +789,7 @@ def load_st_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_st_fex_intf1,
playbook_have_all_data,
@@ -772,6 +807,7 @@ def load_st_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_st_fex_intf1,
@@ -793,6 +829,7 @@ def load_st_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_st_fex_intf1,
self.playbook_mock_succ_resp,
@@ -807,8 +844,10 @@ def load_st_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_st_fex_intf1,
+ playbook_st_fex_intf1,
]
if "_st_fex_replaced_existing" in self._testMethodName:
playbook_st_fex_intf1 = self.payloads_data.get("st_fex_merged_payloads_150")
@@ -817,6 +856,7 @@ def load_st_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_st_fex_intf1,
playbook_have_all_data,
@@ -833,6 +873,7 @@ def load_st_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_st_fex_intf1,
playbook_have_all_data,
@@ -863,6 +904,7 @@ def load_st_fex_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_st_fex_intf1,
playbook_have_all_data,
@@ -900,6 +942,7 @@ def load_pc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf1,
playbook_pc_intf2,
@@ -930,6 +973,7 @@ def load_pc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf1,
playbook_have_all_data,
@@ -964,6 +1008,7 @@ def load_pc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf1,
playbook_pc_intf2,
@@ -1003,6 +1048,7 @@ def load_pc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf1,
playbook_pc_intf2,
@@ -1019,6 +1065,74 @@ def load_pc_fixtures(self):
self.playbook_mock_succ_resp,
]
+ if "_intf_deleted_existing_no_deploy" in self._testMethodName:
+ playbook_pc_intf1 = self.payloads_data.get(
+ "pc_merged_trunk_payloads"
+ )
+ playbook_have_all_data = self.have_all_payloads_data.get(
+ "payloads"
+ )
+
+ self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
+ self.playbook_mock_vpc_resp,
+ playbook_pc_intf1,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ ]
+
+ if "_intf_deleted_deploy" in self._testMethodName:
+ playbook_pc_intf1 = []
+ playbook_have_all_data = self.have_all_payloads_data.get(
+ "deleted_intf_payloads"
+ )
+
+ self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
+ self.playbook_mock_vpc_resp,
+ playbook_pc_intf1,
+ playbook_have_all_data,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ ]
+
+ if "_intf_deleted_existing_no_deploy" in self._testMethodName:
+ playbook_pc_intf1 = self.payloads_data.get(
+ "pc_merged_trunk_payloads"
+ )
+ playbook_have_all_data = self.have_all_payloads_data.get(
+ "payloads"
+ )
+
+ self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
+ self.playbook_mock_vpc_resp,
+ playbook_pc_intf1,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ self.playbook_mock_succ_resp,
+ ]
+
if "_pc_replaced_existing" in self._testMethodName:
playbook_pc_intf1 = self.payloads_data.get(
"pc_merged_trunk_payloads"
@@ -1035,6 +1149,7 @@ def load_pc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf1,
playbook_pc_intf2,
@@ -1066,6 +1181,7 @@ def load_pc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_pc_intf1,
playbook_have_all_data,
@@ -1107,6 +1223,7 @@ def load_eth_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_eth_intf1,
playbook_eth_intf2,
@@ -1141,6 +1258,7 @@ def load_eth_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_eth_intf1,
playbook_have_all_data,
@@ -1182,6 +1300,7 @@ def load_eth_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_eth_intf1,
playbook_eth_intf2,
@@ -1231,6 +1350,7 @@ def load_eth_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_eth_intf1,
playbook_eth_intf2,
@@ -1277,6 +1397,7 @@ def load_eth_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_have_all_data,
playbook_eth_intf1,
@@ -1313,6 +1434,7 @@ def load_eth_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_eth_intf1,
playbook_have_all_data,
@@ -1352,6 +1474,7 @@ def load_subint_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_sub_intf1,
playbook_sub_intf2,
@@ -1383,6 +1506,7 @@ def load_subint_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_subint_intf1,
playbook_subint_intf2,
@@ -1407,6 +1531,7 @@ def load_subint_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_subint_intf1,
playbook_subint_intf2,
@@ -1437,6 +1562,7 @@ def load_subint_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_subint_intf1,
playbook_have_all_data,
@@ -1466,6 +1592,7 @@ def load_subint_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_subint_intf1,
playbook_subint_intf2,
@@ -1487,6 +1614,7 @@ def load_subint_fixtures(self):
"payloads"
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
[],
self.playbook_mock_succ_resp,
@@ -1514,6 +1642,7 @@ def load_subint_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_subint_intf1,
playbook_have_all_data,
@@ -1550,6 +1679,7 @@ def load_lo_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_lo_intf1,
playbook_lo_intf2,
@@ -1577,6 +1707,7 @@ def load_lo_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_lo_intf1,
playbook_lo_intf2,
@@ -1605,6 +1736,7 @@ def load_lo_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_lo_intf1,
playbook_have_all_data,
@@ -1633,6 +1765,7 @@ def load_lo_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_lo_intf1,
playbook_lo_intf2,
@@ -1659,6 +1792,7 @@ def load_lo_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_lo_intf1,
playbook_lo_intf2,
@@ -1688,6 +1822,7 @@ def load_lo_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_lo_intf1,
playbook_lo_intf2,
@@ -1720,6 +1855,7 @@ def load_lo_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_lo_intf1,
playbook_have_all_data,
@@ -1748,6 +1884,7 @@ def load_lo_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
playbook_lo_intf1,
playbook_have_all_data,
@@ -1783,6 +1920,7 @@ def load_vpc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_vpc_intf1,
@@ -1816,6 +1954,7 @@ def load_vpc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_vpc_intf1,
@@ -1849,6 +1988,7 @@ def load_vpc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_vpc_intf1,
@@ -1879,6 +2019,7 @@ def load_vpc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_vpc_intf1,
@@ -1913,6 +2054,7 @@ def load_vpc_fixtures(self):
)
self.run_dcnm_send.side_effect = [
+ self.mock_monitor_false_resp,
self.playbook_mock_vpc_resp,
self.playbook_mock_vpc_resp,
playbook_vpc_intf1,
@@ -1987,6 +2129,7 @@ def load_fixtures(self, response=None, device=""):
self.load_missing_state_fixtures()
self.load_missing_members_fixtures()
self.load_query_state_fixtures()
+ self.load_intf_misc_fixtures()
# -------------------------- GEN-INTF --------------------------
@@ -2005,6 +2148,8 @@ def test_dcnm_intf_multi_intf_merged_new(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
set_module_args(
dict(
@@ -2049,6 +2194,8 @@ def test_dcnm_intf_multi_intf_merged_exist(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
set_module_args(
dict(
@@ -2102,6 +2249,8 @@ def test_dcnm_intf_missing_intf_elems_merged_new(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2145,6 +2294,8 @@ def test_dcnm_intf_check_multi_intf_merged_new(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
set_module_args(
dict(
@@ -2190,6 +2341,8 @@ def test_dcnm_intf_pc_merged_new(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2233,6 +2386,8 @@ def test_dcnm_intf_pc_merged_idempotent(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2261,6 +2416,8 @@ def test_dcnm_intf_pc_merged_policy_change(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2287,6 +2444,8 @@ def test_dcnm_intf_pc_deleted_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2313,6 +2472,76 @@ def test_dcnm_intf_pc_deleted_existing(self):
True,
)
+ def test_dcnm_intf_deleted_existing_no_deploy(self):
+
+ # load the json from playbooks
+ self.config_data = loadPlaybookData("dcnm_intf_pc_configs")
+ self.payloads_data = loadPlaybookData("dcnm_intf_pc_payloads")
+ self.have_all_payloads_data = loadPlaybookData(
+ "dcnm_intf_have_all_payloads"
+ )
+
+ # load required config data
+ self.playbook_config = self.config_data.get("pc_deleted_config_no_deploy")
+ self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
+ self.mock_ip_sn = self.config_data.get("mock_ip_sn")
+ self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
+ self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
+
+ set_module_args(
+ dict(
+ state="deleted",
+ fabric="test_fabric",
+ config=self.playbook_config,
+ )
+ )
+ result = self.execute_module(changed=True, failed=False)
+
+ self.assertEqual(len(result["diff"][0]["deleted"]), 1)
+ for intf in result["diff"][0]["deleted"]:
+ self.assertEqual(
+ (
+ intf["ifName"]
+ in [
+ "Port-channel300",
+ ]
+ ),
+ True,
+ )
+ self.assertEqual(len(result["diff"][0]["delete_deploy"]), 0)
+
+ def test_dcnm_intf_deleted_deploy(self):
+
+ # load the json from playbooks
+ self.config_data = loadPlaybookData("dcnm_intf_pc_configs")
+ self.payloads_data = loadPlaybookData("dcnm_intf_pc_payloads")
+ self.have_all_payloads_data = loadPlaybookData(
+ "dcnm_intf_have_all_payloads"
+ )
+
+ # load required config data
+ self.playbook_config = self.config_data.get("pc_deleted_config_deploy")
+ self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
+ self.mock_ip_sn = self.config_data.get("mock_ip_sn")
+ self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
+ self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
+
+ set_module_args(
+ dict(
+ state="deleted",
+ fabric="test_fabric",
+ config=self.playbook_config,
+ )
+ )
+ result = self.execute_module(changed=True, failed=False)
+
+ self.assertEqual(len(result["diff"][0]["deleted"]), 0)
+ self.assertEqual(len(result["diff"][0]["delete_deploy"]), 1)
+
def test_dcnm_intf_pc_replaced_existing(self):
# load the json from playbooks
@@ -2327,6 +2556,8 @@ def test_dcnm_intf_pc_replaced_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2380,6 +2611,8 @@ def test_dcnm_intf_pc_overridden_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2444,6 +2677,8 @@ def test_dcnm_intf_eth_merged_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2473,6 +2708,8 @@ def test_dcnm_intf_eth_merged_new(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2514,6 +2751,8 @@ def test_dcnm_intf_eth_merged_idempotent(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
for cfg in self.playbook_config:
@@ -2543,6 +2782,8 @@ def test_dcnm_intf_eth_replaced_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2598,6 +2839,8 @@ def test_dcnm_intf_eth_deleted_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2627,6 +2870,8 @@ def test_dcnm_intf_eth_overridden_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2685,6 +2930,8 @@ def test_dcnm_intf_subint_merged_new(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2717,6 +2964,8 @@ def test_dcnm_intf_subint_merged_idempotent(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
for cfg in self.playbook_config:
@@ -2746,6 +2995,8 @@ def test_dcnm_intf_subint_replaced_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2798,6 +3049,8 @@ def test_dcnm_intf_subint_replaced_non_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2826,6 +3079,8 @@ def test_dcnm_intf_subint_deleted_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2859,6 +3114,8 @@ def test_dcnm_intf_subint_deleted_non_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2886,6 +3143,8 @@ def test_dcnm_intf_subint_overridden_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2944,6 +3203,8 @@ def test_dcnm_intf_lo_merged_new(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -2977,6 +3238,8 @@ def test_dcnm_intf_lo_merged_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3006,6 +3269,8 @@ def test_dcnm_intf_lo_merged_idempotent(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
for cfg in self.playbook_config:
@@ -3035,6 +3300,8 @@ def test_dcnm_intf_lo_replaced_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3082,6 +3349,8 @@ def test_dcnm_intf_lo_deleted_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3113,6 +3382,8 @@ def test_dcnm_intf_lo_overridden_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3171,6 +3442,8 @@ def test_dcnm_intf_lo_overridden_existing_2(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3228,6 +3501,8 @@ def test_dcnm_intf_lo_overridden_non_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3287,6 +3562,8 @@ def test_dcnm_intf_vpc_merged_new(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3319,6 +3596,8 @@ def test_dcnm_intf_vpc_merged_idempotent(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
for cfg in self.playbook_config:
@@ -3326,6 +3605,8 @@ def test_dcnm_intf_vpc_merged_idempotent(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
set_module_args(
dict(
@@ -3352,6 +3633,8 @@ def test_dcnm_intf_vpc_deleted_existing(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3382,6 +3665,8 @@ def test_dcnm_intf_vpc_replaced_existing(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3441,6 +3726,8 @@ def test_dcnm_intf_vpc_overridden_existing(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3504,6 +3791,8 @@ def test_dcnm_intf_svi_merged_new(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3536,6 +3825,8 @@ def test_dcnm_intf_svi_merged_idempotent(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3564,6 +3855,8 @@ def test_dcnm_intf_svi_deleted_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3595,6 +3888,8 @@ def test_dcnm_intf_svi_deleted_non_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3624,6 +3919,8 @@ def test_dcnm_intf_svi_replaced_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3695,6 +3992,8 @@ def test_dcnm_intf_svi_overridden_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3758,6 +4057,8 @@ def test_dcnm_intf_aa_fex_merged_new(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3790,6 +4091,8 @@ def test_dcnm_intf_aa_fex_merged_idempotent(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3816,6 +4119,8 @@ def test_dcnm_intf_aa_fex_merged_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3846,6 +4151,8 @@ def test_dcnm_intf_aa_fex_merged_multi_switches(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3878,6 +4185,8 @@ def test_dcnm_intf_aa_fex_deleted_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3909,6 +4218,8 @@ def test_dcnm_intf_aa_fex_deleted_non_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3936,6 +4247,8 @@ def test_dcnm_intf_aa_fex_replaced_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -3989,6 +4302,8 @@ def test_dcnm_intf_aa_fex_overridden_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4051,6 +4366,8 @@ def test_dcnm_intf_aa_fex_overridden_modify_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4115,6 +4432,8 @@ def test_dcnm_intf_st_fex_merged_new(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4147,6 +4466,8 @@ def test_dcnm_intf_st_fex_merged_idempotent(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4173,6 +4494,8 @@ def test_dcnm_intf_st_fex_merged_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4203,6 +4526,8 @@ def test_dcnm_intf_st_fex_merged_multi_switches(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4235,6 +4560,8 @@ def test_dcnm_intf_st_fex_deleted_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4266,6 +4593,8 @@ def test_dcnm_intf_st_fex_deleted_non_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4293,6 +4622,8 @@ def test_dcnm_intf_st_fex_replaced_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4344,6 +4675,8 @@ def test_dcnm_intf_st_fex_overridden_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4406,6 +4739,8 @@ def test_dcnm_intf_st_fex_overridden_modify_existing(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4470,6 +4805,8 @@ def test_dcnm_intf_gen_missing_ip_sn(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = []
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
dict(
@@ -4500,6 +4837,8 @@ def test_dcnm_intf_mixed_intf_merged_new(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
set_module_args(
dict(
@@ -4531,6 +4870,8 @@ def test_dcnm_intf_bunched_intf_merged_new(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
set_module_args(
dict(
@@ -4579,6 +4920,8 @@ def test_dcnm_intf_type_missing_merged_new(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4609,6 +4952,8 @@ def test_dcnm_intf_missing_state(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4642,6 +4987,8 @@ def test_dcnm_intf_missing_peer_members(self):
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
set_module_args(
dict(
@@ -4677,6 +5024,8 @@ def test_dcnm_intf_query(self):
self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
self.mock_ip_sn = self.config_data.get("mock_ip_sn")
self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
set_module_args(
@@ -4695,3 +5044,73 @@ def test_dcnm_intf_query(self):
self.assertEqual(len(result["diff"][0]["replaced"]), 0)
self.assertEqual(len(result["diff"][0]["deploy"]), 0)
self.assertEqual(len(result["diff"][0]["query"]), 8)
+
+ def test_dcnm_intf_merge_fabric_monitoring(self):
+
+ # load the json from playbooks
+ self.config_data = loadPlaybookData("dcnm_intf_pc_configs")
+ self.payloads_data = loadPlaybookData("dcnm_intf_pc_payloads")
+ self.have_all_payloads_data = loadPlaybookData(
+ "dcnm_intf_have_all_payloads"
+ )
+
+ # load required config data
+ self.playbook_config = self.config_data.get("pc_merged_config")
+ self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
+ self.mock_ip_sn = self.config_data.get("mock_ip_sn")
+ self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
+ self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
+
+ set_module_args(
+ dict(
+ state="merged",
+ fabric="fabric_monitoring",
+ config=self.playbook_config,
+ )
+ )
+
+ result = None
+
+ try:
+ result = self.execute_module(changed=False, failed=False)
+ except Exception as e:
+ self.assertEqual(result, None)
+ self.assertEqual(("is in Monitoring mode" in str(e)), True)
+ self.assertEqual(("No changes are allowed on the fabric" in str(e)), True)
+
+ def test_dcnm_intf_merge_unmanagable_switch(self):
+
+ # load the json from playbooks
+ self.config_data = loadPlaybookData("dcnm_intf_pc_configs")
+ self.payloads_data = loadPlaybookData("dcnm_intf_pc_payloads")
+ self.have_all_payloads_data = loadPlaybookData(
+ "dcnm_intf_have_all_payloads"
+ )
+
+ # load required config data
+ self.playbook_config = self.config_data.get("pc_unmanagable_merged_config")
+ self.playbook_mock_succ_resp = self.config_data.get("mock_succ_resp")
+ self.mock_ip_sn = self.config_data.get("mock_ip_sn")
+ self.mock_fab_inv = self.config_data.get("mock_fab_inv_data")
+ self.mock_monitor_true_resp = self.config_data.get("mock_monitor_true_resp")
+ self.mock_monitor_false_resp = self.config_data.get("mock_monitor_false_resp")
+ self.playbook_mock_vpc_resp = self.config_data.get("mock_vpc_resp")
+
+ set_module_args(
+ dict(
+ state="merged",
+ fabric="test_fabric",
+ config=self.playbook_config,
+ )
+ )
+
+ result = None
+
+ try:
+ result = self.execute_module(changed=False, failed=False)
+ except Exception as e:
+ self.assertEqual(result, None)
+ self.assertEqual(("are not managable in Fabric" in str(e)), True)
+ self.assertEqual(("No changes are allowed on these switches" in str(e)), True)
From f4ce6fc042ce7df8464068f64a41c545e76a90de Mon Sep 17 00:00:00 2001
From: Shangxin Du
Date: Mon, 7 Aug 2023 07:51:22 -0700
Subject: [PATCH 02/11] add save and deploy options to dcnm_inventory module
(#238)
---
docs/cisco.dcnm.dcnm_inventory_module.rst | 38 +++++++++++++++++++++++
plugins/modules/dcnm_inventory.py | 28 ++++++++++++++---
2 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/docs/cisco.dcnm.dcnm_inventory_module.rst b/docs/cisco.dcnm.dcnm_inventory_module.rst
index 9420708eb..29ca51e2b 100644
--- a/docs/cisco.dcnm.dcnm_inventory_module.rst
+++ b/docs/cisco.dcnm.dcnm_inventory_module.rst
@@ -475,6 +475,25 @@ Parameters
|
+