def test_update_port_pair_group_precommit_driver_manager_exception(self):
     self.fake_driver_manager.update_port_pair_group_precommit = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(
             method='update_port_pair_group_precommit'
         )
     )
     self._test_update_port_pair_group_driver_manager_exception(False)
 def test_create_port_pair_postcommit_driver_manager_exception(self):
     self.fake_driver_manager.create_port_pair_postcommit = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(
             method='create_port_pair_postcommit'
         )
     )
     with self.port(
         name='port1',
         device_id='default'
     ) as src_port, self.port(
         name='port2',
         device_id='default'
     ) as dst_port:
         self._create_port_pair(
             self.fmt,
             {
                 'ingress': src_port['port']['id'],
                 'egress': dst_port['port']['id']
             },
             expected_res_status=500)
         self._test_list_resources('port_pair', [])
         driver_manager = self.fake_driver_manager
         driver_manager.create_port_pair_precommit.assert_called_once_with(
             mock.ANY
         )
         driver_manager.delete_port_pair.assert_called_once_with(
             mock.ANY
         )
         driver_manager.delete_port_pair_precommit.assert_called_once_with(
             mock.ANY
         )
         driver_manager.delete_port_pair_postcommit.assert_called_once_with(
             mock.ANY
         )
示例#3
0
 def test_update_port_pair_driver_manager_exception(self):
     self.fake_driver_manager.update_port_pair = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(method='update_port_pair'))
     with self.port(name='port1',
                    device_id='default') as src_port, self.port(
                        name='port2', device_id='default') as dst_port:
         with self.port_pair(
                 port_pair={
                     'name': 'test1',
                     'ingress': src_port['port']['id'],
                     'egress': dst_port['port']['id']
                 }) as pc:
             self.assertIn('port_pair', pc)
             original_port_pair = pc['port_pair']
             req = self.new_update_request('port_pairs',
                                           {'port_pair': {
                                               'name': 'test2'
                                           }}, pc['port_pair']['id'])
             updated_port_pair = copy.copy(original_port_pair)
             updated_port_pair['name'] = 'test2'
             res = req.get_response(self.ext_api)
             self.assertEqual(res.status_int, 500)
             res = self._list('port_pairs')
             self.assertIn('port_pairs', res)
             self.assertItemsEqual(res['port_pairs'], [updated_port_pair])
 def test_delete_port_chain_driver_manager_exception(self):
     self.fake_driver_manager.delete_port_chain = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(
             method='delete_port_chain'
         )
     )
     self._test_delete_port_chain_driver_manager_exception()
示例#5
0
 def _parse_ipaddress_prefix(self, cidr):
     try:
         net = IPNetwork(cidr)
         return (str(net.ip), net.prefixlen)
     except AddrFormatError:
         raise exc.SfcDriverError(message=(
             "Malformed IP prefix: %s" % cidr))
 def test_create_service_graph_postcommit_driver_manager_exception(self):
     self.fake_driver_manager.create_service_graph_postcommit = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(
             method='create_service_graph_postcommit'
         )
     )
     with self.port_pair_group(
         port_pair_group={}
     ) as pg1, self.port_pair_group(
         port_pair_group={}
     ) as pg2:
         with self.port_chain(
             port_chain={'port_pair_groups': [pg1['port_pair_group']['id']]}
         ) as pc1, self.port_chain(
             port_chain={'port_pair_groups': [pg2['port_pair_group']['id']]}
         ) as pc2:
             self._create_service_graph(self.fmt, {
                 'port_chains': {
                     pc1['port_chain']['id']: [pc2['port_chain']['id']]
                 }
             }, expected_res_status=500)
             self._test_list_resources('service_graph', [])
         (self.fake_driver_manager.create_service_graph_precommit
          .assert_called_once_with(mock.ANY))
         self.fake_driver_manager.delete_service_graph_postcommit.\
             assert_called_once_with(mock.ANY)
 def test_update_service_graph_postcommit_driver_manager_exception(self):
     self.fake_driver_manager.update_service_graph_postcommit = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(
             method='update_service_graph_postcommit'
         )
     )
     self._test_update_service_graph_driver_manager_exception(True)
示例#8
0
    def update_port_chain(self, context):
        current = context.current
        original = context.original

        # Delete existing BaGPipeChainHop objects if not valid PortChain
        if not self._is_valid_port_chain(context, current):
            self._delete_portchain_hops(context, current)

            return

        # Create BaGPipeChainHop objects
        if (not original['flow_classifiers'] or
            (original['port_pair_groups'] == current['port_pair_groups'] and
             not sfc_obj.BaGPipeChainHop.get_objects(
                context._plugin_context,
                portchain_id=current['id']))):
            self._create_portchain_hops(context, current)

            return

        # If Flow Classifier has been modified, raise not supported exception
        if current['flow_classifiers'] != original['flow_classifiers']:
            LOG.error('BaGPipe driver not supporting Flow Classifiers update')
            raise exc.SfcDriverError(method='update_port_chain')

        # Delete and re-create BaGPipeChainHop objects (Better to update
        # BaGPipeChainHop objects
        if current['port_pair_groups'] != original['port_pair_groups']:
            self._delete_portchain_hops(context, current)

            self._create_portchain_hops(context, current)
 def test_delete_port_pair_precommit_driver_manager_exception(self):
     self.fake_driver_manager.delete_port_pair_precommit = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(
             method='delete_port_pair_precommit'
         )
     )
     self._test_delete_port_pair_driver_manager_exception()
示例#10
0
 def test_create_port_pair_group_driver_manager_exception(self):
     self.fake_driver_manager.create_port_pair_group = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(
             method='create_port_pair_group'))
     self._create_port_pair_group(self.fmt, {}, expected_res_status=500)
     self._test_list_resources('port_pair_group', [])
     driver_manager = self.fake_driver_manager
     driver_manager.delete_port_pair_group.assert_called_once_with(mock.ANY)
示例#11
0
 def test_create_port_chain_driver_manager_exception(self):
     self.fake_driver_manager.create_port_chain = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(method='create_port_chain'))
     with self.port_pair_group(port_pair_group={}) as pg:
         self._create_port_chain(
             self.fmt, {'port_pair_groups': [pg['port_pair_group']['id']]},
             expected_res_status=500)
         self._test_list_resources('port_chain', [])
     self.fake_driver_manager.delete_port_chain.assert_called_once_with(
         mock.ANY)
示例#12
0
 def test_delete_port_pair_group_driver_manager_exception(self):
     self.fake_driver_manager.delete_port_pair_group = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(
             method='delete_port_pair_group'))
     with self.port_pair_group(port_pair_group={'name': 'test1'},
                               do_delete=False) as pc:
         req = self.new_delete_request('port_pair_groups',
                                       pc['port_pair_group']['id'])
         res = req.get_response(self.ext_api)
         self.assertEqual(res.status_int, 500)
         self._test_list_resources('port_pair_group', [pc])
示例#13
0
 def test_delete_port_pair_driver_manager_exception(self):
     self.fake_driver_manager.delete_port_pair = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(method='delete_port_pair'))
     with self.port(name='port1',
                    device_id='default') as src_port, self.port(
                        name='port2', device_id='default') as dst_port:
         with self.port_pair(port_pair={
                 'name': 'test1',
                 'ingress': src_port['port']['id'],
                 'egress': dst_port['port']['id']
         },
                             do_delete=False) as pc:
             req = self.new_delete_request('port_pairs',
                                           pc['port_pair']['id'])
             res = req.get_response(self.ext_api)
             self.assertEqual(res.status_int, 500)
             self._test_list_resources('port_pair', [pc])
示例#14
0
    def _call_drivers(self, method_name, context):
        """Helper method for calling a method across all SFC drivers.

        :param method_name: name of the method to call
        :param context: context parameter to pass to each method call
        """
        for driver in self.ordered_drivers:
            try:
                getattr(driver.obj, method_name)(context)
            except Exception as e:
                # This is an internal failure.
                LOG.exception(e)
                LOG.error(_LE("SFC driver '%(name)s' failed in %(method)s"), {
                    'name': driver.name,
                    'method': method_name
                })
                raise sfc_exc.SfcDriverError(method=method_name)
示例#15
0
 def test_update_port_pair_group_driver_manager_exception(self):
     self.fake_driver_manager.update_port_pair_group = mock.Mock(
         side_effect=sfc_exc.SfcDriverError(
             method='update_port_pair_group'))
     with self.port_pair_group(port_pair_group={'name': 'test1'}) as pc:
         self.assertIn('port_pair_group', pc)
         original_port_pair_group = pc['port_pair_group']
         req = self.new_update_request(
             'port_pair_groups', {'port_pair_group': {
                 'name': 'test2'
             }}, pc['port_pair_group']['id'])
         updated_port_pair_group = copy.copy(original_port_pair_group)
         updated_port_pair_group['name'] = 'test2'
         res = req.get_response(self.ext_api)
         self.assertEqual(res.status_int, 500)
         res = self._list('port_pair_groups')
         self.assertIn('port_pair_groups', res)
         self.assertItemsEqual(res['port_pair_groups'],
                               [updated_port_pair_group])
示例#16
0
    def _call_drivers(self, method_name, context, raise_orig_exc=False):
        """Helper method for calling a method across all SFC drivers.

        :param method_name: name of the method to call
        :param context: context parameter to pass to each method call
        :param raise_orig_exc: whether or not to raise the original
        driver exception, or use a general one
        """
        for driver in self.ordered_drivers:
            try:
                getattr(driver.obj, method_name)(context)
            except Exception as e:
                # This is an internal failure.
                LOG.exception(e)
                LOG.error(_LE("SFC driver '%(name)s' failed in %(method)s"), {
                    'name': driver.name,
                    'method': method_name
                })
                if raise_orig_exc:
                    raise
                else:
                    raise sfc_exc.SfcDriverError(method=method_name)
示例#17
0
    def _create_portchain_path(self, context, port_chain):
        src_node, src_pd, dst_node, dst_pd = (({}, ) * 4)
        path_nodes = []
        # Create an assoc object for chain_id and path_id
        # context = context._plugin_context
        path_id = port_chain['chain_id']

        if not path_id:
            LOG.error(_LE('No path_id available for creating port chain path'))
            return

        port_pair_groups = port_chain['port_pair_groups']
        sf_path_length = len(port_pair_groups)

        # Detect cross-subnet transit
        # Compare subnets for logical source ports
        # and first PPG ingress ports
        for fc in self._get_fcs_by_ids(port_chain['flow_classifiers']):
            subnet1 = self._get_subnet_by_port(fc['logical_source_port'])
            cidr1 = subnet1['cidr']
            ppg = context._plugin.get_port_pair_group(context._plugin_context,
                                                      port_pair_groups[0])
            for pp_id1 in ppg['port_pairs']:
                pp1 = context._plugin.get_port_pair(context._plugin_context,
                                                    pp_id1)
                filter1 = {}
                if pp1.get('ingress', None):
                    filter1 = dict(dict(ingress=pp1['ingress']), **filter1)
                    pd1 = self.get_port_detail_by_filter(filter1)
                    subnet2 = self._get_subnet_by_port(pd1['ingress'])
                    cidr2 = subnet2['cidr']
                    if cidr1 != cidr2:
                        LOG.error(_LE('Cross-subnet chain not supported'))
                        raise exc.SfcDriverError()
                        return None

        # Compare subnets for PPG egress ports
        # and next PPG ingress ports
        for i in range(sf_path_length - 1):
            ppg = context._plugin.get_port_pair_group(context._plugin_context,
                                                      port_pair_groups[i])
            next_ppg = context._plugin.get_port_pair_group(
                context._plugin_context, port_pair_groups[i + 1])
            for pp_id1 in ppg['port_pairs']:
                pp1 = context._plugin.get_port_pair(context._plugin_context,
                                                    pp_id1)
                filter1 = {}
                if pp1.get('egress', None):
                    filter1 = dict(dict(egress=pp1['egress']), **filter1)
                    pd1 = self.get_port_detail_by_filter(filter1)
                    subnet1 = self._get_subnet_by_port(pd1['egress'])
                    cidr3 = subnet1['cidr']

                for pp_id2 in next_ppg['port_pairs']:
                    pp2 = context._plugin.get_port_pair(
                        context._plugin_context, pp_id2)
                    filter2 = {}
                    if pp2.get('ingress', None):
                        filter2 = dict(dict(ingress=pp2['ingress']), **filter2)
                        pd2 = self.get_port_detail_by_filter(filter2)
                        subnet2 = self._get_subnet_by_port(pd2['ingress'])
                        cidr4 = subnet2['cidr']
                        if cidr3 != cidr4:
                            LOG.error(_LE('Cross-subnet chain not supported'))
                            raise exc.SfcDriverError()
                            return None

        next_group_intid, next_group_members = self._get_portgroup_members(
            context, port_chain['port_pair_groups'][0])

        # Create a head node object for port chain
        src_args = {
            'tenant_id': port_chain['tenant_id'],
            'node_type': ovs_const.SRC_NODE,
            'nsp': path_id,
            'nsi': 0xff,
            'portchain_id': port_chain['id'],
            'status': ovs_const.STATUS_BUILDING,
            'next_group_id': next_group_intid,
            'next_hop': jsonutils.dumps(next_group_members),
        }
        src_node = self.create_path_node(src_args)
        LOG.debug('create src node: %s', src_node)
        path_nodes.append(src_node)

        # Create a destination node object for port chain
        dst_args = {
            'tenant_id': port_chain['tenant_id'],
            'node_type': ovs_const.DST_NODE,
            'nsp': path_id,
            'nsi': 0xff - sf_path_length - 1,
            'portchain_id': port_chain['id'],
            'status': ovs_const.STATUS_BUILDING,
            'next_group_id': None,
            'next_hop': None
        }
        dst_node = self.create_path_node(dst_args)
        LOG.debug('create dst node: %s', dst_node)
        path_nodes.append(dst_node)

        self._add_flowclassifier_port_assoc(port_chain['flow_classifiers'],
                                            port_chain['tenant_id'], src_node)

        for i in range(sf_path_length):
            cur_group_members = next_group_members
            # next_group for next hop
            if i < sf_path_length - 1:
                next_group_intid, next_group_members = (
                    self._get_portgroup_members(context,
                                                port_pair_groups[i + 1]))
            else:
                next_group_intid = None
                next_group_members = None

            # Create a node object
            node_args = {
                'tenant_id':
                port_chain['tenant_id'],
                'node_type':
                ovs_const.SF_NODE,
                'nsp':
                path_id,
                'nsi':
                0xfe - i,
                'portchain_id':
                port_chain['id'],
                'status':
                ovs_const.STATUS_BUILDING,
                'next_group_id':
                next_group_intid,
                'next_hop': (None if not next_group_members else
                             jsonutils.dumps(next_group_members))
            }
            sf_node = self.create_path_node(node_args)
            LOG.debug('chain path node: %s', sf_node)
            # Create the assocation objects that combine the pathnode_id with
            # the ingress of the port_pairs in the current group
            # when port_group does not reach tail
            for member in cur_group_members:
                assco_args = {
                    'portpair_id': member['portpair_id'],
                    'pathnode_id': sf_node['id'],
                    'weight': member['weight'],
                }
                sfna = self.create_pathport_assoc(assco_args)
                LOG.debug('create assoc port with node: %s', sfna)
                sf_node['portpair_details'].append(member['portpair_id'])
            path_nodes.append(sf_node)

        return path_nodes