- def get_classification(self, class_id):
- self.logger.debug(" Getting Classification %s from VIM", class_id)
- filter_dict = {"id": class_id}
- class_list = self.get_classification_list(filter_dict)
-
- if len(class_list) == 0:
- raise vimconn.VimConnNotFoundException(
- "Classification '{}' not found".format(class_id)
- )
- elif len(class_list) > 1:
- raise vimconn.VimConnConflictException(
- "Found more than one Classification with this criteria"
- )
-
- classification = class_list[0]
-
- return classification
-
- def get_classification_list(self, filter_dict={}):
- self.logger.debug(
- "Getting Classifications from VIM filter: '%s'", str(filter_dict)
- )
-
- try:
- filter_dict_os = filter_dict.copy()
- self._reload_connection()
-
- if self.api_version3 and "tenant_id" in filter_dict_os:
- filter_dict_os["project_id"] = filter_dict_os.pop("tenant_id")
-
- classification_dict = self.neutron.list_sfc_flow_classifiers(
- **filter_dict_os
- )
- classification_list = classification_dict["flow_classifiers"]
- self.__classification_os2mano(classification_list)
-
- return classification_list
- except (
- neExceptions.ConnectionFailed,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- self._format_exception(e)
-
- def delete_classification(self, class_id):
- self.logger.debug("Deleting Classification '%s' from VIM", class_id)
-
- try:
- self._reload_connection()
- self.neutron.delete_sfc_flow_classifier(class_id)
-
- return class_id
- except (
- neExceptions.ConnectionFailed,
- neExceptions.NeutronException,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- self._format_exception(e)
-
- def new_sfi(self, name, ingress_ports, egress_ports, sfc_encap=True):
- self.logger.debug(
- "Adding a new Service Function Instance to VIM, named '%s'", name
- )
-
- try:
- new_sfi = None
- self._reload_connection()
- correlation = None
-
- if sfc_encap:
- correlation = "nsh"
-
- if len(ingress_ports) != 1:
- raise vimconn.VimConnNotSupportedException(
- "OpenStack VIM connector can only have 1 ingress port per SFI"
- )
-
- if len(egress_ports) != 1:
- raise vimconn.VimConnNotSupportedException(
- "OpenStack VIM connector can only have 1 egress port per SFI"
- )
-
- sfi_dict = {
- "name": name,
- "ingress": ingress_ports[0],
- "egress": egress_ports[0],
- "service_function_parameters": {"correlation": correlation},
- }
- new_sfi = self.neutron.create_sfc_port_pair({"port_pair": sfi_dict})
-
- return new_sfi["port_pair"]["id"]
- except (
- neExceptions.ConnectionFailed,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- if new_sfi:
- try:
- self.neutron.delete_sfc_port_pair(new_sfi["port_pair"]["id"])
- except Exception:
- self.logger.error(
- "Creation of Service Function Instance failed, with "
- "subsequent deletion failure as well."
- )
-
- self._format_exception(e)
-
- def get_sfi(self, sfi_id):
- self.logger.debug("Getting Service Function Instance %s from VIM", sfi_id)
- filter_dict = {"id": sfi_id}
- sfi_list = self.get_sfi_list(filter_dict)
-
- if len(sfi_list) == 0:
- raise vimconn.VimConnNotFoundException(
- "Service Function Instance '{}' not found".format(sfi_id)
- )
- elif len(sfi_list) > 1:
- raise vimconn.VimConnConflictException(
- "Found more than one Service Function Instance with this criteria"
- )
-
- sfi = sfi_list[0]
-
- return sfi
-
- def get_sfi_list(self, filter_dict={}):
- self.logger.debug(
- "Getting Service Function Instances from VIM filter: '%s'", str(filter_dict)
- )
-
- try:
- self._reload_connection()
- filter_dict_os = filter_dict.copy()
-
- if self.api_version3 and "tenant_id" in filter_dict_os:
- filter_dict_os["project_id"] = filter_dict_os.pop("tenant_id")
-
- sfi_dict = self.neutron.list_sfc_port_pairs(**filter_dict_os)
- sfi_list = sfi_dict["port_pairs"]
- self.__sfi_os2mano(sfi_list)
-
- return sfi_list
- except (
- neExceptions.ConnectionFailed,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- self._format_exception(e)
-
- def delete_sfi(self, sfi_id):
- self.logger.debug("Deleting Service Function Instance '%s' from VIM", sfi_id)
-
- try:
- self._reload_connection()
- self.neutron.delete_sfc_port_pair(sfi_id)
-
- return sfi_id
- except (
- neExceptions.ConnectionFailed,
- neExceptions.NeutronException,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- self._format_exception(e)
-
- def new_sf(self, name, sfis, sfc_encap=True):
- self.logger.debug("Adding a new Service Function to VIM, named '%s'", name)
-
- try:
- new_sf = None
- self._reload_connection()
- # correlation = None
- # if sfc_encap:
- # correlation = "nsh"
-
- for instance in sfis:
- sfi = self.get_sfi(instance)
-
- if sfi.get("sfc_encap") != sfc_encap:
- raise vimconn.VimConnNotSupportedException(
- "OpenStack VIM connector requires all SFIs of the "
- "same SF to share the same SFC Encapsulation"
- )
-
- sf_dict = {"name": name, "port_pairs": sfis}
- new_sf = self.neutron.create_sfc_port_pair_group(
- {"port_pair_group": sf_dict}
- )
-
- return new_sf["port_pair_group"]["id"]
- except (
- neExceptions.ConnectionFailed,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- if new_sf:
- try:
- self.neutron.delete_sfc_port_pair_group(
- new_sf["port_pair_group"]["id"]
- )
- except Exception:
- self.logger.error(
- "Creation of Service Function failed, with "
- "subsequent deletion failure as well."
- )
-
- self._format_exception(e)
-
- def get_sf(self, sf_id):
- self.logger.debug("Getting Service Function %s from VIM", sf_id)
- filter_dict = {"id": sf_id}
- sf_list = self.get_sf_list(filter_dict)
-
- if len(sf_list) == 0:
- raise vimconn.VimConnNotFoundException(
- "Service Function '{}' not found".format(sf_id)
- )
- elif len(sf_list) > 1:
- raise vimconn.VimConnConflictException(
- "Found more than one Service Function with this criteria"
- )
-
- sf = sf_list[0]
-
- return sf
-
- def get_sf_list(self, filter_dict={}):
- self.logger.debug(
- "Getting Service Function from VIM filter: '%s'", str(filter_dict)
- )
-
- try:
- self._reload_connection()
- filter_dict_os = filter_dict.copy()
-
- if self.api_version3 and "tenant_id" in filter_dict_os:
- filter_dict_os["project_id"] = filter_dict_os.pop("tenant_id")
-
- sf_dict = self.neutron.list_sfc_port_pair_groups(**filter_dict_os)
- sf_list = sf_dict["port_pair_groups"]
- self.__sf_os2mano(sf_list)
-
- return sf_list
- except (
- neExceptions.ConnectionFailed,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- self._format_exception(e)
-
- def delete_sf(self, sf_id):
- self.logger.debug("Deleting Service Function '%s' from VIM", sf_id)
-
- try:
- self._reload_connection()
- self.neutron.delete_sfc_port_pair_group(sf_id)
-
- return sf_id
- except (
- neExceptions.ConnectionFailed,
- neExceptions.NeutronException,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- self._format_exception(e)
-
- def new_sfp(self, name, classifications, sfs, sfc_encap=True, spi=None):
- self.logger.debug("Adding a new Service Function Path to VIM, named '%s'", name)
-
- try:
- new_sfp = None
- self._reload_connection()
- # In networking-sfc the MPLS encapsulation is legacy
- # should be used when no full SFC Encapsulation is intended
- correlation = "mpls"
-
- if sfc_encap:
- correlation = "nsh"
-
- sfp_dict = {
- "name": name,
- "flow_classifiers": classifications,
- "port_pair_groups": sfs,
- "chain_parameters": {"correlation": correlation},
- }
-
- if spi:
- sfp_dict["chain_id"] = spi
-
- new_sfp = self.neutron.create_sfc_port_chain({"port_chain": sfp_dict})
-
- return new_sfp["port_chain"]["id"]
- except (
- neExceptions.ConnectionFailed,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- if new_sfp:
- try:
- self.neutron.delete_sfc_port_chain(new_sfp["port_chain"]["id"])
- except Exception:
- self.logger.error(
- "Creation of Service Function Path failed, with "
- "subsequent deletion failure as well."
- )
-
- self._format_exception(e)
-
- def get_sfp(self, sfp_id):
- self.logger.debug(" Getting Service Function Path %s from VIM", sfp_id)
-
- filter_dict = {"id": sfp_id}
- sfp_list = self.get_sfp_list(filter_dict)
-
- if len(sfp_list) == 0:
- raise vimconn.VimConnNotFoundException(
- "Service Function Path '{}' not found".format(sfp_id)
- )
- elif len(sfp_list) > 1:
- raise vimconn.VimConnConflictException(
- "Found more than one Service Function Path with this criteria"
- )
-
- sfp = sfp_list[0]
-
- return sfp
-
- def get_sfp_list(self, filter_dict={}):
- self.logger.debug(
- "Getting Service Function Paths from VIM filter: '%s'", str(filter_dict)
- )
-
- try:
- self._reload_connection()
- filter_dict_os = filter_dict.copy()
-
- if self.api_version3 and "tenant_id" in filter_dict_os:
- filter_dict_os["project_id"] = filter_dict_os.pop("tenant_id")
-
- sfp_dict = self.neutron.list_sfc_port_chains(**filter_dict_os)
- sfp_list = sfp_dict["port_chains"]
- self.__sfp_os2mano(sfp_list)
-
- return sfp_list
- except (
- neExceptions.ConnectionFailed,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- self._format_exception(e)
-
- def delete_sfp(self, sfp_id):
- self.logger.debug("Deleting Service Function Path '%s' from VIM", sfp_id)
-
- try:
- self._reload_connection()
- self.neutron.delete_sfc_port_chain(sfp_id)
-
- return sfp_id
- except (
- neExceptions.ConnectionFailed,
- neExceptions.NeutronException,
- ksExceptions.ClientException,
- neExceptions.NeutronException,
- ConnectionError,
- ) as e:
- self._format_exception(e)
-
- def refresh_sfps_status(self, sfp_list):
- """Get the status of the service function path
- Params: the list of sfp identifiers
- Returns a dictionary with:
- vm_id: #VIM id of this service function path
- 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,
- # CREATING (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)F
- """
- sfp_dict = {}
- self.logger.debug(
- "refresh_sfps status: Getting tenant SFP information from VIM"
- )
-
- for sfp_id in sfp_list:
- sfp = {}
-
- try:
- sfp_vim = self.get_sfp(sfp_id)
-
- if sfp_vim["spi"]:
- sfp["status"] = vmStatus2manoFormat["ACTIVE"]
- else:
- sfp["status"] = "OTHER"
- sfp["error_msg"] = "VIM status reported " + sfp["status"]
-
- sfp["vim_info"] = self.serialize(sfp_vim)
-
- if sfp_vim.get("fault"):
- sfp["error_msg"] = str(sfp_vim["fault"])
- except vimconn.VimConnNotFoundException as e:
- self.logger.error("Exception getting sfp status: %s", str(e))
- sfp["status"] = "DELETED"
- sfp["error_msg"] = str(e)
- except vimconn.VimConnException as e:
- self.logger.error("Exception getting sfp status: %s", str(e))
- sfp["status"] = "VIM_ERROR"
- sfp["error_msg"] = str(e)
-
- sfp_dict[sfp_id] = sfp
-
- return sfp_dict
-
- def refresh_sfis_status(self, sfi_list):
- """Get the status of the service function instances
- Params: the list of sfi identifiers
- Returns a dictionary with:
- vm_id: #VIM id of this service function instance
- 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,
- # CREATING (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)
- """
- sfi_dict = {}
- self.logger.debug(
- "refresh_sfis status: Getting tenant sfi information from VIM"
- )
-
- for sfi_id in sfi_list:
- sfi = {}
-
- try:
- sfi_vim = self.get_sfi(sfi_id)
-
- if sfi_vim:
- sfi["status"] = vmStatus2manoFormat["ACTIVE"]
- else:
- sfi["status"] = "OTHER"
- sfi["error_msg"] = "VIM status reported " + sfi["status"]
-
- sfi["vim_info"] = self.serialize(sfi_vim)
-
- if sfi_vim.get("fault"):
- sfi["error_msg"] = str(sfi_vim["fault"])
- except vimconn.VimConnNotFoundException as e:
- self.logger.error("Exception getting sfi status: %s", str(e))
- sfi["status"] = "DELETED"
- sfi["error_msg"] = str(e)
- except vimconn.VimConnException as e:
- self.logger.error("Exception getting sfi status: %s", str(e))
- sfi["status"] = "VIM_ERROR"
- sfi["error_msg"] = str(e)
-
- sfi_dict[sfi_id] = sfi
-
- return sfi_dict
-
- def refresh_sfs_status(self, sf_list):
- """Get the status of the service functions
- Params: the list of sf identifiers
- Returns a dictionary with:
- vm_id: #VIM id of this service function
- 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,
- # CREATING (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)
- """
- sf_dict = {}
- self.logger.debug("refresh_sfs status: Getting tenant sf information from VIM")
-
- for sf_id in sf_list:
- sf = {}
-
- try:
- sf_vim = self.get_sf(sf_id)
-
- if sf_vim:
- sf["status"] = vmStatus2manoFormat["ACTIVE"]
- else:
- sf["status"] = "OTHER"
- sf["error_msg"] = "VIM status reported " + sf_vim["status"]
-
- sf["vim_info"] = self.serialize(sf_vim)
-
- if sf_vim.get("fault"):
- sf["error_msg"] = str(sf_vim["fault"])
- except vimconn.VimConnNotFoundException as e:
- self.logger.error("Exception getting sf status: %s", str(e))
- sf["status"] = "DELETED"
- sf["error_msg"] = str(e)
- except vimconn.VimConnException as e:
- self.logger.error("Exception getting sf status: %s", str(e))
- sf["status"] = "VIM_ERROR"
- sf["error_msg"] = str(e)
-
- sf_dict[sf_id] = sf
-
- return sf_dict
-
- def refresh_classifications_status(self, classification_list):
- """Get the status of the classifications
- Params: the list of classification identifiers
- Returns a dictionary with:
- vm_id: #VIM id of this classifier
- 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,
- # CREATING (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)
- """
- classification_dict = {}
- self.logger.debug(
- "refresh_classifications status: Getting tenant classification information from VIM"
- )
-
- for classification_id in classification_list:
- classification = {}
-
- try:
- classification_vim = self.get_classification(classification_id)
-
- if classification_vim:
- classification["status"] = vmStatus2manoFormat["ACTIVE"]
- else:
- classification["status"] = "OTHER"
- classification["error_msg"] = (
- "VIM status reported " + classification["status"]
- )
-
- classification["vim_info"] = self.serialize(classification_vim)
-
- if classification_vim.get("fault"):
- classification["error_msg"] = str(classification_vim["fault"])
- except vimconn.VimConnNotFoundException as e:
- self.logger.error("Exception getting classification status: %s", str(e))
- classification["status"] = "DELETED"
- classification["error_msg"] = str(e)
- except vimconn.VimConnException as e:
- self.logger.error("Exception getting classification status: %s", str(e))
- classification["status"] = "VIM_ERROR"
- classification["error_msg"] = str(e)
-
- classification_dict[classification_id] = classification
-
- return classification_dict
-
- def new_affinity_group(self, affinity_group_data):
- """Adds a server group to VIM
- affinity_group_data contains a dictionary with information, keys:
- name: name in VIM for the server group
- type: affinity or anti-affinity
- scope: Only nfvi-node allowed
- Returns the server group identifier"""
- self.logger.debug("Adding Server Group '%s'", str(affinity_group_data))
-
- try:
- name = affinity_group_data["name"]
- policy = affinity_group_data["type"]
-
- self._reload_connection()
- new_server_group = self.nova.server_groups.create(name, policy)
-
- return new_server_group.id
- except (
- ksExceptions.ClientException,
- nvExceptions.ClientException,
- ConnectionError,
- KeyError,
- ) as e:
- self._format_exception(e)
-
- def get_affinity_group(self, affinity_group_id):
- """Obtain server group details from the VIM. Returns the server group detais as a dict"""
- self.logger.debug("Getting flavor '%s'", affinity_group_id)
- try:
- self._reload_connection()
- server_group = self.nova.server_groups.find(id=affinity_group_id)