X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_lcm%2FROclient.py;h=32dd1bf3ac6e6c59cb9edeb1b322c2c1b36c541e;hb=refs%2Fchanges%2F34%2F10534%2F3;hp=de61c23d60c657c7a9636b54206bbc7f5bd54871;hpb=021e70d2eb5caa25a7e731ed70f2a008cf8057d7;p=osm%2FLCM.git diff --git a/osm_lcm/ROclient.py b/osm_lcm/ROclient.py index de61c23..32dd1bf 100644 --- a/osm_lcm/ROclient.py +++ b/osm_lcm/ROclient.py @@ -57,23 +57,29 @@ def remove_envelop(item, indata=None): if not indata: return {} if item == "vnfd": - if clean_indata.get('vnfd:vnfd-catalog'): - clean_indata = clean_indata['vnfd:vnfd-catalog'] - elif clean_indata.get('vnfd-catalog'): - clean_indata = clean_indata['vnfd-catalog'] - if clean_indata.get('vnfd'): - if not isinstance(clean_indata['vnfd'], list) or len(clean_indata['vnfd']) != 1: + if clean_indata.get("vnfd:vnfd-catalog"): + clean_indata = clean_indata["vnfd:vnfd-catalog"] + elif clean_indata.get("vnfd-catalog"): + clean_indata = clean_indata["vnfd-catalog"] + if clean_indata.get("vnfd"): + if ( + not isinstance(clean_indata["vnfd"], list) + or len(clean_indata["vnfd"]) != 1 + ): raise ROClientException("'vnfd' must be a list only one element") - clean_indata = clean_indata['vnfd'][0] + clean_indata = clean_indata["vnfd"][0] elif item == "nsd": - if clean_indata.get('nsd:nsd-catalog'): - clean_indata = clean_indata['nsd:nsd-catalog'] - elif clean_indata.get('nsd-catalog'): - clean_indata = clean_indata['nsd-catalog'] - if clean_indata.get('nsd'): - if not isinstance(clean_indata['nsd'], list) or len(clean_indata['nsd']) != 1: + if clean_indata.get("nsd:nsd-catalog"): + clean_indata = clean_indata["nsd:nsd-catalog"] + elif clean_indata.get("nsd-catalog"): + clean_indata = clean_indata["nsd-catalog"] + if clean_indata.get("nsd"): + if ( + not isinstance(clean_indata["nsd"], list) + or len(clean_indata["nsd"]) != 1 + ): raise ROClientException("'nsd' must be a list only one element") - clean_indata = clean_indata['nsd'][0] + clean_indata = clean_indata["nsd"][0] elif item == "sdn": if len(indata) == 1 and "sdn_controller" in indata: clean_indata = indata["sdn_controller"] @@ -99,20 +105,28 @@ def remove_envelop(item, indata=None): class ROClient: - headers_req = {'Accept': 'application/yaml', 'content-type': 'application/yaml'} - client_to_RO = {'tenant': 'tenants', 'vim': 'datacenters', 'vim_account': 'datacenters', 'sdn': 'sdn_controllers', - 'vnfd': 'vnfs', 'nsd': 'scenarios', 'wim': 'wims', 'wim_account': 'wims', - 'ns': 'instances'} + headers_req = {"Accept": "application/yaml", "content-type": "application/yaml"} + client_to_RO = { + "tenant": "tenants", + "vim": "datacenters", + "vim_account": "datacenters", + "sdn": "sdn_controllers", + "vnfd": "vnfs", + "nsd": "scenarios", + "wim": "wims", + "wim_account": "wims", + "ns": "instances", + } mandatory_for_create = { - 'tenant': ("name", ), - 'vnfd': ("name", "id"), - 'nsd': ("name", "id"), - 'ns': ("name", "scenario", "datacenter"), - 'vim': ("name", "vim_url"), - 'wim': ("name", "wim_url"), - 'vim_account': (), - 'wim_account': (), - 'sdn': ("name", 'type'), + "tenant": ("name",), + "vnfd": ("name", "id"), + "nsd": ("name", "id"), + "ns": ("name", "scenario", "datacenter"), + "vim": ("name", "vim_url"), + "wim": ("name", "wim_url"), + "vim_account": (), + "wim_account": (), + "sdn": ("name", "type"), } timeout_large = 120 timeout_short = 30 @@ -127,7 +141,7 @@ class ROClient: self.tenant = None self.datacenter_id_name = kwargs.get("datacenter") self.datacenter = None - logger_name = kwargs.get('logger_name', 'lcm.ro') + logger_name = kwargs.get("logger_name", "lcm.ro") self.logger = logging.getLogger(logger_name) if kwargs.get("loglevel"): self.logger.setLevel(kwargs["loglevel"]) @@ -135,47 +149,55 @@ class ROClient: requests = kwargs.get("TODO remove") def __getitem__(self, index): - if index == 'tenant': + if index == "tenant": return self.tenant_id_name - elif index == 'datacenter': + elif index == "datacenter": return self.datacenter_id_name - elif index == 'username': + elif index == "username": return self.username - elif index == 'password': + elif index == "password": return self.password - elif index == 'uri': + elif index == "uri": return self.uri else: raise KeyError("Invalid key '{}'".format(index)) def __setitem__(self, index, value): - if index == 'tenant': + if index == "tenant": self.tenant_id_name = value - elif index == 'datacenter' or index == 'vim': + elif index == "datacenter" or index == "vim": self.datacenter_id_name = value - elif index == 'username': + elif index == "username": self.username = value - elif index == 'password': + elif index == "password": self.password = value - elif index == 'uri': + elif index == "uri": self.uri = value else: raise KeyError("Invalid key '{}'".format(index)) - self.tenant = None # force to reload tenant with different credentials + self.tenant = None # force to reload tenant with different credentials self.datacenter = None # force to reload datacenter with different credentials @staticmethod def _parse(descriptor, descriptor_format, response=False): - if descriptor_format and descriptor_format != "json" and descriptor_format != "yaml": - raise ROClientException("'descriptor_format' must be a 'json' or 'yaml' text") + if ( + descriptor_format + and descriptor_format != "json" + and descriptor_format != "yaml" + ): + raise ROClientException( + "'descriptor_format' must be a 'json' or 'yaml' text" + ) if descriptor_format != "json": try: return yaml.load(descriptor) except yaml.YAMLError as exc: error_pos = "" - if hasattr(exc, 'problem_mark'): + if hasattr(exc, "problem_mark"): mark = exc.problem_mark - error_pos = " at line:{} column:{}s".format(mark.line + 1, mark.column + 1) + error_pos = " at line:{} column:{}s".format( + mark.line + 1, mark.column + 1 + ) error_text = "yaml format error" + error_pos elif descriptor_format != "yaml": try: @@ -203,9 +225,11 @@ class ROClient: return yaml.load(descriptor, Loader=yaml.Loader) except yaml.YAMLError as exc: error_pos = "" - if hasattr(exc, 'problem_mark'): + if hasattr(exc, "problem_mark"): mark = exc.problem_mark - error_pos = " at line:{} column:{}s".format(mark.line + 1, mark.column + 1) + error_pos = " at line:{} column:{}s".format( + mark.line + 1, mark.column + 1 + ) error_text = "yaml format error" + error_pos if response: raise ROClientException(error_text) @@ -233,21 +257,21 @@ class ROClient: :return: a new dic with {: {indata} } where envelop can be e.g. tenant, datacenter, ... """ if item == "vnfd": - return {'vnfd-catalog': {'vnfd': [indata]}} + return {"vnfd-catalog": {"vnfd": [indata]}} elif item == "nsd": - return {'nsd-catalog': {'nsd': [indata]}} + return {"nsd-catalog": {"nsd": [indata]}} elif item == "tenant": - return {'tenant': indata} + return {"tenant": indata} elif item in ("vim", "vim_account", "datacenter"): - return {'datacenter': indata} + return {"datacenter": indata} elif item == "wim": - return {'wim': indata} + return {"wim": indata} elif item == "wim_account": - return {'wim_account': indata} + return {"wim_account": indata} elif item == "ns" or item == "instances": - return {'instance': indata} + return {"instance": indata} elif item == "sdn": - return {'sdn_controller': indata} + return {"sdn_controller": indata} else: assert False, "_create_envelop with unknown item {}".format(item) @@ -268,7 +292,10 @@ class ROClient: kitem_old = int(kitem) else: raise ROClientException( - "Invalid query string '{}'. Descriptor is not a list nor dict at '{}'".format(k, kitem)) + "Invalid query string '{}'. Descriptor is not a list nor dict at '{}'".format( + k, kitem + ) + ) if v == "__DELETE__": del update_content[kitem_old] else: @@ -276,13 +303,22 @@ class ROClient: return desc except KeyError: raise ROClientException( - "Invalid query string '{}'. Descriptor does not contain '{}'".format(k, kitem_old)) + "Invalid query string '{}'. Descriptor does not contain '{}'".format( + k, kitem_old + ) + ) except ValueError: - raise ROClientException("Invalid query string '{}'. Expected integer index list instead of '{}'".format( - k, kitem)) + raise ROClientException( + "Invalid query string '{}'. Expected integer index list instead of '{}'".format( + k, kitem + ) + ) except IndexError: raise ROClientException( - "Invalid query string '{}'. Index '{}' out of range".format(k, kitem_old)) + "Invalid query string '{}'. Index '{}' out of range".format( + k, kitem_old + ) + ) @staticmethod def check_ns_status(ns_descriptor): @@ -313,7 +349,10 @@ class ROClient: def _get_sdn_ref(sce_net_id): # look for the network associated to the SDN network and obtain the identification - net = next((x for x in ns_descriptor["nets"] if x.get("sce_net_id") == sce_net_id), None) + net = next( + (x for x in ns_descriptor["nets"] if x.get("sce_net_id") == sce_net_id), + None, + ) if not sce_net_id or not net: return "" return _get_ref(net) @@ -322,15 +361,23 @@ class ROClient: total["networks"] = len(ns_descriptor["nets"]) for net in ns_descriptor["nets"]: if net["status"] in ("ERROR", "VIM_ERROR"): - error_list.append("Error at VIM network {}: {}".format(_get_ref(net), net["error_msg"])) + error_list.append( + "Error at VIM network {}: {}".format( + _get_ref(net), net["error_msg"] + ) + ) elif net["status"] == "ACTIVE": done["networks"] += 1 total["SDN_networks"] = len(ns_descriptor["sdn_nets"]) for sdn_net in ns_descriptor["sdn_nets"]: if sdn_net["status"] in ("ERROR", "VIM_ERROR", "WIM_ERROR"): - error_list.append("Error at SDN network {}: {}".format(_get_sdn_ref(sdn_net.get("sce_net_id")), - sdn_net["error_msg"])) + error_list.append( + "Error at SDN network {}: {}".format( + _get_sdn_ref(sdn_net.get("sce_net_id")), + sdn_net["error_msg"], + ) + ) elif sdn_net["status"] == "ACTIVE": done["SDN_networks"] += 1 @@ -338,19 +385,35 @@ class ROClient: for vm in vnf["vms"]: total["VMs"] += 1 if vm["status"] in ("ERROR", "VIM_ERROR"): - error_list.append("Error at VIM VM {}: {}".format(_get_ref(vm), vm["error_msg"])) + error_list.append( + "Error at VIM VM {}: {}".format( + _get_ref(vm), vm["error_msg"] + ) + ) elif vm["status"] == "ACTIVE": done["VMs"] += 1 if error_list: # skip errors caused because other dependendent task is on error - return "ERROR", "; ".join([el for el in error_list if "because depends on failed ACTION" not in el]) + return "ERROR", "; ".join( + [ + el + for el in error_list + if "because depends on failed ACTION" not in el + ] + ) if all(total[x] == done[x] for x in total): # DONE == TOTAL for all items - return "ACTIVE", str({x: total[x] for x in total if total[x]}) # print only those which value is not 0 + return "ACTIVE", str( + {x: total[x] for x in total if total[x]} + ) # print only those which value is not 0 else: - return "BUILD", str({x: "{}/{}".format(done[x], total[x]) for x in total if total[x]}) + return "BUILD", str( + {x: "{}/{}".format(done[x], total[x]) for x in total if total[x]} + ) # print done/total for each item if total is not 0 except Exception as e: - raise ROClientException("Unexpected RO ns descriptor. Wrong version? {}".format(e)) from e + raise ROClientException( + "Unexpected RO ns descriptor. Wrong version? {}".format(e) + ) from e @staticmethod def check_action_status(action_descriptor): @@ -385,10 +448,13 @@ class ROClient: other_done += 1 if net_total == net_done and vm_total == vm_done and other_total == other_done: - return "ACTIVE", "VMs {}, networks: {}, other: {} ".format(vm_total, net_total, other_total) + return "ACTIVE", "VMs {}, networks: {}, other: {} ".format( + vm_total, net_total, other_total + ) else: - return "BUILD", "VMs: {}/{}, networks: {}/{}, other: {}/{}".format(vm_done, vm_total, net_done, net_total, - other_done, other_total) + return "BUILD", "VMs: {}/{}, networks: {}/{}, other: {}/{}".format( + vm_done, vm_total, net_done, net_total, other_done, other_total + ) @staticmethod def get_ns_vnf_info(ns_descriptor): @@ -410,27 +476,35 @@ class ROClient: ns_info = {} for vnf in ns_descriptor["vnfs"]: if not vnf.get("ip_address") and vnf.get("vms"): - raise ROClientException("ns member_vnf_index '{}' has no IP address".format( - vnf["member_vnf_index"]), http_code=409) - vnfr_info = { - "ip_address": vnf.get("ip_address"), - "vdur": {} - } + raise ROClientException( + "ns member_vnf_index '{}' has no IP address".format( + vnf["member_vnf_index"] + ), + http_code=409, + ) + vnfr_info = {"ip_address": vnf.get("ip_address"), "vdur": {}} for vm in vnf["vms"]: vdur = { "vim_id": vm.get("vim_vm_id"), "ip_address": vm.get("ip_address"), - "interfaces": {} + "interfaces": {}, } for iface in vm["interfaces"]: if iface.get("type") == "mgmt" and not iface.get("ip_address"): - raise ROClientException("ns member_vnf_index '{}' vm '{}' management interface '{}' has no IP " - "address".format(vnf["member_vnf_index"], vm["vdu_osm_id"], - iface["external_name"]), http_code=409) - vdur["interfaces"][iface["internal_name"]] = {"ip_address": iface.get("ip_address"), - "mac_address": iface.get("mac_address"), - "vim_id": iface.get("vim_interface_id"), - } + raise ROClientException( + "ns member_vnf_index '{}' vm '{}' management interface '{}' has no IP " + "address".format( + vnf["member_vnf_index"], + vm["vdu_osm_id"], + iface["external_name"], + ), + http_code=409, + ) + vdur["interfaces"][iface["internal_name"]] = { + "ip_address": iface.get("ip_address"), + "mac_address": iface.get("mac_address"), + "vim_id": iface.get("vim_interface_id"), + } vnfr_info["vdur"][vm["vdu_osm_id"]] = vdur ns_info[str(vnf["member_vnf_index"])] = vnfr_info return ns_info @@ -450,38 +524,62 @@ class ROClient: if self.check_if_uuid(item_id_name): item_id = item_id_name url += "/" + item_id_name - elif item_id_name and item_id_name.startswith("'") and item_id_name.endswith("'"): + elif ( + item_id_name and item_id_name.startswith("'") and item_id_name.endswith("'") + ): item_id_name = item_id_name[1:-1] self.logger.debug("RO GET %s", url) # timeout = aiohttp.ClientTimeout(total=self.timeout_short) async with session.get(url, headers=self.headers_req) as response: response_text = await response.read() - self.logger.debug("GET {} [{}] {}".format(url, response.status, response_text[:100])) + self.logger.debug( + "GET {} [{}] {}".format(url, response.status, response_text[:100]) + ) if response.status == 404: # NOT_FOUND - raise ROClientException("No {} found with id '{}'".format(item[:-1], item_id_name), - http_code=404) + raise ROClientException( + "No {} found with id '{}'".format(item[:-1], item_id_name), + http_code=404, + ) if response.status >= 300: - raise ROClientException(self._parse_error_yaml(response_text), http_code=response.status) + raise ROClientException( + self._parse_error_yaml(response_text), http_code=response.status + ) content = self._parse_yaml(response_text, response=True) if item_id: return item_id desc = content[item] - assert isinstance(desc, list), "_get_item_uuid get a non dict with a list inside {}".format(type(desc)) + assert isinstance( + desc, list + ), "_get_item_uuid get a non dict with a list inside {}".format(type(desc)) uuid = None for i in desc: if item_id_name and i["name"] != item_id_name: continue if uuid: # found more than one raise ROClientException( - "Found more than one {} with name '{}'. uuid must be used".format(item, item_id_name), - http_code=404) + "Found more than one {} with name '{}'. uuid must be used".format( + item, item_id_name + ), + http_code=404, + ) uuid = i["uuid"] if not uuid: - raise ROClientException("No {} found with name '{}'".format(item[:-1], item_id_name), http_code=404) + raise ROClientException( + "No {} found with name '{}'".format(item[:-1], item_id_name), + http_code=404, + ) return uuid - async def _get_item(self, session, item, item_id_name, extra_item=None, extra_item_id=None, all_tenants=False): + async def _get_item( + self, + session, + item, + item_id_name, + extra_item=None, + extra_item_id=None, + all_tenants=False, + ): if all_tenants: tenant_text = "/any" elif all_tenants is None: @@ -506,25 +604,41 @@ class ROClient: # timeout = aiohttp.ClientTimeout(total=self.timeout_short) async with session.get(url, headers=self.headers_req) as response: response_text = await response.read() - self.logger.debug("GET {} [{}] {}".format(url, response.status, response_text[:100])) + self.logger.debug( + "GET {} [{}] {}".format(url, response.status, response_text[:100]) + ) if response.status >= 300: - raise ROClientException(self._parse_error_yaml(response_text), http_code=response.status) + raise ROClientException( + self._parse_error_yaml(response_text), http_code=response.status + ) return self._parse_yaml(response_text, response=True) async def _get_tenant(self, session): if not self.tenant: - self.tenant = await self._get_item_uuid(session, "tenants", self.tenant_id_name, None) + self.tenant = await self._get_item_uuid( + session, "tenants", self.tenant_id_name, None + ) return self.tenant async def _get_datacenter(self, session): if not self.tenant: await self._get_tenant(session) if not self.datacenter: - self.datacenter = await self._get_item_uuid(session, "datacenters", self.datacenter_id_name, True) + self.datacenter = await self._get_item_uuid( + session, "datacenters", self.datacenter_id_name, True + ) return self.datacenter - async def _create_item(self, session, item, descriptor, item_id_name=None, action=None, all_tenants=False): + async def _create_item( + self, + session, + item, + descriptor, + item_id_name=None, + action=None, + all_tenants=False, + ): if all_tenants: tenant_text = "/any" elif all_tenants is None: @@ -559,15 +673,27 @@ class ROClient: else: action = "/{}".format(action) - url = "{}{apiver}{tenant}/{item}{id}{action}".format(self.uri, apiver=api_version_text, - tenant=tenant_text, item=item, id=uuid, action=action) + url = "{}{apiver}{tenant}/{item}{id}{action}".format( + self.uri, + apiver=api_version_text, + tenant=tenant_text, + item=item, + id=uuid, + action=action, + ) self.logger.debug("RO POST %s %s", url, payload_req) # timeout = aiohttp.ClientTimeout(total=self.timeout_large) - async with session.post(url, headers=self.headers_req, data=payload_req) as response: + async with session.post( + url, headers=self.headers_req, data=payload_req + ) as response: response_text = await response.read() - self.logger.debug("POST {} [{}] {}".format(url, response.status, response_text[:100])) + self.logger.debug( + "POST {} [{}] {}".format(url, response.status, response_text[:100]) + ) if response.status >= 300: - raise ROClientException(self._parse_error_yaml(response_text), http_code=response.status) + raise ROClientException( + self._parse_error_yaml(response_text), http_code=response.status + ) return self._parse_yaml(response_text, response=True) @@ -583,9 +709,11 @@ class ROClient: if not self.check_if_uuid(item_id_name): # check that exist _all_tenants = all_tenants - if item in ("datacenters", 'wims'): + if item in ("datacenters", "wims"): _all_tenants = True - uuid = await self._get_item_uuid(session, item, item_id_name, all_tenants=_all_tenants) + uuid = await self._get_item_uuid( + session, item, item_id_name, all_tenants=_all_tenants + ) else: uuid = item_id_name @@ -594,9 +722,13 @@ class ROClient: # timeout = aiohttp.ClientTimeout(total=self.timeout_short) async with session.delete(url, headers=self.headers_req) as response: response_text = await response.read() - self.logger.debug("DELETE {} [{}] {}".format(url, response.status, response_text[:100])) + self.logger.debug( + "DELETE {} [{}] {}".format(url, response.status, response_text[:100]) + ) if response.status >= 300: - raise ROClientException(self._parse_error_yaml(response_text), http_code=response.status) + raise ROClientException( + self._parse_error_yaml(response_text), http_code=response.status + ) return self._parse_yaml(response_text, response=True) @@ -620,9 +752,13 @@ class ROClient: # timeout = aiohttp.ClientTimeout(total=self.timeout_short) async with session.get(url, headers=self.headers_req) as response: response_text = await response.read() - self.logger.debug("GET {} [{}] {}".format(url, response.status, response_text[:100])) + self.logger.debug( + "GET {} [{}] {}".format(url, response.status, response_text[:100]) + ) if response.status >= 300: - raise ROClientException(self._parse_error_yaml(response_text), http_code=response.status) + raise ROClientException( + self._parse_error_yaml(response_text), http_code=response.status + ) return self._parse_yaml(response_text, response=True) @@ -642,11 +778,17 @@ class ROClient: url = "{}{}/{}/{}".format(self.uri, tenant_text, item, item_id) self.logger.debug("RO PUT %s %s", url, payload_req) # timeout = aiohttp.ClientTimeout(total=self.timeout_large) - async with session.put(url, headers=self.headers_req, data=payload_req) as response: + async with session.put( + url, headers=self.headers_req, data=payload_req + ) as response: response_text = await response.read() - self.logger.debug("PUT {} [{}] {}".format(url, response.status, response_text[:100])) + self.logger.debug( + "PUT {} [{}] {}".format(url, response.status, response_text[:100]) + ) if response.status >= 300: - raise ROClientException(self._parse_error_yaml(response_text), http_code=response.status) + raise ROClientException( + self._parse_error_yaml(response_text), http_code=response.status + ) return self._parse_yaml(response_text, response=True) @@ -663,22 +805,36 @@ class ROClient: # timeout = aiohttp.ClientTimeout(total=self.timeout_short) async with session.get(url, headers=self.headers_req) as response: response_text = await response.read() - self.logger.debug("GET {} [{}] {}".format(url, response.status, response_text[:100])) + self.logger.debug( + "GET {} [{}] {}".format( + url, response.status, response_text[:100] + ) + ) if response.status >= 300: - raise ROClientException(self._parse_error_yaml(response_text), http_code=response.status) + raise ROClientException( + self._parse_error_yaml(response_text), + http_code=response.status, + ) for word in str(response_text).split(" "): if "." in word: version_text, _, _ = word.partition("-") return version_text - raise ROClientException("Got invalid version text: '{}'".format(response_text), http_code=500) + raise ROClientException( + "Got invalid version text: '{}'".format(response_text), + http_code=500, + ) except (aiohttp.ClientOSError, aiohttp.ClientError) as e: raise ROClientException(e, http_code=504) except asyncio.TimeoutError: raise ROClientException("Timeout", http_code=504) except Exception as e: - raise ROClientException("Got invalid version text: '{}'; causing exception {}".format(response_text, e), - http_code=500) + raise ROClientException( + "Got invalid version text: '{}'; causing exception {}".format( + response_text, e + ), + http_code=500, + ) async def get_list(self, item, all_tenants=False, filter_by=None): """ @@ -691,25 +847,38 @@ class ROClient: try: if item not in self.client_to_RO: raise ROClientException("Invalid item {}".format(item)) - if item == 'tenant': + if item == "tenant": all_tenants = None async with aiohttp.ClientSession(loop=self.loop) as session: - content = await self._list_item(session, self.client_to_RO[item], all_tenants=all_tenants, - filter_dict=filter_by) + content = await self._list_item( + session, + self.client_to_RO[item], + all_tenants=all_tenants, + filter_dict=filter_by, + ) if isinstance(content, dict): if len(content) == 1: for _, v in content.items(): return v return content.values()[0] else: - raise ROClientException("Output not a list neither dict with len equal 1", http_code=500) + raise ROClientException( + "Output not a list neither dict with len equal 1", http_code=500 + ) return content except (aiohttp.ClientOSError, aiohttp.ClientError) as e: raise ROClientException(e, http_code=504) except asyncio.TimeoutError: raise ROClientException("Timeout", http_code=504) - async def show(self, item, item_id_name=None, extra_item=None, extra_item_id=None, all_tenants=False): + async def show( + self, + item, + item_id_name=None, + extra_item=None, + extra_item_id=None, + all_tenants=False, + ): """ Obtain the information of an item from its id or name :param item: can be 'tenant', 'vim', 'vnfd', 'nsd', 'ns' @@ -723,16 +892,22 @@ class ROClient: try: if item not in self.client_to_RO: raise ROClientException("Invalid item {}".format(item)) - if item == 'tenant': + if item == "tenant": all_tenants = None - elif item == 'vim': + elif item == "vim": all_tenants = True - elif item == 'vim_account': + elif item == "vim_account": all_tenants = False async with aiohttp.ClientSession(loop=self.loop) as session: - content = await self._get_item(session, self.client_to_RO[item], item_id_name, extra_item=extra_item, - extra_item_id=extra_item_id, all_tenants=all_tenants) + content = await self._get_item( + session, + self.client_to_RO[item], + item_id_name, + extra_item=extra_item, + extra_item_id=extra_item_id, + all_tenants=all_tenants, + ) return remove_envelop(item, content) except (aiohttp.ClientOSError, aiohttp.ClientError) as e: raise ROClientException(e, http_code=504) @@ -750,11 +925,16 @@ class ROClient: try: if item not in self.client_to_RO: raise ROClientException("Invalid item {}".format(item)) - if item in ('tenant', 'vim', 'wim'): + if item in ("tenant", "vim", "wim"): all_tenants = None async with aiohttp.ClientSession(loop=self.loop) as session: - result = await self._del_item(session, self.client_to_RO[item], item_id_name, all_tenants=all_tenants) + result = await self._del_item( + session, + self.client_to_RO[item], + item_id_name, + all_tenants=all_tenants, + ) # in case of ns delete, get the action_id embeded in text if item == "ns" and result.get("result"): _, _, action_id = result["result"].partition("action_id=") @@ -767,8 +947,10 @@ class ROClient: except asyncio.TimeoutError: raise ROClientException("Timeout", http_code=504) - async def edit(self, item, item_id_name, descriptor=None, descriptor_format=None, **kwargs): - """ Edit an item + async def edit( + self, item, item_id_name, descriptor=None, descriptor_format=None, **kwargs + ): + """Edit an item :param item: can be 'tenant', 'vim', 'vnfd', 'nsd', 'ns', 'vim' :param item_id_name: RO id or name of the item. Raise and exception if more than one found :param descriptor: can be a dict, or a yaml/json text. Autodetect unless descriptor_format is provided @@ -793,22 +975,31 @@ class ROClient: if kwargs: desc = self.update_descriptor(desc, kwargs) all_tenants = False - if item in ('tenant', 'vim'): + if item in ("tenant", "vim"): all_tenants = None create_desc = self._create_envelop(item, desc) async with aiohttp.ClientSession(loop=self.loop) as session: _all_tenants = all_tenants - if item == 'vim': + if item == "vim": _all_tenants = True - item_id = await self._get_item_uuid(session, self.client_to_RO[item], item_id_name, - all_tenants=_all_tenants) - if item == 'vim': + item_id = await self._get_item_uuid( + session, + self.client_to_RO[item], + item_id_name, + all_tenants=_all_tenants, + ) + if item == "vim": _all_tenants = None # await self._get_tenant(session) - outdata = await self._edit_item(session, self.client_to_RO[item], item_id, create_desc, - all_tenants=_all_tenants) + outdata = await self._edit_item( + session, + self.client_to_RO[item], + item_id, + create_desc, + all_tenants=_all_tenants, + ) return remove_envelop(item, outdata) except (aiohttp.ClientOSError, aiohttp.ClientError) as e: raise ROClientException(e, http_code=504) @@ -843,24 +1034,32 @@ class ROClient: for mandatory in self.mandatory_for_create[item]: if mandatory not in desc: - raise ROClientException("'{}' is mandatory parameter for {}".format(mandatory, item)) + raise ROClientException( + "'{}' is mandatory parameter for {}".format(mandatory, item) + ) all_tenants = False - if item in ('tenant', 'vim', 'wim'): + if item in ("tenant", "vim", "wim"): all_tenants = None create_desc = self._create_envelop(item, desc) async with aiohttp.ClientSession(loop=self.loop) as session: - outdata = await self._create_item(session, self.client_to_RO[item], create_desc, - all_tenants=all_tenants) + outdata = await self._create_item( + session, + self.client_to_RO[item], + create_desc, + all_tenants=all_tenants, + ) return remove_envelop(item, outdata) except (aiohttp.ClientOSError, aiohttp.ClientError) as e: raise ROClientException(e, http_code=504) except asyncio.TimeoutError: raise ROClientException("Timeout", http_code=504) - async def create_action(self, item, item_id_name, descriptor=None, descriptor_format=None, **kwargs): + async def create_action( + self, item, item_id_name, descriptor=None, descriptor_format=None, **kwargs + ): """ Performs an action over an item :param item: can be 'tenant', 'vnfd', 'nsd', 'ns', 'vim', 'vim_account', 'sdn' @@ -888,7 +1087,7 @@ class ROClient: desc = self.update_descriptor(desc, kwargs) all_tenants = False - if item in ('tenant', 'vim'): + if item in ("tenant", "vim"): all_tenants = None action = None @@ -902,20 +1101,27 @@ class ROClient: async with aiohttp.ClientSession(loop=self.loop) as session: _all_tenants = all_tenants - if item == 'vim': + if item == "vim": _all_tenants = True # item_id = await self._get_item_uuid(session, self.client_to_RO[item], item_id_name, # all_tenants=_all_tenants) - outdata = await self._create_item(session, self.client_to_RO[item], create_desc, - item_id_name=item_id_name, # item_id_name=item_id - action=action, all_tenants=_all_tenants) + outdata = await self._create_item( + session, + self.client_to_RO[item], + create_desc, + item_id_name=item_id_name, # item_id_name=item_id + action=action, + all_tenants=_all_tenants, + ) return remove_envelop(item, outdata) except (aiohttp.ClientOSError, aiohttp.ClientError) as e: raise ROClientException(e, http_code=504) except asyncio.TimeoutError: raise ROClientException("Timeout", http_code=504) - async def attach(self, item, item_id_name=None, descriptor=None, descriptor_format=None, **kwargs): + async def attach( + self, item, item_id_name=None, descriptor=None, descriptor_format=None, **kwargs + ): """ Attach a datacenter or wim to a tenant, creating a vim_account, wim_account :param item: can be vim_account or wim_account @@ -943,27 +1149,47 @@ class ROClient: if item == "vim_account": if not desc.get("vim_tenant_name") and not desc.get("vim_tenant_id"): - raise ROClientException("Wrong descriptor. At least vim_tenant_name or vim_tenant_id must be " - "provided") + raise ROClientException( + "Wrong descriptor. At least vim_tenant_name or vim_tenant_id must be " + "provided" + ) elif item != "wim_account": - raise ROClientException("Attach with unknown item {}. Must be 'vim_account' or 'wim_account'". - format(item)) + raise ROClientException( + "Attach with unknown item {}. Must be 'vim_account' or 'wim_account'".format( + item + ) + ) create_desc = self._create_envelop(item, desc) payload_req = yaml.safe_dump(create_desc) async with aiohttp.ClientSession(loop=self.loop) as session: # check that exist - item_id = await self._get_item_uuid(session, self.client_to_RO[item], item_id_name, all_tenants=True) + item_id = await self._get_item_uuid( + session, self.client_to_RO[item], item_id_name, all_tenants=True + ) await self._get_tenant(session) - url = "{}/{tenant}/{item}/{item_id}".format(self.uri, tenant=self.tenant, - item=self.client_to_RO[item], item_id=item_id) + url = "{}/{tenant}/{item}/{item_id}".format( + self.uri, + tenant=self.tenant, + item=self.client_to_RO[item], + item_id=item_id, + ) self.logger.debug("RO POST %s %s", url, payload_req) # timeout = aiohttp.ClientTimeout(total=self.timeout_large) - async with session.post(url, headers=self.headers_req, data=payload_req) as response: + async with session.post( + url, headers=self.headers_req, data=payload_req + ) as response: response_text = await response.read() - self.logger.debug("POST {} [{}] {}".format(url, response.status, response_text[:100])) + self.logger.debug( + "POST {} [{}] {}".format( + url, response.status, response_text[:100] + ) + ) if response.status >= 300: - raise ROClientException(self._parse_error_yaml(response_text), http_code=response.status) + raise ROClientException( + self._parse_error_yaml(response_text), + http_code=response.status, + ) response_desc = self._parse_yaml(response_text, response=True) desc = remove_envelop(item, response_desc) @@ -978,19 +1204,32 @@ class ROClient: try: async with aiohttp.ClientSession(loop=self.loop) as session: # check that exist - item_id = await self._get_item_uuid(session, self.client_to_RO[item], item_id_name, all_tenants=False) + item_id = await self._get_item_uuid( + session, self.client_to_RO[item], item_id_name, all_tenants=False + ) tenant = await self._get_tenant(session) - url = "{}/{tenant}/{item}/{datacenter}".format(self.uri, tenant=tenant, - item=self.client_to_RO[item], datacenter=item_id) + url = "{}/{tenant}/{item}/{datacenter}".format( + self.uri, + tenant=tenant, + item=self.client_to_RO[item], + datacenter=item_id, + ) self.logger.debug("RO DELETE %s", url) # timeout = aiohttp.ClientTimeout(total=self.timeout_large) async with session.delete(url, headers=self.headers_req) as response: response_text = await response.read() - self.logger.debug("DELETE {} [{}] {}".format(url, response.status, response_text[:100])) + self.logger.debug( + "DELETE {} [{}] {}".format( + url, response.status, response_text[:100] + ) + ) if response.status >= 300: - raise ROClientException(self._parse_error_yaml(response_text), http_code=response.status) + raise ROClientException( + self._parse_error_yaml(response_text), + http_code=response.status, + ) response_desc = self._parse_yaml(response_text, response=True) desc = remove_envelop(item, response_desc) @@ -1003,8 +1242,15 @@ class ROClient: # TODO convert to asyncio # DATACENTERS - def edit_datacenter(self, uuid=None, name=None, descriptor=None, descriptor_format=None, all_tenants=False, - **kwargs): + def edit_datacenter( + self, + uuid=None, + name=None, + descriptor=None, + descriptor_format=None, + all_tenants=False, + **kwargs + ): """Edit the parameters of a datacenter Params: must supply a descriptor or/and a parameter to change uuid or/and name. If only name is supplied, there must be only one or an exception is raised @@ -1030,16 +1276,26 @@ class ROClient: else: raise ROClientException("Missing descriptor") - if 'datacenter' not in descriptor or len(descriptor) != 1: - raise ROClientException("Descriptor must contain only one 'datacenter' field") + if "datacenter" not in descriptor or len(descriptor) != 1: + raise ROClientException( + "Descriptor must contain only one 'datacenter' field" + ) for param in kwargs: - if param == 'new_name': - descriptor['datacenter']['name'] = kwargs[param] + if param == "new_name": + descriptor["datacenter"]["name"] = kwargs[param] else: - descriptor['datacenter'][param] = kwargs[param] + descriptor["datacenter"][param] = kwargs[param] return self._edit_item("datacenters", descriptor, uuid, name, all_tenants=None) - def edit_scenario(self, uuid=None, name=None, descriptor=None, descriptor_format=None, all_tenants=False, **kwargs): + def edit_scenario( + self, + uuid=None, + name=None, + descriptor=None, + descriptor_format=None, + all_tenants=False, + **kwargs + ): """Edit the parameters of a scenario Params: must supply a descriptor or/and a parameters to change uuid or/and name. If only name is supplied, there must be only one or an exception is raised @@ -1063,13 +1319,13 @@ class ROClient: else: raise ROClientException("Missing descriptor") - if 'scenario' not in descriptor or len(descriptor) > 2: + if "scenario" not in descriptor or len(descriptor) > 2: raise ROClientException("Descriptor must contain only one 'scenario' field") for param in kwargs: - if param == 'new_name': - descriptor['scenario']['name'] = kwargs[param] + if param == "new_name": + descriptor["scenario"]["name"] = kwargs[param] else: - descriptor['scenario'][param] = kwargs[param] + descriptor["scenario"][param] = kwargs[param] return self._edit_item("scenarios", descriptor, uuid, name, all_tenants=None) # VIM ACTIONS @@ -1091,20 +1347,31 @@ class ROClient: """ session = None # TODO remove when changed to asyncio if item not in ("tenants", "networks", "images"): - raise ROClientException("Unknown value for item '{}', must be 'tenants', 'nets' or " - "images".format(str(item))) + raise ROClientException( + "Unknown value for item '{}', must be 'tenants', 'nets' or " + "images".format(str(item)) + ) - image_actions = ['list', 'get', 'show', 'delete'] + image_actions = ["list", "get", "show", "delete"] if item == "images" and action not in image_actions: - raise ROClientException("Only available actions for item '{}' are {}\n" - "Requested action was '{}'".format(item, ', '.join(image_actions), action)) + raise ROClientException( + "Only available actions for item '{}' are {}\n" + "Requested action was '{}'".format( + item, ", ".join(image_actions), action + ) + ) if all_tenants: tenant_text = "/any" else: tenant_text = "/" + self._get_tenant() if "datacenter_id" in kwargs or "datacenter_name" in kwargs: - datacenter = self._get_item_uuid(session, "datacenters", kwargs.get("datacenter"), all_tenants=all_tenants) + datacenter = self._get_item_uuid( + session, + "datacenters", + kwargs.get("datacenter"), + all_tenants=all_tenants, + ) else: datacenter = self.get_datacenter(session) @@ -1119,7 +1386,9 @@ class ROClient: else: raise ROClientException(str(content), http_code=mano_response.status) elif action == "get" or action == "show": - url = "{}{}/vim/{}/{}/{}".format(self.uri, tenant_text, datacenter, item, uuid) + url = "{}{}/vim/{}/{}/{}".format( + self.uri, tenant_text, datacenter, item, uuid + ) self.logger.debug("GET %s", url) mano_response = requests.get(url, headers=self.headers_req) self.logger.debug("RO response: %s", mano_response.text) @@ -1129,7 +1398,9 @@ class ROClient: else: raise ROClientException(str(content), http_code=mano_response.status) elif action == "delete": - url = "{}{}/vim/{}/{}/{}".format(self.uri, tenant_text, datacenter, item, uuid) + url = "{}{}/vim/{}/{}/{}".format( + self.uri, tenant_text, datacenter, item, uuid + ) self.logger.debug("DELETE %s", url) mano_response = requests.delete(url, headers=self.headers_req) self.logger.debug("RO response: %s", mano_response.text) @@ -1141,7 +1412,9 @@ class ROClient: elif action == "create": if "descriptor" in kwargs: if isinstance(kwargs["descriptor"], str): - descriptor = self._parse(kwargs["descriptor"], kwargs.get("descriptor_format")) + descriptor = self._parse( + kwargs["descriptor"], kwargs.get("descriptor_format") + ) else: descriptor = kwargs["descriptor"] elif "name" in kwargs: @@ -1150,16 +1423,20 @@ class ROClient: raise ROClientException("Missing descriptor") if item[:-1] not in descriptor or len(descriptor) != 1: - raise ROClientException("Descriptor must contain only one 'tenant' field") + raise ROClientException( + "Descriptor must contain only one 'tenant' field" + ) if "name" in kwargs: - descriptor[item[:-1]]['name'] = kwargs["name"] + descriptor[item[:-1]]["name"] = kwargs["name"] if "description" in kwargs: - descriptor[item[:-1]]['description'] = kwargs["description"] + descriptor[item[:-1]]["description"] = kwargs["description"] payload_req = yaml.safe_dump(descriptor) # print payload_req url = "{}{}/vim/{}/{}".format(self.uri, tenant_text, datacenter, item) self.logger.debug("RO POST %s %s", url, payload_req) - mano_response = requests.post(url, headers=self.headers_req, data=payload_req) + mano_response = requests.post( + url, headers=self.headers_req, data=payload_req + ) self.logger.debug("RO response: %s", mano_response.text) content = self._parse_yaml(mano_response.text, response=True) if mano_response.status_code == 200: @@ -1170,7 +1447,7 @@ class ROClient: raise ROClientException("Unknown value for action '{}".format(str(action))) -if __name__ == '__main__': +if __name__ == "__main__": RO_URL = "http://localhost:9090/openmano" TEST_TENANT = "myTenant" TEST_VIM1 = "myvim" @@ -1198,37 +1475,67 @@ if __name__ == '__main__': tenant_id = True content = loop.run_until_complete(myClient.show("tenant", TEST_TENANT)) print("tenant", TEST_TENANT, content) - content = loop.run_until_complete(myClient.edit("tenant", TEST_TENANT, description="another description")) + content = loop.run_until_complete( + myClient.edit("tenant", TEST_TENANT, description="another description") + ) content = loop.run_until_complete(myClient.show("tenant", TEST_TENANT)) print("tenant edited", TEST_TENANT, content) myClient["tenant"] = TEST_TENANT # test VIM - content = loop.run_until_complete(myClient.create("vim", name=TEST_VIM1, type=TEST_TYPE1, vim_url=TEST_URL1, - config=TEST_CONFIG1)) + content = loop.run_until_complete( + myClient.create( + "vim", + name=TEST_VIM1, + type=TEST_TYPE1, + vim_url=TEST_URL1, + config=TEST_CONFIG1, + ) + ) vim_id = True content = loop.run_until_complete(myClient.get_list("vim")) print("vim", content) content = loop.run_until_complete(myClient.show("vim", TEST_VIM1)) print("vim", TEST_VIM1, content) - content = loop.run_until_complete(myClient.edit("vim", TEST_VIM1, description="another description", - name=TEST_VIM2, type=TEST_TYPE2, vim_url=TEST_URL2, - config=TEST_CONFIG2)) + content = loop.run_until_complete( + myClient.edit( + "vim", + TEST_VIM1, + description="another description", + name=TEST_VIM2, + type=TEST_TYPE2, + vim_url=TEST_URL2, + config=TEST_CONFIG2, + ) + ) content = loop.run_until_complete(myClient.show("vim", TEST_VIM2)) print("vim edited", TEST_VIM2, content) # test VIM_ACCOUNT - content = loop.run_until_complete(myClient.attach_datacenter(TEST_VIM2, vim_username='user', - vim_password='pass', vim_tenant_name='vimtenant1', - config=TEST_CONFIG1)) + content = loop.run_until_complete( + myClient.attach_datacenter( + TEST_VIM2, + vim_username="user", + vim_password="pass", + vim_tenant_name="vimtenant1", + config=TEST_CONFIG1, + ) + ) vim_id = True content = loop.run_until_complete(myClient.get_list("vim_account")) print("vim_account", content) content = loop.run_until_complete(myClient.show("vim_account", TEST_VIM2)) print("vim_account", TEST_VIM2, content) - content = loop.run_until_complete(myClient.edit("vim_account", TEST_VIM2, vim_username='user2', - vim_password='pass2', vim_tenant_name="vimtenant2", - config=TEST_CONFIG2)) + content = loop.run_until_complete( + myClient.edit( + "vim_account", + TEST_VIM2, + vim_username="user2", + vim_password="pass2", + vim_tenant_name="vimtenant2", + config=TEST_CONFIG2, + ) + ) content = loop.run_until_complete(myClient.show("vim_account", TEST_VIM2)) print("vim_account edited", TEST_VIM2, content) @@ -1237,9 +1544,13 @@ if __name__ == '__main__': except Exception as e: logger.error("Error {}".format(e), exc_info=True) - for item in (("vim_account", TEST_VIM1), ("vim", TEST_VIM1), - ("vim_account", TEST_VIM2), ("vim", TEST_VIM2), - ("tenant", TEST_TENANT)): + for item in ( + ("vim_account", TEST_VIM1), + ("vim", TEST_VIM1), + ("vim_account", TEST_VIM2), + ("vim", TEST_VIM2), + ("tenant", TEST_TENANT), + ): try: content = loop.run_until_complete(myClient.delete(item[0], item[1])) print("{} {} deleted; {}".format(item[0], item[1], content))