def load_event_service_info(): """Loads Event Service information Loads DeliveryRetryAttempts and DeliveryRetryIntervalSeconds from CONFIG file and store it in a global var. Exceptions: OneViewRedfishError: DeliveryRetryAttempts and DeliveryRetryIntervalSeconds must be integers greater than zero. """ config = globals()['config'] event_service = dict(config.items("event_service")) try: delivery_retry_attempts = \ int(event_service["DeliveryRetryAttempts"]) delivery_retry_interval = \ int(event_service["DeliveryRetryIntervalSeconds"]) if delivery_retry_attempts <= 0 or delivery_retry_interval <= 0: raise OneViewRedfishError( "DeliveryRetryAttempts and DeliveryRetryIntervalSeconds must" " be an integer greater than zero.") except ValueError: raise OneViewRedfishError( "DeliveryRetryAttempts and DeliveryRetryIntervalSeconds " "must be valid integers.") globals()['delivery_retry_attempts'] = delivery_retry_attempts globals()['delivery_retry_interval'] = delivery_retry_interval
def load_config(conf_file): """Loads redfish.conf file Loads and parsers the system conf file into config global var Loads json schemas into schemas_dict global var Established a connection with OneView and sets in as ov_conn global var Args: conf_file: string with the conf file name Returns: None Exception: OneViewRedfishResourceNotFoundError: - if conf file not found - if any of the schemas files are not found - if the schema directory is not found OneViewRedFishResourceNotAccessibleError: - if can't access schema's directory HPOneViewException: - if fails to connect to oneview """ config = load_conf(conf_file) globals()['config'] = config # Config file read set global vars # Setting ov_config ov_config = dict(config.items('oneview_config')) ov_config['credentials'] = dict(config.items('credentials')) ov_config['api_version'] = int(ov_config['api_version']) globals()['ov_config'] = ov_config # Setting schemas_dict schemas = dict(config.items('schemas')) globals()['schemas'] = schemas registries = dict(config.items('registry')) load_event_service_info() # Load schemas | Store schemas | Connect to OneView try: ov_client = OneViewClient(ov_config) globals()['ov_client'] = ov_client registry_dict = load_registry(config['redfish']['registry_dir'], registries) globals()['registry_dict'] = registry_dict store_schemas(config['redfish']['schema_dir']) except OneViewRedfishResourceNotFoundError as e: raise OneViewRedfishError( 'Failed to load schemas or registries: {}'.format(e)) except Exception as e: raise OneViewRedfishError('Failed to connect to OneView: {}'.format(e))
def __init__(self, device_id, device_function_id, server_hardware): """NetworkDeviceFunction constructor Populates self.redfish with the contents of server hardware dict from Oneview Args: device_id: ID of the NetworkAdapter device_function_id: ID of the DeviceFunction. Expected format: portNumber_virtualPortNumber_virtualPortFunction server_hardware: Oneview's server hardware dict """ super().__init__(self.SCHEMA_NAME) # device_function_id validation try: port_number, virtual_port_number, virtual_port_function = \ device_function_id.split("_") physical_ports = self.get_resource_by_id( server_hardware["portMap"]["deviceSlots"], "deviceNumber", device_id)["physicalPorts"] port = self.get_resource_by_id(physical_ports, "portNumber", port_number) virtual_port = self.get_resource_by_id(port["virtualPorts"], "portNumber", virtual_port_number) except Exception: raise OneViewRedfishResourceNotFoundError(device_function_id, "NetworkDeviceFunction") self.redfish["@odata.type"] = \ "#NetworkDeviceFunction.v1_1_0.NetworkDeviceFunction" self.redfish["Id"] = device_function_id self.redfish["Name"] = "Physical port {}, virtual port {}, device "\ "function {}".format( port_number, virtual_port_number, virtual_port_function) if port["type"] == "Ethernet": self.redfish["Ethernet"] = dict() self.redfish["Ethernet"]["MACAddress"] = virtual_port["mac"] self.redfish["NetDevFuncType"] = "Ethernet" elif port["type"] == "FibreChannel": raise OneViewRedfishError("FibreChannel not implemented") else: raise OneViewRedfishError("Type not supported") self.redfish["@odata.context"] = \ "/redfish/v1/$metadata#NetworkDeviceFunction.NetworkDeviceFunction" self.redfish["@odata.id"] = "/redfish/v1/Chassis/" + \ server_hardware["uuid"] + \ "/NetworkAdapters/" + device_id + \ "/NetworkDeviceFunctions/" + device_function_id self._validate()
def get_chassis(uuid): """Get the Redfish Chassis. Get method to return Chassis JSON when /redfish/v1/Chassis/id is requested. Returns: JSON: JSON with Chassis. """ try: resource_index = g.oneview_client.index_resources.get_all( filter='uuid=' + uuid) if resource_index: category = resource_index[0]["category"] else: raise OneViewRedfishError('Cannot find Index resource') if category == 'server-hardware': server_hardware = g.oneview_client.server_hardware.get(uuid) etag = server_hardware['eTag'] ch = BladeChassis(server_hardware) elif category == 'enclosures': enclosure = g.oneview_client.enclosures.get(uuid) etag = enclosure['eTag'] enclosure_environment_config = g.oneview_client.enclosures.\ get_environmental_configuration(uuid) ch = EnclosureChassis(enclosure, enclosure_environment_config) elif category == 'racks': racks = g.oneview_client.racks.get(uuid) etag = racks['eTag'] ch = RackChassis(racks) else: raise OneViewRedfishError('Chassis type not found') json_str = ch.serialize() response = Response(response=json_str, status=status.HTTP_200_OK, mimetype="application/json") response.headers.add("ETag", "W/" + etag) return response except HPOneViewException as e: # In case of error log exception and abort logging.exception(e) abort(status.HTTP_404_NOT_FOUND) except OneViewRedfishError as e: # In case of error log exception and abort logging.exception('Unexpected error: {}'.format(e)) abort(status.HTTP_404_NOT_FOUND, "Chassis not found") 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)
def get_managers(uuid): """Get the Redfish Managers. Get method to return Managers JSON when /redfish/v1/Managers/id is requested. Returns: JSON: JSON with Managers info for Enclosure or ServerHardware. """ try: appliance_information = \ g.oneview_client.appliance_node_information.get_version() oneview_version = appliance_information['softwareVersion'] resource_index = g.oneview_client.index_resources.get_all( filter='uuid=' + uuid) if resource_index: category = resource_index[0]["category"] else: raise OneViewRedfishError('Cannot find Index resource') if category == 'server-hardware': server_hardware = g.oneview_client.server_hardware.get(uuid) etag = server_hardware['eTag'] manager = BladeManager(server_hardware) elif category == 'enclosures': enclosure = g.oneview_client.enclosures.get(uuid) etag = enclosure['eTag'] manager = EnclosureManager(enclosure, oneview_version) else: raise OneViewRedfishError('Enclosure type not found') json_str = manager.serialize() response = Response(response=json_str, status=status.HTTP_200_OK, mimetype="application/json") response.headers.add("ETag", "W/" + etag) return response except HPOneViewException as e: # In case of error log exception and abort logging.exception(e) abort(status.HTTP_404_NOT_FOUND, "Manager not found") except OneViewRedfishError as e: # In case of error log exception and abort logging.exception('Unexpected error: {}'.format(e)) abort(status.HTTP_404_NOT_FOUND, e.msg) 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)
def execute_test_event_action(): """Executes the SubmitTestEvent Action Return a JSON containing the EventType received. Logs exception of any error and return abort. Returns: JSON: JSON containing the EventType. Exceptions: OneViewRedfishError: When an invalid JSON is received. return abort(400) Exception: Unexpected error. return abort(500) """ try: try: event_type = request.get_json()['EventType'] except Exception: raise OneViewRedfishError( {'message': 'Invalid JSON data. Missing EventType property.'}) if (event_type not in util.subscriptions_by_type.keys()): raise OneViewRedfishError( {'message': 'Invalid EventType value: %s' % event_type}) # Creates a sample OneView SCMB message according to # the value of 'event_type' if (event_type == "Alert"): message = deepcopy(ONEVIEW_TEST_ALERT) else: message = deepcopy(ONEVIEW_TEST_TASK) message['changeType'] = REDFISH_TO_ONEVIEW_EVENTS[event_type] event = Event(message) util.dispatch_event(event) json_str = event.serialize() return Response(response=json_str, status=status.HTTP_202_ACCEPTED, mimetype='application/json') except OneViewRedfishError as e: logging.exception('Mapping error: {}'.format(e)) abort(status.HTTP_400_BAD_REQUEST, e.msg['message']) except Exception as e: logging.exception('Unexpected error: {}'.format(e)) abort(status.HTTP_500_INTERNAL_SERVER_ERROR)
def _validate(self): """Validates self.redfish against self.schema_obj Validates a redfish OrderedDict against the schema object passed on the object creation. Returns: None Exception: ValidationError: Raises this exception on validation failure. OneViewRedfishError: Raises this exception if schema is not found. """ schema_version = util.schemas[self.schema_name] stored_schemas = util.stored_schemas try: schema_obj = stored_schemas["http://redfish.dmtf.org/schemas/v1/" + schema_version] except KeyError: raise OneViewRedfishError("{} not found".format(schema_version)) resolver = jsonschema.RefResolver('', schema_obj, store=stored_schemas) jsonschema.validate(self.redfish, schema_obj, resolver=resolver)
def get_resource_by_id(self, resource_list, resource_number_key, resource_id): """Gets a specific resource in the resource list Validates the resource ID and gets the resource in the resource list. Args: resource_list: List of resources. resource_number_key: Field name of the resource number in the JSON. resource_id: Resource's ID that will be searched in the resource list. Returns: Resource in the list. Exception: OneViewRedfishError: If the ID is not an integer. OneViewRedfishResourceNotFoundError: If the resource was not found. """ try: resource_id = int(resource_id) except ValueError: raise OneViewRedfishError("Invalid {} ID".format( self.__class__.__name__)) for resource in resource_list: if resource[resource_number_key] == resource_id: return resource raise OneViewRedfishResourceNotFoundError("Object", self.__class__.__name__)
def get_resource_block_computer_system(uuid, serial): """Get Computer System of a Resource Block Return ResourceBlock Computer System redfish JSON for a given UUID and serial number. Logs exception of any error and return Internal Server Error or Not Found. Returns: JSON: Redfish json with ResourceBlock Computer System. """ try: server_hardware = g.oneview_client.server_hardware.get(uuid) if server_hardware["serialNumber"] != serial: raise OneViewRedfishError( "Computer system of resource block {} not found".format(uuid)) computer_system = ResourceBlockComputerSystem(server_hardware) return ResponseBuilder.success( computer_system, {"ETag": "W/" + server_hardware["eTag"]}) except OneViewRedfishError as e: # In case of error log exception and abort logging.exception('Unexpected error: {}'.format(e)) abort(status.HTTP_404_NOT_FOUND, e.msg)
def get_resource_block(uuid): """Get the Redfish ResourceBlock for a given UUID. Return ResourceBlock 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. """ try: resource = _get_oneview_resource(uuid) category = resource["category"] if category == "server-hardware": resource_block = _build_computer_system_resource_block( uuid, resource) elif category == "server-profile-templates": resource_block = \ ServerProfileTemplateResourceBlock(uuid, resource) elif category == "drives": resource_block = StorageResourceBlock(resource) else: raise OneViewRedfishError('Resource block not found') return ResponseBuilder.success(resource_block, {"ETag": "W/" + resource["eTag"]}) except OneViewRedfishError as e: # In case of error log exception and abort logging.exception('Unexpected error: {}'.format(e)) abort(status.HTTP_404_NOT_FOUND, e.msg)
def _get_oneview_resource(uuid): drives_param = "/rest/drives/" + uuid categories = [{ "func": g.oneview_client.server_hardware.get, "param": uuid }, { "func": g.oneview_client.server_profile_templates.get, "param": uuid }, { "func": g.oneview_client.index_resources.get, "param": drives_param }] for category in categories: try: resource = category["func"](category["param"]) return resource except HPOneViewException as e: if e.oneview_response["errorCode"] == 'RESOURCE_NOT_FOUND': pass else: raise # Raise any unexpected errors raise OneViewRedfishError("Could not find resource block with id " + uuid)
def __init__(self, device_id, port_id, server_hardware): """NetworkPort constructor Populates self.redfish with the contents of server hardware dict from Oneview Args: device_id: ID of the NetworkAdapter port_id: ID of the Port. server_hardware: Oneview's server hardware dict """ super().__init__(self.SCHEMA_NAME) physical_ports = self.get_resource_by_id( server_hardware["portMap"]["deviceSlots"], "deviceNumber", device_id)["physicalPorts"] port = self.get_resource_by_id(physical_ports, "portNumber", port_id) if port["type"] not in ["Ethernet", "FibreChannel", "InfiniBand"]: raise OneViewRedfishError("Port ID refers to invalid port type.") self.redfish["@odata.type"] = \ "#NetworkPort.v1_1_0.NetworkPort" self.redfish["Id"] = port_id self.redfish["Name"] = "Physical port {}".format(port_id) self.redfish["PhysicalPortNumber"] = port_id self.redfish["ActiveLinkTechnology"] = port["type"] self.redfish["AssociatedNetworkAddresses"] = list() if port["type"] == "Ethernet": self.redfish["AssociatedNetworkAddresses"].append(port["mac"]) elif port["type"] == "FibreChannel": self.redfish["AssociatedNetworkAddresses"].append(port["wwn"]) else: raise OneViewRedfishError("Type not supported") self.redfish["@odata.context"] = \ "/redfish/v1/$metadata#NetworkPort.NetworkPort" self.redfish["@odata.id"] = "/redfish/v1/Chassis/" + \ server_hardware["uuid"] + \ "/NetworkAdapters/" + device_id + \ "/NetworkPorts/" + port_id self._validate()
def check_oneview_availability(ov_config): """Check OneView availability by doing a GET request to OneView""" attempts = 3 retry_interval_sec = 3 for attempt_counter in range(attempts): try: connection = HTTPSConnection(ov_config['ip'], context=ssl.SSLContext( ssl.PROTOCOL_TLSv1_2)) connection.request(method='GET', url='/controller-state.json', headers={'Content-Type': 'application/json'}) response = connection.getresponse() if response.status != status.HTTP_200_OK: message = "OneView is unreachable at {}".format( ov_config['ip']) raise OneViewRedfishError(message) text = response.read().decode('UTF-8') status_ov = json.loads(text) if status_ov['state'] != 'OK': message = "OneView state is not OK at {}".format( ov_config['ip']) raise OneViewRedfishError(message) return except Exception as e: logging.exception('Attempt {} to check OneView availability. ' 'Error: {}'.format(attempt_counter + 1, e)) if attempt_counter + 1 < attempts: time.sleep(retry_interval_sec) finally: connection.close() message = "After {} attempts OneView is unreachable at {}".format( attempts, ov_config['ip']) raise OneViewRedfishError(message)
def get_oneview_power_configuration(self, reset_type): """Maps Redfish's power options to OneView's power option Maps the known Redfish power options to OneView Power option. If a unknown power option shows up it will raise an Exception. Args: reset_type: Redfish power option. Returns: dict: Dict with OneView power configuration. Exception: OneViewRedfishError: raises an exception if reset_type is an unmapped value. """ if reset_type == "ForceOn" or reset_type == "Nmi": raise OneViewRedfishError({ "errorCode": "NOT_IMPLEMENTED", "message": "{} not mapped to OneView".format(reset_type) }) try: power_state_map = POWER_STATE_MAP[reset_type] except Exception: raise OneViewRedfishError({ "errorCode": "INVALID_INFORMATION", "message": "There is no mapping for {} on the OneView".format(reset_type) }) if reset_type == "PushPowerButton": if self.server_hardware["powerState"] == "On": power_state_map["powerState"] = "Off" else: power_state_map["powerState"] = "On" return power_state_map
def generate_certificate(dir_name, file_name, key_length, key_type="rsa"): """Create self-signed cert and key files Args: dir_name: name of the directory to store the files file_name: name of the files that will be created. It will append .crt to certificate file and .key to key file key_length: key length in bits key_type: crypto type: RSA or DSA; defaults to RSA Returns: Nothing Exceptions: Raise exceptions on error """ config = globals()['config'] private_key = OpenSSL.crypto.PKey() if key_type == "rsa": private_key.generate_key(OpenSSL.crypto.TYPE_RSA, key_length) elif key_type == "dsa": private_key.generate_key(OpenSSL.crypto.TYPE_DSA, key_length) else: message = "Invalid key_type" logging.error(message) raise OneViewRedfishError(message) if not config.has_option("ssl-cert-defaults", "commonName"): config["ssl-cert-defaults"]["commonName"] = get_ip() cert = OpenSSL.crypto.X509() cert_subject = cert.get_subject() cert_defaults = dict(config.items("ssl-cert-defaults")) for key, value in cert_defaults.items(): setattr(cert_subject, key, value) cert.set_serial_number(1) cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60) cert.set_issuer(cert.get_subject()) cert.set_pubkey(private_key) cert.sign(private_key, "sha1") # Save Files with open(os.path.join(dir_name, file_name + ".crt"), "wt") as f: f.write( OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert).decode("UTF-8")) with open(os.path.join(dir_name, file_name + ".key"), "wt") as f: f.write( OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, private_key).decode("UTF-8"))
def add_extended_info(self, message_id, message_args=[], related_properties=[]): """Adds an item to ExtendedInfo list using values from DMTF registry Adds an item to ExtendedInfo list using the values for Message, Severity and Resolution from DMTF Base Registry. Parameters: message_id: Id of the message; oneOf the keys in Redfish Registry Messages message_args: List of string to replace markers on Redfish messages. Must have the same length as the number of % signs found in the registry Message field related_properties: Properties relates to this e error if necessary """ messages = util.registry_dict["Base"]["Messages"] # Verify if message_id exists in registry try: severity = messages[message_id]["Severity"] except Exception: raise OneViewRedfishResourceNotFoundError(message_id, "message_id") message = messages[message_id]["Message"] # Check if numbers of replacemets and message_args length match replaces = message.count('%') replacements = len(message_args) if replaces != replacements: raise OneViewRedfishError( 'Message has {} replacements to be made but {} args ' 'where sent'.format(replaces, replacements)) # Replacing the marks in the message. A better way to do this # is welcome. for i in range(replaces): message = message.replace('%' + str(i + 1), message_args[i]) # Construct the dict extended_info = collections.OrderedDict() extended_info["@odata.type"] = "#Message.v1_0_5.Message" extended_info["MessageId"] = "Base.1.1." + message_id extended_info["Message"] = message extended_info["RelatedProperties"] = related_properties extended_info["MessageArgs"] = message_args extended_info["Severity"] = severity extended_info["Resolution"] = messages[message_id]["Resolution"] # Append it to the list self.redfish["error"]["@Message.ExtendedInfo"].append(extended_info)
def get_resource_block_ethernet_interface(uuid, id): """Get the Redfish ResourceBlock of type Network for the given UUID and ID. Return ResourceBlock redfish JSON for a given UUID and ID. Logs exception of any error and return Internal Server Error or Not Found. Returns: JSON: Redfish json with ResourceBlock. """ try: server_profile_template = \ g.oneview_client.server_profile_templates.get(uuid) connSettings = server_profile_template["connectionSettings"] connection = None for conn in connSettings["connections"]: if str(conn["id"]) == id: connection = conn break if not connection: raise OneViewRedfishError("Ethernet interface not found") network = g.oneview_client.ethernet_networks.get(conn["networkUri"]) ethernet_interface = ResourceBlockEthernetInterface( server_profile_template, connection, network) return ResponseBuilder.success( ethernet_interface, {"ETag": "W/" + server_profile_template["eTag"]}) except OneViewRedfishError as e: # In case of error log exception and abort logging.exception('Unexpected error: {}'.format(e)) abort(status.HTTP_404_NOT_FOUND, e.msg)
def post_session(): """Posts Session The response to the POST request to create a session includes: - An X-Auth-Token header that contains a session auth token that the client can use an subsequent requests. - A Location header that contains a link to the newly created session resource. - The JSON response body that contains a full representation of the newly created session object. Exception: HPOneViewException: Invalid username or password. return abort(401) OneViewRedfishError: When occur a credential key mapping error. return abort(400) Exception: Unexpected error. return abort(500) """ try: try: body = request.get_json() username = body["UserName"] password = body["Password"] except Exception: raise OneViewRedfishError({ "errorCode": "INVALID_INFORMATION", "message": "Invalid JSON key. The JSON request body" " must have the keys UserName and Password" }) config = dict() config["ip"] = util.ov_config["ip"] config["credentials"] = dict() config["credentials"]["userName"] = username config["credentials"]["password"] = password oneview_client = OneViewClient(config) session_id = oneview_client.connection.get_session_id() sess = Session(username) json_str = sess.serialize() response = Response(response=json_str, status=200, mimetype='application/json') response.headers.add("Location", "/redfish/v1/SessionService/Sessions/1") response.headers.add("X-Auth-Token", session_id) return response except HPOneViewException as e: logging.exception('Unauthorized error: {}'.format(e)) abort(status.HTTP_401_UNAUTHORIZED) except OneViewRedfishError as e: logging.exception('Mapping error: {}'.format(e)) abort(status.HTTP_400_BAD_REQUEST, e.msg['message']) except Exception as e: logging.exception('Unexpected error: {}'.format(e)) 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)
def get_thermal(uuid): """Get the Redfish Thermal for a given UUID. Return Thermal Redfish JSON for a given hardware UUID. Logs exception of any error and return abort(500) Internal Server Error. Returns: JSON: Redfish json with Thermal When hardware is not found calls abort(404) Exceptions: Logs the exception and call abort(500) """ try: index_obj = g.oneview_client.index_resources.get_all( filter='uuid=' + uuid ) if index_obj: category = index_obj[0]["category"] else: raise OneViewRedfishError('Cannot find Index resource') if category == 'server-hardware': server_hardware = g.oneview_client.server_hardware. \ get_utilization(uuid, fields='AmbientTemperature') thrml = Thermal(server_hardware, uuid, 'Blade') elif category == 'enclosures': enclosure = g.oneview_client.enclosures. \ get_utilization(uuid, fields='AmbientTemperature') thrml = Thermal(enclosure, uuid, 'Enclosure') elif category == 'racks': rack = g.oneview_client.racks.\ get_device_topology(uuid) thrml = Thermal(rack, uuid, 'Rack') else: raise OneViewRedfishError('OneView resource not found') json_str = thrml.serialize() return Response( response=json_str, status=status.HTTP_200_OK, mimetype="application/json") except HPOneViewException as e: # In case of error print exception and abort logging.exception(e) if e.oneview_response['errorCode'] == "RESOURCE_NOT_FOUND": abort(status.HTTP_404_NOT_FOUND, "Resource not found") else: abort(status.HTTP_500_INTERNAL_SERVER_ERROR) except OneViewRedfishError as e: # In case of error print exception and abort logging.exception('Unexpected error: {}'.format(e)) abort(status.HTTP_404_NOT_FOUND, "Resource not found") except Exception as e: # In case of error print exception and abort logging.exception(e) logging.exception('Unexpected error: {}'.format(e)) abort(status.HTTP_500_INTERNAL_SERVER_ERROR)
def add_subscription(): """Add the Redfish Subscription. Add a new subscription when this POST operation is requested. The body of the request must have the Destination, an array of EventTypes. Context is optional. EventTypes: - StatusChange - ResourceUpdated - ResourceAdded - ResourceRemoved - Alert Returns: JSON: JSON with Subscription information. Exception: OneViewRedfishError: When occur a key mapping error. return abort(400) Exception: Unexpected error. return abort(500) """ try: # get Destination, EventTypes and Context from post # generate subscription uuid # add subscription in subscriptions_by_type # add subscription in all_subscriptions try: body = request.get_json() destination = body["Destination"] if not validators.url(destination): raise OneViewRedfishError({ "errorCode": "INVALID_INFORMATION", "message": "Destination must be an URI." }) event_types = body["EventTypes"] if not event_types: raise OneViewRedfishError({ "errorCode": "INVALID_INFORMATION", "message": "EventTypes cannot be empty." }) context = body.get("Context") except KeyError: raise OneViewRedfishError({ "errorCode": "INVALID_INFORMATION", "message": "Invalid JSON key. The JSON request body" " must have the keys Destination and EventTypes." " The Context is optional." }) subscription_id = str(uuid.uuid1()) try: # Build Subscription object and validates it sc = Subscription(subscription_id, destination, event_types, context) except ValidationError: raise OneViewRedfishError({ "errorCode": "INVALID_INFORMATION", "message": "Invalid EventType. The EventTypes are " "StatusChange, ResourceUpdated, ResourceAdded," " ResourceRemoved and Alert." }) for event_type in sc.get_event_types(): util.subscriptions_by_type[event_type][subscription_id] = sc util.all_subscriptions[subscription_id] = sc # Build redfish json json_str = sc.serialize() # Build response and returns response = Response(response=json_str, status=status.HTTP_201_CREATED, mimetype="application/json") response.headers.add( "Location", "/redfish/v1/EventService/EventSubscriptions/" "{}".format(subscription_id)) return response except OneViewRedfishError as e: logging.exception(e) abort(status.HTTP_400_BAD_REQUEST, e.msg['message']) except Exception as e: logging.exception(e) return abort(status.HTTP_500_INTERNAL_SERVER_ERROR)