+ 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
+ sfc_encap = '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)