X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_lcm%2Fng_ro.py;h=03819c850bd3b27e2f60875a2f2f4bb813f59f84;hb=refs%2Fchanges%2F84%2F11984%2F12;hp=6e9f6831466dbb87ec6e387a258353811a3fe913;hpb=69f0d388812e3befeba6c6115803ebdfb76b7294;p=osm%2FLCM.git diff --git a/osm_lcm/ng_ro.py b/osm_lcm/ng_ro.py index 6e9f683..03819c8 100644 --- a/osm_lcm/ng_ro.py +++ b/osm_lcm/ng_ro.py @@ -41,20 +41,28 @@ class NgRoException(Exception): class NgRoClient: - 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 @@ -73,7 +81,7 @@ class NgRoClient: 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"]) @@ -98,9 +106,84 @@ class NgRoClient: async with aiohttp.ClientSession(loop=self.loop) as session: self.logger.debug("NG-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] + ) + ) + if response.status >= 300: + raise NgRoException(response_text, http_code=response.status) + return self._parse_yaml(response_text, response=True) + except (aiohttp.ClientOSError, aiohttp.ClientError) as e: + raise NgRoException(e, http_code=504) + except asyncio.TimeoutError: + raise NgRoException("Timeout", http_code=504) + + async def migrate(self, nsr_id, target): + """ + Performs migration of VNFs + :param nsr_id: NS Instance Id + :param target: payload data for migrate operation + :return: dictionary with the information or raises NgRoException on Error + """ + try: + if isinstance(target, str): + target = self._parse_yaml(target) + payload_req = yaml.safe_dump(target) + + url = "{}/ns/v1/migrate/{nsr_id}".format(self.endpoint_url, nsr_id=nsr_id) + async with aiohttp.ClientSession(loop=self.loop) as session: + self.logger.debug("NG-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: + response_text = await response.read() + self.logger.debug( + "POST {} [{}] {}".format( + url, response.status, response_text[:100] + ) + ) + if response.status >= 300: + raise NgRoException(response_text, http_code=response.status) + return self._parse_yaml(response_text, response=True) + except (aiohttp.ClientOSError, aiohttp.ClientError) as e: + raise NgRoException(e, http_code=504) + except asyncio.TimeoutError: + raise NgRoException("Timeout", http_code=504) + + async def operate(self, nsr_id, target, operation_type): + """ + Performs start/stop/rebuil of VNFs + :param nsr_id: NS Instance Id + :param target: payload data for migrate operation + :param operation_type: start/stop/rebuil of VNFs + :return: dictionary with the information or raises NgRoException on Error + """ + try: + if isinstance(target, str): + target = self._parse_yaml(target) + payload_req = yaml.safe_dump(target) + + url = "{}/ns/v1/{operation_type}/{nsr_id}".format( + self.endpoint_url, operation_type=operation_type, nsr_id=nsr_id + ) + async with aiohttp.ClientSession(loop=self.loop) as session: + self.logger.debug("NG-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: 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 NgRoException(response_text, http_code=response.status) return self._parse_yaml(response_text, response=True) @@ -111,13 +194,19 @@ class NgRoClient: async def status(self, nsr_id, action_id): try: - url = "{}/ns/v1/deploy/{nsr_id}/{action_id}".format(self.endpoint_url, nsr_id=nsr_id, action_id=action_id) + url = "{}/ns/v1/deploy/{nsr_id}/{action_id}".format( + self.endpoint_url, nsr_id=nsr_id, action_id=action_id + ) async with aiohttp.ClientSession(loop=self.loop) as session: self.logger.debug("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 >= 300: raise NgRoException(response_text, http_code=response.status) return self._parse_yaml(response_text, response=True) @@ -136,7 +225,9 @@ class NgRoClient: async with session.delete(url, headers=self.headers_req) as response: self.logger.debug("DELETE {} [{}]".format(url, response.status)) if response.status >= 300: - raise NgRoException("Delete {}".format(nsr_id), http_code=response.status) + raise NgRoException( + "Delete {}".format(nsr_id), http_code=response.status + ) return except (aiohttp.ClientOSError, aiohttp.ClientError) as e: @@ -157,7 +248,11 @@ class NgRoClient: # 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 NgRoException(response_text, http_code=response.status) @@ -165,14 +260,112 @@ class NgRoClient: if "." in word: version_text, _, _ = word.partition("-") return version_text - raise NgRoException("Got invalid version text: '{}'".format(response_text), http_code=500) + raise NgRoException( + "Got invalid version text: '{}'".format(response_text), + http_code=500, + ) except (aiohttp.ClientOSError, aiohttp.ClientError) as e: raise NgRoException(e, http_code=504) except asyncio.TimeoutError: raise NgRoException("Timeout", http_code=504) except Exception as e: - raise NgRoException("Got invalid version text: '{}'; causing exception {}".format(response_text, e), - http_code=500) + raise NgRoException( + "Got invalid version text: '{}'; causing exception {}".format( + response_text, e + ), + http_code=500, + ) + + async def recreate(self, nsr_id, target): + """ + Performs an action over an item + :param item: can be 'tenant', 'vnfd', 'nsd', 'ns', 'vim', 'vim_account', 'sdn' + :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 + :param descriptor_format: Can be 'json' or 'yaml' + :param kwargs: Overrides descriptor with values as name, description, vim_url, vim_url_admin, vim_type + keys can be a dot separated list to specify elements inside dict + :return: dictionary with the information or raises NgRoException on Error + """ + try: + if isinstance(target, str): + target = self._parse_yaml(target) + payload_req = yaml.safe_dump(target) + + url = "{}/ns/v1/recreate/{nsr_id}".format(self.endpoint_url, nsr_id=nsr_id) + async with aiohttp.ClientSession(loop=self.loop) as session: + self.logger.debug("NG-RO POST %s %s", url, payload_req) + 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] + ) + ) + if response.status >= 300: + raise NgRoException(response_text, http_code=response.status) + return self._parse_yaml(response_text, response=True) + except (aiohttp.ClientOSError, aiohttp.ClientError) as e: + raise NgRoException(e, http_code=504) + except asyncio.TimeoutError: + raise NgRoException("Timeout", http_code=504) + + async def recreate_status(self, nsr_id, action_id): + try: + url = "{}/ns/v1/recreate/{nsr_id}/{action_id}".format( + self.endpoint_url, nsr_id=nsr_id, action_id=action_id + ) + async with aiohttp.ClientSession(loop=self.loop) as session: + self.logger.debug("GET %s", url) + 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] + ) + ) + if response.status >= 300: + raise NgRoException(response_text, http_code=response.status) + return self._parse_yaml(response_text, response=True) + + except (aiohttp.ClientOSError, aiohttp.ClientError) as e: + raise NgRoException(e, http_code=504) + except asyncio.TimeoutError: + raise NgRoException("Timeout", http_code=504) + + async def vertical_scale(self, nsr_id, target): + """ + Performs migration of VNFs + :param nsr_id: NS Instance Id + :param target: payload data for migrate operation + :return: dictionary with the information or raises NgRoException on Error + """ + try: + if isinstance(target, str): + target = self._parse_yaml(target) + payload_req = yaml.safe_dump(target) + + url = "{}/ns/v1/verticalscale/{nsr_id}".format(self.endpoint_url, nsr_id=nsr_id) + async with aiohttp.ClientSession(loop=self.loop) as session: + self.logger.debug("NG-RO POST %s %s", url, payload_req) + 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] + ) + ) + if response.status >= 300: + raise NgRoException(response_text, http_code=response.status) + return self._parse_yaml(response_text, response=True) + except (aiohttp.ClientOSError, aiohttp.ClientError) as e: + raise NgRoException(e, http_code=504) + except asyncio.TimeoutError: + raise NgRoException("Timeout", http_code=504) @staticmethod def _parse_yaml(descriptor, response=False): @@ -180,9 +373,11 @@ class NgRoClient: return yaml.safe_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 if response: raise NgRoException("reponse with " + error_text)