X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FRO.git;a=blobdiff_plain;f=RO-VIM-openvim%2Fosm_rovim_openvim%2Fvimconn_openvim.py;fp=RO-VIM-openvim%2Fosm_rovim_openvim%2Fvimconn_openvim.py;h=eab0e75aa0c100fcd12e4a20d5d65e69752fdde5;hp=8fb02ccb345e19c8231dc1eef474eaeac42c9a77;hb=80135b928ab442c38898750b4751480205b4affc;hpb=e493e9b91720e5116e00b4c06cf66c767bccce2f diff --git a/RO-VIM-openvim/osm_rovim_openvim/vimconn_openvim.py b/RO-VIM-openvim/osm_rovim_openvim/vimconn_openvim.py index 8fb02ccb..eab0e75a 100644 --- a/RO-VIM-openvim/osm_rovim_openvim/vimconn_openvim.py +++ b/RO-VIM-openvim/osm_rovim_openvim/vimconn_openvim.py @@ -21,11 +21,11 @@ # contact with: nfvlabs@tid.es ## -''' +""" vimconnector implements all the methods to interact with openvim using the openvim API. -''' -__author__="Alfonso Tierno, Gerardo Garcia" -__date__ ="$26-aug-2014 11:09:29$" +""" +__author__ = "Alfonso Tierno, Gerardo Garcia" +__date__ = "$26-aug-2014 11:09:29$" from osm_ro_plugin import vimconn import requests @@ -33,143 +33,160 @@ import json import yaml import logging import math -from osm_ro.openmano_schemas import id_schema, name_schema, nameshort_schema, description_schema, \ - vlan1000_schema, integer0_schema +from osm_ro.openmano_schemas import ( + id_schema, + name_schema, + nameshort_schema, + description_schema, + vlan1000_schema, + integer0_schema, +) from jsonschema import validate as js_v, exceptions as js_e from urllib.parse import quote -'''contain the openvim virtual machine status to openmano status''' -vmStatus2manoFormat={'ACTIVE':'ACTIVE', - 'PAUSED':'PAUSED', - 'SUSPENDED': 'SUSPENDED', - 'INACTIVE':'INACTIVE', - 'CREATING':'BUILD', - 'ERROR':'ERROR','DELETED':'DELETED' - } -netStatus2manoFormat={'ACTIVE':'ACTIVE','INACTIVE':'INACTIVE','BUILD':'BUILD','ERROR':'ERROR','DELETED':'DELETED', 'DOWN':'DOWN' - } +"""contain the openvim virtual machine status to openmano status""" +vmStatus2manoFormat = { + "ACTIVE": "ACTIVE", + "PAUSED": "PAUSED", + "SUSPENDED": "SUSPENDED", + "INACTIVE": "INACTIVE", + "CREATING": "BUILD", + "ERROR": "ERROR", + "DELETED": "DELETED", +} +netStatus2manoFormat = { + "ACTIVE": "ACTIVE", + "INACTIVE": "INACTIVE", + "BUILD": "BUILD", + "ERROR": "ERROR", + "DELETED": "DELETED", + "DOWN": "DOWN", +} host_schema = { - "type":"object", - "properties":{ + "type": "object", + "properties": { "id": id_schema, "name": name_schema, }, - "required": ["id"] + "required": ["id"], } image_schema = { - "type":"object", - "properties":{ + "type": "object", + "properties": { "id": id_schema, "name": name_schema, }, - "required": ["id","name"] + "required": ["id", "name"], } server_schema = { - "type":"object", - "properties":{ - "id":id_schema, + "type": "object", + "properties": { + "id": id_schema, "name": name_schema, }, - "required": ["id","name"] + "required": ["id", "name"], } new_host_response_schema = { - "title":"host response information schema", + "title": "host response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "host": host_schema - }, + "type": "object", + "properties": {"host": host_schema}, "required": ["host"], - "additionalProperties": False + "additionalProperties": False, } get_images_response_schema = { - "title":"openvim images response information schema", + "title": "openvim images response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "images":{ - "type":"array", + "type": "object", + "properties": { + "images": { + "type": "array", "items": image_schema, } }, "required": ["images"], - "additionalProperties": False + "additionalProperties": False, } get_hosts_response_schema = { - "title":"openvim hosts response information schema", + "title": "openvim hosts response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "hosts":{ - "type":"array", + "type": "object", + "properties": { + "hosts": { + "type": "array", "items": host_schema, } }, "required": ["hosts"], - "additionalProperties": False + "additionalProperties": False, } -get_host_detail_response_schema = new_host_response_schema # TODO: Content is not parsed yet +get_host_detail_response_schema = ( + new_host_response_schema # TODO: Content is not parsed yet +) get_server_response_schema = { - "title":"openvim server response information schema", + "title": "openvim server response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "servers":{ - "type":"array", + "type": "object", + "properties": { + "servers": { + "type": "array", "items": server_schema, } }, "required": ["servers"], - "additionalProperties": False + "additionalProperties": False, } new_tenant_response_schema = { - "title":"tenant response information schema", + "title": "tenant response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "tenant":{ - "type":"object", - "properties":{ + "type": "object", + "properties": { + "tenant": { + "type": "object", + "properties": { "id": id_schema, "name": nameshort_schema, - "description":description_schema, - "enabled":{"type" : "boolean"} + "description": description_schema, + "enabled": {"type": "boolean"}, }, - "required": ["id"] + "required": ["id"], } }, "required": ["tenant"], - "additionalProperties": False + "additionalProperties": False, } new_network_response_schema = { - "title":"network response information schema", + "title": "network response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "network":{ - "type":"object", - "properties":{ - "id":id_schema, - "name":name_schema, - "type":{"type":"string", "enum":["bridge_man","bridge_data","data", "ptp"]}, - "shared":{"type":"boolean"}, - "tenant_id":id_schema, - "admin_state_up":{"type":"boolean"}, - "vlan":vlan1000_schema + "type": "object", + "properties": { + "network": { + "type": "object", + "properties": { + "id": id_schema, + "name": name_schema, + "type": { + "type": "string", + "enum": ["bridge_man", "bridge_data", "data", "ptp"], + }, + "shared": {"type": "boolean"}, + "tenant_id": id_schema, + "admin_state_up": {"type": "boolean"}, + "vlan": vlan1000_schema, }, - "required": ["id"] + "required": ["id"], } }, "required": ["network"], - "additionalProperties": False + "additionalProperties": False, } @@ -198,226 +215,272 @@ new_network_response_schema = { new_port_response_schema = { - "title":"port response information schema", + "title": "port response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "port":{ - "type":"object", - "properties":{ - "id":id_schema, + "type": "object", + "properties": { + "port": { + "type": "object", + "properties": { + "id": id_schema, }, - "required": ["id"] + "required": ["id"], } }, "required": ["port"], - "additionalProperties": False + "additionalProperties": False, } get_flavor_response_schema = { - "title":"openvim flavors response information schema", + "title": "openvim flavors response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "flavor":{ - "type":"object", - "properties":{ - "id": id_schema, + "type": "object", + "properties": { + "flavor": { + "type": "object", + "properties": { + "id": id_schema, "name": name_schema, - "extended": {"type":"object"}, + "extended": {"type": "object"}, }, "required": ["id", "name"], } }, "required": ["flavor"], - "additionalProperties": False + "additionalProperties": False, } new_flavor_response_schema = { - "title":"flavor response information schema", + "title": "flavor response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "flavor":{ - "type":"object", - "properties":{ - "id":id_schema, + "type": "object", + "properties": { + "flavor": { + "type": "object", + "properties": { + "id": id_schema, }, - "required": ["id"] + "required": ["id"], } }, "required": ["flavor"], - "additionalProperties": False + "additionalProperties": False, } get_image_response_schema = { - "title":"openvim images response information schema", + "title": "openvim images response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "image":{ - "type":"object", - "properties":{ - "id": id_schema, + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "id": id_schema, "name": name_schema, }, "required": ["id", "name"], } }, "required": ["flavor"], - "additionalProperties": False + "additionalProperties": False, } new_image_response_schema = { - "title":"image response information schema", + "title": "image response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "image":{ - "type":"object", - "properties":{ - "id":id_schema, + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "id": id_schema, }, - "required": ["id"] + "required": ["id"], } }, "required": ["image"], - "additionalProperties": False + "additionalProperties": False, } new_vminstance_response_schema = { - "title":"server response information schema", + "title": "server response information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "server":{ - "type":"object", - "properties":{ - "id":id_schema, + "type": "object", + "properties": { + "server": { + "type": "object", + "properties": { + "id": id_schema, }, - "required": ["id"] + "required": ["id"], } }, "required": ["server"], - "additionalProperties": False + "additionalProperties": False, } get_processor_rankings_response_schema = { - "title":"processor rankings information schema", + "title": "processor rankings information schema", "$schema": "http://json-schema.org/draft-04/schema#", - "type":"object", - "properties":{ - "rankings":{ - "type":"array", - "items":{ - "type":"object", - "properties":{ - "model": description_schema, - "value": integer0_schema - }, + "type": "object", + "properties": { + "rankings": { + "type": "array", + "items": { + "type": "object", + "properties": {"model": description_schema, "value": integer0_schema}, "additionalProperties": False, - "required": ["model","value"] - } + "required": ["model", "value"], + }, }, "additionalProperties": False, - "required": ["rankings"] - } + "required": ["rankings"], + }, } class vimconnector(vimconn.VimConnector): - def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, - log_level="DEBUG", config={}, persistent_info={}): - vimconn.VimConnector.__init__(self, uuid, name, tenant_id, tenant_name, url, url_admin, user, passwd, log_level, config) + def __init__( + self, + uuid, + name, + tenant_id, + tenant_name, + url, + url_admin=None, + user=None, + passwd=None, + log_level="DEBUG", + config={}, + persistent_info={}, + ): + vimconn.VimConnector.__init__( + self, + uuid, + name, + tenant_id, + tenant_name, + url, + url_admin, + user, + passwd, + log_level, + config, + ) self.tenant = None - self.headers_req = {'content-type': 'application/json'} - self.logger = logging.getLogger('ro.vim.openvim') + self.headers_req = {"content-type": "application/json"} + self.logger = logging.getLogger("ro.vim.openvim") self.persistent_info = persistent_info if tenant_id: self.tenant = tenant_id - def __setitem__(self,index, value): - '''Set individuals parameters + def __setitem__(self, index, value): + """Set individuals parameters Throw TypeError, KeyError - ''' - if index=='tenant_id': + """ + if index == "tenant_id": self.tenant = value - elif index=='tenant_name': + elif index == "tenant_name": self.tenant = None - vimconn.VimConnector.__setitem__(self,index, value) + vimconn.VimConnector.__setitem__(self, index, value) def _get_my_tenant(self): - '''Obtain uuid of my tenant from name - ''' + """Obtain uuid of my tenant from name""" if self.tenant: return self.tenant - url = self.url+'/tenants?name='+ quote(self.tenant_name) + url = self.url + "/tenants?name=" + quote(self.tenant_name) self.logger.info("Getting VIM tenant_id GET %s", url) - vim_response = requests.get(url, headers = self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) self._check_http_request_response(vim_response) try: tenant_list = vim_response.json()["tenants"] if len(tenant_list) == 0: - raise vimconn.VimConnNotFoundException("No tenant found for name '{}'".format(self.tenant_name)) + raise vimconn.VimConnNotFoundException( + "No tenant found for name '{}'".format(self.tenant_name) + ) elif len(tenant_list) > 1: - raise vimconn.VimConnConflictException ("More that one tenant found for name '{}'".format(self.tenant_name)) + raise vimconn.VimConnConflictException( + "More that one tenant found for name '{}'".format(self.tenant_name) + ) self.tenant = tenant_list[0]["id"] return self.tenant except Exception as e: - raise vimconn.VimConnUnexpectedResponse("Get VIM tenant {} '{}'".format(type(e).__name__, str(e))) + raise vimconn.VimConnUnexpectedResponse( + "Get VIM tenant {} '{}'".format(type(e).__name__, str(e)) + ) - def _format_jsonerror(self,http_response): - #DEPRECATED, to delete in the future + def _format_jsonerror(self, http_response): + # DEPRECATED, to delete in the future try: data = http_response.json() return data["error"]["description"] - except: + except Exception: return http_response.text def _format_in(self, http_response, schema): - #DEPRECATED, to delete in the future + # DEPRECATED, to delete in the future try: client_data = http_response.json() js_v(client_data, schema) - #print "Input data: ", str(client_data) + # print "Input data: ", str(client_data) return True, client_data except js_e.ValidationError as exc: - print("validate_in error, jsonschema exception ", exc.message, "at", exc.path) - return False, ("validate_in error, jsonschema exception ", exc.message, "at", exc.path) - + print( + "validate_in error, jsonschema exception ", exc.message, "at", exc.path + ) + return False, ( + "validate_in error, jsonschema exception ", + exc.message, + "at", + exc.path, + ) + def _remove_extra_items(self, data, schema): - deleted=[] + deleted = [] if type(data) is tuple or type(data) is list: for d in data: - a= self._remove_extra_items(d, schema['items']) - if a is not None: deleted.append(a) + a = self._remove_extra_items(d, schema["items"]) + if a is not None: + deleted.append(a) elif type(data) is dict: to_delete = [] for k in data.keys(): - if 'properties' not in schema or k not in schema['properties'].keys(): + if "properties" not in schema or k not in schema["properties"].keys(): to_delete.append(k) deleted.append(k) else: - a = self._remove_extra_items(data[k], schema['properties'][k]) - if a is not None: deleted.append({k:a}) + a = self._remove_extra_items(data[k], schema["properties"][k]) + if a is not None: + deleted.append({k: a}) for k in to_delete: del data[k] - if len(deleted) == 0: return None - elif len(deleted) == 1: return deleted[0] - else: return deleted - + if len(deleted) == 0: + return None + elif len(deleted) == 1: + return deleted[0] + else: + return deleted + def _format_request_exception(self, request_exception): - '''Transform a request exception into a vimconn exception''' + """Transform a request exception into a vimconn exception""" if isinstance(request_exception, js_e.ValidationError): - raise vimconn.VimConnUnexpectedResponse("jsonschema exception '{}' at '{}'".format(request_exception.message, request_exception.path)) + raise vimconn.VimConnUnexpectedResponse( + "jsonschema exception '{}' at '{}'".format( + request_exception.message, request_exception.path + ) + ) elif isinstance(request_exception, requests.exceptions.HTTPError): - raise vimconn.VimConnUnexpectedResponse(type(request_exception).__name__ + ": " + str(request_exception)) + raise vimconn.VimConnUnexpectedResponse( + type(request_exception).__name__ + ": " + str(request_exception) + ) else: - raise vimconn.VimConnConnectionException(type(request_exception).__name__ + ": " + str(request_exception)) + raise vimconn.VimConnConnectionException( + type(request_exception).__name__ + ": " + str(request_exception) + ) def _check_http_request_response(self, request_response): - '''Raise a vimconn exception if the response is not Ok''' - if request_response.status_code >= 200 and request_response.status_code < 300: + """Raise a vimconn exception if the response is not Ok""" + if request_response.status_code >= 200 and request_response.status_code < 300: return if request_response.status_code == vimconn.HTTP_Unauthorized: raise vimconn.VimConnAuthException(request_response.text) @@ -425,70 +488,89 @@ class vimconnector(vimconn.VimConnector): raise vimconn.VimConnNotFoundException(request_response.text) elif request_response.status_code == vimconn.HTTP_Conflict: raise vimconn.VimConnConflictException(request_response.text) - else: - raise vimconn.VimConnUnexpectedResponse("VIM HTTP_response {}, {}".format(request_response.status_code, str(request_response.text))) + else: + raise vimconn.VimConnUnexpectedResponse( + "VIM HTTP_response {}, {}".format( + request_response.status_code, str(request_response.text) + ) + ) - def new_tenant(self,tenant_name,tenant_description): - '''Adds a new tenant to VIM with this name and description, returns the tenant identifier''' - #print "VIMConnector: Adding a new tenant to VIM" - payload_dict = {"tenant": {"name":tenant_name,"description": tenant_description, "enabled": True}} + def new_tenant(self, tenant_name, tenant_description): + """Adds a new tenant to VIM with this name and description, returns the tenant identifier""" + # print "VIMConnector: Adding a new tenant to VIM" + payload_dict = { + "tenant": { + "name": tenant_name, + "description": tenant_description, + "enabled": True, + } + } payload_req = json.dumps(payload_dict) try: - url = self.url_admin+'/tenants' + url = self.url_admin + "/tenants" self.logger.info("Adding a new tenant %s", url) - vim_response = requests.post(url, headers = self.headers_req, data=payload_req) + vim_response = requests.post( + url, headers=self.headers_req, data=payload_req + ) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, new_tenant_response_schema) - #r = self._remove_extra_items(response, new_tenant_response_schema) - #if r is not None: + # r = self._remove_extra_items(response, new_tenant_response_schema) + # if r is not None: # self.logger.warn("Warning: remove extra items %s", str(r)) - tenant_id = response['tenant']['id'] + tenant_id = response["tenant"]["id"] return tenant_id except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - def delete_tenant(self,tenant_id): - '''Delete a tenant from VIM. Returns the old tenant identifier''' + def delete_tenant(self, tenant_id): + """Delete a tenant from VIM. Returns the old tenant identifier""" try: - url = self.url_admin+'/tenants/'+tenant_id + url = self.url_admin + "/tenants/" + tenant_id self.logger.info("Delete a tenant DELETE %s", url) - vim_response = requests.delete(url, headers = self.headers_req) + vim_response = requests.delete(url, headers=self.headers_req) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) return tenant_id except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) def get_tenant_list(self, filter_dict={}): - '''Obtain tenants of VIM + """Obtain tenants of VIM filter_dict can contain the following keys: name: filter by tenant name id: filter by tenant uuid/id Returns the tenant list of dictionaries: [{'name':', 'id':', ...}, ...] - ''' - filterquery=[] - filterquery_text='' - for k,v in filter_dict.items(): - filterquery.append(str(k)+'='+str(v)) - if len(filterquery)>0: - filterquery_text='?'+ '&'.join(filterquery) + """ + filterquery = [] + filterquery_text = "" + for k, v in filter_dict.items(): + filterquery.append(str(k) + "=" + str(v)) + if len(filterquery) > 0: + filterquery_text = "?" + "&".join(filterquery) try: - url = self.url+'/tenants'+filterquery_text + url = self.url + "/tenants" + filterquery_text self.logger.info("get_tenant_list GET %s", url) - vim_response = requests.get(url, headers = self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) return vim_response.json()["tenants"] except requests.exceptions.RequestException as e: self._format_request_exception(e) - def new_network(self,net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None): #, **vim_specific): + def new_network( + self, + net_name, + net_type, + ip_profile=None, + shared=False, + provider_network_profile=None, + ): # , **vim_specific): """Adds a tenant network to VIM Params: 'net_name': name of the network @@ -518,30 +600,39 @@ class vimconnector(vimconn.VimConnector): vlan = provider_network_profile.get("segmentation-id") created_items = {} self._get_my_tenant() - if net_type=="bridge": - net_type="bridge_data" - payload_req = {"name": net_name, "type": net_type, "tenant_id": self.tenant, "shared": shared} + if net_type == "bridge": + net_type = "bridge_data" + payload_req = { + "name": net_name, + "type": net_type, + "tenant_id": self.tenant, + "shared": shared, + } if vlan: payload_req["provider:vlan"] = vlan # payload_req.update(vim_specific) - url = self.url+'/networks' - self.logger.info("Adding a new network POST: %s DATA: %s", url, str(payload_req)) - vim_response = requests.post(url, headers = self.headers_req, data=json.dumps({"network": payload_req}) ) + url = self.url + "/networks" + self.logger.info( + "Adding a new network POST: %s DATA: %s", url, str(payload_req) + ) + vim_response = requests.post( + url, headers=self.headers_req, data=json.dumps({"network": payload_req}) + ) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, new_network_response_schema) - #r = self._remove_extra_items(response, new_network_response_schema) - #if r is not None: + # r = self._remove_extra_items(response, new_network_response_schema) + # if r is not None: # self.logger.warn("Warning: remove extra items %s", str(r)) - network_id = response['network']['id'] + network_id = response["network"]["id"] return network_id, created_items except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - + def get_network_list(self, filter_dict={}): - '''Obtain tenant networks of VIM + """Obtain tenant networks of VIM Filter_dict can be: name: network name id: network uuid @@ -550,43 +641,43 @@ class vimconnector(vimconn.VimConnector): admin_state_up: boolean status: 'ACTIVE' Returns the network list of dictionaries - ''' + """ try: - if 'tenant_id' not in filter_dict: + if "tenant_id" not in filter_dict: filter_dict["tenant_id"] = self._get_my_tenant() elif not filter_dict["tenant_id"]: del filter_dict["tenant_id"] - filterquery=[] - filterquery_text='' - for k,v in filter_dict.items(): - filterquery.append(str(k)+'='+str(v)) - if len(filterquery)>0: - filterquery_text='?'+ '&'.join(filterquery) - url = self.url+'/networks'+filterquery_text + filterquery = [] + filterquery_text = "" + for k, v in filter_dict.items(): + filterquery.append(str(k) + "=" + str(v)) + if len(filterquery) > 0: + filterquery_text = "?" + "&".join(filterquery) + url = self.url + "/networks" + filterquery_text self.logger.info("Getting network list GET %s", url) - vim_response = requests.get(url, headers = self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() - return response['networks'] + return response["networks"] except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) def get_network(self, net_id): - '''Obtain network details of network id''' + """Obtain network details of network id""" try: - url = self.url+'/networks/'+net_id + url = self.url + "/networks/" + net_id self.logger.info("Getting network GET %s", url) - vim_response = requests.get(url, headers = self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() - return response['network'] + return response["network"] except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - + def delete_network(self, net_id, created_items=None): """ Removes a tenant network from VIM and its associated elements @@ -596,50 +687,54 @@ class vimconnector(vimconn.VimConnector): """ try: self._get_my_tenant() - url = self.url+'/networks/'+net_id + url = self.url + "/networks/" + net_id self.logger.info("Deleting VIM network DELETE %s", url) vim_response = requests.delete(url, headers=self.headers_req) self._check_http_request_response(vim_response) - #self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # self.logger.debug(vim_response.text) + # print json.dumps(vim_response.json(), indent=4) return net_id except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) def get_flavor(self, flavor_id): - '''Obtain flavor details from the VIM''' + """Obtain flavor details from the VIM""" try: self._get_my_tenant() - url = self.url+'/'+self.tenant+'/flavors/'+flavor_id + url = self.url + "/" + self.tenant + "/flavors/" + flavor_id self.logger.info("Getting flavor GET %s", url) - vim_response = requests.get(url, headers = self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, get_flavor_response_schema) r = self._remove_extra_items(response, get_flavor_response_schema) - if r is not None: + if r is not None: self.logger.warn("Warning: remove extra items %s", str(r)) - return response['flavor'] + return response["flavor"] except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - + def new_flavor(self, flavor_data): - '''Adds a tenant flavor to VIM''' - '''Returns the flavor identifier''' + """Adds a tenant flavor to VIM""" + """Returns the flavor identifier""" try: new_flavor_dict = flavor_data.copy() - for device in new_flavor_dict.get('extended', {}).get('devices', ()): - if 'image name' in device: - del device['image name'] - if 'name' in device: - del device['name'] - numas = new_flavor_dict.get('extended', {}).get('numas') + for device in new_flavor_dict.get("extended", {}).get("devices", ()): + if "image name" in device: + del device["image name"] + if "name" in device: + del device["name"] + numas = new_flavor_dict.get("extended", {}).get("numas") if numas: numa = numas[0] # translate memory, cpus to EPA - if "cores" not in numa and "threads" not in numa and "paired-threads" not in numa: + if ( + "cores" not in numa + and "threads" not in numa + and "paired-threads" not in numa + ): numa["paired-threads"] = new_flavor_dict["vcpus"] if "memory" not in numa: numa["memory"] = int(math.ceil(new_flavor_dict["ram"] / 1024.0)) @@ -649,125 +744,135 @@ class vimconnector(vimconn.VimConnector): new_flavor_dict["name"] = flavor_data["name"][:64] self._get_my_tenant() - payload_req = json.dumps({'flavor': new_flavor_dict}) - url = self.url+'/'+self.tenant+'/flavors' + payload_req = json.dumps({"flavor": new_flavor_dict}) + url = self.url + "/" + self.tenant + "/flavors" self.logger.info("Adding a new VIM flavor POST %s", url) - vim_response = requests.post(url, headers = self.headers_req, data=payload_req) + vim_response = requests.post( + url, headers=self.headers_req, data=payload_req + ) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, new_flavor_response_schema) r = self._remove_extra_items(response, new_flavor_response_schema) - if r is not None: + if r is not None: self.logger.warn("Warning: remove extra items %s", str(r)) - flavor_id = response['flavor']['id'] + flavor_id = response["flavor"]["id"] return flavor_id except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - def delete_flavor(self,flavor_id): - '''Deletes a tenant flavor from VIM''' - '''Returns the old flavor_id''' + def delete_flavor(self, flavor_id): + """Deletes a tenant flavor from VIM""" + """Returns the old flavor_id""" try: self._get_my_tenant() - url = self.url+'/'+self.tenant+'/flavors/'+flavor_id + url = self.url + "/" + self.tenant + "/flavors/" + flavor_id self.logger.info("Deleting VIM flavor DELETE %s", url) vim_response = requests.delete(url, headers=self.headers_req) self._check_http_request_response(vim_response) - #self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # self.logger.debug(vim_response.text) + # print json.dumps(vim_response.json(), indent=4) return flavor_id except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) def get_image(self, image_id): - '''Obtain image details from the VIM''' + """Obtain image details from the VIM""" try: self._get_my_tenant() - url = self.url+'/'+self.tenant+'/images/'+image_id + url = self.url + "/" + self.tenant + "/images/" + image_id self.logger.info("Getting image GET %s", url) - vim_response = requests.get(url, headers = self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, get_image_response_schema) r = self._remove_extra_items(response, get_image_response_schema) - if r is not None: + if r is not None: self.logger.warn("Warning: remove extra items %s", str(r)) - return response['image'] + return response["image"] except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - def new_image(self,image_dict): - ''' Adds a tenant image to VIM, returns image_id''' + def new_image(self, image_dict): + """ Adds a tenant image to VIM, returns image_id""" try: self._get_my_tenant() - new_image_dict={'name': image_dict['name'][:64]} - if image_dict.get('description'): - new_image_dict['description'] = image_dict['description'] - if image_dict.get('metadata'): - new_image_dict['metadata'] = yaml.load(image_dict['metadata'], Loader=yaml.SafeLoader) - if image_dict.get('location'): - new_image_dict['path'] = image_dict['location'] - payload_req = json.dumps({"image":new_image_dict}) - url=self.url + '/' + self.tenant + '/images' + new_image_dict = {"name": image_dict["name"][:64]} + if image_dict.get("description"): + new_image_dict["description"] = image_dict["description"] + if image_dict.get("metadata"): + new_image_dict["metadata"] = yaml.load( + image_dict["metadata"], Loader=yaml.SafeLoader + ) + if image_dict.get("location"): + new_image_dict["path"] = image_dict["location"] + payload_req = json.dumps({"image": new_image_dict}) + url = self.url + "/" + self.tenant + "/images" self.logger.info("Adding a new VIM image POST %s", url) - vim_response = requests.post(url, headers = self.headers_req, data=payload_req) + vim_response = requests.post( + url, headers=self.headers_req, data=payload_req + ) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, new_image_response_schema) r = self._remove_extra_items(response, new_image_response_schema) - if r is not None: + if r is not None: self.logger.warn("Warning: remove extra items %s", str(r)) - image_id = response['image']['id'] + image_id = response["image"]["id"] return image_id except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - + def delete_image(self, image_id): - '''Deletes a tenant image from VIM''' - '''Returns the deleted image_id''' + """Deletes a tenant image from VIM""" + """Returns the deleted image_id""" try: self._get_my_tenant() - url = self.url + '/'+ self.tenant +'/images/'+image_id + url = self.url + "/" + self.tenant + "/images/" + image_id self.logger.info("Deleting VIM image DELETE %s", url) vim_response = requests.delete(url, headers=self.headers_req) self._check_http_request_response(vim_response) - #self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # self.logger.debug(vim_response.text) + # print json.dumps(vim_response.json(), indent=4) return image_id except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) def get_image_id_from_path(self, path): - '''Get the image id from image path in the VIM database. Returns the image_id''' + """Get the image id from image path in the VIM database. Returns the image_id""" try: self._get_my_tenant() - url=self.url + '/' + self.tenant + '/images?path='+quote(path) + url = self.url + "/" + self.tenant + "/images?path=" + quote(path) self.logger.info("Getting images GET %s", url) vim_response = requests.get(url) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, get_images_response_schema) - #r = self._remove_extra_items(response, get_images_response_schema) - #if r is not None: + # r = self._remove_extra_items(response, get_images_response_schema) + # if r is not None: # self.logger.warn("Warning: remove extra items %s", str(r)) - if len(response['images'])==0: - raise vimconn.VimConnNotFoundException("Image not found at VIM with path '{}'".format(path)) - elif len(response['images'])>1: - raise vimconn.VimConnConflictException("More than one image found at VIM with path '{}'".format(path)) - return response['images'][0]['id'] + if len(response["images"]) == 0: + raise vimconn.VimConnNotFoundException( + "Image not found at VIM with path '{}'".format(path) + ) + elif len(response["images"]) > 1: + raise vimconn.VimConnConflictException( + "More than one image found at VIM with path '{}'".format(path) + ) + return response["images"][0]["id"] except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) def get_image_list(self, filter_dict={}): - '''Obtain tenant images from VIM + """Obtain tenant images from VIM Filter_dict can be: name: image name id: image uuid @@ -776,29 +881,29 @@ class vimconnector(vimconn.VimConnector): Returns the image list of dictionaries: [{}, ...] List can be empty - ''' + """ try: self._get_my_tenant() - filterquery=[] - filterquery_text='' - for k,v in filter_dict.items(): - filterquery.append(str(k)+'='+str(v)) - if len(filterquery)>0: - filterquery_text='?'+ '&'.join(filterquery) - url = self.url+'/'+self.tenant+'/images'+filterquery_text + filterquery = [] + filterquery_text = "" + for k, v in filter_dict.items(): + filterquery.append(str(k) + "=" + str(v)) + if len(filterquery) > 0: + filterquery_text = "?" + "&".join(filterquery) + url = self.url + "/" + self.tenant + "/images" + filterquery_text self.logger.info("Getting image list GET %s", url) - vim_response = requests.get(url, headers = self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() - return response['images'] + return response["images"] except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) def new_vminstancefromJSON(self, vm_data): - '''Adds a VM instance to VIM''' - '''Returns the instance identifier''' + """Adds a VM instance to VIM""" + """Returns the instance identifier""" try: self._get_my_tenant() except Exception as e: @@ -806,35 +911,53 @@ class vimconnector(vimconn.VimConnector): print("VIMConnector: Adding a new VM instance from JSON to VIM") payload_req = vm_data try: - vim_response = requests.post(self.url+'/'+self.tenant+'/servers', headers = self.headers_req, data=payload_req) + vim_response = requests.post( + self.url + "/" + self.tenant + "/servers", + headers=self.headers_req, + data=payload_req, + ) except requests.exceptions.RequestException as e: - print( "new_vminstancefromJSON Exception: ", e.args) + print("new_vminstancefromJSON Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) # print vim_response - #print vim_response.status_code + # print vim_response.status_code if vim_response.status_code == 200: - #print vim_response.json() - #print json.dumps(vim_response.json(), indent=4) - res,http_content = self._format_in(vim_response, new_image_response_schema) - #print http_content + # print vim_response.json() + # print json.dumps(vim_response.json(), indent=4) + res, http_content = self._format_in(vim_response, new_image_response_schema) + # print http_content if res: r = self._remove_extra_items(http_content, new_image_response_schema) - if r is not None: print("Warning: remove extra items ", r) - #print http_content - vminstance_id = http_content['server']['id'] - print( "Tenant image id: ",vminstance_id) - return vim_response.status_code,vminstance_id - else: return -vimconn.HTTP_Bad_Request,http_content + if r is not None: + print("Warning: remove extra items ", r) + # print http_content + vminstance_id = http_content["server"]["id"] + print("Tenant image id: ", vminstance_id) + return vim_response.status_code, vminstance_id + else: + return -vimconn.HTTP_Bad_Request, http_content else: - #print vim_response.text + # print vim_response.text jsonerror = self._format_jsonerror(vim_response) text = 'Error in VIM "{}": not possible to add new vm instance. HTTP Response: {}. Error: {}'.format( - self.url, vim_response.status_code, jsonerror) - #print text - return -vim_response.status_code,text + self.url, vim_response.status_code, jsonerror + ) + # print text + return -vim_response.status_code, text - def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, disk_list=None, - availability_zone_index=None, availability_zone_list=None): + def new_vminstance( + self, + name, + description, + start, + image_id, + flavor_id, + net_list, + cloud_config=None, + disk_list=None, + availability_zone_index=None, + availability_zone_list=None, + ): """Adds a VM instance to VIM Params: start: indicates if VM must start or boot in pause mode. Ignored @@ -844,7 +967,7 @@ class vimconnector(vimconn.VimConnector): net_id: network uuid to connect vpci: virtual vcpi to assign model: interface model, virtio, e1000, ... - mac_address: + mac_address: use: 'data', 'bridge', 'mgmt' type: 'virtual', 'PCI-PASSTHROUGH'('PF'), 'SR-IOV'('VF'), 'VFnotShared' vim_id: filled/added by this function @@ -855,19 +978,24 @@ class vimconnector(vimconn.VimConnector): Format is vimconnector dependent, but do not use nested dictionaries and a value of None should be the same as not present. """ - self.logger.debug("new_vminstance input: image='%s' flavor='%s' nics='%s'", image_id, flavor_id, str(net_list)) + self.logger.debug( + "new_vminstance input: image='%s' flavor='%s' nics='%s'", + image_id, + flavor_id, + str(net_list), + ) try: self._get_my_tenant() -# net_list = [] -# for k,v in net_dict.items(): -# print k,v -# net_list.append('{"name":"' + k + '", "uuid":"' + v + '"}') -# net_list_string = ', '.join(net_list) - virtio_net_list=[] + # net_list = [] + # for k,v in net_dict.items(): + # print k,v + # net_list.append('{"name":"' + k + '", "uuid":"' + v + '"}') + # net_list_string = ', '.join(net_list) + virtio_net_list = [] for net in net_list: if not net.get("net_id"): continue - net_dict = {'uuid': net["net_id"]} + net_dict = {"uuid": net["net_id"]} if net.get("type"): if net["type"] == "SR-IOV": net_dict["type"] = "VF" @@ -889,134 +1017,140 @@ class vimconnector(vimconn.VimConnector): if net.get("ip_address"): net_dict["ip_address"] = net["ip_address"] virtio_net_list.append(net_dict) - payload_dict={ "name": name[:64], - "description": description, - "imageRef": image_id, - "flavorRef": flavor_id, - "networks": virtio_net_list - } - if start != None: + payload_dict = { + "name": name[:64], + "description": description, + "imageRef": image_id, + "flavorRef": flavor_id, + "networks": virtio_net_list, + } + if start is not None: payload_dict["start"] = start payload_req = json.dumps({"server": payload_dict}) - url = self.url+'/'+self.tenant+'/servers' + url = self.url + "/" + self.tenant + "/servers" self.logger.info("Adding a new vm POST %s DATA %s", url, payload_req) - vim_response = requests.post(url, headers = self.headers_req, data=payload_req) + vim_response = requests.post( + url, headers=self.headers_req, data=payload_req + ) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, new_vminstance_response_schema) - #r = self._remove_extra_items(response, new_vminstance_response_schema) - #if r is not None: + # r = self._remove_extra_items(response, new_vminstance_response_schema) + # if r is not None: # self.logger.warn("Warning: remove extra items %s", str(r)) - vminstance_id = response['server']['id'] + vminstance_id = response["server"]["id"] - #connect data plane interfaces to network + # connect data plane interfaces to network for net in net_list: - if net["type"]=="virtual": + if net["type"] == "virtual": if not net.get("net_id"): continue - for iface in response['server']['networks']: + for iface in response["server"]["networks"]: if "name" in net: - if net["name"]==iface["name"]: - net["vim_id"] = iface['iface_id'] + if net["name"] == iface["name"]: + net["vim_id"] = iface["iface_id"] break elif "net_id" in net: - if net["net_id"]==iface["net_id"]: - net["vim_id"] = iface['iface_id'] + if net["net_id"] == iface["net_id"]: + net["vim_id"] = iface["iface_id"] break - else: #dataplane - for numa in response['server'].get('extended',{}).get('numas',() ): - for iface in numa.get('interfaces',() ): - if net['name'] == iface['name']: - net['vim_id'] = iface['iface_id'] - #Code bellow is not needed, current openvim connect dataplane interfaces - #if net.get("net_id"): - ##connect dataplane interface + else: # dataplane + for numa in response["server"].get("extended", {}).get("numas", ()): + for iface in numa.get("interfaces", ()): + if net["name"] == iface["name"]: + net["vim_id"] = iface["iface_id"] + # Code bellow is not needed, current openvim connect dataplane interfaces + # if net.get("net_id"): + # connect dataplane interface # result, port_id = self.connect_port_network(iface['iface_id'], net["net_id"]) # if result < 0: - # error_text = "Error attaching port %s to network %s: %s." % (iface['iface_id'], net["net_id"], port_id) + # error_text = "Error attaching port %s to network %s: %s." % (iface['iface_id'] + # , net["net_id"], port_id) # print "new_vminstance: " + error_text # self.delete_vminstance(vminstance_id) # return result, error_text break - + return vminstance_id, None except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - + def get_vminstance(self, vm_id): - '''Returns the VM instance information from VIM''' + """Returns the VM instance information from VIM""" try: self._get_my_tenant() - url = self.url+'/'+self.tenant+'/servers/'+vm_id + url = self.url + "/" + self.tenant + "/servers/" + vm_id self.logger.info("Getting vm GET %s", url) - vim_response = requests.get(url, headers = self.headers_req) - vim_response = requests.get(url, headers = self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, new_vminstance_response_schema) - #r = self._remove_extra_items(response, new_vminstance_response_schema) - #if r is not None: + # r = self._remove_extra_items(response, new_vminstance_response_schema) + # if r is not None: # self.logger.warn("Warning: remove extra items %s", str(r)) - return response['server'] + return response["server"] except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - + def delete_vminstance(self, vm_id, created_items=None): - '''Removes a VM instance from VIM, returns the deleted vm_id''' + """Removes a VM instance from VIM, returns the deleted vm_id""" try: self._get_my_tenant() - url = self.url+'/'+self.tenant+'/servers/'+vm_id + url = self.url + "/" + self.tenant + "/servers/" + vm_id self.logger.info("Deleting VIM vm DELETE %s", url) vim_response = requests.delete(url, headers=self.headers_req) self._check_http_request_response(vim_response) - #self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # self.logger.debug(vim_response.text) + # print json.dumps(vim_response.json(), indent=4) return vm_id except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) def refresh_vms_status(self, vm_list): - '''Refreshes the status of the virtual machines''' + """Refreshes the status of the virtual machines""" try: self._get_my_tenant() except requests.exceptions.RequestException as e: self._format_request_exception(e) - vm_dict={} + vm_dict = {} for vm_id in vm_list: - vm={} - #print "VIMConnector refresh_tenant_vms and nets: Getting tenant VM instance information from VIM" + vm = {} + # print "VIMConnector refresh_tenant_vms and nets: Getting tenant VM instance information from VIM" try: - url = self.url + '/' + self.tenant + '/servers/' + vm_id + url = self.url + "/" + self.tenant + "/servers/" + vm_id self.logger.info("Getting vm GET %s", url) - vim_response = requests.get(url, headers = self.headers_req) + vim_response = requests.get(url, headers=self.headers_req) self._check_http_request_response(vim_response) response = vim_response.json() js_v(response, new_vminstance_response_schema) - if response['server']['status'] in vmStatus2manoFormat: - vm['status'] = vmStatus2manoFormat[ response['server']['status'] ] + if response["server"]["status"] in vmStatus2manoFormat: + vm["status"] = vmStatus2manoFormat[response["server"]["status"]] else: - vm['status'] = "OTHER" - vm['error_msg'] = "VIM status reported " + response['server']['status'] - if response['server'].get('last_error'): - vm['error_msg'] = response['server']['last_error'] - vm["vim_info"] = yaml.safe_dump(response['server']) - #get interfaces info + vm["status"] = "OTHER" + vm["error_msg"] = ( + "VIM status reported " + response["server"]["status"] + ) + if response["server"].get("last_error"): + vm["error_msg"] = response["server"]["last_error"] + vm["vim_info"] = yaml.safe_dump(response["server"]) + # get interfaces info try: management_ip = False - url2 = self.url + '/ports?device_id=' + quote(vm_id) + url2 = self.url + "/ports?device_id=" + quote(vm_id) self.logger.info("Getting PORTS GET %s", url2) - vim_response2 = requests.get(url2, headers = self.headers_req) + vim_response2 = requests.get(url2, headers=self.headers_req) self._check_http_request_response(vim_response2) client_data = vim_response2.json() if isinstance(client_data.get("ports"), list): - vm["interfaces"]=[] + vm["interfaces"] = [] for port in client_data.get("ports"): - interface={} - interface['vim_info'] = yaml.safe_dump(port) + interface = {} + interface["vim_info"] = yaml.safe_dump(port) interface["mac_address"] = port.get("mac_address") interface["vim_net_id"] = port.get("network_id") interface["vim_interface_id"] = port["id"] @@ -1026,363 +1160,475 @@ class vimconnector(vimconn.VimConnector): if interface["ip_address"] == "0.0.0.0": interface["ip_address"] = None vm["interfaces"].append(interface) - + except Exception as e: - self.logger.error("refresh_vms_and_nets. Port get %s: %s", type(e).__name__, str(e)) + self.logger.error( + "refresh_vms_and_nets. Port get %s: %s", + type(e).__name__, + str(e), + ) + + if vm["status"] == "ACTIVE" and not management_ip: + vm["status"] = "ACTIVE:NoMgmtIP" - if vm['status'] == "ACTIVE" and not management_ip: - vm['status'] = "ACTIVE:NoMgmtIP" - except vimconn.VimConnNotFoundException as e: self.logger.error("Exception getting vm status: %s", str(e)) - vm['status'] = "DELETED" - vm['error_msg'] = str(e) - except (requests.exceptions.RequestException, js_e.ValidationError, vimconn.VimConnException) as e: + vm["status"] = "DELETED" + vm["error_msg"] = str(e) + except ( + requests.exceptions.RequestException, + js_e.ValidationError, + vimconn.VimConnException, + ) as e: self.logger.error("Exception getting vm status: %s", str(e)) - vm['status'] = "VIM_ERROR" - vm['error_msg'] = str(e) + vm["status"] = "VIM_ERROR" + vm["error_msg"] = str(e) vm_dict[vm_id] = vm return vm_dict def refresh_nets_status(self, net_list): - '''Get the status of the networks - Params: the list of network identifiers - Returns a dictionary with: - net_id: #VIM id of this network - status: #Mandatory. Text with one of: - # DELETED (not found at vim) - # VIM_ERROR (Cannot connect to VIM, VIM response error, ...) - # OTHER (Vim reported other status not understood) - # ERROR (VIM indicates an ERROR status) - # ACTIVE, INACTIVE, DOWN (admin down), - # BUILD (on building process) - # - error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR - vim_info: #Text with plain information obtained from vim (yaml.safe_dump) - - ''' + """Get the status of the networks + Params: the list of network identifiers + Returns a dictionary with: + net_id: #VIM id of this network + status: #Mandatory. Text with one of: + # DELETED (not found at vim) + # VIM_ERROR (Cannot connect to VIM, VIM response error, ...) + # OTHER (Vim reported other status not understood) + # ERROR (VIM indicates an ERROR status) + # ACTIVE, INACTIVE, DOWN (admin down), + # BUILD (on building process) + # + error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR + vim_info: #Text with plain information obtained from vim (yaml.safe_dump) + + """ try: self._get_my_tenant() except requests.exceptions.RequestException as e: self._format_request_exception(e) - - net_dict={} + + net_dict = {} for net_id in net_list: net = {} - #print "VIMConnector refresh_tenant_vms_and_nets: Getting tenant network from VIM (tenant: " + str(self.tenant) + "): " + # print "VIMConnector refresh_tenant_vms_and_nets: + # Getting tenant network from VIM (tenant: " + str(self.tenant) + "): " try: net_vim = self.get_network(net_id) - if net_vim['status'] in netStatus2manoFormat: - net["status"] = netStatus2manoFormat[ net_vim['status'] ] + if net_vim["status"] in netStatus2manoFormat: + net["status"] = netStatus2manoFormat[net_vim["status"]] else: net["status"] = "OTHER" - net["error_msg"] = "VIM status reported " + net_vim['status'] - - if net["status"] == "ACTIVE" and not net_vim['admin_state_up']: + net["error_msg"] = "VIM status reported " + net_vim["status"] + + if net["status"] == "ACTIVE" and not net_vim["admin_state_up"]: net["status"] = "DOWN" - if net_vim.get('last_error'): - net['error_msg'] = net_vim['last_error'] + if net_vim.get("last_error"): + net["error_msg"] = net_vim["last_error"] net["vim_info"] = yaml.safe_dump(net_vim) except vimconn.VimConnNotFoundException as e: self.logger.error("Exception getting net status: %s", str(e)) - net['status'] = "DELETED" - net['error_msg'] = str(e) - except (requests.exceptions.RequestException, js_e.ValidationError, vimconn.VimConnException) as e: + net["status"] = "DELETED" + net["error_msg"] = str(e) + except ( + requests.exceptions.RequestException, + js_e.ValidationError, + vimconn.VimConnException, + ) as e: self.logger.error("Exception getting net status: %s", str(e)) - net['status'] = "VIM_ERROR" - net['error_msg'] = str(e) + net["status"] = "VIM_ERROR" + net["error_msg"] = str(e) net_dict[net_id] = net return net_dict - + def action_vminstance(self, vm_id, action_dict, created_items={}): - '''Send and action over a VM instance from VIM''' - '''Returns the status''' + """Send and action over a VM instance from VIM""" + """Returns the status""" try: self._get_my_tenant() if "console" in action_dict: - raise vimconn.VimConnException("getting console is not available at openvim", http_code=vimconn.HTTP_Service_Unavailable) - url = self.url+'/'+self.tenant+'/servers/'+vm_id+"/action" + raise vimconn.VimConnException( + "getting console is not available at openvim", + http_code=vimconn.HTTP_Service_Unavailable, + ) + url = self.url + "/" + self.tenant + "/servers/" + vm_id + "/action" self.logger.info("Action over VM instance POST %s", url) - vim_response = requests.post(url, headers = self.headers_req, data=json.dumps(action_dict) ) + vim_response = requests.post( + url, headers=self.headers_req, data=json.dumps(action_dict) + ) self._check_http_request_response(vim_response) return None except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) -#NOT USED METHODS in current version - + # NOT USED METHODS in current version + def host_vim2gui(self, host, server_dict): - '''Transform host dictionary from VIM format to GUI format, + """Transform host dictionary from VIM format to GUI format, and append to the server_dict - ''' - if type(server_dict) is not dict: - print( 'vimconnector.host_vim2gui() ERROR, param server_dict must be a dictionary') + """ + if type(server_dict) is not dict: + print( + "vimconnector.host_vim2gui() ERROR, param server_dict must be a dictionary" + ) return - RAD={} - occupation={} - for numa in host['host']['numas']: - RAD_item={} - occupation_item={} - #memory - RAD_item['memory']={'size': str(numa['memory'])+'GB', 'eligible': str(numa['hugepages'])+'GB'} - occupation_item['memory']= str(numa['hugepages_consumed'])+'GB' - #cpus - RAD_item['cpus']={} - RAD_item['cpus']['cores'] = [] - RAD_item['cpus']['eligible_cores'] = [] - occupation_item['cores']=[] - for _ in range(0, len(numa['cores']) // 2): - RAD_item['cpus']['cores'].append( [] ) - for core in numa['cores']: - RAD_item['cpus']['cores'][core['core_id']].append(core['thread_id']) - if not 'status' in core: RAD_item['cpus']['eligible_cores'].append(core['thread_id']) - if 'instance_id' in core: occupation_item['cores'].append(core['thread_id']) - #ports - RAD_item['ports']={} - occupation_item['ports']={} - for iface in numa['interfaces']: - RAD_item['ports'][ iface['pci'] ] = 'speed:'+str(iface['Mbps'])+'M' - occupation_item['ports'][ iface['pci'] ] = { 'occupied': str(100*iface['Mbps_consumed'] // iface['Mbps']) + "%" } - - RAD[ numa['numa_socket'] ] = RAD_item - occupation[ numa['numa_socket'] ] = occupation_item - server_dict[ host['host']['name'] ] = {'RAD':RAD, 'occupation':occupation} + RAD = {} + occupation = {} + for numa in host["host"]["numas"]: + RAD_item = {} + occupation_item = {} + # memory + RAD_item["memory"] = { + "size": str(numa["memory"]) + "GB", + "eligible": str(numa["hugepages"]) + "GB", + } + occupation_item["memory"] = str(numa["hugepages_consumed"]) + "GB" + # cpus + RAD_item["cpus"] = {} + RAD_item["cpus"]["cores"] = [] + RAD_item["cpus"]["eligible_cores"] = [] + occupation_item["cores"] = [] + for _ in range(0, len(numa["cores"]) // 2): + RAD_item["cpus"]["cores"].append([]) + for core in numa["cores"]: + RAD_item["cpus"]["cores"][core["core_id"]].append(core["thread_id"]) + if "status" not in core: + RAD_item["cpus"]["eligible_cores"].append(core["thread_id"]) + if "instance_id" in core: + occupation_item["cores"].append(core["thread_id"]) + # ports + RAD_item["ports"] = {} + occupation_item["ports"] = {} + for iface in numa["interfaces"]: + RAD_item["ports"][iface["pci"]] = "speed:" + str(iface["Mbps"]) + "M" + occupation_item["ports"][iface["pci"]] = { + "occupied": str(100 * iface["Mbps_consumed"] // iface["Mbps"]) + "%" + } + + RAD[numa["numa_socket"]] = RAD_item + occupation[numa["numa_socket"]] = occupation_item + server_dict[host["host"]["name"]] = {"RAD": RAD, "occupation": occupation} def get_hosts_info(self): - '''Get the information of deployed hosts - Returns the hosts content''' - #obtain hosts list - url=self.url+'/hosts' + """Get the information of deployed hosts + Returns the hosts content""" + # obtain hosts list + url = self.url + "/hosts" try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: - print( "get_hosts_info Exception: ", e.args) + print("get_hosts_info Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print("vim get", url, "response:", vim_response.status_code, vim_response.json()) - #print vim_response.status_code - #print json.dumps(vim_response.json(), indent=4) + print( + "vim get", url, "response:", vim_response.status_code, vim_response.json() + ) + # print vim_response.status_code + # print json.dumps(vim_response.json(), indent=4) if vim_response.status_code != 200: # TODO: get error - print('vimconnector.get_hosts_info error getting host list {} {}'.format(vim_response.status_code, vim_response.json())) + print( + "vimconnector.get_hosts_info error getting host list {} {}".format( + vim_response.status_code, vim_response.json() + ) + ) return -vim_response.status_code, "Error getting host list" - - res,hosts = self._format_in(vim_response, get_hosts_response_schema) - - if res==False: - print("vimconnector.get_hosts_info error parsing GET HOSTS vim response", hosts) + + res, hosts = self._format_in(vim_response, get_hosts_response_schema) + + if not res: + print( + "vimconnector.get_hosts_info error parsing GET HOSTS vim response", + hosts, + ) return vimconn.HTTP_Internal_Server_Error, hosts - #obtain hosts details - hosts_dict={} - for host in hosts['hosts']: - url=self.url+'/hosts/'+host['id'] + # obtain hosts details + hosts_dict = {} + for host in hosts["hosts"]: + url = self.url + "/hosts/" + host["id"] try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: - print( "get_hosts_info Exception: ", e.args) + print("get_hosts_info Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print("vim get", url, "response:", vim_response.status_code, vim_response.json()) + print( + "vim get", + url, + "response:", + vim_response.status_code, + vim_response.json(), + ) if vim_response.status_code != 200: - print('vimconnector.get_hosts_info error getting detailed host {} {}'.format(vim_response.status_code, vim_response.json())) + print( + "vimconnector.get_hosts_info error getting detailed host {} {}".format( + vim_response.status_code, vim_response.json() + ) + ) continue - res,host_detail = self._format_in(vim_response, get_host_detail_response_schema) - if res==False: - print ("vimconnector.get_hosts_info error parsing GET HOSTS/{} vim response {}".format(host['id']), host_detail) + res, host_detail = self._format_in( + vim_response, get_host_detail_response_schema + ) + if not res: + print( + "vimconnector.get_hosts_info error parsing GET HOSTS/{} vim response {}".format( + host["id"], host_detail + ), + ) continue - #print 'host id '+host['id'], json.dumps(host_detail, indent=4) + # print 'host id '+host['id'], json.dumps(host_detail, indent=4) self.host_vim2gui(host_detail, hosts_dict) return 200, hosts_dict def get_hosts(self, vim_tenant): - '''Get the hosts and deployed instances - Returns the hosts content''' - #obtain hosts list - url=self.url+'/hosts' + """Get the hosts and deployed instances + Returns the hosts content""" + # obtain hosts list + url = self.url + "/hosts" try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: print("get_hosts Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print("vim get", url, "response:", vim_response.status_code, vim_response.json()) - #print vim_response.status_code - #print json.dumps(vim_response.json(), indent=4) + print( + "vim get", url, "response:", vim_response.status_code, vim_response.json() + ) + # print vim_response.status_code + # print json.dumps(vim_response.json(), indent=4) if vim_response.status_code != 200: - #TODO: get error - print('vimconnector.get_hosts error getting host list {} {}'.format(vim_response.status_code, vim_response.json())) + # TODO: get error + print( + "vimconnector.get_hosts error getting host list {} {}".format( + vim_response.status_code, vim_response.json() + ) + ) return -vim_response.status_code, "Error getting host list" - - res,hosts = self._format_in(vim_response, get_hosts_response_schema) - - if res==False: + + res, hosts = self._format_in(vim_response, get_hosts_response_schema) + + if not res: print("vimconnector.get_host error parsing GET HOSTS vim response", hosts) return vimconn.HTTP_Internal_Server_Error, hosts - #obtain instances from hosts - for host in hosts['hosts']: - url=self.url+'/' + vim_tenant + '/servers?hostId='+host['id'] + # obtain instances from hosts + for host in hosts["hosts"]: + url = self.url + "/" + vim_tenant + "/servers?hostId=" + host["id"] try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: print("get_hosts Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print("vim get", url, "response:", vim_response.status_code, vim_response.json()) + print( + "vim get", + url, + "response:", + vim_response.status_code, + vim_response.json(), + ) if vim_response.status_code != 200: - print('vimconnector.get_hosts error getting instances at host {} {}'.format(vim_response.status_code, vim_response.json())) + print( + "vimconnector.get_hosts error getting instances at host {} {}".format( + vim_response.status_code, vim_response.json() + ) + ) continue - res,servers = self._format_in(vim_response, get_server_response_schema) - if res==False: - print("vimconnector.get_host error parsing GET SERVERS/{} vim response {}".format(host['id']), servers) + res, servers = self._format_in(vim_response, get_server_response_schema) + if not res: + print( + "vimconnector.get_host error parsing GET SERVERS/{} vim response {}".format( + host["id"], servers + ), + ) continue - #print 'host id '+host['id'], json.dumps(host_detail, indent=4) - host['instances'] = servers['servers'] - return 200, hosts['hosts'] + # print 'host id '+host['id'], json.dumps(host_detail, indent=4) + host["instances"] = servers["servers"] + return 200, hosts["hosts"] def get_processor_rankings(self): - '''Get the processor rankings in the VIM database''' - url=self.url+'/processor_ranking' + """Get the processor rankings in the VIM database""" + url = self.url + "/processor_ranking" try: vim_response = requests.get(url) except requests.exceptions.RequestException as e: print("get_processor_rankings Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print("vim get", url, "response:", vim_response.status_code, vim_response.json()) - #print vim_response.status_code - #print json.dumps(vim_response.json(), indent=4) + print( + "vim get", url, "response:", vim_response.status_code, vim_response.json() + ) + # print vim_response.status_code + # print json.dumps(vim_response.json(), indent=4) if vim_response.status_code != 200: - #TODO: get error - print('vimconnector.get_processor_rankings error getting processor rankings {} {}'.format(vim_response.status_code, vim_response.json())) + # TODO: get error + print( + "vimconnector.get_processor_rankings error getting processor rankings {} {}".format( + vim_response.status_code, vim_response.json() + ) + ) return -vim_response.status_code, "Error getting processor rankings" - - res,rankings = self._format_in(vim_response, get_processor_rankings_response_schema) - return res, rankings['rankings'] - + + res, rankings = self._format_in( + vim_response, get_processor_rankings_response_schema + ) + return res, rankings["rankings"] + def new_host(self, host_data): - '''Adds a new host to VIM''' - '''Returns status code of the VIM response''' + """Adds a new host to VIM""" + """Returns status code of the VIM response""" payload_req = host_data try: - url = self.url_admin+'/hosts' + url = self.url_admin + "/hosts" self.logger.info("Adding a new host POST %s", url) - vim_response = requests.post(url, headers = self.headers_req, data=payload_req) + vim_response = requests.post( + url, headers=self.headers_req, data=payload_req + ) self._check_http_request_response(vim_response) self.logger.debug(vim_response.text) - #print json.dumps(vim_response.json(), indent=4) + # print json.dumps(vim_response.json(), indent=4) response = vim_response.json() js_v(response, new_host_response_schema) r = self._remove_extra_items(response, new_host_response_schema) - if r is not None: + if r is not None: self.logger.warn("Warning: remove extra items %s", str(r)) - host_id = response['host']['id'] + host_id = response["host"]["id"] return host_id except (requests.exceptions.RequestException, js_e.ValidationError) as e: self._format_request_exception(e) - + def new_external_port(self, port_data): - '''Adds a external port to VIM''' - '''Returns the port identifier''' - #TODO change to logging exception code policies - print( "VIMConnector: Adding a new external port") + """Adds a external port to VIM""" + """Returns the port identifier""" + # TODO change to logging exception code policies + print("VIMConnector: Adding a new external port") payload_req = port_data try: - vim_response = requests.post(self.url_admin+'/ports', headers = self.headers_req, data=payload_req) + vim_response = requests.post( + self.url_admin + "/ports", headers=self.headers_req, data=payload_req + ) except requests.exceptions.RequestException as e: self.logger.error("new_external_port Exception: ", str(e)) return -vimconn.HTTP_Not_Found, str(e.args[0]) - print( vim_response) - #print vim_response.status_code + print(vim_response) + # print vim_response.status_code if vim_response.status_code == 200: - #print vim_response.json() - #print json.dumps(vim_response.json(), indent=4) + # print vim_response.json() + # print json.dumps(vim_response.json(), indent=4) res, http_content = self._format_in(vim_response, new_port_response_schema) - #print http_content + # print http_content if res: r = self._remove_extra_items(http_content, new_port_response_schema) - if r is not None: print("Warning: remove extra items ", r) - #print http_content - port_id = http_content['port']['id'] - print("Port id: ",port_id) - return vim_response.status_code,port_id - else: return -vimconn.HTTP_Bad_Request,http_content + if r is not None: + print("Warning: remove extra items ", r) + # print http_content + port_id = http_content["port"]["id"] + print("Port id: ", port_id) + return vim_response.status_code, port_id + else: + return -vimconn.HTTP_Bad_Request, http_content else: - #print vim_response.text + # print vim_response.text jsonerror = self._format_jsonerror(vim_response) text = 'Error in VIM "{}": not possible to add new external port. HTTP Response: {}. Error: {}'.format( - self.url_admin, vim_response.status_code, jsonerror) - #print text - return -vim_response.status_code,text - - def new_external_network(self,net_name,net_type): - '''Adds a external network to VIM (shared)''' - '''Returns the network identifier''' - #TODO change to logging exception code policies - print("VIMConnector: Adding external shared network to VIM (type " + net_type + "): "+ net_name) - - payload_req = '{"network":{"name": "' + net_name + '","shared":true,"type": "' + net_type + '"}}' + self.url_admin, vim_response.status_code, jsonerror + ) + # print text + return -vim_response.status_code, text + + def new_external_network(self, net_name, net_type): + """Adds a external network to VIM (shared)""" + """Returns the network identifier""" + # TODO change to logging exception code policies + print( + "VIMConnector: Adding external shared network to VIM (type " + + net_type + + "): " + + net_name + ) + + payload_req = ( + '{"network":{"name": "' + + net_name + + '","shared":true,"type": "' + + net_type + + '"}}' + ) try: - vim_response = requests.post(self.url+'/networks', headers = self.headers_req, data=payload_req) + vim_response = requests.post( + self.url + "/networks", headers=self.headers_req, data=payload_req + ) except requests.exceptions.RequestException as e: - self.logger.error( "new_external_network Exception: ", e.args) + self.logger.error("new_external_network Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) print(vim_response) - #print vim_response.status_code + # print vim_response.status_code if vim_response.status_code == 200: - #print vim_response.json() - #print json.dumps(vim_response.json(), indent=4) - res,http_content = self._format_in(vim_response, new_network_response_schema) - #print http_content + # print vim_response.json() + # print json.dumps(vim_response.json(), indent=4) + res, http_content = self._format_in( + vim_response, new_network_response_schema + ) + # print http_content if res: r = self._remove_extra_items(http_content, new_network_response_schema) - if r is not None: print("Warning: remove extra items ", r) - #print http_content - network_id = http_content['network']['id'] - print( "Network id: ",network_id) - return vim_response.status_code,network_id - else: return -vimconn.HTTP_Bad_Request,http_content + if r is not None: + print("Warning: remove extra items ", r) + # print http_content + network_id = http_content["network"]["id"] + print("Network id: ", network_id) + return vim_response.status_code, network_id + else: + return -vimconn.HTTP_Bad_Request, http_content else: - #print vim_response.text + # print vim_response.text jsonerror = self._format_jsonerror(vim_response) text = 'Error in VIM "{}": not possible to add new external network. HTTP Response: {}. Error: {}'.format( - self.url, vim_response.status_code, jsonerror) - #print text - return -vim_response.status_code,text - + self.url, vim_response.status_code, jsonerror + ) + # print text + return -vim_response.status_code, text + def connect_port_network(self, port_id, network_id, admin=False): - '''Connects a external port to a network''' - '''Returns status code of the VIM response''' - #TODO change to logging exception code policies + """Connects a external port to a network""" + """Returns status code of the VIM response""" + # TODO change to logging exception code policies print("VIMConnector: Connecting external port to network") - + payload_req = '{"port":{"network_id":"' + network_id + '"}}' if admin: - if self.url_admin==None: - return -vimconn.HTTP_Unauthorized, "datacenter cannot contain admin URL" - url= self.url_admin + if self.url_admin is None: + return ( + -vimconn.HTTP_Unauthorized, + "datacenter cannot contain admin URL", + ) + url = self.url_admin else: - url= self.url + url = self.url try: - vim_response = requests.put(url +'/ports/'+port_id, headers = self.headers_req, data=payload_req) + vim_response = requests.put( + url + "/ports/" + port_id, headers=self.headers_req, data=payload_req + ) except requests.exceptions.RequestException as e: print("connect_port_network Exception: ", e.args) return -vimconn.HTTP_Not_Found, str(e.args[0]) print(vim_response) - #print vim_response.status_code + # print vim_response.status_code if vim_response.status_code == 200: - #print vim_response.json() - #print json.dumps(vim_response.json(), indent=4) - res,http_content = self._format_in(vim_response, new_port_response_schema) - #print http_content + # print vim_response.json() + # print json.dumps(vim_response.json(), indent=4) + res, http_content = self._format_in(vim_response, new_port_response_schema) + # print http_content if res: r = self._remove_extra_items(http_content, new_port_response_schema) - if r is not None: print("Warning: remove extra items ", r) - #print http_content - port_id = http_content['port']['id'] - print("Port id: ",port_id) - return vim_response.status_code,port_id - else: return -vimconn.HTTP_Bad_Request,http_content + if r is not None: + print("Warning: remove extra items ", r) + # print http_content + port_id = http_content["port"]["id"] + print("Port id: ", port_id) + return vim_response.status_code, port_id + else: + return -vimconn.HTTP_Bad_Request, http_content else: print(vim_response.text) jsonerror = self._format_jsonerror(vim_response) - text = 'Error in VIM "{}": not possible to connect external port to network. HTTP Response: {}.' \ - ' Error: {}'.format(self.url_admin, vim_response.status_code, jsonerror) + text = ( + 'Error in VIM "{}": not possible to connect external port to network. HTTP Response: {}.' + " Error: {}".format(self.url_admin, vim_response.status_code, jsonerror) + ) print(text) - return -vim_response.status_code,text - - + return -vim_response.status_code, text