1# -*- coding: utf-8 -*- 2 3# 4# Dell EMC OpenManage Ansible Modules 5# Version 3.6.0 6# Copyright (C) 2020-2021 Dell Inc. or its subsidiaries. All Rights Reserved. 7 8# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 9# 10 11from __future__ import (absolute_import, division, print_function) 12 13__metaclass__ = type 14 15import pytest 16import json 17from ansible_collections.dellemc.openmanage.plugins.modules import ome_smart_fabric 18from ansible_collections.dellemc.openmanage.tests.unit.plugins.modules.common import FakeAnsibleModule, Constants 19from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError 20from ansible.module_utils.urls import ConnectionError, SSLValidationError 21from io import StringIO 22from ansible.module_utils._text import to_text 23 24CHECK_MODE_CHANGE_FOUND_MSG = "Changes found to be applied." 25CHECK_MODE_CHANGE_NOT_FOUND_MSG = "No Changes found to be applied." 26FABRIC_NOT_FOUND_ERROR_MSG = "The smart fabric '{0}' is not present in the system." 27DOMAIN_SERVICE_TAG_ERROR_MSG = "Unable to retrieve the domain information because the" \ 28 " domain of the provided service tag {0} is not available." 29LEAD_CHASSIS_ERROR_MSG = "System should be a lead chassis if the assigned fabric topology type is {0}." 30SYSTEM_NOT_SUPPORTED_ERROR_MSG = "Fabric management is not supported on the specified system." 31DESIGN_MODEL_ERROR_MSG = "The network type of the {0} must be {1}." 32DEVICE_SERVICE_TAG_TYPE_ERROR_MSG = "The {0} type must be {1}." 33DEVICE_SERVICE_TAG_NOT_FOUND_ERROR_MSG = "Unable to retrieve the device information because the device" \ 34 " with the provided service tag {0} is not available." 35IDEMPOTENCY_MSG = "Specified fabric details are the same as the existing settings." 36REQUIRED_FIELD = "Options 'fabric_design', 'primary_switch_service_tag' and 'secondary_switch_service_tag'" \ 37 " are required for fabric creation." 38DUPLICATE_TAGS = "The switch details of the primary switch overlaps with the secondary switch details." 39PRIMARY_SWITCH_OVERLAP_MSG = "The primary switch service tag is overlapping with existing secondary switch details." 40SECONDARY_SWITCH_OVERLAP_MSG = "The switch details of the secondary switch overlaps with the existing primary" \ 41 " switch details." 42MODULE_PATH = 'ansible_collections.dellemc.openmanage.plugins.modules.' 43device_details = { 44 "Id": Constants.device_id1, 45 "Type": 4000, 46 "Identifier": "GTCT8T2", 47 "DeviceServiceTag": "GTCT8T2", 48 "ChassisServiceTag": "FPTN6Z2", 49 "Model": "MX9116n Fabric Engine", 50 "PowerState": 17, 51 "ManagedState": 3000, 52 "Status": 1000, 53 "SystemId": 2031, 54 "DeviceName": "IOM-A2", 55 "SlotConfiguration": { 56 "ChassisName": "MX-FPTN6Z2", 57 "SlotId": "13313", 58 "DeviceType": "4000", 59 "ChassisId": "13294", 60 "SlotNumber": "2", 61 "SledBlockPowerOn": "null", 62 "SlotName": "IOM-A2", 63 "ChassisServiceTag": "FPTN6Z2", 64 "SlotType": "4000" 65 }, 66 "DeviceManagement": [ 67 { 68 "ManagementId": 76383, 69 "NetworkAddress": Constants.hostname1, 70 "MacAddress": "00:00:00:00:00", 71 "ManagementType": 2, 72 "InstrumentationName": "MX9116n Fabric Engine", 73 "DnsName": "", 74 "ManagementProfile": [ 75 { 76 "ManagementProfileId": 76383, 77 "ProfileId": "FX7_BASE", 78 "ManagementId": 76383, 79 "AgentName": "", 80 "Version": "", 81 "ManagementURL": "", 82 "HasCreds": 0, 83 "Status": 1000, 84 "StatusDateTime": "2020-05-07 15:00:14.718" 85 } 86 ] 87 } 88 ] 89} 90all_fabric_details = [ 91 { 92 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 93 "Name": "Fabric_1", 94 "Description": "create new fabric1", 95 "OverrideLLDPConfiguration": "NA", 96 "ScaleVLANProfile": "NA", 97 "FabricDesignMapping": [ 98 { 99 "DesignNode": "Switch-A", 100 "PhysicalNode": "2HB7NX2" 101 }, 102 { 103 "DesignNode": "Switch-B", 104 "PhysicalNode": "2HBFNX2" 105 } 106 ], 107 "FabricDesign": { 108 "@odata.id": "/api/NetworkService/Fabrics('1312cceb-c3dd-4348-95c1-d8541a17d776')/FabricDesign" 109 } 110 }, 111 { 112 "Id": "1312cceb-c3dd-4348-95c1-123456", 113 "Name": "Fabric_1_2", 114 "Description": "create new fabric2", 115 "OverrideLLDPConfiguration": "Enabled", 116 "ScaleVLANProfile": "NA", 117 "FabricDesignMapping": [ 118 { 119 "DesignNode": "Switch-A", 120 "PhysicalNode": Constants.service_tag1 121 }, 122 { 123 "DesignNode": "Switch-B", 124 "PhysicalNode": Constants.service_tag2 125 } 126 ], 127 "FabricDesign": { 128 "@odata.id": "/api/NetworkService/Fabrics('1312cceb-c3dd-4348-95c1-123456')/FabricDesign" 129 } 130 } 131] 132 133 134@pytest.fixture 135def ome_connection_mock_for_smart_fabric(mocker, ome_response_mock): 136 connection_class_mock = mocker.patch(MODULE_PATH + 'ome_smart_fabric.RestOME') 137 ome_connection_mock_obj = connection_class_mock.return_value.__enter__.return_value 138 ome_connection_mock_obj.invoke_request.return_value = ome_response_mock 139 return ome_connection_mock_obj 140 141 142class TestOmeSmartFabric(FakeAnsibleModule): 143 module = ome_smart_fabric 144 145 @pytest.mark.parametrize("exc_type", 146 [URLError, HTTPError, SSLValidationError, ConnectionError, TypeError, ValueError]) 147 def test_main_ome_smart_fabric_exception_handling_case(self, exc_type, ome_default_args, 148 ome_connection_mock_for_smart_fabric, 149 ome_response_mock, mocker): 150 ome_default_args.update({"name": "name", "new_name": "new_name"}) 151 ome_response_mock.status_code = 400 152 ome_response_mock.success = False 153 json_str = to_text(json.dumps({"data": "out"})) 154 if exc_type == URLError: 155 mocker.patch(MODULE_PATH + 'ome_smart_fabric.fabric_actions', 156 side_effect=exc_type("url open error")) 157 result = self._run_module(ome_default_args) 158 assert result["unreachable"] is True 159 elif exc_type not in [HTTPError, SSLValidationError]: 160 mocker.patch(MODULE_PATH + 'ome_smart_fabric.fabric_actions', 161 side_effect=exc_type("exception message")) 162 result = self._run_module_with_fail_json(ome_default_args) 163 assert result['failed'] is True 164 else: 165 for status_code, msg in {501: SYSTEM_NOT_SUPPORTED_ERROR_MSG, 400: 'http error message'}.items(): 166 mocker.patch(MODULE_PATH + 'ome_smart_fabric.fabric_actions', 167 side_effect=exc_type('http://testhost.com', status_code, msg, 168 {"accept-type": "application/json"}, StringIO(json_str))) 169 result = self._run_module_with_fail_json(ome_default_args) 170 assert result['failed'] is True 171 assert msg in result['msg'] 172 assert 'msg' in result 173 174 def test_get_msm_device_details_success_case(self, ome_connection_mock_for_smart_fabric, ome_default_args, mocker): 175 """ 176 success case: when provided design type and role type natches return the service tag and msm details 177 """ 178 ome_default_args.update({"fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_different_chassis"}) 179 f_module = self.get_module_mock(params=ome_default_args) 180 resp_data = { 181 "Id": Constants.device_id1, 182 "value": [ 183 { 184 "Id": 10086, 185 "DeviceId": 10061, 186 "PublicAddress": [ 187 ome_default_args["hostname"], 188 "1000:mock_val" 189 ], 190 "Identifier": Constants.service_tag1, 191 "DomainRoleTypeValue": "LEAD", 192 "Version": "1.20.00", 193 }, 194 { 195 "Id": 13341, 196 "DeviceId": 13294, 197 "PublicAddress": [ 198 Constants.hostname2, 199 "1000:mocked_val" 200 ], 201 "Identifier": Constants.service_tag2, 202 "DomainTypeValue": "MSM", 203 "DomainRoleTypeValue": "MEMBER", 204 "Version": "1.20.00", 205 } 206 ] 207 } 208 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 209 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_service_tag_with_fqdn', 210 return_value=None) 211 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_ip_from_host', 212 return_value=ome_default_args["hostname"]) 213 service_tag, msm_version = self.module.get_msm_device_details(ome_connection_mock_for_smart_fabric, f_module) 214 assert service_tag == Constants.service_tag1 215 assert msm_version == "1.20.00" 216 217 def test_get_msm_device_details_fqdn_success_case1(self, ome_connection_mock_for_smart_fabric, ome_default_args, 218 mocker): 219 """ 220 when hostname provided is fqdn and 221 success case: when provided design type and role type matches return the service tag and msm details 222 """ 223 ome_default_args.update( 224 {"hostname": "XX-XXXX.yyy.lab", "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_different_chassis"}) 225 f_module = self.get_module_mock(params=ome_default_args) 226 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_ip_from_host', 227 return_value=ome_default_args["hostname"]) 228 resp_data = { 229 "Id": Constants.device_id1, 230 "value": [ 231 { 232 "Id": 10086, 233 "DeviceId": 10061, 234 "PublicAddress": [ 235 ome_default_args["hostname"], 236 "1000:mock_val" 237 ], 238 "Identifier": Constants.service_tag1, 239 "DomainRoleTypeValue": "LEAD", 240 "Version": "1.20.00", 241 }, 242 { 243 "Id": 13341, 244 "DeviceId": 13294, 245 "PublicAddress": [ 246 Constants.hostname2, 247 "1000:mocked_val" 248 ], 249 "Identifier": Constants.service_tag2, 250 "DomainTypeValue": "MSM", 251 "DomainRoleTypeValue": "MEMBER", 252 "Version": "1.20.00", 253 } 254 ] 255 } 256 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 257 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_service_tag_with_fqdn', 258 return_value="FKMLRZ2") 259 service_tag, msm_version = self.module.get_msm_device_details(ome_connection_mock_for_smart_fabric, f_module) 260 assert service_tag == Constants.service_tag1 261 assert msm_version == "1.20.00" 262 263 def test_get_msm_device_details_fqdn_success_case2(self, ome_connection_mock_for_smart_fabric, ome_default_args, 264 mocker): 265 """ 266 when hostname provided is fqdn and 267 success case: when provided design type is same and fqdn is not of lead type 268 """ 269 ome_default_args.update( 270 {"hostname": "XX-XXXX.yyy.lab", "fabric_design": "2xMX5108n_Ethernet_Switches_in_same_chassis"}) 271 f_module = self.get_module_mock(params=ome_default_args) 272 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_ip_from_host', 273 return_value=ome_default_args["hostname"]) 274 resp_data = { 275 "Id": Constants.device_id1, 276 "value": [ 277 { 278 "Id": 10086, 279 "DeviceId": 10061, 280 "PublicAddress": [ 281 Constants.hostname1, 282 "1000:mock_ipv6" 283 ], 284 "Identifier": Constants.service_tag1, 285 "DomainRoleTypeValue": "LEAD", 286 "Version": "1.20.00", 287 }, 288 { 289 "Id": 13341, 290 "DeviceId": 13294, 291 "PublicAddress": [ 292 Constants.hostname2, 293 "1001:mocked_ippv6" 294 ], 295 "Identifier": Constants.service_tag2, 296 "DomainTypeValue": "MSM", 297 "DomainRoleTypeValue": "MEMBER", 298 "Version": "1.20.10", 299 } 300 ] 301 } 302 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 303 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_service_tag_with_fqdn', 304 return_value=Constants.service_tag2) 305 service_tag, msm_version = self.module.get_msm_device_details(ome_connection_mock_for_smart_fabric, f_module) 306 assert service_tag == Constants.service_tag2 307 assert msm_version == "1.20.10" 308 309 def test_get_msm_device_details_fqdn_failure_case1(self, ome_connection_mock_for_smart_fabric, ome_default_args, 310 mocker): 311 """ 312 when hostname provided is fqdn and 313 failure case: when provided design type is 2xMX9116n_Fabric_Switching_Engines_in_different_chassis 314 but fqdn is not of lead type 315 """ 316 ome_default_args.update( 317 {"hostname": "XX-XXXX.yyy.lab", "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_different_chassis"}) 318 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_ip_from_host', 319 return_value=ome_default_args["hostname"]) 320 f_module = self.get_module_mock(params=ome_default_args) 321 resp_data = { 322 "Id": Constants.device_id1, 323 "value": [ 324 { 325 "Id": 10086, 326 "DeviceId": 10061, 327 "PublicAddress": [ 328 Constants.hostname1, 329 "1000:mock_val" 330 ], 331 "Identifier": Constants.service_tag1, 332 "DomainRoleTypeValue": "LEAD", 333 "Version": "1.20.00", 334 }, 335 { 336 "Id": 13341, 337 "DeviceId": 13294, 338 "PublicAddress": [ 339 Constants.hostname2, 340 "1000:mocked_val" 341 ], 342 "Identifier": Constants.service_tag2, 343 "DomainTypeValue": "MSM", 344 "DomainRoleTypeValue": "MEMBER", 345 "Version": "1.20.00", 346 } 347 ] 348 } 349 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 350 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_service_tag_with_fqdn', 351 return_value=Constants.service_tag2) 352 with pytest.raises(Exception, match=LEAD_CHASSIS_ERROR_MSG.format(ome_default_args["fabric_design"])) as ex: 353 self.module.get_msm_device_details(ome_connection_mock_for_smart_fabric, f_module) 354 355 def test_get_msm_device_details_fqdn_failure_case2(self, ome_connection_mock_for_smart_fabric, ome_default_args, 356 mocker): 357 """ 358 when hostname provided is fqdn and 359 failure case: when provided fqdn not available in domain list should throw an error 360 """ 361 ome_default_args.update( 362 {"hostname": "XX-XXXX.yyy.lab", "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_different_chassis"}) 363 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_ip_from_host', 364 return_value=ome_default_args["hostname"]) 365 f_module = self.get_module_mock(params=ome_default_args) 366 resp_data = { 367 "value": [ 368 ] 369 } 370 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 371 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_service_tag_with_fqdn', 372 return_value="FPTN6Z2") 373 with pytest.raises(Exception, match=SYSTEM_NOT_SUPPORTED_ERROR_MSG): 374 self.module.get_msm_device_details(ome_connection_mock_for_smart_fabric, f_module) 375 376 def test_get_msm_device_details_failure_case_01(self, ome_connection_mock_for_smart_fabric, ome_default_args, 377 mocker): 378 """ 379 raise exception if design type is 2xMX9116n_Fabric_Switching_Engines_in_different_chassis but domain type is not lead 380 """ 381 ome_default_args.update({"fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_different_chassis"}) 382 f_module = self.get_module_mock(params=ome_default_args) 383 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_ip_from_host', 384 return_value=ome_default_args["hostname"]) 385 resp_data = {"Id": Constants.device_id1, "value": [ 386 { 387 "@odata.id": "/api/ManagementDomainService/Domains(25038)", 388 "Id": 25038, 389 "DeviceId": Constants.device_id1, 390 "PublicAddress": [ 391 ome_default_args["hostname"] 392 ], 393 "Name": "MX-2H5DNX2", 394 "Description": "PowerEdge MX7000", 395 "Identifier": Constants.service_tag1, 396 "DomainTypeId": 4000, 397 "DomainTypeValue": "MSM", 398 "DomainRoleTypeId": 3002, 399 "DomainRoleTypeValue": "STANDALONE", 400 "Version": "1.20.00", 401 "Local": True, 402 "GroupId": "d78ba475-f5d5-4dbb-97da-b4b1f190caa2", 403 "GroupName": None, 404 "BackupLead": False, 405 "Capabilities": [], 406 "BackupLeadHealth": 2000 407 } 408 ]} 409 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 410 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_service_tag_with_fqdn', 411 return_value=None) 412 with pytest.raises(Exception, match=LEAD_CHASSIS_ERROR_MSG.format(ome_default_args["fabric_design"])) as ex: 413 self.module.get_msm_device_details(ome_connection_mock_for_smart_fabric, f_module) 414 415 def test_get_msm_device_details_failure_case_02(self, ome_connection_mock_for_smart_fabric, ome_default_args, 416 mocker): 417 """ 418 raise exception if there is no domain values in system 419 """ 420 ome_default_args.update({"fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_different_chassis"}) 421 f_module = self.get_module_mock(params=ome_default_args) 422 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_ip_from_host', 423 return_value=ome_default_args["hostname"]) 424 resp_data = {"Id": None, "value": [ 425 ]} 426 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 427 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_service_tag_with_fqdn', 428 return_value=None) 429 with pytest.raises(Exception, match=SYSTEM_NOT_SUPPORTED_ERROR_MSG): 430 self.module.get_msm_device_details(ome_connection_mock_for_smart_fabric, f_module) 431 432 @pytest.mark.parametrize("modify_payload", [ 433 {"Name": "Fabric-2"}, 434 {"Name": "Fabric-1", "Description": "This is a fabric1."}, 435 {"FabricDesignMapping": [ 436 { 437 "DesignNode": "Switch-A", 438 "PhysicalNode": Constants.service_tag1 439 }, 440 { 441 "DesignNode": "Switch-B", 442 "PhysicalNode": Constants.service_tag2 443 } 444 ], }, 445 { 446 "FabricDesign": { 447 "Name": "2xMX9116n_Fabric_Switching_Engines_in_different_chassis" 448 } 449 }, 450 { 451 "FabricDesignMapping": [ 452 {"DesignNode": "Switch-B", "PhysicalNode": Constants.service_tag2}, 453 {"DesignNode": "Switch-A", "PhysicalNode": Constants.service_tag1}] 454 } 455 ]) 456 def test_compare_payloads_diff_case_01(self, modify_payload): 457 current_payload = { 458 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 459 "Name": "Fabric-1", 460 "Description": "This is a fabric.", 461 "FabricDesignMapping": [ 462 { 463 "DesignNode": "Switch-A", 464 "PhysicalNode": "2HB7NX2" 465 }, 466 { 467 "DesignNode": "Switch-B", 468 "PhysicalNode": "2HBFNX2" 469 } 470 ], 471 "FabricDesign": { 472 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 473 } 474 } 475 diff = self.module.compare_payloads(modify_payload, current_payload) 476 assert diff is True 477 478 @pytest.mark.parametrize("current_payload", [ 479 {"Name": "Fabric-1", "Description": "This is a fabric1."}, 480 {"Name": "Fabric-1", "Description": "This is a fabric.", "FabricDesignMapping": [ 481 { 482 "DesignNode": "Switch-A", 483 "PhysicalNode": Constants.service_tag1 484 }, 485 { 486 "DesignNode": "Switch-B", 487 "PhysicalNode": Constants.service_tag2 488 } 489 ], "FabricDesign": { 490 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 491 }}]) 492 def test_compare_payloads_diff_case_02(self, current_payload): 493 modify_payload = { 494 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 495 "Name": "Fabric-1", 496 "Description": "This is a fabric.", 497 "FabricDesignMapping": [ 498 { 499 "DesignNode": "Switch-A", 500 "PhysicalNode": "2HB7NX2" 501 }, 502 { 503 "DesignNode": "Switch-B", 504 "PhysicalNode": "2HBFNX2" 505 } 506 ], 507 "FabricDesign": { 508 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 509 } 510 } 511 diff = self.module.compare_payloads(modify_payload, current_payload) 512 assert diff is True 513 514 @pytest.mark.parametrize("modify_payload", [ 515 {"Name": "Fabric-1", "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f"}, 516 {"Name": "Fabric-1", "Description": "This is a fabric.", "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", }, 517 {"Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", "Name": "Fabric-1", "FabricDesignMapping": [ 518 { 519 "DesignNode": "Switch-A", 520 "PhysicalNode": Constants.service_tag1 521 }, 522 { 523 "DesignNode": "Switch-B", 524 "PhysicalNode": Constants.service_tag2 525 } 526 ], }, 527 { 528 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 529 "Name": "Fabric-1", 530 "FabricDesign": { 531 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 532 } 533 }, 534 { 535 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 536 "Name": "Fabric-1", 537 "Description": "This is a fabric.", 538 "FabricDesignMapping": [ 539 { 540 "DesignNode": "Switch-A", 541 "PhysicalNode": Constants.service_tag1 542 }, 543 { 544 "DesignNode": "Switch-B", 545 "PhysicalNode": Constants.service_tag2 546 } 547 ], 548 "FabricDesign": { 549 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 550 } 551 } 552 ]) 553 def test_compare_payloads_no_diff_case_01(self, modify_payload): 554 current_payload = { 555 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 556 "Name": "Fabric-1", 557 "Description": "This is a fabric.", 558 "FabricDesignMapping": [ 559 { 560 "DesignNode": "Switch-A", 561 "PhysicalNode": Constants.service_tag1 562 }, 563 { 564 "DesignNode": "Switch-B", 565 "PhysicalNode": Constants.service_tag2 566 } 567 ], 568 "FabricDesign": { 569 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 570 } 571 } 572 val = self.module.compare_payloads(modify_payload, current_payload) 573 # print(val) 574 assert val is False 575 576 @pytest.mark.parametrize('val', [{'msg': CHECK_MODE_CHANGE_FOUND_MSG, 577 "current_payload": {"Name": "Fabric-1", "Description": "This is a fabric.", 578 "FabricDesignMapping": [{"DesignNode": "Switch-A", 579 "PhysicalNode": Constants.service_tag1}, 580 {"DesignNode": "Switch-B", 581 "PhysicalNode": Constants.service_tag2}], 582 "FabricDesign": { 583 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"}}, 584 "expected_payload": {"Name": "Fabric-1", "Description": "This is a fabric.", 585 "FabricDesignMapping": [{"DesignNode": "Switch-A", 586 "PhysicalNode": Constants.service_tag2}, 587 {"DesignNode": "Switch-B", 588 "PhysicalNode": Constants.service_tag1}], 589 "FabricDesign": { 590 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"}}}, 591 {'msg': CHECK_MODE_CHANGE_NOT_FOUND_MSG, 592 "current_payload": {"Name": "Fabric-1", "Description": "This is a fabric.", 593 "FabricDesignMapping": [{"DesignNode": "Switch-A", 594 "PhysicalNode": Constants.service_tag1}, 595 {"DesignNode": "Switch-B", 596 "PhysicalNode": Constants.service_tag2}], 597 "FabricDesign": { 598 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"}}, 599 "expected_payload": {"Name": "Fabric-1", "Description": "This is a fabric.", 600 "FabricDesignMapping": [{"DesignNode": "Switch-A", 601 "PhysicalNode": Constants.service_tag1}, 602 {"DesignNode": "Switch-B", 603 "PhysicalNode": Constants.service_tag2}], 604 "FabricDesign": { 605 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"}}}, 606 {'msg': CHECK_MODE_CHANGE_NOT_FOUND_MSG, "current_payload": {"Name": "Fabric-1", 607 "Description": "This is list order change case.", 608 "FabricDesignMapping": [ 609 { 610 "DesignNode": "Switch-A", 611 "PhysicalNode": Constants.service_tag1}, 612 { 613 "DesignNode": "Switch-B", 614 "PhysicalNode": Constants.service_tag2}], 615 "FabricDesign": { 616 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"}}, 617 "expected_payload": {"Name": "Fabric-1", 618 "Description": "This is list order change case.", 619 "FabricDesignMapping": [{"DesignNode": "Switch-B", 620 "PhysicalNode": Constants.service_tag2}, 621 {"DesignNode": "Switch-A", 622 "PhysicalNode": Constants.service_tag1}], 623 "FabricDesign": { 624 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"}}}, 625 {'msg': CHECK_MODE_CHANGE_NOT_FOUND_MSG, 626 "current_payload": {'Id': 'fa9f1b12-c003-4772-8b90-601d0bf87c69', 627 'Name': 'MX9116N', 'OverrideLLDPConfiguration': 'Disabled', 628 'FabricDesignMapping': [ 629 {'DesignNode': 'Switch-B', 'PhysicalNode': '6XLVMR2'}, 630 {'DesignNode': 'Switch-A', 'PhysicalNode': '6XLTMR2'}], 631 'FabricDesign': { 632 'Name': '2xMX9116n_Fabric_Switching_Engines_in_different_chassis'}}, 633 "expected_payload": {'Name': 'MX9116N', 'OverrideLLDPConfiguration': 'Disabled', 634 'FabricDesignMapping': [ 635 {'DesignNode': 'Switch-A', 'PhysicalNode': '6XLTMR2'}, 636 {'DesignNode': 'Switch-B', 'PhysicalNode': '6XLVMR2'}], 637 'FabricDesign': { 638 'Name': '2xMX9116n_Fabric_Switching_Engines_in_different_chassis'}, 639 'Id': 'fa9f1b12-c003-4772-8b90-601d0bf87c69'}} 640 ]) 641 def test_idempotency_check_for_state_present_modify_check_mode_case01(self, mocker, val): 642 f_module = self.get_module_mock(params={}, check_mode=True) 643 error_message = val["msg"] 644 with pytest.raises(Exception) as err: 645 self.module.idempotency_check_for_state_present("8f25f714-9ea8-48e9-8eac-162d5d842e9f", 646 val['current_payload'], val['expected_payload'], 647 f_module) 648 assert err.value.args[0] == error_message 649 650 def test_idempotency_check_for_state_present_modify_non_check_mode_case01(self, mocker): 651 f_module = self.get_module_mock(params={}, check_mode=False) 652 mocker.patch(MODULE_PATH + 'ome_smart_fabric.compare_payloads', 653 return_value=False) 654 with pytest.raises(Exception, match=IDEMPOTENCY_MSG): 655 self.module.idempotency_check_for_state_present("8f25f714-9ea8-48e9-8eac-162d5d842e9f", 656 {}, {}, 657 f_module) 658 659 def test_idempotency_check_for_state_present_create_non_check_mode_case01(self, mocker): 660 f_module = self.get_module_mock(params={}, check_mode=True) 661 mocker.patch(MODULE_PATH + 'ome_smart_fabric.compare_payloads', 662 return_value=False) 663 with pytest.raises(Exception, match=CHECK_MODE_CHANGE_FOUND_MSG): 664 self.module.idempotency_check_for_state_present(None, 665 {}, {}, 666 f_module) 667 668 def test_design_node_dict_update_case_01(self): 669 design_node_map = [ 670 { 671 "DesignNode": "Switch-A", 672 "PhysicalNode": Constants.service_tag1 673 }, 674 { 675 "DesignNode": "Switch-B", 676 "PhysicalNode": Constants.service_tag2 677 } 678 ] 679 val = self.module.design_node_dict_update(design_node_map) 680 assert val == { 681 'PhysicalNode1': Constants.service_tag1, 682 'PhysicalNode2': Constants.service_tag2 683 } 684 685 def test_design_node_dict_update_case_02(self): 686 design_node_map = [ 687 { 688 "DesignNode": "Switch-B", 689 "PhysicalNode": Constants.service_tag2 690 } 691 ] 692 val = self.module.design_node_dict_update(design_node_map) 693 assert val == { 694 'PhysicalNode2': Constants.service_tag2 695 } 696 697 def test_design_node_dict_update_case_03(self): 698 design_node_map = [ 699 { 700 "DesignNode": "Switch-B", 701 "PhysicalNode": Constants.service_tag2 702 } 703 ] 704 val = self.module.design_node_dict_update(design_node_map) 705 assert val == { 706 'PhysicalNode2': Constants.service_tag2 707 } 708 709 @pytest.mark.parametrize("modify_payload", [ 710 { 711 'PhysicalNode1': Constants.service_tag2, 712 'PhysicalNode2': Constants.service_tag1 713 } 714 ]) 715 def test_validate_switches_overlap_case_01(self, modify_payload): 716 current_dict = { 717 'PhysicalNode1': Constants.service_tag1, 718 'PhysicalNode2': Constants.service_tag2 719 } 720 modify_dict = modify_payload 721 f_module = self.get_module_mock(params={"primary_switch_service_tag": Constants.service_tag2, 722 "secondary_switch_service_tag": Constants.service_tag1 723 }) 724 with pytest.raises(Exception, match="The modify operation does not support primary_switch_service_tag update."): 725 self.module.validate_switches_overlap(current_dict, modify_dict, f_module) 726 727 @pytest.mark.parametrize("modify_payload", [ 728 { 729 'PhysicalNode1': Constants.service_tag2, 730 'PhysicalNode2': Constants.service_tag1 731 } 732 ]) 733 def test_validate_switches_overlap_case_02(self, modify_payload): 734 current_dict = { 735 'PhysicalNode1': Constants.service_tag2, 736 'PhysicalNode2': Constants.service_tag1 737 } 738 modify_dict = modify_payload 739 f_module = self.get_module_mock(params={"primary_switch_service_tag": Constants.service_tag2, 740 "secondary_switch_service_tag": Constants.service_tag1 741 }) 742 self.module.validate_switches_overlap(current_dict, modify_dict, f_module) 743 744 def test_validate_switches_overlap_case_03(self): 745 """ 746 interchanging switches should be allowed 747 """ 748 current_dict = { 749 'PhysicalNode1': Constants.service_tag1, 750 'PhysicalNode2': Constants.service_tag2 751 } 752 modify_dict = { 753 'PhysicalNode1': Constants.service_tag1, 754 'PhysicalNode2': Constants.service_tag2 755 } 756 f_module = self.get_module_mock(params={"primary_switch_service_tag": Constants.service_tag1, 757 "secondary_switch_service_tag": Constants.service_tag2 758 }) 759 self.module.validate_switches_overlap(current_dict, modify_dict, f_module) 760 761 def test_fabric_design_map_payload_creation_case01(self, mocker): 762 modify_payload = [ 763 { 764 "DesignNode": "Switch-A", 765 "PhysicalNode": Constants.service_tag1 766 }, 767 { 768 "DesignNode": "Switch-B", 769 "PhysicalNode": Constants.service_tag2 770 } 771 ] 772 current_payload = [ 773 { 774 "DesignNode": "Switch-A", 775 "PhysicalNode": "xyz123" 776 }, 777 { 778 "DesignNode": "Switch-B", 779 "PhysicalNode": "abc456" 780 } 781 ] 782 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_switches_overlap', return_value=None) 783 f_module = self.get_module_mock(params={}) 784 design_map = self.module.fabric_design_map_payload_creation(modify_payload, current_payload, f_module) 785 assert design_map == modify_payload 786 787 def test_fabric_design_map_payload_creation_case02(self, mocker): 788 modify_payload = [ 789 { 790 "DesignNode": "Switch-A", 791 "PhysicalNode": Constants.service_tag1 792 } 793 ] 794 current_payload = [ 795 { 796 "DesignNode": "Switch-A", 797 "PhysicalNode": "xyz123" 798 }, 799 { 800 "DesignNode": "Switch-B", 801 "PhysicalNode": "abc456" 802 } 803 ] 804 f_module = self.get_module_mock(params={}) 805 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_switches_overlap', return_value=None) 806 design_map = self.module.fabric_design_map_payload_creation(modify_payload, current_payload, f_module) 807 assert design_map == [ 808 { 809 "DesignNode": "Switch-A", 810 "PhysicalNode": Constants.service_tag1 811 }, 812 { 813 "DesignNode": "Switch-B", 814 "PhysicalNode": "abc456" 815 } 816 ] 817 818 def test_fabric_design_map_payload_creation_case03(self, mocker): 819 modify_payload = [ 820 ] 821 current_payload = [ 822 ] 823 f_module = self.get_module_mock(params={}) 824 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_switches_overlap', return_value=None) 825 design_map = self.module.fabric_design_map_payload_creation(modify_payload, current_payload, f_module) 826 assert design_map == [] 827 828 def test_merge_payload_case_01(self): 829 modify_payload = { 830 "Name": "new_name", 831 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 832 } 833 current_payload = { 834 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 835 "Name": "Fabric-1", 836 "Description": "This is a fabric.", 837 "FabricDesignMapping": [ 838 { 839 "DesignNode": "Switch-A", 840 "PhysicalNode": Constants.service_tag1 841 }, 842 { 843 "DesignNode": "Switch-B", 844 "PhysicalNode": Constants.service_tag2 845 } 846 ], 847 "FabricDesign": { 848 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 849 } 850 } 851 f_module = self.get_module_mock(params={}) 852 payload = self.module.merge_payload(modify_payload, current_payload, f_module) 853 assert payload["Name"] == modify_payload["Name"] 854 assert payload["Id"] == modify_payload["Id"] 855 assert payload["Description"] == current_payload["Description"] 856 assert payload["FabricDesignMapping"] == current_payload["FabricDesignMapping"] 857 assert payload["FabricDesign"] == current_payload["FabricDesign"] 858 859 def test_merge_payload_case_02(self): 860 modify_payload = { 861 "Name": "new_name", 862 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 863 "FabricDesignMapping": [ 864 { 865 "DesignNode": "Switch-A", 866 "PhysicalNode": Constants.service_tag1 867 }], 868 "FabricDesign": { 869 "Name": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis" 870 } 871 } 872 current_payload = { 873 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 874 "Name": "Fabric-1", 875 "Description": "This is a fabric.", 876 "FabricDesignMapping": [ 877 { 878 "DesignNode": "Switch-A", 879 "PhysicalNode": Constants.service_tag1 880 }, 881 { 882 "DesignNode": "Switch-B", 883 "PhysicalNode": Constants.service_tag2 884 } 885 ], 886 "FabricDesign": { 887 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 888 } 889 } 890 f_module = self.get_module_mock(params={}) 891 payload = self.module.merge_payload(modify_payload, current_payload, f_module) 892 assert payload["Name"] == modify_payload["Name"] 893 assert payload["Id"] == modify_payload["Id"] 894 assert payload["Description"] == current_payload["Description"] 895 assert payload["FabricDesign"] == modify_payload["FabricDesign"] 896 assert payload["FabricDesignMapping"] == [ 897 { 898 "DesignNode": "Switch-A", 899 "PhysicalNode": Constants.service_tag1 900 }, 901 { 902 "DesignNode": "Switch-B", 903 "PhysicalNode": Constants.service_tag2 904 } 905 ] 906 907 def test_merge_payload_case_03(self): 908 modify_payload = { 909 "Name": "new_name", 910 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 911 "FabricDesign": { 912 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 913 } 914 } 915 current_payload = { 916 "Id": "8f25f714-9ea8-48e9-8eac-162d5d842e9f", 917 "Name": "Fabric-1", 918 "FabricDesignMapping": [ 919 { 920 "DesignNode": "Switch-A", 921 "PhysicalNode": Constants.service_tag1 922 }, 923 { 924 "DesignNode": "Switch-B", 925 "PhysicalNode": Constants.service_tag2 926 } 927 ], 928 "Description": "This is a fabric." 929 } 930 f_module = self.get_module_mock(params={}) 931 payload = self.module.merge_payload(modify_payload, current_payload, f_module) 932 assert payload["Name"] == modify_payload["Name"] 933 assert payload["Id"] == modify_payload["Id"] 934 assert payload["Description"] == current_payload["Description"] 935 assert payload["FabricDesign"] == modify_payload["FabricDesign"] 936 assert payload["FabricDesignMapping"] == current_payload["FabricDesignMapping"] 937 938 def test_get_fabric_design(self, ome_connection_mock_for_smart_fabric, ome_response_mock): 939 resp_data = { 940 "Name": "2xMX5108n_Ethernet_Switches_in_same_chassis" 941 } 942 ome_response_mock.json_data = resp_data 943 fabric_design_uri = "/api/NetworkService/Fabrics('0bebadec-b61b-4b16-b354-5196396a4a18')/FabricDesign" 944 fabric_design = self.module.get_fabric_design(fabric_design_uri, ome_connection_mock_for_smart_fabric) 945 assert fabric_design == {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 946 947 def test_get_current_payload(self, mocker, ome_connection_mock_for_smart_fabric): 948 fabric_details = { 949 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 950 "Name": "Fabric_", 951 "Description": "create new fabric1", 952 "OverrideLLDPConfiguration": "NA", 953 "ScaleVLANProfile": "NA", 954 "FabricDesignMapping": [ 955 { 956 "DesignNode": "Switch-A", 957 "PhysicalNode": "2HB7NX2" 958 }, 959 { 960 "DesignNode": "Switch-B", 961 "PhysicalNode": "2HBFNX2" 962 } 963 ], 964 "FabricDesign": { 965 "@odata.id": "/api/NetworkService/Fabrics('1312cceb-c3dd-4348-95c1-d8541a17d776')/FabricDesign" 966 } 967 } 968 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_fabric_design', 969 return_value={"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"}) 970 payload = self.module.get_current_payload(fabric_details, ome_connection_mock_for_smart_fabric) 971 assert payload == { 972 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 973 "Name": "Fabric_", 974 "Description": "create new fabric1", 975 "FabricDesignMapping": [ 976 { 977 "DesignNode": "Switch-A", 978 "PhysicalNode": "2HB7NX2" 979 }, 980 { 981 "DesignNode": "Switch-B", 982 "PhysicalNode": "2HBFNX2" 983 } 984 ], 985 "FabricDesign": {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 986 } 987 988 def test_get_current_payload_case02(self, mocker, ome_connection_mock_for_smart_fabric): 989 fabric_details = { 990 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 991 "Name": "Fabric_", 992 "Description": "create new fabric1", 993 "OverrideLLDPConfiguration": "Disabled", 994 "ScaleVLANProfile": "NA", 995 "FabricDesignMapping": [ 996 { 997 "DesignNode": "Switch-A", 998 "PhysicalNode": "2HB7NX2" 999 }, 1000 { 1001 "DesignNode": "Switch-B", 1002 "PhysicalNode": "2HBFNX2" 1003 } 1004 ], 1005 "FabricDesign": { 1006 "@odata.id": "/api/NetworkService/Fabrics('1312cceb-c3dd-4348-95c1-d8541a17d776')/FabricDesign" 1007 } 1008 } 1009 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_fabric_design', 1010 return_value={"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"}) 1011 payload = self.module.get_current_payload(fabric_details, ome_connection_mock_for_smart_fabric) 1012 assert payload == { 1013 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 1014 "OverrideLLDPConfiguration": "Disabled", 1015 "Name": "Fabric_", 1016 "Description": "create new fabric1", 1017 "FabricDesignMapping": [ 1018 { 1019 "DesignNode": "Switch-A", 1020 "PhysicalNode": "2HB7NX2" 1021 }, 1022 { 1023 "DesignNode": "Switch-B", 1024 "PhysicalNode": "2HBFNX2" 1025 } 1026 ], 1027 "FabricDesign": {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 1028 } 1029 1030 @pytest.mark.parametrize("params, expected", [({"name": "fabric1"}, {"Name": "fabric1"}), 1031 ({"name": "fabric1", "description": "fabric desc"}, 1032 {"Name": "fabric1", "Description": "fabric desc"}), 1033 ({"name": "fabric1", "description": "fabric desc", 1034 "override_LLDP_configuration": "Enabled"}, 1035 {"Name": "fabric1", "Description": "fabric desc", 1036 "OverrideLLDPConfiguration": "Enabled"} 1037 )]) 1038 def test_create_modify_payload_case_01(self, params, expected, ome_default_args): 1039 ome_default_args.update(params) 1040 payload = self.module.create_modify_payload(ome_default_args, None, "1.1") 1041 assert payload == expected 1042 1043 def test_create_modify_payload_case_02(self, ome_default_args): 1044 params = {"name": "fabric1", "new_name": "fabric2", "primary_switch_service_tag": Constants.service_tag1, 1045 "secondary_switch_service_tag": Constants.service_tag2, 1046 "fabric_design": "2xMX5108n_Ethernet_Switches_in_same_chassis", 1047 "override_LLDP_configuration": "Disabled"} 1048 ome_default_args.update(params) 1049 payload = self.module.create_modify_payload(ome_default_args, "1312cceb-c3dd-4348-95c1-d8541a17d776", "1.0") 1050 assert payload["FabricDesignMapping"] == [{"DesignNode": "Switch-A", 1051 "PhysicalNode": Constants.service_tag1}, 1052 {"DesignNode": "Switch-B", 1053 "PhysicalNode": Constants.service_tag2} 1054 ] 1055 assert payload["Name"] == "fabric2" 1056 assert "OverrideLLDPConfiguration" not in payload 1057 assert payload["FabricDesign"] == {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 1058 assert payload["Id"] == "1312cceb-c3dd-4348-95c1-d8541a17d776" 1059 1060 def test_get_fabric_id_cse_01(self): 1061 fabric_id, fabric_id_details = self.module.get_fabric_id_details("Fabric_1", all_fabric_details) 1062 assert fabric_id == "1312cceb-c3dd-4348-95c1-d8541a17d776" 1063 assert fabric_id_details == all_fabric_details[0] 1064 1065 def test_get_fabric_id_cse_02(self): 1066 fabric_id, fabric_id_details = self.module.get_fabric_id_details("Fabric_New", all_fabric_details) 1067 assert fabric_id is None 1068 assert fabric_id_details is None 1069 1070 def test_get_fabric_id_cse_03(self): 1071 fabric_id, fabric_id_details = self.module.get_fabric_id_details("Fabric_1", []) 1072 assert fabric_id is None 1073 assert fabric_id_details is None 1074 1075 @pytest.mark.parametrize("identifier, expected_type", [("primary_switch_service_tag", "NETWORK_IOM"), 1076 ("secondary_switch_service_tag", "NETWORK_IOM"), 1077 ("hostname", "CHASSIS")]) 1078 def test_validate_device_type_case_01(self, ome_default_args, identifier, expected_type): 1079 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1080 "secondary_switch_service_tag": Constants.service_tag2}) 1081 f_module = self.get_module_mock(params={identifier: "val"}) 1082 with pytest.raises(Exception, match=DEVICE_SERVICE_TAG_TYPE_ERROR_MSG.format(identifier, expected_type)): 1083 self.module.validate_device_type("SERVER", identifier, {}, f_module) 1084 1085 @pytest.mark.parametrize("identifier", ["primary_switch_service_tag", "secondary_switch_service_tag"]) 1086 def test_validate_device_type_case_02(self, ome_default_args, identifier): 1087 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1088 "secondary_switch_service_tag": Constants.service_tag2, 1089 "fabric_design": "2xMX5108n_Ethernet_Switches_in_same_chassis" 1090 }) 1091 1092 f_module = self.get_module_mock(params=ome_default_args) 1093 with pytest.raises(Exception, match=DESIGN_MODEL_ERROR_MSG.format(identifier, 'MX5108n')): 1094 self.module.validate_device_type("NETWORK_IOM", identifier, device_details, f_module) 1095 1096 @pytest.mark.parametrize("identifier", ["primary_switch_service_tag", "secondary_switch_service_tag"]) 1097 def test_validate_device_type_case_03(self, ome_default_args, identifier): 1098 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1099 "secondary_switch_service_tag": Constants.service_tag2, 1100 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis" 1101 }) 1102 1103 f_module = self.get_module_mock(params=ome_default_args) 1104 self.module.validate_device_type("NETWORK_IOM", identifier, device_details, f_module) 1105 1106 def test_validate_service_tag_case_01(self, mocker, ome_connection_mock_for_smart_fabric, ome_default_args): 1107 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1108 "secondary_switch_service_tag": Constants.service_tag2, 1109 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis" 1110 }) 1111 1112 f_module = self.get_module_mock(params=ome_default_args) 1113 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_device_type', return_value=None) 1114 ome_connection_mock_for_smart_fabric.get_device_id_from_service_tag.return_value = {"value": device_details, 1115 "Id": Constants.device_id1} 1116 self.module.validate_service_tag(Constants.service_tag1, "primary_switch_service_tag", 1117 {2000: "CHASSIS", 4000: "NETWORK_IOM", 1118 1000: "SERVER", 1119 3000: "STORAGE"}, ome_connection_mock_for_smart_fabric, f_module) 1120 1121 def test_validate_service_tag_exception_case_01(self, mocker, ome_connection_mock_for_smart_fabric, 1122 ome_default_args): 1123 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1124 "secondary_switch_service_tag": Constants.service_tag2, 1125 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis" 1126 }) 1127 1128 f_module = self.get_module_mock(params=ome_default_args) 1129 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_device_type', return_value=None) 1130 ome_connection_mock_for_smart_fabric.get_device_id_from_service_tag.return_value = {"value": {}, "Id": None} 1131 with pytest.raises(Exception, match=DEVICE_SERVICE_TAG_NOT_FOUND_ERROR_MSG.format(Constants.service_tag1)): 1132 self.module.validate_service_tag(Constants.service_tag1, "primary_switch_service_tag", 1133 {2000: "CHASSIS", 4000: "NETWORK_IOM", 1134 1000: "SERVER", 1135 3000: "STORAGE"}, ome_connection_mock_for_smart_fabric, f_module) 1136 1137 @pytest.mark.parametrize("params", [{"primary_switch_service_tag": Constants.service_tag1, 1138 "secondary_switch_service_tag": Constants.service_tag2, 1139 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis" 1140 }, 1141 {"primary_switch_service_tag": None, 1142 "secondary_switch_service_tag": None, 1143 } 1144 ]) 1145 def test_validate_devices_case_01(self, params, mocker, ome_connection_mock_for_smart_fabric, ome_default_args): 1146 ome_default_args.update(params) 1147 1148 f_module = self.get_module_mock(params=ome_default_args) 1149 ome_connection_mock_for_smart_fabric.get_device_type.return_value = {2000: "CHASSIS", 4000: "NETWORK_IOM", 1150 1000: "SERVER", 1151 3000: "STORAGE"} 1152 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_service_tag', return_value=None) 1153 self.module.validate_devices(Constants.service_tag1, ome_connection_mock_for_smart_fabric, f_module) 1154 1155 def test_validate_devices_case_02(self, mocker, ome_connection_mock_for_smart_fabric, ome_default_args): 1156 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag2, 1157 "secondary_switch_service_tag": Constants.service_tag2, 1158 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis" 1159 }) 1160 1161 f_module = self.get_module_mock(params=ome_default_args) 1162 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_service_tag', return_value=None) 1163 ome_connection_mock_for_smart_fabric.get_device_type.return_value = {2000: "CHASSIS", 1164 4000: "NETWORK_IOM", 1165 1000: "SERVER", 1166 3000: "STORAGE"} 1167 self.module.validate_devices(Constants.service_tag1, ome_connection_mock_for_smart_fabric, f_module) 1168 1169 def test_required_field_check_for_create_case_01(self, ome_default_args): 1170 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1171 "secondary_switch_service_tag": Constants.service_tag2, 1172 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis", 1173 "state": "present" 1174 }) 1175 1176 f_module = self.get_module_mock(params=ome_default_args) 1177 self.module.required_field_check_for_create("fabric_id", f_module) 1178 1179 def test_required_field_check_for_create_case_02(self, ome_default_args): 1180 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1181 "secondary_switch_service_tag": Constants.service_tag2, 1182 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis", 1183 "state": "present" 1184 }) 1185 1186 f_module = self.get_module_mock(params=ome_default_args) 1187 self.module.required_field_check_for_create(None, f_module) 1188 1189 @pytest.mark.parametrize("params", [{"primary_switch_service_tag": Constants.service_tag1}, 1190 {"secondary_switch_service_tag": Constants.service_tag1}, 1191 {"fabric_design": Constants.service_tag1}, 1192 {"fabric_design": Constants.service_tag1, 1193 "primary_switch_service_tag": Constants.service_tag1}, 1194 {"fabric_design": Constants.service_tag1, 1195 "secondary_switch_service_tag": Constants.service_tag1}, 1196 {"primary_switch_service_tag": Constants.service_tag1, 1197 "secondary_switch_service_tag": Constants.service_tag2}, 1198 {"primary_switch_service_tag": None, 1199 "secondary_switch_service_tag": None}, 1200 {"primary_switch_service_tag": None, 1201 "secondary_switch_service_tag": None} 1202 ]) 1203 def test_required_field_check_for_create_case_03(self, params, ome_default_args): 1204 ome_default_args.update(params) 1205 f_module = self.get_module_mock(params=ome_default_args) 1206 with pytest.raises(Exception, match=REQUIRED_FIELD): 1207 self.module.required_field_check_for_create(None, f_module) 1208 1209 def test_process_output_case01(self, ome_connection_mock_for_smart_fabric, ome_default_args): 1210 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1211 "secondary_switch_service_tag": Constants.service_tag2, 1212 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis", 1213 "state": "present" 1214 }) 1215 f_module = self.get_module_mock(params=ome_default_args) 1216 with pytest.raises(Exception, match="Fabric modification operation is initiated.") as err: 1217 self.module.process_output("Fabric1", True, "Fabric modification operation is initiated.", "1234", 1218 ome_connection_mock_for_smart_fabric, f_module) 1219 err.value.fail_kwargs['fabric_id'] == "1234" 1220 1221 def test_process_output_case02(self, mocker, ome_connection_mock_for_smart_fabric, ome_default_args): 1222 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1223 "secondary_switch_service_tag": Constants.service_tag2, 1224 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis", 1225 "state": "present" 1226 }) 1227 f_module = self.get_module_mock(params=ome_default_args) 1228 resp = { 1229 "error": { 1230 "code": "Base.1.0.GeneralError", 1231 "message": "A general error has occurred. See ExtendedInfo for more information.", 1232 "@Message.ExtendedInfo": 1233 [ 1234 { 1235 "MessageId": "CDEV7154", 1236 "RelatedProperties": [], 1237 "Message": "Fabric update is successful. The OverrideLLDPConfiguration attribute is not" 1238 " provided " 1239 " in the payload, so it preserves the previous value.", 1240 "MessageArgs": [], 1241 "Severity": "Informational", 1242 "Resolution": "Please update the Fabric with the OverrideLLDPConfiguration as Disabled or" 1243 " Enabled " 1244 " if necessary. " 1245 } 1246 ] 1247 } 1248 } 1249 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = {"value": all_fabric_details, 1250 "total_count": 2} 1251 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_fabric_id_details', 1252 return_value=(all_fabric_details[0]["Id"], all_fabric_details[0])) 1253 with pytest.raises(Exception, match="Fabric creation operation is initiated.") as err: 1254 self.module.process_output("Fabric1", resp, "Fabric creation operation is initiated.", None, 1255 ome_connection_mock_for_smart_fabric, f_module) 1256 err.value.fail_kwargs['fabric_id'] == all_fabric_details[0]["Id"] 1257 err.value.fail_kwargs['additional_info'] == resp 1258 1259 def test_process_output_case03(self, ome_connection_mock_for_smart_fabric, ome_default_args): 1260 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1261 "secondary_switch_service_tag": Constants.service_tag2, 1262 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis", 1263 "state": "present" 1264 }) 1265 f_module = self.get_module_mock(params=ome_default_args) 1266 with pytest.raises(Exception, match="Fabric creation operation is initiated.") as err: 1267 self.module.process_output("Fabric1", "1234", "Fabric creation operation is initiated.", None, 1268 ome_connection_mock_for_smart_fabric, f_module) 1269 err.value.fail_kwargs['fabric_id'] == "1234" 1270 1271 def test_create_modify_fabric_modify_case_01(self, ome_connection_mock_for_smart_fabric, ome_default_args, mocker, 1272 ome_response_mock): 1273 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1274 "secondary_switch_service_tag": Constants.service_tag2, 1275 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis", 1276 "state": "present" 1277 }) 1278 1279 mocker.patch(MODULE_PATH + 'ome_smart_fabric.required_field_check_for_create', 1280 return_value=None) 1281 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_msm_device_details', 1282 return_value=(Constants.service_tag1, "1.1")) 1283 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_devices', return_value=None) 1284 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_modify', return_value=None) 1285 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_fabric_id_details', 1286 return_value=(all_fabric_details[0]["Id"], all_fabric_details[0])) 1287 mocker.patch(MODULE_PATH + 'ome_smart_fabric.create_modify_payload', 1288 return_value={"Name": "fabric2", "Description": "fabric desc2", 1289 "OverrideLLDPConfiguration": "Enabled"}) 1290 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_current_payload', 1291 return_value={ 1292 "Name": "fabric1", 1293 "Description": "fabric desc1", 1294 "OverrideLLDPConfiguration": "Enabled", 1295 "FabricDesignMapping": [ 1296 { 1297 "DesignNode": "Switch-A", 1298 "PhysicalNode": "3QM4WV2" 1299 }, 1300 { 1301 "DesignNode": "Switch-B", 1302 "PhysicalNode": "GTCT8T2" 1303 } 1304 ], 1305 "FabricDesign": { 1306 "Name": "2xMX9116n_Fabric_Switching_Engines_in_different_chassis" 1307 } 1308 }) 1309 mocker_merge_payload = mocker.patch(MODULE_PATH + 'ome_smart_fabric.merge_payload', 1310 return_value={ 1311 "Name": "fabric2", 1312 "Description": "fabric desc2", 1313 "OverrideLLDPConfiguration": "Enabled", 1314 "FabricDesignMapping": [ 1315 { 1316 "DesignNode": "Switch-A", 1317 "PhysicalNode": "3QM4WV2" 1318 }, 1319 { 1320 "DesignNode": "Switch-B", 1321 "PhysicalNode": "GTCT8T2" 1322 } 1323 ], 1324 "FabricDesign": { 1325 "Name": "2xMX9116n_Fabric_Switching_Engines_in_different_chassis" 1326 } 1327 }) 1328 mocker.patch(MODULE_PATH + 'ome_smart_fabric.idempotency_check_for_state_present', return_value=None) 1329 mocker_process_output = mocker.patch(MODULE_PATH + 'ome_smart_fabric.process_output', return_value=None) 1330 ome_response_mock.json_data = "true" 1331 f_module = self.get_module_mock(params=ome_default_args) 1332 self.module.create_modify_fabric("Fabric1", all_fabric_details, ome_connection_mock_for_smart_fabric, 1333 f_module) 1334 assert mocker_process_output.called 1335 assert mocker_merge_payload.called 1336 1337 def test_create_modify_fabric_create_case_02(self, ome_connection_mock_for_smart_fabric, ome_default_args, mocker, 1338 ome_response_mock): 1339 ome_default_args.update({"primary_switch_service_tag": Constants.service_tag1, 1340 "secondary_switch_service_tag": Constants.service_tag2, 1341 "fabric_design": "2xMX9116n_Fabric_Switching_Engines_in_same_chassis", 1342 "state": "present" 1343 }) 1344 1345 f_module = self.get_module_mock(params=ome_default_args) 1346 mocker.patch(MODULE_PATH + 'ome_smart_fabric.required_field_check_for_create', 1347 return_value=None) 1348 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_msm_device_details', 1349 return_value=(Constants.service_tag1, "1.1")) 1350 mocker.patch(MODULE_PATH + 'ome_smart_fabric.validate_devices', return_value=None) 1351 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_fabric_id_details', 1352 return_value=(None, {})) 1353 mocker_create_modify_payload = mocker.patch(MODULE_PATH + 'ome_smart_fabric.create_modify_payload', 1354 return_value={"Name": "fabric2", "Description": "fabric desc2", 1355 "OverrideLLDPConfiguration": "Enabled"}) 1356 mocker.patch(MODULE_PATH + 'ome_smart_fabric.idempotency_check_for_state_present', return_value=None) 1357 ome_response_mock.json_data = "123456789abcd" 1358 mocker_process_output = mocker.patch(MODULE_PATH + 'ome_smart_fabric.process_output', return_value=None) 1359 self.module.create_modify_fabric("Fabric1", all_fabric_details, ome_connection_mock_for_smart_fabric, 1360 f_module) 1361 assert mocker_process_output.called 1362 assert mocker_create_modify_payload.called 1363 1364 def test_check_fabric_exits_for_state_absent_non_check_mode_case01(self, mocker, 1365 ome_connection_mock_for_smart_fabric, 1366 ome_default_args): 1367 ome_default_args.update({ 1368 "state": "absent", 1369 "name": "Fabric1" 1370 }) 1371 1372 f_module = self.get_module_mock(params=ome_default_args, check_mode=False) 1373 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_fabric_id_details', 1374 return_value=(None, {})) 1375 with pytest.raises(Exception, match=FABRIC_NOT_FOUND_ERROR_MSG.format("Fabric1")): 1376 self.module.check_fabric_exits_for_state_absent(all_fabric_details[0], f_module, "Fabric1") 1377 1378 def test_check_fabric_exits_for_state_absent_non_check_mode_case02(self, mocker, 1379 ome_connection_mock_for_smart_fabric, 1380 ome_default_args): 1381 ome_default_args.update({ 1382 "state": "absent", 1383 "name": "Fabric1" 1384 }) 1385 1386 f_module = self.get_module_mock(params=ome_default_args, check_mode=False) 1387 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_fabric_id_details', 1388 return_value=(all_fabric_details[0]["Id"], all_fabric_details[0])) 1389 fabric_id = self.module.check_fabric_exits_for_state_absent(all_fabric_details[0], f_module, "Fabric1") 1390 assert fabric_id == all_fabric_details[0]["Id"] 1391 1392 def test_check_fabric_exits_for_state_absent_check_mode_case01(self, mocker, 1393 ome_connection_mock_for_smart_fabric, 1394 ome_default_args): 1395 ome_default_args.update({ 1396 "state": "absent", 1397 "name": "Fabric1" 1398 }) 1399 1400 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1401 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_fabric_id_details', 1402 return_value=(None, {})) 1403 with pytest.raises(Exception, match=CHECK_MODE_CHANGE_NOT_FOUND_MSG): 1404 self.module.check_fabric_exits_for_state_absent(all_fabric_details[0], f_module, "Fabric1") 1405 1406 def test_check_fabric_exits_for_state_absent_check_mode_case02(self, mocker, 1407 ome_connection_mock_for_smart_fabric, 1408 ome_default_args): 1409 ome_default_args.update({ 1410 "state": "absent", 1411 "name": "Fabric1" 1412 }) 1413 1414 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1415 mocker.patch(MODULE_PATH + 'ome_smart_fabric.get_fabric_id_details', 1416 return_value=(all_fabric_details[0]["Id"], all_fabric_details[0])) 1417 with pytest.raises(Exception, match=CHECK_MODE_CHANGE_FOUND_MSG): 1418 self.module.check_fabric_exits_for_state_absent(all_fabric_details[0], f_module, "Fabric1") 1419 1420 def test_delete_fabric(self, ome_connection_mock_for_smart_fabric, ome_default_args, mocker): 1421 ome_default_args.update({ 1422 "state": "absent", 1423 "name": "Fabric1" 1424 }) 1425 1426 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1427 mocker.patch(MODULE_PATH + 'ome_smart_fabric.check_fabric_exits_for_state_absent', 1428 return_value=all_fabric_details[0]["Id"]) 1429 with pytest.raises(Exception, match="Fabric deletion operation is initiated.") as err: 1430 self.module.delete_fabric(all_fabric_details, ome_connection_mock_for_smart_fabric, f_module, "Fabric1") 1431 err.value.fail_kwargs['fabric_id'] == all_fabric_details[0]["Id"] 1432 1433 def test_fabric_actions_case_01(self, mocker, ome_connection_mock_for_smart_fabric, ome_default_args): 1434 ome_default_args.update({ 1435 "state": "absent", 1436 "name": "Fabric1" 1437 }) 1438 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = {"value": all_fabric_details, 1439 "total_count": 2} 1440 delete_fabric = mocker.patch(MODULE_PATH + 'ome_smart_fabric.delete_fabric', 1441 return_value=None) 1442 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1443 self.module.fabric_actions(ome_connection_mock_for_smart_fabric, f_module) 1444 assert delete_fabric.called 1445 1446 def test_fabric_actions_case_02(self, mocker, ome_connection_mock_for_smart_fabric, ome_default_args): 1447 ome_default_args.update({ 1448 "state": "present", 1449 "name": "Fabric1" 1450 }) 1451 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = {"value": all_fabric_details, 1452 "total_count": 2} 1453 create_modify_fabric = mocker.patch(MODULE_PATH + 'ome_smart_fabric.create_modify_fabric', 1454 return_value=None) 1455 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1456 self.module.fabric_actions(ome_connection_mock_for_smart_fabric, f_module) 1457 assert create_modify_fabric.called 1458 1459 def test_get_service_tag_with_fqdn_success_case(self, ome_default_args, ome_connection_mock_for_smart_fabric): 1460 ome_default_args.update({"hostname": "M-YYYY.abcd.lab"}) 1461 resp_data = { 1462 "@odata.context": "/api/$metadata#Collection(DeviceService.Device)", 1463 "@odata.count": 2, 1464 "value": [ 1465 { 1466 "@odata.type": "#DeviceService.Device", 1467 "@odata.id": "/api/DeviceService/Devices(Constants.device_id1)", 1468 "Id": Constants.device_id1, 1469 "Type": 2000, 1470 "Identifier": Constants.service_tag1, 1471 "DeviceServiceTag": Constants.service_tag1, 1472 "ChassisServiceTag": None, 1473 "Model": "PowerEdge MX7000", 1474 "PowerState": 17, 1475 "ManagedState": 3000, 1476 "Status": 4000, 1477 "ConnectionState": True, 1478 "AssetTag": None, 1479 "SystemId": 2031, 1480 "DeviceName": "MX-Constants.service_tag1", 1481 "LastInventoryTime": "2020-07-11 17:00:18.925", 1482 "LastStatusTime": "2020-07-11 09:00:07.444", 1483 "DeviceSubscription": None, 1484 "DeviceCapabilities": [ 1485 18, 1486 8, 1487 201, 1488 202 1489 ], 1490 "SlotConfiguration": { 1491 "ChassisName": None 1492 }, 1493 "DeviceManagement": [ 1494 { 1495 "ManagementId": 111111, 1496 "NetworkAddress": ome_default_args["hostname"], 1497 "MacAddress": "xx:yy:zz:x1x1", 1498 "ManagementType": 2, 1499 "InstrumentationName": "MX-Constants.service_tag1", 1500 "DnsName": "M-YYYY.abcd.lab", 1501 "ManagementProfile": [ 1502 { 1503 "ManagementProfileId": 111111, 1504 "ProfileId": "MSM_BASE", 1505 "ManagementId": 111111, 1506 "ManagementURL": "https://" + ome_default_args["hostname"] + ":443", 1507 "HasCreds": 0, 1508 "Status": 1000, 1509 "StatusDateTime": "2020-07-11 17:00:18.925" 1510 } 1511 ] 1512 }, 1513 { 1514 "ManagementId": 33333, 1515 "NetworkAddress": "[1234.abcd:5678:345]", 1516 "MacAddress": "22:xx:yy:11", 1517 "ManagementType": 2, 1518 "InstrumentationName": "MX-Constants.service_tag1", 1519 "DnsName": "M-YYYY.abcd.lab", 1520 "ManagementProfile": [ 1521 { 1522 "ManagementProfileId": 33333, 1523 "ProfileId": "MSM_BASE", 1524 "ManagementId": 33333, 1525 "ManagementURL": "https://[1234:abcd:567:xyzs]:443", 1526 "HasCreds": 0, 1527 "Status": 1000, 1528 "StatusDateTime": "2020-07-11 17:00:18.925" 1529 } 1530 ] 1531 } 1532 ], 1533 "Actions": None 1534 }, 1535 { 1536 "@odata.type": "#DeviceService.Device", 1537 "@odata.id": "/api/DeviceService/Devices(Constants.device_id1)", 1538 "Id": Constants.device_id1, 1539 "Type": 2000, 1540 "Identifier": Constants.service_tag2, 1541 "DeviceServiceTag": Constants.service_tag2, 1542 "ChassisServiceTag": None, 1543 "Model": "PowerEdge MX7000", 1544 "PowerState": 17, 1545 "ManagedState": 3000, 1546 "Status": 4000, 1547 "ConnectionState": True, 1548 "AssetTag": None, 1549 "SystemId": 2031, 1550 "DeviceName": "MX-Constants.service_tag2", 1551 "LastInventoryTime": "2020-07-11 17:00:18.925", 1552 "LastStatusTime": "2020-07-11 09:00:07.444", 1553 "DeviceSubscription": None, 1554 "DeviceCapabilities": [ 1555 18, 1556 8, 1557 201, 1558 202 1559 ], 1560 "SlotConfiguration": { 1561 "ChassisName": None 1562 }, 1563 "DeviceManagement": [ 1564 { 1565 "ManagementId": 111111, 1566 "NetworkAddress": ome_default_args["hostname"], 1567 "MacAddress": "xx:yy:zz:x1x1", 1568 "ManagementType": 2, 1569 "InstrumentationName": "MX-Constants.service_tag2", 1570 "DnsName": "M-XXXX.abcd.lab", 1571 "ManagementProfile": [ 1572 { 1573 "ManagementProfileId": 111111, 1574 "ProfileId": "MSM_BASE", 1575 "ManagementId": 111111, 1576 "ManagementURL": "https://" + ome_default_args["hostname"] + ":443", 1577 "HasCreds": 0, 1578 "Status": 1000, 1579 "StatusDateTime": "2020-07-11 17:00:18.925" 1580 } 1581 ] 1582 }, 1583 { 1584 "ManagementId": 22222, 1585 "NetworkAddress": "[1234.abcd:5678:345]", 1586 "MacAddress": "22:xx:yy:11", 1587 "ManagementType": 2, 1588 "InstrumentationName": "MX-Constants.service_tag2", 1589 "DnsName": "M-XXXX.abcd.lab", 1590 "ManagementProfile": [{ 1591 "ManagementProfileId": 22222, 1592 "ProfileId": "MSM_BASE", 1593 "ManagementId": 22222, 1594 "ManagementURL": "https://[1234:abcd:567:xyzs]:443", 1595 "HasCreds": 0, 1596 "Status": 1000, 1597 "StatusDateTime": "2020-07-11 17:00:18.925" 1598 }] 1599 } 1600 ], 1601 "Actions": None 1602 } 1603 ] 1604 } 1605 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1606 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 1607 service_tag = self.module.get_service_tag_with_fqdn(ome_connection_mock_for_smart_fabric, f_module) 1608 assert service_tag == Constants.service_tag1 1609 1610 def test_get_service_tag_with_fqdn_success_case2(self, ome_default_args, ome_connection_mock_for_smart_fabric): 1611 ome_default_args.update({"hostname": Constants.hostname1}) 1612 resp_data = { 1613 "@odata.context": "/api/$metadata#Collection(DeviceService.Device)", 1614 "@odata.count": 2, 1615 "value": [ 1616 { 1617 "@odata.type": "#DeviceService.Device", 1618 "@odata.id": "/api/DeviceService/Devices(Constants.device_id1)", 1619 "Id": Constants.device_id1, 1620 "Type": 2000, 1621 "Identifier": Constants.service_tag1, 1622 "DeviceServiceTag": Constants.service_tag1, 1623 "ChassisServiceTag": None, 1624 "Model": "PowerEdge MX7000", 1625 "PowerState": 17, 1626 "ManagedState": 3000, 1627 "Status": 4000, 1628 "ConnectionState": True, 1629 "AssetTag": None, 1630 "SystemId": 2031, 1631 "DeviceName": "MX-Constants.service_tag1", 1632 "LastInventoryTime": "2020-07-11 17:00:18.925", 1633 "LastStatusTime": "2020-07-11 09:00:07.444", 1634 "DeviceSubscription": None, 1635 "DeviceCapabilities": [ 1636 18, 1637 8, 1638 201, 1639 202 1640 ], 1641 "SlotConfiguration": { 1642 "ChassisName": None 1643 }, 1644 "DeviceManagement": [ 1645 { 1646 "ManagementId": 111111, 1647 "NetworkAddress": "192.168.1.1", 1648 "MacAddress": "xx:yy:zz:x1x1", 1649 "ManagementType": 2, 1650 "InstrumentationName": "MX-Constants.service_tag1", 1651 "DnsName": "M-YYYY.abcd.lab", 1652 "ManagementProfile": [ 1653 { 1654 "ManagementProfileId": 111111, 1655 "ProfileId": "MSM_BASE", 1656 "ManagementId": 111111, 1657 "ManagementURL": "https://" + ome_default_args["hostname"] + ":443", 1658 "HasCreds": 0, 1659 "Status": 1000, 1660 "StatusDateTime": "2020-07-11 17:00:18.925" 1661 } 1662 ] 1663 }, 1664 { 1665 "ManagementId": 33333, 1666 "NetworkAddress": "[1234.abcd:5678:345]", 1667 "MacAddress": "22:xx:yy:11", 1668 "ManagementType": 2, 1669 "InstrumentationName": "MX-Constants.service_tag1", 1670 "DnsName": "M-YYYY.abcd.lab", 1671 "ManagementProfile": [ 1672 { 1673 "ManagementProfileId": 33333, 1674 "ProfileId": "MSM_BASE", 1675 "ManagementId": 33333, 1676 "ManagementURL": "https://[1234:abcd:567:xyzs]:443", 1677 "HasCreds": 0, 1678 "Status": 1000, 1679 "StatusDateTime": "2020-07-11 17:00:18.925" 1680 } 1681 ] 1682 } 1683 ], 1684 "Actions": None 1685 }, 1686 { 1687 "@odata.type": "#DeviceService.Device", 1688 "@odata.id": "/api/DeviceService/Devices(Constants.device_id1)", 1689 "Id": Constants.device_id1, 1690 "Type": 2000, 1691 "Identifier": Constants.service_tag2, 1692 "DeviceServiceTag": Constants.service_tag2, 1693 "ChassisServiceTag": None, 1694 "Model": "PowerEdge MX7000", 1695 "PowerState": 17, 1696 "ManagedState": 3000, 1697 "Status": 4000, 1698 "ConnectionState": True, 1699 "AssetTag": None, 1700 "SystemId": 2031, 1701 "DeviceName": "MX-Constants.service_tag2", 1702 "LastInventoryTime": "2020-07-11 17:00:18.925", 1703 "LastStatusTime": "2020-07-11 09:00:07.444", 1704 "DeviceSubscription": None, 1705 "DeviceCapabilities": [ 1706 18, 1707 8, 1708 201, 1709 202 1710 ], 1711 "SlotConfiguration": { 1712 "ChassisName": None 1713 }, 1714 "DeviceManagement": [ 1715 { 1716 "ManagementId": 111111, 1717 "NetworkAddress": "192.168.1.2", 1718 "MacAddress": "xx:yy:zz:x1x1", 1719 "ManagementType": 2, 1720 "InstrumentationName": "MX-Constants.service_tag2", 1721 "DnsName": "M-XXXX.abcd.lab", 1722 "ManagementProfile": [ 1723 { 1724 "ManagementProfileId": 111111, 1725 "ProfileId": "MSM_BASE", 1726 "ManagementId": 111111, 1727 "ManagementURL": "https://" + ome_default_args["hostname"] + ":443", 1728 "HasCreds": 0, 1729 "Status": 1000, 1730 "StatusDateTime": "2020-07-11 17:00:18.925" 1731 } 1732 ] 1733 }, 1734 { 1735 "ManagementId": 22222, 1736 "NetworkAddress": "[1234.abcd:5678:345]", 1737 "MacAddress": "22:xx:yy:11", 1738 "ManagementType": 2, 1739 "InstrumentationName": "MX-Constants.service_tag2", 1740 "DnsName": "M-XXXX.abcd.lab", 1741 "ManagementProfile": [ 1742 { 1743 "ManagementProfileId": 22222, 1744 "ProfileId": "MSM_BASE", 1745 "ManagementId": 22222, 1746 "ManagementURL": "https://[1234:abcd:567:xyzs]:443", 1747 "HasCreds": 0, 1748 "Status": 1000, 1749 "StatusDateTime": "2020-07-11 17:00:18.925" 1750 } 1751 ] 1752 } 1753 ], 1754 "Actions": None 1755 } 1756 ] 1757 } 1758 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1759 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 1760 service_tag = self.module.get_service_tag_with_fqdn(ome_connection_mock_for_smart_fabric, f_module) 1761 assert service_tag is None 1762 1763 def test_get_service_tag_with_fqdn_success_case3(self, ome_default_args, ome_connection_mock_for_smart_fabric): 1764 ome_default_args.update({"hostname": Constants.hostname1}) 1765 resp_data = {"value": []} 1766 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1767 ome_connection_mock_for_smart_fabric.get_all_items_with_pagination.return_value = resp_data 1768 service_tag = self.module.get_service_tag_with_fqdn(ome_connection_mock_for_smart_fabric, f_module) 1769 assert service_tag is None 1770 1771 def test_fabric_validate_modify_case01(self, ome_default_args): 1772 ome_default_args.update({"fabric_design": "2xMX5108n_Ethernet_Switches_in_same_chassis"}) 1773 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1774 current_payload = { 1775 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 1776 "Name": "Fabric_", 1777 "Description": "create new fabric1", 1778 "FabricDesignMapping": [ 1779 { 1780 "DesignNode": "Switch-A", 1781 "PhysicalNode": "2HB7NX2" 1782 }, 1783 { 1784 "DesignNode": "Switch-B", 1785 "PhysicalNode": "2HBFNX2" 1786 } 1787 ], 1788 "FabricDesign": {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 1789 } 1790 self.module.validate_modify(f_module, current_payload) 1791 1792 def test_fabric_validate_modify_case02(self, ome_default_args): 1793 ome_default_args.update({"name": "abc"}) 1794 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1795 current_payload = { 1796 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 1797 "Name": "Fabric_", 1798 "Description": "create new fabric1", 1799 "FabricDesignMapping": [ 1800 { 1801 "DesignNode": "Switch-A", 1802 "PhysicalNode": "2HB7NX2" 1803 }, 1804 { 1805 "DesignNode": "Switch-B", 1806 "PhysicalNode": "2HBFNX2" 1807 } 1808 ], 1809 "FabricDesign": {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 1810 } 1811 self.module.validate_modify(f_module, current_payload) 1812 1813 def test_fabric_validate_modify_case03(self, ome_default_args): 1814 ome_default_args.update({"fabric_design": "2xMX5108n_Ethernet_Switches_in_same_chassis"}) 1815 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1816 current_payload = { 1817 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 1818 "Name": "Fabric_", 1819 "Description": "create new fabric1", 1820 "FabricDesign": {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"}, 1821 "FabricDesignMapping": [ 1822 { 1823 "DesignNode": "Switch-A", 1824 "PhysicalNode": "2HB7NX2" 1825 }, 1826 { 1827 "DesignNode": "Switch-B", 1828 "PhysicalNode": "2HBFNX2" 1829 } 1830 ], 1831 } 1832 self.module.validate_modify(f_module, current_payload) 1833 1834 def test_fabric_validate_modify_case05(self, ome_default_args): 1835 ome_default_args.update({"primary_switch_service_tag": "abc"}) 1836 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1837 current_payload = { 1838 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 1839 "Name": "Fabric_", 1840 "Description": "create new fabric1", 1841 "FabricDesignMapping": [ 1842 { 1843 "DesignNode": "Switch-B", 1844 "PhysicalNode": "2HBFNX2" 1845 } 1846 ], 1847 "FabricDesign": {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 1848 } 1849 self.module.validate_modify(f_module, current_payload) 1850 1851 def test_fabric_validate_modify_case07(self, ome_default_args): 1852 ome_default_args.update({"name": "abc"}) 1853 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1854 current_payload = { 1855 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 1856 "Name": "Fabric_", 1857 "Description": "create new fabric1", 1858 "FabricDesignMapping": [ 1859 { 1860 "DesignNode": "Switch-B", 1861 "PhysicalNode": "2HBFNX2" 1862 } 1863 ], 1864 "FabricDesign": {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 1865 } 1866 self.module.validate_modify(f_module, current_payload) 1867 1868 @pytest.mark.parametrize("param", [{"secondary_switch_service_tag": "abc"}, {"primary_switch_service_tag": "abc"}]) 1869 def test_fabric_validate_modify_case08(self, param, ome_default_args): 1870 ome_default_args.update(param) 1871 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1872 current_payload = { 1873 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 1874 "Name": "Fabric_", 1875 "Description": "create new fabric1", 1876 "FabricDesignMapping": [ 1877 ], 1878 "FabricDesign": {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 1879 } 1880 self.module.validate_modify(f_module, current_payload) 1881 1882 @pytest.mark.parametrize("param", [{"secondary_switch_service_tag": "abc"}, {"primary_switch_service_tag": "abc"}]) 1883 def test_fabric_validate_modify_case09(self, param, ome_default_args): 1884 ome_default_args.update(param) 1885 f_module = self.get_module_mock(params=ome_default_args, check_mode=True) 1886 current_payload = { 1887 "Id": "1312cceb-c3dd-4348-95c1-d8541a17d776", 1888 "Name": "Fabric_", 1889 "Description": "create new fabric1", 1890 "FabricDesign": {"Name": "2xMX5108n_Ethernet_Switches_in_same_chassis"} 1891 } 1892 self.module.validate_modify(f_module, current_payload) 1893