Merge "Qos rule not update after vm bound qos"

This commit is contained in:
Zuul 2018-10-15 04:11:51 +00:00 committed by Gerrit Code Review
commit 6866ffba52
3 changed files with 92 additions and 12 deletions

View File

@ -43,6 +43,7 @@ from neutron.db import l3_hamode_db # noqa
from neutron.db import models_v2 from neutron.db import models_v2
from neutron.db import portbindings_db from neutron.db import portbindings_db
from neutron.extensions import providernet as provider from neutron.extensions import providernet as provider
from neutron.objects import ports as q_ports
from neutron.objects.qos import policy as policy_object from neutron.objects.qos import policy as policy_object
import neutron.objects.router as router_object import neutron.objects.router as router_object
from neutron.plugins.ml2 import managers as n_managers from neutron.plugins.ml2 import managers as n_managers
@ -50,6 +51,7 @@ from neutron_lib.api.definitions import availability_zone as az_def
from neutron_lib.api.definitions import external_net from neutron_lib.api.definitions import external_net
from neutron_lib.api.definitions import l3 as l3_apidef from neutron_lib.api.definitions import l3 as l3_apidef
from neutron_lib.api.definitions import portbindings from neutron_lib.api.definitions import portbindings
from neutron_lib.api.definitions import portbindings_extended as pb_ext
from neutron_lib.api.definitions import provider_net from neutron_lib.api.definitions import provider_net
from neutron_lib.api import validators from neutron_lib.api import validators
from neutron_lib.api.validators import availability_zone as az_validator from neutron_lib.api.validators import availability_zone as az_validator
@ -558,12 +560,16 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
# do not reserve snat port for bridge and external subnet # do not reserve snat port for bridge and external subnet
snat_port_id = self.helper.prepare_top_snat_port( snat_port_id = self.helper.prepare_top_snat_port(
t_ctx, context, res['tenant_id'], network['id'], res['id']) t_ctx, context, res['tenant_id'], network['id'], res['id'])
self._create_port_binding(context, snat_port_id)
if res['enable_dhcp']: if res['enable_dhcp']:
self.helper.prepare_top_dhcp_port( dhcp_port_id = self.helper.prepare_top_dhcp_port(
t_ctx, context, res['tenant_id'], network['id'], res['id']) t_ctx, context, res['tenant_id'], network['id'], res['id'])
self._create_port_binding(context, dhcp_port_id)
except Exception: except Exception:
if snat_port_id: if snat_port_id:
super(TricirclePlugin, self).delete_port(context, snat_port_id) super(TricirclePlugin, self).delete_port(context, snat_port_id)
q_ports.PortBinding.delete_objects(context,
port_id=snat_port_id)
self.delete_subnet(context, res['id']) self.delete_subnet(context, res['id'])
raise raise
return res return res
@ -573,6 +579,7 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
q_ctx, {'name': [port_name]}) q_ctx, {'name': [port_name]})
if ports: if ports:
super(TricirclePlugin, self).delete_port(q_ctx, ports[0]['id']) super(TricirclePlugin, self).delete_port(q_ctx, ports[0]['id'])
q_ports.PortBinding.delete_objects(q_ctx, port_id=ports[0]['id'])
db_api.delete_pre_created_resource_mapping(t_ctx, port_name) db_api.delete_pre_created_resource_mapping(t_ctx, port_name)
def delete_subnet(self, context, subnet_id): def delete_subnet(self, context, subnet_id):
@ -642,6 +649,18 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
t_constants.POD_NOT_SPECIFIED) t_constants.POD_NOT_SPECIFIED)
return result return result
def _create_port_binding(self, context, port_id):
port_binding = q_ports.PortBinding(context)
port_binding.unique_keys.append(['port_id'])
port_binding.port_id = port_id
port_binding.host = ''
port_binding.profile = {}
port_binding.vif_type = portbindings.VIF_TYPE_UNBOUND
port_binding.vif_details = {}
port_binding.vnic_type = portbindings.VNIC_NORMAL
port_binding.status = 'ACTIVE'
port_binding.create()
def create_port(self, context, port): def create_port(self, context, port):
port_body = port['port'] port_body = port['port']
if port_body['device_id'] == t_constants.interface_port_device_id: if port_body['device_id'] == t_constants.interface_port_device_id:
@ -655,6 +674,7 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
t_ctx, context, port_body['tenant_id'], pod, t_ctx, context, port_body['tenant_id'], pod,
{'id': port_body['name']}, t_constants.RT_PORT, {'id': port_body['name']}, t_constants.RT_PORT,
gateway_port_body) gateway_port_body)
self._create_port_binding(context, t_gateway_id)
return super(TricirclePlugin, self).get_port(context, t_gateway_id) return super(TricirclePlugin, self).get_port(context, t_gateway_id)
db_port = super(TricirclePlugin, self).create_port_db(context, port) db_port = super(TricirclePlugin, self).create_port_db(context, port)
self._ensure_default_security_group_on_port(context, port) self._ensure_default_security_group_on_port(context, port)
@ -662,6 +682,7 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
result = self._make_port_dict(db_port) result = self._make_port_dict(db_port)
self.extension_manager.process_create_port(context, port_body, result) self.extension_manager.process_create_port(context, port_body, result)
self._process_port_create_security_group(context, result, sgids) self._process_port_create_security_group(context, result, sgids)
self._create_port_binding(context, db_port.id)
return result return result
def _check_mac_update_allowed(self, orig_port, port): def _check_mac_update_allowed(self, orig_port, port):
@ -795,10 +816,28 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
'name': bottom_port['name'] 'name': bottom_port['name']
}}) }})
def _process_port_binding(self, context, port_id, port):
profile = port['port'].get('binding:profile')
if profile is not None and \
set([portbindings.VIF_TYPE, portbindings.HOST_ID,
portbindings.VIF_DETAILS, portbindings.VNIC_TYPE]
).issubset(profile.keys()):
q_ports.PortBinding.update_object(
context,
{
pb_ext.VIF_TYPE: profile[portbindings.VIF_TYPE],
pb_ext.HOST: profile[portbindings.HOST_ID],
pb_ext.VIF_DETAILS: profile[portbindings.VIF_DETAILS],
pb_ext.VNIC_TYPE: profile[portbindings.VNIC_TYPE]
},
port_id=port_id
)
def update_port(self, context, port_id, port): def update_port(self, context, port_id, port):
t_ctx = t_context.get_context_from_neutron_context(context) t_ctx = t_context.get_context_from_neutron_context(context)
top_port = super(TricirclePlugin, self).get_port(context, port_id) top_port = super(TricirclePlugin, self).get_port(context, port_id)
updated_port = None updated_port = None
self._process_port_binding(context, port_id, port)
# be careful that l3_db will call update_port to update device_id of # be careful that l3_db will call update_port to update device_id of
# router interface, we cannot directly update bottom port in this case, # router interface, we cannot directly update bottom port in this case,
# otherwise we will fail when attaching bottom port to bottom router # otherwise we will fail when attaching bottom port to bottom router
@ -993,6 +1032,7 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
'comparator': 'eq', 'comparator': 'eq',
'value': port_id}]) 'value': port_id}])
super(TricirclePlugin, self).delete_port(context, port_id) super(TricirclePlugin, self).delete_port(context, port_id)
q_ports.PortBinding.delete_objects(context, port_id=port_id)
def _get_port_qos_info(self, context, port_id): def _get_port_qos_info(self, context, port_id):
policy = policy_object.QosPolicy.get_port_policy(context, port_id) policy = policy_object.QosPolicy.get_port_policy(context, port_id)

View File

@ -738,8 +738,11 @@ class TricirclePlugin(plugin.Ml2Plugin):
region_name = self._get_neutron_region() region_name = self._get_neutron_region()
update_dict = {portbindings.PROFILE: { update_dict = {portbindings.PROFILE: {
t_constants.PROFILE_REGION: region_name, t_constants.PROFILE_REGION: region_name,
t_constants.PROFILE_DEVICE: b_port['device_owner'] t_constants.PROFILE_DEVICE: b_port['device_owner'],
}} portbindings.VIF_DETAILS: b_port[portbindings.VIF_DETAILS],
portbindings.VNIC_TYPE: b_port[portbindings.VNIC_TYPE],
portbindings.VIF_TYPE: b_port[portbindings.VIF_TYPE],
portbindings.HOST_ID: b_port[portbindings.HOST_ID]}}
if b_port.get(t_constants.PROFILE_STATUS): if b_port.get(t_constants.PROFILE_STATUS):
update_dict[portbindings.PROFILE].update({ update_dict[portbindings.PROFILE].update({
t_constants.PROFILE_STATUS: b_port['status'] t_constants.PROFILE_STATUS: b_port['status']

View File

@ -646,7 +646,11 @@ class PluginTest(unittest.TestCase):
fake_port = { fake_port = {
'id': port_id, 'id': port_id,
'network_id': b_net['id'], 'network_id': b_net['id'],
'binding:vif_type': 'fake_vif_type'} 'binding:vif_type': 'fake_vif_type',
'binding:host_id': host_id,
portbindings.VIF_DETAILS: {},
portbindings.VNIC_TYPE: 'normal'
}
fake_agent = { fake_agent = {
'agent_type': 'Open vSwitch agent', 'agent_type': 'Open vSwitch agent',
'host': host_id, 'host': host_id,
@ -662,7 +666,11 @@ class PluginTest(unittest.TestCase):
mock_update.assert_called_with( mock_update.assert_called_with(
self.context, 'port', port_id, self.context, 'port', port_id,
{'port': {'binding:profile': {'region': 'Pod1', {'port': {'binding:profile': {'region': 'Pod1',
'device': 'compute:None'}}}) 'device': 'compute:None',
'binding:vif_type': 'fake_vif_type',
'binding:host_id': host_id,
portbindings.VIF_DETAILS: {},
portbindings.VNIC_TYPE: 'normal'}}})
# update network type from vlan to vxlan # update network type from vlan to vxlan
update_resource('network', False, b_net['id'], update_resource('network', False, b_net['id'],
@ -673,7 +681,11 @@ class PluginTest(unittest.TestCase):
mock_update.assert_called_with( mock_update.assert_called_with(
self.context, 'port', port_id, self.context, 'port', port_id,
{'port': {'binding:profile': {'region': 'Pod1', {'port': {'binding:profile': {'region': 'Pod1',
'device': 'compute:None'}}}) 'device': 'compute:None',
'binding:vif_type': 'fake_vif_type',
'binding:host_id': host_id,
portbindings.VIF_DETAILS: {},
portbindings.VNIC_TYPE: 'normal'}}})
# update network type from fake_vif_type to ovs # update network type from fake_vif_type to ovs
update_resource('port', False, port_id, update_resource('port', False, port_id,
@ -686,7 +698,12 @@ class PluginTest(unittest.TestCase):
mock_update.assert_called_with( mock_update.assert_called_with(
self.context, 'port', port_id, self.context, 'port', port_id,
{'port': {'binding:profile': {'region': 'Pod1', {'port': {'binding:profile': {'region': 'Pod1',
'device': 'compute:None'}}}) 'device': 'compute:None',
'binding:vif_type': 'ovs',
'binding:host_id':
'fake_another_host',
portbindings.VIF_DETAILS: {},
portbindings.VNIC_TYPE: 'normal'}}})
self.plugin.update_port(self.context, port_id, update_body) self.plugin.update_port(self.context, port_id, update_body)
# default p2p mode, update with agent host tunnel ip # default p2p mode, update with agent host tunnel ip
@ -696,7 +713,11 @@ class PluginTest(unittest.TestCase):
'tunnel_ip': '192.168.1.101', 'tunnel_ip': '192.168.1.101',
'type': 'Open vSwitch agent', 'type': 'Open vSwitch agent',
'host': host_id, 'host': host_id,
'device': 'compute:None'}}}) 'device': 'compute:None',
'binding:vif_type': 'ovs',
'binding:host_id': host_id,
portbindings.VIF_DETAILS: {},
portbindings.VNIC_TYPE: 'normal'}}})
cfg.CONF.set_override('cross_pod_vxlan_mode', 'l2gw', 'client') cfg.CONF.set_override('cross_pod_vxlan_mode', 'l2gw', 'client')
cfg.CONF.set_override('l2gw_tunnel_ip', '192.168.1.105', 'tricircle') cfg.CONF.set_override('l2gw_tunnel_ip', '192.168.1.105', 'tricircle')
@ -710,7 +731,11 @@ class PluginTest(unittest.TestCase):
'tunnel_ip': '192.168.1.105', 'tunnel_ip': '192.168.1.105',
'type': 'Open vSwitch agent', 'type': 'Open vSwitch agent',
'host': 'fake_host', 'host': 'fake_host',
'device': 'compute:None'}}}) 'device': 'compute:None',
'binding:vif_type': 'ovs',
'binding:host_id': host_id,
portbindings.VIF_DETAILS: {},
portbindings.VNIC_TYPE: 'normal'}}})
cfg.CONF.set_override('l2gw_tunnel_ip', None, 'tricircle') cfg.CONF.set_override('l2gw_tunnel_ip', None, 'tricircle')
cfg.CONF.set_override('cross_pod_vxlan_mode', 'l2gw', 'client') cfg.CONF.set_override('cross_pod_vxlan_mode', 'l2gw', 'client')
@ -719,7 +744,11 @@ class PluginTest(unittest.TestCase):
mock_update.assert_called_with( mock_update.assert_called_with(
self.context, 'port', port_id, self.context, 'port', port_id,
{'port': {'binding:profile': {'region': 'Pod1', {'port': {'binding:profile': {'region': 'Pod1',
'device': 'compute:None'}}}) 'device': 'compute:None',
'binding:vif_type': 'ovs',
'binding:host_id': host_id,
portbindings.VIF_DETAILS: {},
portbindings.VNIC_TYPE: 'normal'}}})
cfg.CONF.set_override('cross_pod_vxlan_mode', 'noop', 'client') cfg.CONF.set_override('cross_pod_vxlan_mode', 'noop', 'client')
self.plugin.update_port(self.context, port_id, update_body) self.plugin.update_port(self.context, port_id, update_body)
@ -727,7 +756,11 @@ class PluginTest(unittest.TestCase):
mock_update.assert_called_with( mock_update.assert_called_with(
self.context, 'port', port_id, self.context, 'port', port_id,
{'port': {'binding:profile': {'region': 'Pod1', {'port': {'binding:profile': {'region': 'Pod1',
'device': 'compute:None'}}}) 'device': 'compute:None',
'binding:vif_type': 'ovs',
'binding:host_id': host_id,
portbindings.VIF_DETAILS: {},
portbindings.VNIC_TYPE: 'normal'}}})
FakeCorePlugin.supported_extension_aliases = [] FakeCorePlugin.supported_extension_aliases = []
self.plugin.update_port(self.context, port_id, update_body) self.plugin.update_port(self.context, port_id, update_body)
@ -735,7 +768,11 @@ class PluginTest(unittest.TestCase):
mock_update.assert_called_with( mock_update.assert_called_with(
self.context, 'port', port_id, self.context, 'port', port_id,
{'port': {'binding:profile': {'region': 'Pod1', {'port': {'binding:profile': {'region': 'Pod1',
'device': 'compute:None'}}}) 'device': 'compute:None',
'binding:vif_type': 'ovs',
'binding:host_id': host_id,
portbindings.VIF_DETAILS: {},
portbindings.VNIC_TYPE: 'normal'}}})
FakeCorePlugin.supported_extension_aliases = ['agent'] FakeCorePlugin.supported_extension_aliases = ['agent']
self.plugin.update_port(self.context, port_id, self.plugin.update_port(self.context, port_id,