Qos rule not update after vm bound qos
1. What is the problem? Qos rule cannot be updated after virtual machine creation and qos policy binding. 2. What is the solution to the problem? In central_plugin.py, add maintenance to the neutron0 database table ml2_port_bindings to provide add and delete record. Change-Id: I23462862bbdb33e96a58b67ed4cd6f3abf95076f Signed-off-by: zhang xiaohan <zhangxiaohan@szzt.com.cn> Co-Authored-By: tangzhuo <ztang@hnu.edu.cn>
This commit is contained in:
parent
c3e4a072bb
commit
56c118a638
|
@ -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)
|
||||||
|
|
|
@ -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']
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue