def test_serialize(self): # Tests the serialize function result against known result try: computer_system = ComputerSystem(self.server_hardware, self.server_hardware_types) except Exception as e: self.fail("Failed to instantiate ComputerSystem class." " Error: {}".format(e)) try: result = json.loads(computer_system.serialize()) except Exception as e: self.fail("Failed to serialize. Error: ".format(e)) self.assertEqual(self.computer_system_mockup, result)
def test_failing_class_instantiation(self): # Tests if validation fail # The name must be a string self.server_hardware["name"] = 1 with self.assertRaises(ValidationError): ComputerSystem(self.server_hardware, self.server_hardware_types)
def test_build_composed_system(self): spt_uuid = "61c3a463-1355-4c68-a4e3-4f08c322af1b" computer_system = ComputerSystem.build_composed_system( self.server_hardware, self.server_hardware_types, self.server_profile, [self.drives[4]], spt_uuid, self.manager_uuid) result = json.loads(computer_system.serialize()) self.assertEqualMockup(self.computer_system_mockup, result)
def test_build_physical_system(self): with open('oneview_redfish_toolkit/mockups/redfish' '/ComputerSystemPhysicalType.json') as f: computer_system_mockup = json.load(f) computer_system = ComputerSystem.build_physical_system( self.server_hardware, self.manager_uuid) result = json.loads(computer_system.serialize()) self.assertEqualMockup(computer_system_mockup, result)
def test_get_oneview_power_configuration(self): # Tests invalid mapping values of power state # obj = ComputerSystem(self.server_hardware, self.server_hardware_types) self.assertRaises(OneViewRedfishError, obj.get_oneview_power_configuration, "ForceOn") self.assertRaises(OneViewRedfishError, obj.get_oneview_power_configuration, "INVALID")
def test_class_instantiation(self): # Tests if class is correctly instantiated and validated try: computer_system = ComputerSystem(self.server_hardware, self.server_hardware_types) except Exception as e: self.fail("Failed to instantiate ComputerSystem class." " Error: {}".format(e)) self.assertIsInstance(computer_system, ComputerSystem)
def get_computer_system(uuid): """Get the Redfish Computer System for a given UUID. Return ComputerSystem redfish JSON for a given server profile or server profile template UUID. Returns: JSON: Redfish json with ComputerSystem When Server hardware or Server profilte templates is not found calls abort(404) """ resource = _get_oneview_resource(uuid) category = resource["category"] if category == 'server-profile-templates': computer_system_resource = CapabilitiesObject(resource) elif category == 'server-profiles': server_hardware = g.oneview_client.server_hardware\ .get_by_uri(resource["serverHardwareUri"]).data server_hardware_type = g.oneview_client.server_hardware_types\ .get_by_uri(resource['serverHardwareTypeUri']).data computer_system_service = ComputerSystemService(g.oneview_client) drives = _get_drives_from_sp(resource) spt_uuid = computer_system_service.\ get_server_profile_template_from_sp(resource["uri"]) # Get external storage volumes from server profile volumes_uris = [ volume["volumeUri"] for volume in resource["sanStorage"]["volumeAttachments"] ] # Emptying volume list to suppress external storage changes for # current release. # In future, remove this line to enable external storage support volumes_uris = [] manager_uuid = get_manager_uuid(resource['serverHardwareTypeUri']) # Build Computer System object and validates it computer_system_resource = ComputerSystem.build_composed_system( server_hardware, server_hardware_type, resource, drives, spt_uuid, manager_uuid, volumes_uris) else: abort(status.HTTP_404_NOT_FOUND, 'Computer System UUID {} not found'.format(uuid)) return ResponseBuilder.success(computer_system_resource, {"ETag": "W/" + resource["eTag"]})
def get_computer_system(uuid): """Get the Redfish Computer System for a given UUID. Return ComputerSystem redfish JSON for a given server profile or server profile template UUID. Returns: JSON: Redfish json with ComputerSystem When Server hardware or Server profilte templates is not found calls abort(404) """ resource = _get_oneview_resource(uuid) category = resource["category"] if category == 'server-profile-templates': computer_system_resource = CapabilitiesObject(resource) elif category == 'server-profiles': server_hardware = g.oneview_client.server_hardware\ .get(resource["serverHardwareUri"]) server_hardware_type = g.oneview_client.server_hardware_types\ .get(resource['serverHardwareTypeUri']) computer_system_service = ComputerSystemService(g.oneview_client) drives = _get_drives_from_sp(resource) spt_uuid = computer_system_service.\ get_server_profile_template_from_sp(resource["uri"]) manager_uuid = get_manager_uuid(resource['serverHardwareTypeUri']) # Build Computer System object and validates it computer_system_resource = ComputerSystem.build_composed_system( server_hardware, server_hardware_type, resource, drives, spt_uuid, manager_uuid) else: abort(status.HTTP_404_NOT_FOUND, 'Computer System UUID {} not found'.format(uuid)) return ResponseBuilder.success( computer_system_resource, {"ETag": "W/" + resource["eTag"]})
def test_build_composed_system_with_external_storage(self): volume_resource_block = { "@odata.id": "/redfish/v1/CompositionService/ResourceBlocks/" "volume_uuid" } computer_system_mockup = deepcopy(self.computer_system_mockup) computer_system_mockup["Links"]["ResourceBlocks"].append( volume_resource_block) spt_uuid = "61c3a463-1355-4c68-a4e3-4f08c322af1b" volume_uri = ["/rest/storage-volumes/volume_uuid"] computer_system = ComputerSystem.build_composed_system( self.server_hardware, self.server_hardware_types, self.server_profile, [self.drives[4]], spt_uuid, self.manager_uuid, volume_uri) result = json.loads(computer_system.serialize()) self.assertEqualMockup(computer_system_mockup, result)
def get_resource_block_computer_system(uuid): """Get Computer System of a Resource Block Return ResourceBlock Computer System redfish JSON for a given UUID. Logs exception of any error and return Internal Server Error or Not Found. Returns: JSON: Redfish json with ResourceBlock Computer System. """ server_hardware = g.oneview_client.server_hardware.get_by_id(uuid).data manager_uuid = get_manager_uuid(uuid) computer_system = ComputerSystem.build_physical_system( server_hardware, manager_uuid) return ResponseBuilder.success(computer_system, {"ETag": "W/" + server_hardware["eTag"]})
def test_build_server_profile(self): with open('oneview_redfish_toolkit/mockups/oneview' '/ServerProfileTemplates.json') as f: spt = json.load(f) san_storage = { "hostOSType": "VMware (ESXi)", "manageSanStorage": True, "volumeAttachments": [{ "lunType": "Auto", "volumeUri": "/rest/storage-volumes/" + "B526F59E-9BC7-467F-9205-A9F4015CE296", "volumeStorageSystemUri": "/rest/storage-systems/" "TXQ1000307", "storagePaths": [{ "targetSelector": "Auto", "isEnabled": True, "connectionId": 2, "targets": [] }] }] } spt[0]["sanStorage"] = san_storage system_block = {"uuid": "FE50A6FE-B1AC-4E42-8D40-B73CA8CC0CD2"} computer_system = ComputerSystem.build_server_profile( "Composed System Using Redfish", "", spt[0], system_block, [], [], []) with open('oneview_redfish_toolkit/mockups/oneview/' 'ServerProfileBuiltFromTemplateToCreateASystem.json') as f: expected_server_profile_built = json.load(f) self.assertEqual(computer_system["name"], expected_server_profile_built["name"])
def create_composed_system(): if not request.is_json: abort(status.HTTP_400_BAD_REQUEST, "The request content should be a valid JSON") body = request.get_json() result_location_uri = None try: RedfishJsonValidator.validate(body, 'ComputerSystem') service = ComputerSystemService(g.oneview_client) blocks = body["Links"]["ResourceBlocks"] block_ids = [block["@odata.id"].split("/")[-1] for block in blocks] # Should contain only one computer system entry system_blocks = _get_system_resource_blocks(block_ids) if not system_blocks: raise ValidationError( "Should have a Computer System Resource Block") system_block = system_blocks[0] service.validate_computer_system_resource_block_to_composition( system_block) # Check network block id with the Id attribute in the request network_blocks = _get_network_resource_blocks(block_ids) spt_id = body["Id"] if not (network_blocks and spt_id in network_blocks[0]["uri"]): raise ValidationError( "Should have a valid Network Resource Block") # It can contain zero or more Storage Block storage_blocks = _get_storage_resource_blocks(block_ids) spt = g.oneview_client.server_profile_templates.get(spt_id) server_profile = ComputerSystem.build_server_profile( body["Name"], body.get("Description"), spt, system_block, network_blocks, storage_blocks) service.power_off_server_hardware(system_block["uuid"], on_compose=True) task, resource_uri = service.create_composed_system(server_profile) if resource_uri: result_uuid = resource_uri.split("/")[-1] result_location_uri = ComputerSystem.BASE_URI + "/" + result_uuid server_profile_label = dict( resourceUri=resource_uri, labels=[spt_id.replace("-", " ")]) g.oneview_client.labels.create(server_profile_label) elif task.get("taskErrors"): err_msg = reduce( lambda result, msg: result + msg["message"] + "\n", task["taskErrors"], "") abort(status.HTTP_403_FORBIDDEN, err_msg) except ValidationError as e: abort(status.HTTP_400_BAD_REQUEST, e.message) except KeyError as e: abort(status.HTTP_400_BAD_REQUEST, "Trying access an invalid key {}".format(e.args)) except HPOneViewTaskError as e: abort(status.HTTP_403_FORBIDDEN, e.msg) if not result_location_uri: logging.error("It was not possible get the server profile URI when " "creating a composed system") abort(status.HTTP_500_INTERNAL_SERVER_ERROR) return Response(status=status.HTTP_201_CREATED, headers={"Location": result_location_uri}, mimetype="application/json")
def get_computer_system(uuid): """Get the Redfish Computer System for a given UUID. Return ComputerSystem redfish JSON for a given server hardware UUID. Logs exception of any error and return abort(500) Internal Server Error. Returns: JSON: Redfish json with ComputerSystem When Server hardware is not found calls abort(404) Exceptions: Logs the exception and call abort(500) """ try: # Gets server hardware for given UUID server_hardware = g.oneview_client.server_hardware.get(uuid) # Gets the server hardware type of the given server hardware server_hardware_types = g.oneview_client.server_hardware_types.get( server_hardware['serverHardwareTypeUri']) # Build Computer System object and validates it cs = ComputerSystem(server_hardware, server_hardware_types) # Build redfish json json_str = cs.serialize() # Build response and returns response = Response(response=json_str, status=status.HTTP_200_OK, mimetype="application/json") response.headers.add("ETag", "W/" + server_hardware['eTag']) return response except HPOneViewException as e: if e.oneview_response['errorCode'] == "RESOURCE_NOT_FOUND": if e.msg.find("server-hardware-types") >= 0: logging.warning('ServerHardwareTypes ID {} not found'.format( server_hardware['serverHardwareTypeUri'])) abort(status.HTTP_404_NOT_FOUND, "Server hardware types not found") else: logging.warning( 'Server hardware UUID {} not found'.format(uuid)) abort(status.HTTP_404_NOT_FOUND, "Server hardware not found") elif e.msg.find("server-hardware-types") >= 0: logging.exception( 'OneView Exception while looking for server hardware type' ' {}'.format(e)) abort(status.HTTP_500_INTERNAL_SERVER_ERROR) elif e.msg.find("server-hardware") >= 0: logging.exception('OneView Exception while looking for ' 'server hardware: {}'.format(e)) abort(status.HTTP_500_INTERNAL_SERVER_ERROR) else: logging.exception('Unexpected OneView Exception: {}'.format(e)) abort(status.HTTP_500_INTERNAL_SERVER_ERROR) except Exception as e: # In case of error print exception and abort logging.exception('Unexpected error: {}'.format(e)) return abort(status.HTTP_500_INTERNAL_SERVER_ERROR)
def change_power_state(uuid): """Change the Oneview power state for a specific Server hardware. Return ResetType Computer System redfish JSON for a given server hardware UUID. Logs exception of any error and return abort. Returns: JSON: Redfish JSON with ComputerSystem ResetType. Exceptions: HPOneViewException: When some OneView resource was not found. return abort(404) OneViewRedfishError: When occur a power state mapping error. return abort(400) Exception: Unexpected error. return abort(500) """ try: try: reset_type = request.get_json()["ResetType"] except Exception: raise OneViewRedfishError({ "errorCode": "INVALID_INFORMATION", "message": "Invalid JSON key" }) # Gets ServerHardware for given UUID sh = g.oneview_client.server_hardware.get(uuid) # Gets the ServerHardwareType of the given server hardware sht = g.oneview_client.server_hardware_types. \ get(sh['serverHardwareTypeUri']) # Build Computer System object and validates it cs = ComputerSystem(sh, sht) oneview_power_configuration = \ cs.get_oneview_power_configuration(reset_type) # Changes the ServerHardware power state g.oneview_client.server_hardware.update_power_state( oneview_power_configuration, uuid) return Response(response='{"ResetType": "%s"}' % reset_type, status=status.HTTP_200_OK, mimetype='application/json') except HPOneViewException as e: # In case of error log exception and abort logging.exception(e) if e.oneview_response['errorCode'] == "RESOURCE_NOT_FOUND": abort(status.HTTP_404_NOT_FOUND, "Server hardware not found") else: abort(status.HTTP_500_INTERNAL_SERVER_ERROR) except OneViewRedfishError as e: # In case of error log exception and abort logging.exception('Mapping error: {}'.format(e)) if e.msg["errorCode"] == "NOT_IMPLEMENTED": abort(status.HTTP_501_NOT_IMPLEMENTED, e.msg['message']) else: abort(status.HTTP_400_BAD_REQUEST, e.msg['message']) except Exception as e: # In case of error log exception and abort logging.exception('Unexpected error: {}'.format(e)) abort(status.HTTP_500_INTERNAL_SERVER_ERROR)