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 )
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()
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)
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()
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)
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)
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])
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])
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)
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])
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)
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