Handle network and port create/update, ENS + QOS
Bug fix 2082554: handle the exception in neutron side for Qos since its not supported from NSXT for ENS TZ Change-Id: I8ca4c7d04286830ce785a60d7a24439b9a39d801 Signed-off-by: Michal Kelner Mishali <mkelnermishal@vmware.com>
This commit is contained in:
parent
db32fcec6f
commit
9ce4e29a3e
@ -965,6 +965,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
provider_data = self._validate_provider_create(context, net_data, az,
|
provider_data = self._validate_provider_create(context, net_data, az,
|
||||||
transparent_vlan)
|
transparent_vlan)
|
||||||
|
|
||||||
|
physical_net = provider_data['physical_net']
|
||||||
|
self._assert_on_ens_with_qos(physical_net, net_data)
|
||||||
if (provider_data['switch_mode'] ==
|
if (provider_data['switch_mode'] ==
|
||||||
self.nsxlib.transport_zone.HOST_SWITCH_MODE_ENS):
|
self.nsxlib.transport_zone.HOST_SWITCH_MODE_ENS):
|
||||||
if not cfg.CONF.nsx_v3.ens_support:
|
if not cfg.CONF.nsx_v3.ens_support:
|
||||||
@ -1256,6 +1258,12 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
|
|
||||||
return created_net
|
return created_net
|
||||||
|
|
||||||
|
def _assert_on_ens_with_qos(self, tz_id, net_data):
|
||||||
|
qos_id = net_data.get(qos_consts.QOS_POLICY_ID)
|
||||||
|
if validators.is_attr_set(qos_id) and tz_id and self._is_ens_tz(tz_id):
|
||||||
|
err_msg = _("Cannot configure QOS on ENS networks")
|
||||||
|
raise n_exc.InvalidInput(error_message=err_msg)
|
||||||
|
|
||||||
def _has_active_port(self, context, network_id):
|
def _has_active_port(self, context, network_id):
|
||||||
ports_in_use = context.session.query(models_v2.Port).filter_by(
|
ports_in_use = context.session.query(models_v2.Port).filter_by(
|
||||||
network_id=network_id).all()
|
network_id=network_id).all()
|
||||||
@ -1357,6 +1365,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
is_nsx_net = self._network_is_nsx_net(context, id)
|
is_nsx_net = self._network_is_nsx_net(context, id)
|
||||||
if extern_net:
|
if extern_net:
|
||||||
self._assert_on_external_net_with_qos(net_data)
|
self._assert_on_external_net_with_qos(net_data)
|
||||||
|
else:
|
||||||
|
self._assert_on_ens_with_qos(self._get_net_tz(context, id),
|
||||||
|
net_data)
|
||||||
updated_net = super(NsxV3Plugin, self).update_network(context, id,
|
updated_net = super(NsxV3Plugin, self).update_network(context, id,
|
||||||
network)
|
network)
|
||||||
self._extension_manager.process_update_network(context, net_data,
|
self._extension_manager.process_update_network(context, net_data,
|
||||||
@ -2232,11 +2243,13 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
tz_id = self._get_net_tz(context, net_id)
|
tz_id = self._get_net_tz(context, net_id)
|
||||||
if tz_id:
|
if tz_id:
|
||||||
# Check the mode of this TZ
|
# Check the mode of this TZ
|
||||||
mode = self.nsxlib.transport_zone.get_host_switch_mode(tz_id)
|
return self._is_ens_tz(tz_id)
|
||||||
return (mode ==
|
|
||||||
self.nsxlib.transport_zone.HOST_SWITCH_MODE_ENS)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _is_ens_tz(self, tz_id):
|
||||||
|
mode = self.nsxlib.transport_zone.get_host_switch_mode(tz_id)
|
||||||
|
return mode == self.nsxlib.transport_zone.HOST_SWITCH_MODE_ENS
|
||||||
|
|
||||||
def _is_ens_tz_port(self, context, port_data):
|
def _is_ens_tz_port(self, context, port_data):
|
||||||
# Check the host-switch-mode of the TZ connected to the ports network
|
# Check the host-switch-mode of the TZ connected to the ports network
|
||||||
return self._is_ens_tz_net(context, port_data['network_id'])
|
return self._is_ens_tz_net(context, port_data['network_id'])
|
||||||
@ -2726,6 +2739,12 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
port_data.get('device_owner'))
|
port_data.get('device_owner'))
|
||||||
self._assert_on_dhcp_relay_without_router(context, port_data)
|
self._assert_on_dhcp_relay_without_router(context, port_data)
|
||||||
is_ens_tz_port = self._is_ens_tz_port(context, port_data)
|
is_ens_tz_port = self._is_ens_tz_port(context, port_data)
|
||||||
|
qos_selected = validators.is_attr_set(port_data.get(
|
||||||
|
qos_consts.QOS_POLICY_ID))
|
||||||
|
|
||||||
|
if is_ens_tz_port and qos_selected:
|
||||||
|
err_msg = _("Cannot configure QOS on ENS networks")
|
||||||
|
raise n_exc.InvalidInput(error_message=err_msg)
|
||||||
|
|
||||||
# TODO(salv-orlando): Undo logical switch creation on failure
|
# TODO(salv-orlando): Undo logical switch creation on failure
|
||||||
with db_api.context_manager.writer.using(context):
|
with db_api.context_manager.writer.using(context):
|
||||||
@ -3202,6 +3221,13 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
self._assert_on_dhcp_relay_without_router(context, port_data,
|
self._assert_on_dhcp_relay_without_router(context, port_data,
|
||||||
original_port)
|
original_port)
|
||||||
|
|
||||||
|
is_ens_tz_port = self._is_ens_tz_port(context, original_port)
|
||||||
|
qos_selected = validators.is_attr_set(port_data.get
|
||||||
|
(qos_consts.QOS_POLICY_ID))
|
||||||
|
if is_ens_tz_port and qos_selected:
|
||||||
|
err_msg = _("Cannot configure QOS on ENS networks")
|
||||||
|
raise n_exc.InvalidInput(error_message=err_msg)
|
||||||
|
|
||||||
dhcp_opts = port_data.get(ext_edo.EXTRADHCPOPTS)
|
dhcp_opts = port_data.get(ext_edo.EXTRADHCPOPTS)
|
||||||
self._validate_extra_dhcp_options(dhcp_opts)
|
self._validate_extra_dhcp_options(dhcp_opts)
|
||||||
|
|
||||||
|
@ -509,6 +509,65 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxV3PluginTestCaseMixin):
|
|||||||
self.assertEqual('NsxENSPortSecurity',
|
self.assertEqual('NsxENSPortSecurity',
|
||||||
res['NeutronError']['type'])
|
res['NeutronError']['type'])
|
||||||
|
|
||||||
|
def test_create_ens_network_with_qos(self):
|
||||||
|
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
|
||||||
|
mock_ens = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibTransportZone'
|
||||||
|
'.get_host_switch_mode', return_value='ENS')
|
||||||
|
mock_tz = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibLogicalSwitch.get',
|
||||||
|
return_value={'transport_zone_id': 'xxx'})
|
||||||
|
mock_tt = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibTransportZone'
|
||||||
|
'.get_transport_type', return_value='VLAN')
|
||||||
|
policy_id = uuidutils.generate_uuid()
|
||||||
|
data = {'network': {
|
||||||
|
'name': 'qos_net',
|
||||||
|
'tenant_id': 'some_tenant',
|
||||||
|
'provider:network_type': 'flat',
|
||||||
|
'provider:physical_network': 'xxx',
|
||||||
|
'qos_policy_id': policy_id,
|
||||||
|
'port_security_enabled': False}}
|
||||||
|
with mock_ens, mock_tz, mock_tt:
|
||||||
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
|
self.plugin.create_network,
|
||||||
|
context.get_admin_context(), data)
|
||||||
|
|
||||||
|
def test_update_ens_network_with_qos(self):
|
||||||
|
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
|
||||||
|
mock_ens = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibTransportZone'
|
||||||
|
'.get_host_switch_mode', return_value='ENS')
|
||||||
|
mock_tz = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibLogicalSwitch.get',
|
||||||
|
return_value={'transport_zone_id': 'xxx'})
|
||||||
|
mock_tt = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibTransportZone'
|
||||||
|
'.get_transport_type', return_value='VLAN')
|
||||||
|
data = {'network': {
|
||||||
|
'name': 'qos_net',
|
||||||
|
'tenant_id': 'some_tenant',
|
||||||
|
'provider:network_type': 'flat',
|
||||||
|
'provider:physical_network': 'xxx',
|
||||||
|
'admin_state_up': True,
|
||||||
|
'shared': False,
|
||||||
|
'port_security_enabled': False}}
|
||||||
|
with mock_ens, mock_tz, mock_tt:
|
||||||
|
network = self.plugin.create_network(context.get_admin_context(),
|
||||||
|
data)
|
||||||
|
policy_id = uuidutils.generate_uuid()
|
||||||
|
data = {'network': {
|
||||||
|
'id': network['id'],
|
||||||
|
'admin_state_up': True,
|
||||||
|
'shared': False,
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'tenant_id': 'some_tenant',
|
||||||
|
'qos_policy_id': policy_id}}
|
||||||
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
|
self.plugin.update_network,
|
||||||
|
context.get_admin_context(),
|
||||||
|
network['id'], data)
|
||||||
|
|
||||||
def test_update_ens_network(self):
|
def test_update_ens_network(self):
|
||||||
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
|
cfg.CONF.set_override('ens_support', True, 'nsx_v3')
|
||||||
providernet_args = {psec.PORTSECURITY: False}
|
providernet_args = {psec.PORTSECURITY: False}
|
||||||
@ -819,6 +878,75 @@ class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin,
|
|||||||
self.assertRaises(n_exc.InvalidInput,
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
self.plugin.create_port, self.ctx, data)
|
self.plugin.create_port, self.ctx, data)
|
||||||
|
|
||||||
|
def test_create_port_ens_with_qos_fail(self):
|
||||||
|
with self.network() as network:
|
||||||
|
with self.subnet(network=network, cidr='10.0.0.0/24'):
|
||||||
|
policy_id = uuidutils.generate_uuid()
|
||||||
|
mock_ens = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibTransportZone'
|
||||||
|
'.get_host_switch_mode',
|
||||||
|
return_value='ENS')
|
||||||
|
mock_tz = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources'
|
||||||
|
'.NsxLibLogicalSwitch.get',
|
||||||
|
return_value={
|
||||||
|
'transport_zone_id': 'xxx'})
|
||||||
|
mock_tt = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibTransportZone'
|
||||||
|
'.get_transport_type',
|
||||||
|
return_value='VLAN')
|
||||||
|
data = {'port': {
|
||||||
|
'network_id': network['network']['id'],
|
||||||
|
'tenant_id': self._tenant_id,
|
||||||
|
'name': 'qos_port',
|
||||||
|
'admin_state_up': True,
|
||||||
|
'device_id': 'fake_device',
|
||||||
|
'device_owner': 'fake_owner',
|
||||||
|
'fixed_ips': [],
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'mac_address': '00:00:00:00:00:01',
|
||||||
|
'qos_policy_id': policy_id}
|
||||||
|
}
|
||||||
|
# Cannot add qos policy to this type of port
|
||||||
|
with mock_ens, mock_tz, mock_tt:
|
||||||
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
|
self.plugin.create_port, self.ctx, data)
|
||||||
|
|
||||||
|
def test_update_port_ens_with_qos_fail(self):
|
||||||
|
with self.network() as network:
|
||||||
|
with self.subnet(network=network, cidr='10.0.0.0/24'):
|
||||||
|
policy_id = uuidutils.generate_uuid()
|
||||||
|
mock_ens = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibTransportZone'
|
||||||
|
'.get_host_switch_mode',
|
||||||
|
return_value='ENS')
|
||||||
|
mock_tz = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources'
|
||||||
|
'.NsxLibLogicalSwitch.get',
|
||||||
|
return_value={
|
||||||
|
'transport_zone_id': 'xxx'})
|
||||||
|
mock_tt = mock.patch('vmware_nsxlib.v3'
|
||||||
|
'.core_resources.NsxLibTransportZone'
|
||||||
|
'.get_transport_type',
|
||||||
|
return_value='VLAN')
|
||||||
|
data = {'port': {
|
||||||
|
'network_id': network['network']['id'],
|
||||||
|
'tenant_id': self._tenant_id,
|
||||||
|
'name': 'qos_port',
|
||||||
|
'admin_state_up': True,
|
||||||
|
'device_id': 'fake_device',
|
||||||
|
'device_owner': 'fake_owner',
|
||||||
|
'fixed_ips': [],
|
||||||
|
'port_security_enabled': False,
|
||||||
|
'mac_address': '00:00:00:00:00:01'}
|
||||||
|
}
|
||||||
|
with mock_ens, mock_tz, mock_tt:
|
||||||
|
port = self.plugin.create_port(self.ctx, data)
|
||||||
|
data['port'] = {'qos_policy_id': policy_id}
|
||||||
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
|
self.plugin.update_port,
|
||||||
|
self.ctx, port['id'], data)
|
||||||
|
|
||||||
def test_create_router_port_with_qos_fail(self):
|
def test_create_router_port_with_qos_fail(self):
|
||||||
self._test_create_illegal_port_with_qos_fail(
|
self._test_create_illegal_port_with_qos_fail(
|
||||||
'network:router_interface')
|
'network:router_interface')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user