Reset API naming scheme for VMware NSX plugin
Introduce new naming scheme, whilst preserving backward compatibility for the extensions affected. Deprecated extensions will be removed from Juno. Partial-implements blueprint: nicira-plugin-renaming Change-Id: Icd68e5db04aa008ac31994ae0cb5c1b7f2551303
This commit is contained in:
parent
898e001442
commit
f58df68fa0
@ -68,13 +68,13 @@ from neutron.plugins.nicira.common import securitygroups as nvp_sec
|
|||||||
from neutron.plugins.nicira.common import sync
|
from neutron.plugins.nicira.common import sync
|
||||||
from neutron.plugins.nicira.dbexts import distributedrouter as dist_rtr
|
from neutron.plugins.nicira.dbexts import distributedrouter as dist_rtr
|
||||||
from neutron.plugins.nicira.dbexts import maclearning as mac_db
|
from neutron.plugins.nicira.dbexts import maclearning as mac_db
|
||||||
|
from neutron.plugins.nicira.dbexts import networkgw_db
|
||||||
from neutron.plugins.nicira.dbexts import nicira_db
|
from neutron.plugins.nicira.dbexts import nicira_db
|
||||||
from neutron.plugins.nicira.dbexts import nicira_networkgw_db as networkgw_db
|
|
||||||
from neutron.plugins.nicira.dbexts import qos_db
|
from neutron.plugins.nicira.dbexts import qos_db
|
||||||
from neutron.plugins.nicira import dhcpmeta_modes
|
from neutron.plugins.nicira import dhcpmeta_modes
|
||||||
from neutron.plugins.nicira.extensions import maclearning as mac_ext
|
from neutron.plugins.nicira.extensions import maclearning as mac_ext
|
||||||
from neutron.plugins.nicira.extensions import nvp_networkgw as networkgw
|
from neutron.plugins.nicira.extensions import networkgw
|
||||||
from neutron.plugins.nicira.extensions import nvp_qos as ext_qos
|
from neutron.plugins.nicira.extensions import qos
|
||||||
from neutron.plugins.nicira.nsxlib import l2gateway as l2gwlib
|
from neutron.plugins.nicira.nsxlib import l2gateway as l2gwlib
|
||||||
from neutron.plugins.nicira.nsxlib import queue as queuelib
|
from neutron.plugins.nicira.nsxlib import queue as queuelib
|
||||||
from neutron.plugins.nicira.nsxlib import router as routerlib
|
from neutron.plugins.nicira.nsxlib import router as routerlib
|
||||||
@ -134,6 +134,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
"nvp-qos",
|
"nvp-qos",
|
||||||
"port-security",
|
"port-security",
|
||||||
"provider",
|
"provider",
|
||||||
|
"qos-queue",
|
||||||
"quotas",
|
"quotas",
|
||||||
"external-net",
|
"external-net",
|
||||||
"router",
|
"router",
|
||||||
@ -418,7 +419,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
port_data['fixed_ips'],
|
port_data['fixed_ips'],
|
||||||
port_data[psec.PORTSECURITY],
|
port_data[psec.PORTSECURITY],
|
||||||
port_data[ext_sg.SECURITYGROUPS],
|
port_data[ext_sg.SECURITYGROUPS],
|
||||||
port_data.get(ext_qos.QUEUE),
|
port_data.get(qos.QUEUE),
|
||||||
port_data.get(mac_ext.MAC_LEARNING),
|
port_data.get(mac_ext.MAC_LEARNING),
|
||||||
port_data.get(addr_pair.ADDRESS_PAIRS))
|
port_data.get(addr_pair.ADDRESS_PAIRS))
|
||||||
|
|
||||||
@ -995,7 +996,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
# DB Operations for setting the network as external
|
# DB Operations for setting the network as external
|
||||||
self._process_l3_create(context, new_net, net_data)
|
self._process_l3_create(context, new_net, net_data)
|
||||||
# Process QoS queue extension
|
# Process QoS queue extension
|
||||||
net_queue_id = net_data.get(ext_qos.QUEUE)
|
net_queue_id = net_data.get(qos.QUEUE)
|
||||||
if net_queue_id:
|
if net_queue_id:
|
||||||
# Raises if not found
|
# Raises if not found
|
||||||
self.get_qos_queue(context, net_queue_id)
|
self.get_qos_queue(context, net_queue_id)
|
||||||
@ -1112,7 +1113,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
if psec.PORTSECURITY in network['network']:
|
if psec.PORTSECURITY in network['network']:
|
||||||
self._process_network_port_security_update(
|
self._process_network_port_security_update(
|
||||||
context, network['network'], net)
|
context, network['network'], net)
|
||||||
net_queue_id = network['network'].get(ext_qos.QUEUE)
|
net_queue_id = network['network'].get(qos.QUEUE)
|
||||||
if net_queue_id:
|
if net_queue_id:
|
||||||
self._delete_network_queue_mapping(context, id)
|
self._delete_network_queue_mapping(context, id)
|
||||||
self._process_network_queue_mapping(context, net, net_queue_id)
|
self._process_network_queue_mapping(context, net, net_queue_id)
|
||||||
@ -1294,8 +1295,8 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
if nsx_port_id:
|
if nsx_port_id:
|
||||||
try:
|
try:
|
||||||
switchlib.update_port(
|
switchlib.update_port(
|
||||||
self.cluster,
|
self.cluster, nsx_switch_id, nsx_port_id,
|
||||||
nsx_switch_id, nsx_port_id, id, tenant_id,
|
id, tenant_id,
|
||||||
ret_port['name'],
|
ret_port['name'],
|
||||||
ret_port['device_id'],
|
ret_port['device_id'],
|
||||||
ret_port['admin_state_up'],
|
ret_port['admin_state_up'],
|
||||||
@ -1303,7 +1304,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
ret_port['fixed_ips'],
|
ret_port['fixed_ips'],
|
||||||
ret_port[psec.PORTSECURITY],
|
ret_port[psec.PORTSECURITY],
|
||||||
ret_port[ext_sg.SECURITYGROUPS],
|
ret_port[ext_sg.SECURITYGROUPS],
|
||||||
ret_port[ext_qos.QUEUE],
|
ret_port[qos.QUEUE],
|
||||||
ret_port.get(mac_ext.MAC_LEARNING),
|
ret_port.get(mac_ext.MAC_LEARNING),
|
||||||
ret_port.get(addr_pair.ADDRESS_PAIRS))
|
ret_port.get(addr_pair.ADDRESS_PAIRS))
|
||||||
|
|
||||||
@ -2225,7 +2226,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
queues = self._get_port_queue_bindings(context, filters)
|
queues = self._get_port_queue_bindings(context, filters)
|
||||||
if queues:
|
if queues:
|
||||||
if raise_in_use:
|
if raise_in_use:
|
||||||
raise ext_qos.QueueInUseByPort()
|
raise qos.QueueInUseByPort()
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
queuelib.delete_lqueue(self.cluster, queue_id)
|
queuelib.delete_lqueue(self.cluster, queue_id)
|
||||||
|
@ -30,7 +30,7 @@ from neutron.db import model_base
|
|||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
from neutron.openstack.common import log as logging
|
from neutron.openstack.common import log as logging
|
||||||
from neutron.openstack.common import uuidutils
|
from neutron.openstack.common import uuidutils
|
||||||
from neutron.plugins.nicira.extensions import nvp_networkgw
|
from neutron.plugins.nicira.extensions import networkgw
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -129,9 +129,9 @@ class NetworkGateway(model_base.BASEV2, models_v2.HasId,
|
|||||||
network_connections = orm.relationship(NetworkConnection, lazy='joined')
|
network_connections = orm.relationship(NetworkConnection, lazy='joined')
|
||||||
|
|
||||||
|
|
||||||
class NetworkGatewayMixin(nvp_networkgw.NetworkGatewayPluginBase):
|
class NetworkGatewayMixin(networkgw.NetworkGatewayPluginBase):
|
||||||
|
|
||||||
resource = nvp_networkgw.RESOURCE_NAME.replace('-', '_')
|
resource = networkgw.RESOURCE_NAME.replace('-', '_')
|
||||||
|
|
||||||
def _get_network_gateway(self, context, gw_id):
|
def _get_network_gateway(self, context, gw_id):
|
||||||
try:
|
try:
|
@ -20,8 +20,8 @@ from sqlalchemy.orm import exc
|
|||||||
import neutron.db.api as db
|
import neutron.db.api as db
|
||||||
from neutron.openstack.common.db import exception as d_exc
|
from neutron.openstack.common.db import exception as d_exc
|
||||||
from neutron.openstack.common import log as logging
|
from neutron.openstack.common import log as logging
|
||||||
|
from neutron.plugins.nicira.dbexts import networkgw_db
|
||||||
from neutron.plugins.nicira.dbexts import nicira_models
|
from neutron.plugins.nicira.dbexts import nicira_models
|
||||||
from neutron.plugins.nicira.dbexts import nicira_networkgw_db
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -136,13 +136,13 @@ def delete_neutron_nsx_router_mapping(session, neutron_id):
|
|||||||
|
|
||||||
def unset_default_network_gateways(session):
|
def unset_default_network_gateways(session):
|
||||||
with session.begin(subtransactions=True):
|
with session.begin(subtransactions=True):
|
||||||
session.query(nicira_networkgw_db.NetworkGateway).update(
|
session.query(networkgw_db.NetworkGateway).update(
|
||||||
{nicira_networkgw_db.NetworkGateway.default: False})
|
{networkgw_db.NetworkGateway.default: False})
|
||||||
|
|
||||||
|
|
||||||
def set_default_network_gateway(session, gw_id):
|
def set_default_network_gateway(session, gw_id):
|
||||||
with session.begin(subtransactions=True):
|
with session.begin(subtransactions=True):
|
||||||
gw = (session.query(nicira_networkgw_db.NetworkGateway).
|
gw = (session.query(networkgw_db.NetworkGateway).
|
||||||
filter_by(id=gw_id).one())
|
filter_by(id=gw_id).one())
|
||||||
gw['default'] = True
|
gw['default'] = True
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ from neutron.db import model_base
|
|||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
from neutron.openstack.common import log
|
from neutron.openstack.common import log
|
||||||
from neutron.openstack.common import uuidutils
|
from neutron.openstack.common import uuidutils
|
||||||
from neutron.plugins.nicira.extensions import nvp_qos as ext_qos
|
from neutron.plugins.nicira.extensions import qos
|
||||||
|
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
@ -73,7 +73,7 @@ class NetworkQueueMapping(model_base.BASEV2):
|
|||||||
cascade='delete', lazy='joined'))
|
cascade='delete', lazy='joined'))
|
||||||
|
|
||||||
|
|
||||||
class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
class NVPQoSDbMixin(qos.QueuePluginBase):
|
||||||
"""Mixin class to add queues."""
|
"""Mixin class to add queues."""
|
||||||
|
|
||||||
def create_qos_queue(self, context, qos_queue):
|
def create_qos_queue(self, context, qos_queue):
|
||||||
@ -98,7 +98,7 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
try:
|
try:
|
||||||
return self._get_by_id(context, QoSQueue, queue_id)
|
return self._get_by_id(context, QoSQueue, queue_id)
|
||||||
except exc.NoResultFound:
|
except exc.NoResultFound:
|
||||||
raise ext_qos.QueueNotFound(id=queue_id)
|
raise qos.QueueNotFound(id=queue_id)
|
||||||
|
|
||||||
def get_qos_queues(self, context, filters=None, fields=None):
|
def get_qos_queues(self, context, filters=None, fields=None):
|
||||||
return self._get_collection(context, QoSQueue,
|
return self._get_collection(context, QoSQueue,
|
||||||
@ -111,7 +111,7 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
context.session.delete(qos_queue)
|
context.session.delete(qos_queue)
|
||||||
|
|
||||||
def _process_port_queue_mapping(self, context, port_data, queue_id):
|
def _process_port_queue_mapping(self, context, port_data, queue_id):
|
||||||
port_data[ext_qos.QUEUE] = queue_id
|
port_data[qos.QUEUE] = queue_id
|
||||||
if not queue_id:
|
if not queue_id:
|
||||||
return
|
return
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
@ -136,7 +136,7 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
context.session.delete(binding)
|
context.session.delete(binding)
|
||||||
|
|
||||||
def _process_network_queue_mapping(self, context, net_data, queue_id):
|
def _process_network_queue_mapping(self, context, net_data, queue_id):
|
||||||
net_data[ext_qos.QUEUE] = queue_id
|
net_data[qos.QUEUE] = queue_id
|
||||||
if not queue_id:
|
if not queue_id:
|
||||||
return
|
return
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
@ -159,7 +159,7 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
def _extend_dict_qos_queue(self, obj_res, obj_db):
|
def _extend_dict_qos_queue(self, obj_res, obj_db):
|
||||||
queue_mapping = obj_db['qos_queue']
|
queue_mapping = obj_db['qos_queue']
|
||||||
if queue_mapping:
|
if queue_mapping:
|
||||||
obj_res[ext_qos.QUEUE] = queue_mapping.get('queue_id')
|
obj_res[qos.QUEUE] = queue_mapping.get('queue_id')
|
||||||
return obj_res
|
return obj_res
|
||||||
|
|
||||||
def _extend_port_dict_qos_queue(self, port_res, port_db):
|
def _extend_port_dict_qos_queue(self, port_res, port_db):
|
||||||
@ -265,8 +265,8 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
|
|
||||||
# create the queue
|
# create the queue
|
||||||
tenant_id = self._get_tenant_id_for_create(context, port)
|
tenant_id = self._get_tenant_id_for_create(context, port)
|
||||||
if port.get(ext_qos.RXTX_FACTOR) and queue_to_create.get('max'):
|
if port.get(qos.RXTX_FACTOR) and queue_to_create.get('max'):
|
||||||
queue_to_create['max'] *= int(port[ext_qos.RXTX_FACTOR])
|
queue_to_create['max'] *= int(port[qos.RXTX_FACTOR])
|
||||||
queue = {'qos_queue': {'name': queue_to_create.get('name'),
|
queue = {'qos_queue': {'name': queue_to_create.get('name'),
|
||||||
'min': queue_to_create.get('min'),
|
'min': queue_to_create.get('min'),
|
||||||
'max': queue_to_create.get('max'),
|
'max': queue_to_create.get('max'),
|
||||||
@ -280,9 +280,9 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
if qos_queue.get('default'):
|
if qos_queue.get('default'):
|
||||||
if context.is_admin:
|
if context.is_admin:
|
||||||
if self.get_qos_queues(context, filters={'default': [True]}):
|
if self.get_qos_queues(context, filters={'default': [True]}):
|
||||||
raise ext_qos.DefaultQueueAlreadyExists()
|
raise qos.DefaultQueueAlreadyExists()
|
||||||
else:
|
else:
|
||||||
raise ext_qos.DefaultQueueCreateNotAdmin()
|
raise qos.DefaultQueueCreateNotAdmin()
|
||||||
if qos_queue.get('qos_marking') == 'trusted':
|
if qos_queue.get('qos_marking') == 'trusted':
|
||||||
dscp = qos_queue.pop('dscp')
|
dscp = qos_queue.pop('dscp')
|
||||||
LOG.info(_("DSCP value (%s) will be ignored with 'trusted' "
|
LOG.info(_("DSCP value (%s) will be ignored with 'trusted' "
|
||||||
@ -291,4 +291,4 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
min = qos_queue.get('min')
|
min = qos_queue.get('min')
|
||||||
# Max can be None
|
# Max can be None
|
||||||
if max and min > max:
|
if max and min > max:
|
||||||
raise ext_qos.QueueMinGreaterMax()
|
raise qos.QueueMinGreaterMax()
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2013 Nicira, Inc.
|
|
||||||
# All Rights Reserved
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
#
|
|
||||||
# @author: Aaron Rosen, Nicira Networks, Inc.
|
|
@ -1,6 +1,6 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
#
|
#
|
||||||
# Copyright 2013 Nicira Networks, Inc. All rights reserved.
|
# Copyright 2013 VMware, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
# not use this file except in compliance with the License. You may obtain
|
# not use this file except in compliance with the License. You may obtain
|
||||||
@ -48,7 +48,7 @@ class Distributedrouter(object):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_description(cls):
|
def get_description(cls):
|
||||||
return "Enables configuration of NSX Distributed routers"
|
return "Enables configuration of NSX Distributed routers."
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_namespace(cls):
|
def get_namespace(cls):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
#
|
#
|
||||||
# Copyright 2013 Nicira Networks, Inc. All rights reserved.
|
# Copyright 2013 VMware, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
# not use this file except in compliance with the License. You may obtain
|
# not use this file except in compliance with the License. You may obtain
|
||||||
@ -43,7 +43,7 @@ class Maclearning(object):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_description(cls):
|
def get_description(cls):
|
||||||
return "Provides mac learning capabilities"
|
return "Provides MAC learning capabilities."
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_namespace(cls):
|
def get_namespace(cls):
|
||||||
|
189
neutron/plugins/nicira/extensions/networkgw.py
Normal file
189
neutron/plugins/nicira/extensions/networkgw.py
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
#
|
||||||
|
# Copyright 2013 VMware. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
from neutron.api import extensions
|
||||||
|
from neutron.api.v2 import attributes
|
||||||
|
from neutron.api.v2 import base
|
||||||
|
from neutron import manager
|
||||||
|
from neutron import quota
|
||||||
|
|
||||||
|
|
||||||
|
RESOURCE_NAME = "network_gateway"
|
||||||
|
# Use dash for alias and collection name
|
||||||
|
EXT_ALIAS = RESOURCE_NAME.replace('_', '-')
|
||||||
|
COLLECTION_NAME = "%ss" % EXT_ALIAS
|
||||||
|
DEVICE_ID_ATTR = 'id'
|
||||||
|
IFACE_NAME_ATTR = 'interface_name'
|
||||||
|
|
||||||
|
# Attribute Map for Network Gateway Resource
|
||||||
|
# TODO(salvatore-orlando): add admin state as other neutron resources
|
||||||
|
RESOURCE_ATTRIBUTE_MAP = {
|
||||||
|
COLLECTION_NAME: {
|
||||||
|
'id': {'allow_post': False, 'allow_put': False,
|
||||||
|
'is_visible': True},
|
||||||
|
'name': {'allow_post': True, 'allow_put': True,
|
||||||
|
'validate': {'type:string': None},
|
||||||
|
'is_visible': True, 'default': ''},
|
||||||
|
'default': {'allow_post': False, 'allow_put': False,
|
||||||
|
'is_visible': True},
|
||||||
|
'devices': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:device_list': None},
|
||||||
|
'is_visible': True},
|
||||||
|
'ports': {'allow_post': False, 'allow_put': False,
|
||||||
|
'default': [],
|
||||||
|
'is_visible': True},
|
||||||
|
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:string': None},
|
||||||
|
'required_by_policy': True,
|
||||||
|
'is_visible': True}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_device_list(data, valid_values=None):
|
||||||
|
"""Validate the list of service definitions."""
|
||||||
|
if not data:
|
||||||
|
# Devices must be provided
|
||||||
|
msg = _("Cannot create a gateway with an empty device list")
|
||||||
|
return msg
|
||||||
|
try:
|
||||||
|
for device in data:
|
||||||
|
key_specs = {DEVICE_ID_ATTR:
|
||||||
|
{'type:regex': attributes.UUID_PATTERN,
|
||||||
|
'required': True},
|
||||||
|
IFACE_NAME_ATTR:
|
||||||
|
{'type:string': None,
|
||||||
|
'required': False}}
|
||||||
|
err_msg = attributes._validate_dict(
|
||||||
|
device, key_specs=key_specs)
|
||||||
|
if err_msg:
|
||||||
|
return err_msg
|
||||||
|
unexpected_keys = [key for key in device if key not in key_specs]
|
||||||
|
if unexpected_keys:
|
||||||
|
err_msg = (_("Unexpected keys found in device description:%s")
|
||||||
|
% ",".join(unexpected_keys))
|
||||||
|
return err_msg
|
||||||
|
except TypeError:
|
||||||
|
return (_("%s: provided data are not iterable") %
|
||||||
|
_validate_device_list.__name__)
|
||||||
|
|
||||||
|
nw_gw_quota_opts = [
|
||||||
|
cfg.IntOpt('quota_network_gateway',
|
||||||
|
default=5,
|
||||||
|
help=_('Number of network gateways allowed per tenant, '
|
||||||
|
'-1 for unlimited'))
|
||||||
|
]
|
||||||
|
|
||||||
|
cfg.CONF.register_opts(nw_gw_quota_opts, 'QUOTAS')
|
||||||
|
|
||||||
|
attributes.validators['type:device_list'] = _validate_device_list
|
||||||
|
|
||||||
|
|
||||||
|
class Networkgw(object):
|
||||||
|
"""API extension for Layer-2 Gateway support.
|
||||||
|
|
||||||
|
The Layer-2 gateway feature allows for connecting neutron networks
|
||||||
|
with external networks at the layer-2 level. No assumption is made on
|
||||||
|
the location of the external network, which might not even be directly
|
||||||
|
reachable from the hosts where the VMs are deployed.
|
||||||
|
|
||||||
|
This is achieved by instantiating 'network gateways', and then connecting
|
||||||
|
Neutron network to them.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_name(cls):
|
||||||
|
return "Network Gateway"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_alias(cls):
|
||||||
|
return EXT_ALIAS
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_description(cls):
|
||||||
|
return "Connects Neutron networks with external networks at layer 2."
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_namespace(cls):
|
||||||
|
return "http://docs.openstack.org/ext/network-gateway/api/v1.0"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_updated(cls):
|
||||||
|
return "2014-01-01T00:00:00-00:00"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_resources(cls):
|
||||||
|
"""Returns Ext Resources."""
|
||||||
|
plugin = manager.NeutronManager.get_plugin()
|
||||||
|
params = RESOURCE_ATTRIBUTE_MAP.get(COLLECTION_NAME, dict())
|
||||||
|
|
||||||
|
member_actions = {'connect_network': 'PUT',
|
||||||
|
'disconnect_network': 'PUT'}
|
||||||
|
|
||||||
|
# register quotas for network gateways
|
||||||
|
quota.QUOTAS.register_resource_by_name(RESOURCE_NAME)
|
||||||
|
collection_name = COLLECTION_NAME.replace('_', '-')
|
||||||
|
controller = base.create_resource(collection_name,
|
||||||
|
RESOURCE_NAME,
|
||||||
|
plugin, params,
|
||||||
|
member_actions=member_actions)
|
||||||
|
return [extensions.ResourceExtension(COLLECTION_NAME,
|
||||||
|
controller,
|
||||||
|
member_actions=member_actions)]
|
||||||
|
|
||||||
|
def get_extended_resources(self, version):
|
||||||
|
if version == "2.0":
|
||||||
|
return RESOURCE_ATTRIBUTE_MAP
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkGatewayPluginBase(object):
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def create_network_gateway(self, context, network_gateway):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def update_network_gateway(self, context, id, network_gateway):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_network_gateway(self, context, id, fields=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def delete_network_gateway(self, context, id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_network_gateways(self, context, filters=None, fields=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def connect_network(self, context, network_gateway_id,
|
||||||
|
network_mapping_info):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def disconnect_network(self, context, network_gateway_id,
|
||||||
|
network_mapping_info):
|
||||||
|
pass
|
@ -1,6 +1,7 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
#
|
|
||||||
# Copyright 2013 VMware. All rights reserved.
|
# Copyright 2013 VMware, Inc.
|
||||||
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
# not use this file except in compliance with the License. You may obtain
|
# not use this file except in compliance with the License. You may obtain
|
||||||
@ -14,101 +15,14 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
# @author: Salvatore Orlando, VMware
|
# TODO(armando-migliaccio): This is deprecated in Icehouse, and
|
||||||
|
# to be removed in Juno.
|
||||||
|
|
||||||
from abc import abstractmethod
|
from neutron.plugins.nicira.extensions import networkgw
|
||||||
|
|
||||||
from oslo.config import cfg
|
|
||||||
|
|
||||||
from neutron.api import extensions
|
|
||||||
from neutron.api.v2 import attributes
|
|
||||||
from neutron.api.v2 import base
|
|
||||||
from neutron import manager
|
|
||||||
from neutron import quota
|
|
||||||
|
|
||||||
|
|
||||||
RESOURCE_NAME = "network_gateway"
|
class Nvp_networkgw(networkgw.Networkgw):
|
||||||
# Use dash for alias and collection name
|
"""(Deprecated) API extension for Layer-2 Gateway support."""
|
||||||
EXT_ALIAS = RESOURCE_NAME.replace('_', '-')
|
|
||||||
COLLECTION_NAME = "%ss" % EXT_ALIAS
|
|
||||||
DEVICE_ID_ATTR = 'id'
|
|
||||||
IFACE_NAME_ATTR = 'interface_name'
|
|
||||||
|
|
||||||
# Attribute Map for Network Gateway Resource
|
|
||||||
# TODO(salvatore-orlando): add admin state as other neutron resources
|
|
||||||
RESOURCE_ATTRIBUTE_MAP = {
|
|
||||||
COLLECTION_NAME: {
|
|
||||||
'id': {'allow_post': False, 'allow_put': False,
|
|
||||||
'is_visible': True},
|
|
||||||
'name': {'allow_post': True, 'allow_put': True,
|
|
||||||
'validate': {'type:string': None},
|
|
||||||
'is_visible': True, 'default': ''},
|
|
||||||
'default': {'allow_post': False, 'allow_put': False,
|
|
||||||
'is_visible': True},
|
|
||||||
'devices': {'allow_post': True, 'allow_put': False,
|
|
||||||
'validate': {'type:device_list': None},
|
|
||||||
'is_visible': True},
|
|
||||||
'ports': {'allow_post': False, 'allow_put': False,
|
|
||||||
'default': [],
|
|
||||||
'is_visible': True},
|
|
||||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
|
||||||
'validate': {'type:string': None},
|
|
||||||
'required_by_policy': True,
|
|
||||||
'is_visible': True}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _validate_device_list(data, valid_values=None):
|
|
||||||
"""Validate the list of service definitions."""
|
|
||||||
if not data:
|
|
||||||
# Devices must be provided
|
|
||||||
msg = _("Cannot create a gateway with an empty device list")
|
|
||||||
return msg
|
|
||||||
try:
|
|
||||||
for device in data:
|
|
||||||
key_specs = {DEVICE_ID_ATTR:
|
|
||||||
{'type:regex': attributes.UUID_PATTERN,
|
|
||||||
'required': True},
|
|
||||||
IFACE_NAME_ATTR:
|
|
||||||
{'type:string': None,
|
|
||||||
'required': False}}
|
|
||||||
err_msg = attributes._validate_dict(
|
|
||||||
device, key_specs=key_specs)
|
|
||||||
if err_msg:
|
|
||||||
return err_msg
|
|
||||||
unexpected_keys = [key for key in device if key not in key_specs]
|
|
||||||
if unexpected_keys:
|
|
||||||
err_msg = (_("Unexpected keys found in device description:%s")
|
|
||||||
% ",".join(unexpected_keys))
|
|
||||||
return err_msg
|
|
||||||
except TypeError:
|
|
||||||
return (_("%s: provided data are not iterable") %
|
|
||||||
_validate_device_list.__name__)
|
|
||||||
|
|
||||||
nw_gw_quota_opts = [
|
|
||||||
cfg.IntOpt('quota_network_gateway',
|
|
||||||
default=5,
|
|
||||||
help=_('Number of network gateways allowed per tenant, '
|
|
||||||
'-1 for unlimited'))
|
|
||||||
]
|
|
||||||
|
|
||||||
cfg.CONF.register_opts(nw_gw_quota_opts, 'QUOTAS')
|
|
||||||
|
|
||||||
attributes.validators['type:device_list'] = _validate_device_list
|
|
||||||
|
|
||||||
|
|
||||||
class Nvp_networkgw(object):
|
|
||||||
"""API extension for Layer-2 Gateway support.
|
|
||||||
|
|
||||||
The Layer-2 gateway feature allows for connecting neutron networks
|
|
||||||
with external networks at the layer-2 level. No assumption is made on
|
|
||||||
the location of the external network, which might not even be directly
|
|
||||||
reachable from the hosts where the VMs are deployed.
|
|
||||||
|
|
||||||
This is achieved by instantiating 'network gateways', and then connecting
|
|
||||||
Neutron network to them.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_name(cls):
|
def get_name(cls):
|
||||||
@ -116,75 +30,13 @@ class Nvp_networkgw(object):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_alias(cls):
|
def get_alias(cls):
|
||||||
return EXT_ALIAS
|
return "network-gateway"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_description(cls):
|
def get_description(cls):
|
||||||
return "Connects Neutron networks with external networks at layer 2"
|
return ("Connects Neutron networks with external "
|
||||||
|
"networks at layer 2 (deprecated).")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_namespace(cls):
|
def get_namespace(cls):
|
||||||
return "http://docs.openstack.org/ext/neutron/network-gateway/api/v1.0"
|
return "http://docs.openstack.org/ext/neutron/network-gateway/api/v1.0"
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_updated(cls):
|
|
||||||
return "2012-11-30T10:00:00-00:00"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_resources(cls):
|
|
||||||
"""Returns Ext Resources."""
|
|
||||||
plugin = manager.NeutronManager.get_plugin()
|
|
||||||
params = RESOURCE_ATTRIBUTE_MAP.get(COLLECTION_NAME, dict())
|
|
||||||
|
|
||||||
member_actions = {'connect_network': 'PUT',
|
|
||||||
'disconnect_network': 'PUT'}
|
|
||||||
|
|
||||||
# register quotas for network gateways
|
|
||||||
quota.QUOTAS.register_resource_by_name(RESOURCE_NAME)
|
|
||||||
collection_name = COLLECTION_NAME.replace('_', '-')
|
|
||||||
controller = base.create_resource(collection_name,
|
|
||||||
RESOURCE_NAME,
|
|
||||||
plugin, params,
|
|
||||||
member_actions=member_actions)
|
|
||||||
return [extensions.ResourceExtension(COLLECTION_NAME,
|
|
||||||
controller,
|
|
||||||
member_actions=member_actions)]
|
|
||||||
|
|
||||||
def get_extended_resources(self, version):
|
|
||||||
if version == "2.0":
|
|
||||||
return RESOURCE_ATTRIBUTE_MAP
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
class NetworkGatewayPluginBase(object):
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def create_network_gateway(self, context, network_gateway):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_network_gateway(self, context, id, network_gateway):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_network_gateway(self, context, id, fields=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_network_gateway(self, context, id):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_network_gateways(self, context, filters=None, fields=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def connect_network(self, context, network_gateway_id,
|
|
||||||
network_mapping_info):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def disconnect_network(self, context, network_gateway_id,
|
|
||||||
network_mapping_info):
|
|
||||||
pass
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
# Copyright 2013 Nicira, Inc.
|
# Copyright 2013 VMware, Inc.
|
||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
@ -15,150 +15,14 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
# @author: Aaron Rosen, Nicira Networks, Inc.
|
# TODO(armando-migliaccio): This is deprecated in Icehouse, and
|
||||||
|
# to be removed in Juno.
|
||||||
|
|
||||||
|
from neutron.plugins.nicira.extensions import qos
|
||||||
|
|
||||||
|
|
||||||
from abc import abstractmethod
|
class Nvp_qos(qos.Qos):
|
||||||
|
"""(Deprecated) Port Queue extension."""
|
||||||
from neutron.api import extensions
|
|
||||||
from neutron.api.v2 import attributes as attr
|
|
||||||
from neutron.api.v2 import base
|
|
||||||
from neutron.common import exceptions as qexception
|
|
||||||
from neutron import manager
|
|
||||||
|
|
||||||
|
|
||||||
# For policy.json/Auth
|
|
||||||
qos_queue_create = "create_qos_queue"
|
|
||||||
qos_queue_delete = "delete_qos_queue"
|
|
||||||
qos_queue_get = "get_qos_queue"
|
|
||||||
qos_queue_list = "get_qos_queues"
|
|
||||||
|
|
||||||
|
|
||||||
class DefaultQueueCreateNotAdmin(qexception.InUse):
|
|
||||||
message = _("Need to be admin in order to create queue called default")
|
|
||||||
|
|
||||||
|
|
||||||
class DefaultQueueAlreadyExists(qexception.InUse):
|
|
||||||
message = _("Default queue already exists.")
|
|
||||||
|
|
||||||
|
|
||||||
class QueueInvalidDscp(qexception.InvalidInput):
|
|
||||||
message = _("Invalid value for dscp %(data)s must be integer value"
|
|
||||||
" between 0 and 63.")
|
|
||||||
|
|
||||||
|
|
||||||
class QueueMinGreaterMax(qexception.InvalidInput):
|
|
||||||
message = _("Invalid bandwidth rate, min greater than max.")
|
|
||||||
|
|
||||||
|
|
||||||
class QueueInvalidBandwidth(qexception.InvalidInput):
|
|
||||||
message = _("Invalid bandwidth rate, %(data)s must be a non negative"
|
|
||||||
" integer.")
|
|
||||||
|
|
||||||
|
|
||||||
class QueueNotFound(qexception.NotFound):
|
|
||||||
message = _("Queue %(id)s does not exist")
|
|
||||||
|
|
||||||
|
|
||||||
class QueueInUseByPort(qexception.InUse):
|
|
||||||
message = _("Unable to delete queue attached to port.")
|
|
||||||
|
|
||||||
|
|
||||||
class QueuePortBindingNotFound(qexception.NotFound):
|
|
||||||
message = _("Port is not associated with lqueue")
|
|
||||||
|
|
||||||
|
|
||||||
def convert_to_unsigned_int_or_none(val):
|
|
||||||
if val is None:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
val = int(val)
|
|
||||||
if val < 0:
|
|
||||||
raise ValueError
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
msg = _("'%s' must be a non negative integer.") % val
|
|
||||||
raise qexception.InvalidInput(error_message=msg)
|
|
||||||
return val
|
|
||||||
|
|
||||||
|
|
||||||
def convert_to_unsigned_int_or_none_max_63(val):
|
|
||||||
val = convert_to_unsigned_int_or_none(val)
|
|
||||||
if val > 63:
|
|
||||||
raise QueueInvalidDscp(data=val)
|
|
||||||
return val
|
|
||||||
|
|
||||||
# As per NVP API, if a queue is trusted, DSCP must be omitted; if a queue is
|
|
||||||
# untrusted, DSCP must be specified. Whichever default values we choose for
|
|
||||||
# the tuple (qos_marking, dscp), there will be at least one combination of a
|
|
||||||
# request with conflicting values: for instance, with the following default:
|
|
||||||
#
|
|
||||||
# qos_marking = 'untrusted', dscp = '0'
|
|
||||||
#
|
|
||||||
# requests with qos_marking = 'trusted' and a default dscp will fail. Since
|
|
||||||
# it is convoluted to ask the admin to specify a None value for dscp when
|
|
||||||
# qos_marking is 'trusted', it is best to ignore the dscp value, regardless
|
|
||||||
# of whether it has been specified or not. This preserves the chosen default
|
|
||||||
# and keeps backward compatibility with the API. A warning will be logged, as
|
|
||||||
# the server is overriding a potentially conflicting request from the admin
|
|
||||||
RESOURCE_ATTRIBUTE_MAP = {
|
|
||||||
'qos_queues': {
|
|
||||||
'id': {'allow_post': False, 'allow_put': False,
|
|
||||||
'is_visible': True},
|
|
||||||
'default': {'allow_post': True, 'allow_put': False,
|
|
||||||
'convert_to': attr.convert_to_boolean,
|
|
||||||
'is_visible': True, 'default': False},
|
|
||||||
'name': {'allow_post': True, 'allow_put': False,
|
|
||||||
'validate': {'type:string': None},
|
|
||||||
'is_visible': True, 'default': ''},
|
|
||||||
'min': {'allow_post': True, 'allow_put': False,
|
|
||||||
'is_visible': True, 'default': '0',
|
|
||||||
'convert_to': convert_to_unsigned_int_or_none},
|
|
||||||
'max': {'allow_post': True, 'allow_put': False,
|
|
||||||
'is_visible': True, 'default': None,
|
|
||||||
'convert_to': convert_to_unsigned_int_or_none},
|
|
||||||
'qos_marking': {'allow_post': True, 'allow_put': False,
|
|
||||||
'validate': {'type:values': ['untrusted', 'trusted']},
|
|
||||||
'default': 'untrusted', 'is_visible': True},
|
|
||||||
'dscp': {'allow_post': True, 'allow_put': False,
|
|
||||||
'is_visible': True, 'default': '0',
|
|
||||||
'convert_to': convert_to_unsigned_int_or_none_max_63},
|
|
||||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
|
||||||
'required_by_policy': True,
|
|
||||||
'validate': {'type:string': None},
|
|
||||||
'is_visible': True},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QUEUE = 'queue_id'
|
|
||||||
RXTX_FACTOR = 'rxtx_factor'
|
|
||||||
EXTENDED_ATTRIBUTES_2_0 = {
|
|
||||||
'ports': {
|
|
||||||
RXTX_FACTOR: {'allow_post': True,
|
|
||||||
# FIXME(arosen): the nvp plugin currently does not
|
|
||||||
# implement updating rxtx factor on port.
|
|
||||||
'allow_put': True,
|
|
||||||
'is_visible': False,
|
|
||||||
'default': 1,
|
|
||||||
'enforce_policy': True,
|
|
||||||
'convert_to': convert_to_unsigned_int_or_none},
|
|
||||||
|
|
||||||
QUEUE: {'allow_post': False,
|
|
||||||
'allow_put': False,
|
|
||||||
'is_visible': True,
|
|
||||||
'default': False,
|
|
||||||
'enforce_policy': True}},
|
|
||||||
'networks': {QUEUE: {'allow_post': True,
|
|
||||||
'allow_put': True,
|
|
||||||
'is_visible': True,
|
|
||||||
'default': False,
|
|
||||||
'enforce_policy': True}}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Nvp_qos(object):
|
|
||||||
"""Port Queue extension."""
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_name(cls):
|
def get_name(cls):
|
||||||
@ -170,55 +34,8 @@ class Nvp_qos(object):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_description(cls):
|
def get_description(cls):
|
||||||
return "NVP QoS extension."
|
return "NVP QoS extension (deprecated)."
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_namespace(cls):
|
def get_namespace(cls):
|
||||||
return "http://docs.openstack.org/ext/nvp-qos/api/v2.0"
|
return "http://docs.openstack.org/ext/nvp-qos/api/v2.0"
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_updated(cls):
|
|
||||||
return "2012-10-05T10:00:00-00:00"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_resources(cls):
|
|
||||||
"""Returns Ext Resources."""
|
|
||||||
exts = []
|
|
||||||
plugin = manager.NeutronManager.get_plugin()
|
|
||||||
resource_name = 'qos_queue'
|
|
||||||
collection_name = resource_name.replace('_', '-') + "s"
|
|
||||||
params = RESOURCE_ATTRIBUTE_MAP.get(resource_name + "s", dict())
|
|
||||||
controller = base.create_resource(collection_name,
|
|
||||||
resource_name,
|
|
||||||
plugin, params, allow_bulk=False)
|
|
||||||
|
|
||||||
ex = extensions.ResourceExtension(collection_name,
|
|
||||||
controller)
|
|
||||||
exts.append(ex)
|
|
||||||
|
|
||||||
return exts
|
|
||||||
|
|
||||||
def get_extended_resources(self, version):
|
|
||||||
if version == "2.0":
|
|
||||||
return dict(EXTENDED_ATTRIBUTES_2_0.items() +
|
|
||||||
RESOURCE_ATTRIBUTE_MAP.items())
|
|
||||||
else:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
class QueuePluginBase(object):
|
|
||||||
@abstractmethod
|
|
||||||
def create_qos_queue(self, context, queue):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_qos_queue(self, context, id):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_qos_queue(self, context, id, fields=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_qos_queues(self, context, filters=None, fields=None):
|
|
||||||
pass
|
|
||||||
|
222
neutron/plugins/nicira/extensions/qos.py
Normal file
222
neutron/plugins/nicira/extensions/qos.py
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013 VMware, Inc.
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from neutron.api import extensions
|
||||||
|
from neutron.api.v2 import attributes as attr
|
||||||
|
from neutron.api.v2 import base
|
||||||
|
from neutron.common import exceptions as qexception
|
||||||
|
from neutron import manager
|
||||||
|
|
||||||
|
|
||||||
|
# For policy.json/Auth
|
||||||
|
qos_queue_create = "create_qos_queue"
|
||||||
|
qos_queue_delete = "delete_qos_queue"
|
||||||
|
qos_queue_get = "get_qos_queue"
|
||||||
|
qos_queue_list = "get_qos_queues"
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultQueueCreateNotAdmin(qexception.InUse):
|
||||||
|
message = _("Need to be admin in order to create queue called default")
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultQueueAlreadyExists(qexception.InUse):
|
||||||
|
message = _("Default queue already exists.")
|
||||||
|
|
||||||
|
|
||||||
|
class QueueInvalidDscp(qexception.InvalidInput):
|
||||||
|
message = _("Invalid value for dscp %(data)s must be integer value"
|
||||||
|
" between 0 and 63.")
|
||||||
|
|
||||||
|
|
||||||
|
class QueueMinGreaterMax(qexception.InvalidInput):
|
||||||
|
message = _("Invalid bandwidth rate, min greater than max.")
|
||||||
|
|
||||||
|
|
||||||
|
class QueueInvalidBandwidth(qexception.InvalidInput):
|
||||||
|
message = _("Invalid bandwidth rate, %(data)s must be a non negative"
|
||||||
|
" integer.")
|
||||||
|
|
||||||
|
|
||||||
|
class QueueNotFound(qexception.NotFound):
|
||||||
|
message = _("Queue %(id)s does not exist")
|
||||||
|
|
||||||
|
|
||||||
|
class QueueInUseByPort(qexception.InUse):
|
||||||
|
message = _("Unable to delete queue attached to port.")
|
||||||
|
|
||||||
|
|
||||||
|
class QueuePortBindingNotFound(qexception.NotFound):
|
||||||
|
message = _("Port is not associated with lqueue")
|
||||||
|
|
||||||
|
|
||||||
|
def convert_to_unsigned_int_or_none(val):
|
||||||
|
if val is None:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
val = int(val)
|
||||||
|
if val < 0:
|
||||||
|
raise ValueError
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
msg = _("'%s' must be a non negative integer.") % val
|
||||||
|
raise qexception.InvalidInput(error_message=msg)
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
def convert_to_unsigned_int_or_none_max_63(val):
|
||||||
|
val = convert_to_unsigned_int_or_none(val)
|
||||||
|
if val > 63:
|
||||||
|
raise QueueInvalidDscp(data=val)
|
||||||
|
return val
|
||||||
|
|
||||||
|
# As per NSX API, if a queue is trusted, DSCP must be omitted; if a queue is
|
||||||
|
# untrusted, DSCP must be specified. Whichever default values we choose for
|
||||||
|
# the tuple (qos_marking, dscp), there will be at least one combination of a
|
||||||
|
# request with conflicting values: for instance, with the following default:
|
||||||
|
#
|
||||||
|
# qos_marking = 'untrusted', dscp = '0'
|
||||||
|
#
|
||||||
|
# requests with qos_marking = 'trusted' and a default dscp will fail. Since
|
||||||
|
# it is convoluted to ask the admin to specify a None value for dscp when
|
||||||
|
# qos_marking is 'trusted', it is best to ignore the dscp value, regardless
|
||||||
|
# of whether it has been specified or not. This preserves the chosen default
|
||||||
|
# and keeps backward compatibility with the API. A warning will be logged, as
|
||||||
|
# the server is overriding a potentially conflicting request from the admin
|
||||||
|
RESOURCE_ATTRIBUTE_MAP = {
|
||||||
|
'qos_queues': {
|
||||||
|
'id': {'allow_post': False, 'allow_put': False,
|
||||||
|
'is_visible': True},
|
||||||
|
'default': {'allow_post': True, 'allow_put': False,
|
||||||
|
'convert_to': attr.convert_to_boolean,
|
||||||
|
'is_visible': True, 'default': False},
|
||||||
|
'name': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:string': None},
|
||||||
|
'is_visible': True, 'default': ''},
|
||||||
|
'min': {'allow_post': True, 'allow_put': False,
|
||||||
|
'is_visible': True, 'default': '0',
|
||||||
|
'convert_to': convert_to_unsigned_int_or_none},
|
||||||
|
'max': {'allow_post': True, 'allow_put': False,
|
||||||
|
'is_visible': True, 'default': None,
|
||||||
|
'convert_to': convert_to_unsigned_int_or_none},
|
||||||
|
'qos_marking': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:values': ['untrusted', 'trusted']},
|
||||||
|
'default': 'untrusted', 'is_visible': True},
|
||||||
|
'dscp': {'allow_post': True, 'allow_put': False,
|
||||||
|
'is_visible': True, 'default': '0',
|
||||||
|
'convert_to': convert_to_unsigned_int_or_none_max_63},
|
||||||
|
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||||
|
'required_by_policy': True,
|
||||||
|
'validate': {'type:string': None},
|
||||||
|
'is_visible': True},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QUEUE = 'queue_id'
|
||||||
|
RXTX_FACTOR = 'rxtx_factor'
|
||||||
|
EXTENDED_ATTRIBUTES_2_0 = {
|
||||||
|
'ports': {
|
||||||
|
RXTX_FACTOR: {'allow_post': True,
|
||||||
|
# FIXME(arosen): the plugin currently does not
|
||||||
|
# implement updating rxtx factor on port.
|
||||||
|
'allow_put': True,
|
||||||
|
'is_visible': False,
|
||||||
|
'default': 1,
|
||||||
|
'enforce_policy': True,
|
||||||
|
'convert_to': convert_to_unsigned_int_or_none},
|
||||||
|
|
||||||
|
QUEUE: {'allow_post': False,
|
||||||
|
'allow_put': False,
|
||||||
|
'is_visible': True,
|
||||||
|
'default': False,
|
||||||
|
'enforce_policy': True}},
|
||||||
|
'networks': {QUEUE: {'allow_post': True,
|
||||||
|
'allow_put': True,
|
||||||
|
'is_visible': True,
|
||||||
|
'default': False,
|
||||||
|
'enforce_policy': True}}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Qos(object):
|
||||||
|
"""Port Queue extension."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_name(cls):
|
||||||
|
return "QoS Queue"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_alias(cls):
|
||||||
|
return "qos-queue"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_description(cls):
|
||||||
|
return "NSX QoS extension."
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_namespace(cls):
|
||||||
|
return "http://docs.openstack.org/ext/qos-queue/api/v2.0"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_updated(cls):
|
||||||
|
return "2014-01-01T00:00:00-00:00"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_resources(cls):
|
||||||
|
"""Returns Ext Resources."""
|
||||||
|
exts = []
|
||||||
|
plugin = manager.NeutronManager.get_plugin()
|
||||||
|
resource_name = 'qos_queue'
|
||||||
|
collection_name = resource_name.replace('_', '-') + "s"
|
||||||
|
params = RESOURCE_ATTRIBUTE_MAP.get(resource_name + "s", dict())
|
||||||
|
controller = base.create_resource(collection_name,
|
||||||
|
resource_name,
|
||||||
|
plugin, params, allow_bulk=False)
|
||||||
|
|
||||||
|
ex = extensions.ResourceExtension(collection_name,
|
||||||
|
controller)
|
||||||
|
exts.append(ex)
|
||||||
|
|
||||||
|
return exts
|
||||||
|
|
||||||
|
def get_extended_resources(self, version):
|
||||||
|
if version == "2.0":
|
||||||
|
return dict(EXTENDED_ATTRIBUTES_2_0.items() +
|
||||||
|
RESOURCE_ATTRIBUTE_MAP.items())
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
class QueuePluginBase(object):
|
||||||
|
@abstractmethod
|
||||||
|
def create_qos_queue(self, context, queue):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def delete_qos_queue(self, context, id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_qos_queue(self, context, id, fields=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_qos_queues(self, context, filters=None, fields=None):
|
||||||
|
pass
|
@ -14,8 +14,6 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
# @author: Kaiwei Fan, VMware, Inc
|
|
||||||
|
|
||||||
|
|
||||||
from neutron.api import extensions
|
from neutron.api import extensions
|
||||||
from neutron.api.v2 import attributes
|
from neutron.api.v2 import attributes
|
||||||
@ -44,11 +42,11 @@ class Servicerouter(extensions.ExtensionDescriptor):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_description(cls):
|
def get_description(cls):
|
||||||
return "Provides service router"
|
return "Provides service router."
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_namespace(cls):
|
def get_namespace(cls):
|
||||||
return ""
|
return "http://docs.openstack.org/ext/service-router/api/v1.0"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_updated(cls):
|
def get_updated(cls):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
# Copyright 2012 Nicira Networks, Inc. All rights reserved.
|
# Copyright 2012 VMware, Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
# not use this file except in compliance with the License. You may obtain
|
# not use this file except in compliance with the License. You may obtain
|
||||||
@ -29,8 +29,8 @@ from neutron import context
|
|||||||
from neutron.db import api as db_api
|
from neutron.db import api as db_api
|
||||||
from neutron.db import db_base_plugin_v2
|
from neutron.db import db_base_plugin_v2
|
||||||
from neutron import manager
|
from neutron import manager
|
||||||
from neutron.plugins.nicira.dbexts import nicira_networkgw_db
|
from neutron.plugins.nicira.dbexts import networkgw_db
|
||||||
from neutron.plugins.nicira.extensions import nvp_networkgw as networkgw
|
from neutron.plugins.nicira.extensions import networkgw
|
||||||
from neutron.plugins.nicira.NeutronPlugin import NVP_EXT_PATH
|
from neutron.plugins.nicira.NeutronPlugin import NVP_EXT_PATH
|
||||||
from neutron import quota
|
from neutron import quota
|
||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
@ -52,7 +52,7 @@ class TestExtensionManager(object):
|
|||||||
# the global attribute map
|
# the global attribute map
|
||||||
attributes.RESOURCE_ATTRIBUTE_MAP.update(
|
attributes.RESOURCE_ATTRIBUTE_MAP.update(
|
||||||
networkgw.RESOURCE_ATTRIBUTE_MAP)
|
networkgw.RESOURCE_ATTRIBUTE_MAP)
|
||||||
return networkgw.Nvp_networkgw.get_resources()
|
return networkgw.Networkgw.get_resources()
|
||||||
|
|
||||||
def get_actions(self):
|
def get_actions(self):
|
||||||
return []
|
return []
|
||||||
@ -357,8 +357,8 @@ class NetworkGatewayDbTestCase(test_db_plugin.NeutronDbPluginV2TestCase):
|
|||||||
pass
|
pass
|
||||||
# Verify nothing left on db
|
# Verify nothing left on db
|
||||||
session = db_api.get_session()
|
session = db_api.get_session()
|
||||||
gw_query = session.query(nicira_networkgw_db.NetworkGateway)
|
gw_query = session.query(networkgw_db.NetworkGateway)
|
||||||
dev_query = session.query(nicira_networkgw_db.NetworkGatewayDevice)
|
dev_query = session.query(networkgw_db.NetworkGatewayDevice)
|
||||||
self.assertEqual(exp_gw_count, gw_query.count())
|
self.assertEqual(exp_gw_count, gw_query.count())
|
||||||
self.assertEqual(0, dev_query.count())
|
self.assertEqual(0, dev_query.count())
|
||||||
|
|
||||||
@ -595,7 +595,7 @@ class NetworkGatewayDbTestCase(test_db_plugin.NeutronDbPluginV2TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestNetworkGatewayPlugin(db_base_plugin_v2.NeutronDbPluginV2,
|
class TestNetworkGatewayPlugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||||
nicira_networkgw_db.NetworkGatewayMixin):
|
networkgw_db.NetworkGatewayMixin):
|
||||||
"""Simple plugin class for testing db support for network gateway ext."""
|
"""Simple plugin class for testing db support for network gateway ext."""
|
||||||
|
|
||||||
supported_extension_aliases = ["network-gateway"]
|
supported_extension_aliases = ["network-gateway"]
|
||||||
|
@ -44,8 +44,8 @@ from neutron.plugins.nicira.common import sync
|
|||||||
from neutron.plugins.nicira.dbexts import nicira_db
|
from neutron.plugins.nicira.dbexts import nicira_db
|
||||||
from neutron.plugins.nicira.dbexts import qos_db
|
from neutron.plugins.nicira.dbexts import qos_db
|
||||||
from neutron.plugins.nicira.extensions import distributedrouter as dist_router
|
from neutron.plugins.nicira.extensions import distributedrouter as dist_router
|
||||||
from neutron.plugins.nicira.extensions import nvp_networkgw
|
from neutron.plugins.nicira.extensions import networkgw
|
||||||
from neutron.plugins.nicira.extensions import nvp_qos as ext_qos
|
from neutron.plugins.nicira.extensions import qos
|
||||||
from neutron.plugins.nicira import NeutronPlugin
|
from neutron.plugins.nicira import NeutronPlugin
|
||||||
from neutron.plugins.nicira import nsxlib
|
from neutron.plugins.nicira import nsxlib
|
||||||
from neutron.plugins.nicira import NvpApiClient
|
from neutron.plugins.nicira import NvpApiClient
|
||||||
@ -1036,7 +1036,7 @@ class TestNiciraL3NatTestCase(NiciraL3NatTest,
|
|||||||
class NvpQoSTestExtensionManager(object):
|
class NvpQoSTestExtensionManager(object):
|
||||||
|
|
||||||
def get_resources(self):
|
def get_resources(self):
|
||||||
return ext_qos.Nvp_qos.get_resources()
|
return qos.Qos.get_resources()
|
||||||
|
|
||||||
def get_actions(self):
|
def get_actions(self):
|
||||||
return []
|
return []
|
||||||
@ -1127,28 +1127,28 @@ class TestQoSQueue(NiciraPluginV2TestCase):
|
|||||||
def test_create_port_with_queue(self):
|
def test_create_port_with_queue(self):
|
||||||
with self.qos_queue(default=True) as q1:
|
with self.qos_queue(default=True) as q1:
|
||||||
res = self._create_network('json', 'net1', True,
|
res = self._create_network('json', 'net1', True,
|
||||||
arg_list=(ext_qos.QUEUE,),
|
arg_list=(qos.QUEUE,),
|
||||||
queue_id=q1['qos_queue']['id'])
|
queue_id=q1['qos_queue']['id'])
|
||||||
net1 = self.deserialize('json', res)
|
net1 = self.deserialize('json', res)
|
||||||
self.assertEqual(net1['network'][ext_qos.QUEUE],
|
self.assertEqual(net1['network'][qos.QUEUE],
|
||||||
q1['qos_queue']['id'])
|
q1['qos_queue']['id'])
|
||||||
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
|
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
|
||||||
with self.port(device_id=device_id, do_delete=False) as p:
|
with self.port(device_id=device_id, do_delete=False) as p:
|
||||||
self.assertEqual(len(p['port'][ext_qos.QUEUE]), 36)
|
self.assertEqual(len(p['port'][qos.QUEUE]), 36)
|
||||||
|
|
||||||
def test_create_shared_queue_networks(self):
|
def test_create_shared_queue_networks(self):
|
||||||
with self.qos_queue(default=True, no_delete=True) as q1:
|
with self.qos_queue(default=True, no_delete=True) as q1:
|
||||||
res = self._create_network('json', 'net1', True,
|
res = self._create_network('json', 'net1', True,
|
||||||
arg_list=(ext_qos.QUEUE,),
|
arg_list=(qos.QUEUE,),
|
||||||
queue_id=q1['qos_queue']['id'])
|
queue_id=q1['qos_queue']['id'])
|
||||||
net1 = self.deserialize('json', res)
|
net1 = self.deserialize('json', res)
|
||||||
self.assertEqual(net1['network'][ext_qos.QUEUE],
|
self.assertEqual(net1['network'][qos.QUEUE],
|
||||||
q1['qos_queue']['id'])
|
q1['qos_queue']['id'])
|
||||||
res = self._create_network('json', 'net2', True,
|
res = self._create_network('json', 'net2', True,
|
||||||
arg_list=(ext_qos.QUEUE,),
|
arg_list=(qos.QUEUE,),
|
||||||
queue_id=q1['qos_queue']['id'])
|
queue_id=q1['qos_queue']['id'])
|
||||||
net2 = self.deserialize('json', res)
|
net2 = self.deserialize('json', res)
|
||||||
self.assertEqual(net1['network'][ext_qos.QUEUE],
|
self.assertEqual(net1['network'][qos.QUEUE],
|
||||||
q1['qos_queue']['id'])
|
q1['qos_queue']['id'])
|
||||||
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
|
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
|
||||||
res = self._create_port('json', net1['network']['id'],
|
res = self._create_port('json', net1['network']['id'],
|
||||||
@ -1157,8 +1157,8 @@ class TestQoSQueue(NiciraPluginV2TestCase):
|
|||||||
res = self._create_port('json', net2['network']['id'],
|
res = self._create_port('json', net2['network']['id'],
|
||||||
device_id=device_id)
|
device_id=device_id)
|
||||||
port2 = self.deserialize('json', res)
|
port2 = self.deserialize('json', res)
|
||||||
self.assertEqual(port1['port'][ext_qos.QUEUE],
|
self.assertEqual(port1['port'][qos.QUEUE],
|
||||||
port2['port'][ext_qos.QUEUE])
|
port2['port'][qos.QUEUE])
|
||||||
|
|
||||||
self._delete('ports', port1['port']['id'])
|
self._delete('ports', port1['port']['id'])
|
||||||
self._delete('ports', port2['port']['id'])
|
self._delete('ports', port2['port']['id'])
|
||||||
@ -1166,40 +1166,40 @@ class TestQoSQueue(NiciraPluginV2TestCase):
|
|||||||
def test_remove_queue_in_use_fail(self):
|
def test_remove_queue_in_use_fail(self):
|
||||||
with self.qos_queue(no_delete=True) as q1:
|
with self.qos_queue(no_delete=True) as q1:
|
||||||
res = self._create_network('json', 'net1', True,
|
res = self._create_network('json', 'net1', True,
|
||||||
arg_list=(ext_qos.QUEUE,),
|
arg_list=(qos.QUEUE,),
|
||||||
queue_id=q1['qos_queue']['id'])
|
queue_id=q1['qos_queue']['id'])
|
||||||
net1 = self.deserialize('json', res)
|
net1 = self.deserialize('json', res)
|
||||||
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
|
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
|
||||||
res = self._create_port('json', net1['network']['id'],
|
res = self._create_port('json', net1['network']['id'],
|
||||||
device_id=device_id)
|
device_id=device_id)
|
||||||
port = self.deserialize('json', res)
|
port = self.deserialize('json', res)
|
||||||
self._delete('qos-queues', port['port'][ext_qos.QUEUE], 409)
|
self._delete('qos-queues', port['port'][qos.QUEUE], 409)
|
||||||
|
|
||||||
def test_update_network_new_queue(self):
|
def test_update_network_new_queue(self):
|
||||||
with self.qos_queue() as q1:
|
with self.qos_queue() as q1:
|
||||||
res = self._create_network('json', 'net1', True,
|
res = self._create_network('json', 'net1', True,
|
||||||
arg_list=(ext_qos.QUEUE,),
|
arg_list=(qos.QUEUE,),
|
||||||
queue_id=q1['qos_queue']['id'])
|
queue_id=q1['qos_queue']['id'])
|
||||||
net1 = self.deserialize('json', res)
|
net1 = self.deserialize('json', res)
|
||||||
with self.qos_queue() as new_q:
|
with self.qos_queue() as new_q:
|
||||||
data = {'network': {ext_qos.QUEUE: new_q['qos_queue']['id']}}
|
data = {'network': {qos.QUEUE: new_q['qos_queue']['id']}}
|
||||||
req = self.new_update_request('networks', data,
|
req = self.new_update_request('networks', data,
|
||||||
net1['network']['id'])
|
net1['network']['id'])
|
||||||
res = req.get_response(self.api)
|
res = req.get_response(self.api)
|
||||||
net1 = self.deserialize('json', res)
|
net1 = self.deserialize('json', res)
|
||||||
self.assertEqual(net1['network'][ext_qos.QUEUE],
|
self.assertEqual(net1['network'][qos.QUEUE],
|
||||||
new_q['qos_queue']['id'])
|
new_q['qos_queue']['id'])
|
||||||
|
|
||||||
def test_update_port_adding_device_id(self):
|
def test_update_port_adding_device_id(self):
|
||||||
with self.qos_queue(no_delete=True) as q1:
|
with self.qos_queue(no_delete=True) as q1:
|
||||||
res = self._create_network('json', 'net1', True,
|
res = self._create_network('json', 'net1', True,
|
||||||
arg_list=(ext_qos.QUEUE,),
|
arg_list=(qos.QUEUE,),
|
||||||
queue_id=q1['qos_queue']['id'])
|
queue_id=q1['qos_queue']['id'])
|
||||||
net1 = self.deserialize('json', res)
|
net1 = self.deserialize('json', res)
|
||||||
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
|
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
|
||||||
res = self._create_port('json', net1['network']['id'])
|
res = self._create_port('json', net1['network']['id'])
|
||||||
port = self.deserialize('json', res)
|
port = self.deserialize('json', res)
|
||||||
self.assertIsNone(port['port'][ext_qos.QUEUE])
|
self.assertIsNone(port['port'][qos.QUEUE])
|
||||||
|
|
||||||
data = {'port': {'device_id': device_id}}
|
data = {'port': {'device_id': device_id}}
|
||||||
req = self.new_update_request('ports', data,
|
req = self.new_update_request('ports', data,
|
||||||
@ -1207,7 +1207,7 @@ class TestQoSQueue(NiciraPluginV2TestCase):
|
|||||||
|
|
||||||
res = req.get_response(self.api)
|
res = req.get_response(self.api)
|
||||||
port = self.deserialize('json', res)
|
port = self.deserialize('json', res)
|
||||||
self.assertEqual(len(port['port'][ext_qos.QUEUE]), 36)
|
self.assertEqual(len(port['port'][qos.QUEUE]), 36)
|
||||||
|
|
||||||
def test_get_port_with_qos_not_admin(self):
|
def test_get_port_with_qos_not_admin(self):
|
||||||
body = {'qos_queue': {'tenant_id': 'not_admin',
|
body = {'qos_queue': {'tenant_id': 'not_admin',
|
||||||
@ -1215,16 +1215,16 @@ class TestQoSQueue(NiciraPluginV2TestCase):
|
|||||||
res = self._create_qos_queue('json', body, tenant_id='not_admin')
|
res = self._create_qos_queue('json', body, tenant_id='not_admin')
|
||||||
q1 = self.deserialize('json', res)
|
q1 = self.deserialize('json', res)
|
||||||
res = self._create_network('json', 'net1', True,
|
res = self._create_network('json', 'net1', True,
|
||||||
arg_list=(ext_qos.QUEUE, 'tenant_id',),
|
arg_list=(qos.QUEUE, 'tenant_id',),
|
||||||
queue_id=q1['qos_queue']['id'],
|
queue_id=q1['qos_queue']['id'],
|
||||||
tenant_id="not_admin")
|
tenant_id="not_admin")
|
||||||
net1 = self.deserialize('json', res)
|
net1 = self.deserialize('json', res)
|
||||||
self.assertEqual(len(net1['network'][ext_qos.QUEUE]), 36)
|
self.assertEqual(len(net1['network'][qos.QUEUE]), 36)
|
||||||
res = self._create_port('json', net1['network']['id'],
|
res = self._create_port('json', net1['network']['id'],
|
||||||
tenant_id='not_admin', set_context=True)
|
tenant_id='not_admin', set_context=True)
|
||||||
|
|
||||||
port = self.deserialize('json', res)
|
port = self.deserialize('json', res)
|
||||||
self.assertNotIn(ext_qos.QUEUE, port['port'])
|
self.assertNotIn(qos.QUEUE, port['port'])
|
||||||
|
|
||||||
def test_dscp_value_out_of_range(self):
|
def test_dscp_value_out_of_range(self):
|
||||||
body = {'qos_queue': {'tenant_id': 'admin', 'dscp': '64',
|
body = {'qos_queue': {'tenant_id': 'admin', 'dscp': '64',
|
||||||
@ -1245,7 +1245,7 @@ class TestQoSQueue(NiciraPluginV2TestCase):
|
|||||||
res = self._create_qos_queue('json', body, tenant_id='not_admin')
|
res = self._create_qos_queue('json', body, tenant_id='not_admin')
|
||||||
q1 = self.deserialize('json', res)
|
q1 = self.deserialize('json', res)
|
||||||
res = self._create_network('json', 'net1', True,
|
res = self._create_network('json', 'net1', True,
|
||||||
arg_list=(ext_qos.QUEUE,),
|
arg_list=(qos.QUEUE,),
|
||||||
tenant_id='not_admin',
|
tenant_id='not_admin',
|
||||||
queue_id=q1['qos_queue']['id'])
|
queue_id=q1['qos_queue']['id'])
|
||||||
|
|
||||||
@ -1258,21 +1258,21 @@ class TestQoSQueue(NiciraPluginV2TestCase):
|
|||||||
neutron_context = context.Context('', 'not_admin')
|
neutron_context = context.Context('', 'not_admin')
|
||||||
port = self._update('ports', port['port']['id'], data,
|
port = self._update('ports', port['port']['id'], data,
|
||||||
neutron_context=neutron_context)
|
neutron_context=neutron_context)
|
||||||
self.assertNotIn(ext_qos.QUEUE, port['port'])
|
self.assertNotIn(qos.QUEUE, port['port'])
|
||||||
|
|
||||||
def test_rxtx_factor(self):
|
def test_rxtx_factor(self):
|
||||||
with self.qos_queue(max=10) as q1:
|
with self.qos_queue(max=10) as q1:
|
||||||
|
|
||||||
res = self._create_network('json', 'net1', True,
|
res = self._create_network('json', 'net1', True,
|
||||||
arg_list=(ext_qos.QUEUE,),
|
arg_list=(qos.QUEUE,),
|
||||||
queue_id=q1['qos_queue']['id'])
|
queue_id=q1['qos_queue']['id'])
|
||||||
net1 = self.deserialize('json', res)
|
net1 = self.deserialize('json', res)
|
||||||
res = self._create_port('json', net1['network']['id'],
|
res = self._create_port('json', net1['network']['id'],
|
||||||
arg_list=(ext_qos.RXTX_FACTOR,),
|
arg_list=(qos.RXTX_FACTOR,),
|
||||||
rxtx_factor=2, device_id='1')
|
rxtx_factor=2, device_id='1')
|
||||||
port = self.deserialize('json', res)
|
port = self.deserialize('json', res)
|
||||||
req = self.new_show_request('qos-queues',
|
req = self.new_show_request('qos-queues',
|
||||||
port['port'][ext_qos.QUEUE])
|
port['port'][qos.QUEUE])
|
||||||
res = req.get_response(self.ext_api)
|
res = req.get_response(self.ext_api)
|
||||||
queue = self.deserialize('json', res)
|
queue = self.deserialize('json', res)
|
||||||
self.assertEqual(queue['qos_queue']['max'], 20)
|
self.assertEqual(queue['qos_queue']['max'], 20)
|
||||||
@ -1475,7 +1475,7 @@ class TestNiciraNetworkGateway(NiciraPluginV2TestCase,
|
|||||||
nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw:
|
nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw:
|
||||||
with self._network_gateway(name='cavani') as nw_gw:
|
with self._network_gateway(name='cavani') as nw_gw:
|
||||||
nw_gw_id = nw_gw[self.resource]['id']
|
nw_gw_id = nw_gw[self.resource]['id']
|
||||||
self._update(nvp_networkgw.COLLECTION_NAME, nw_gw_id,
|
self._update(networkgw.COLLECTION_NAME, nw_gw_id,
|
||||||
{self.resource: {'name': 'higuain'}})
|
{self.resource: {'name': 'higuain'}})
|
||||||
mock_update_gw.assert_called_once_with(
|
mock_update_gw.assert_called_once_with(
|
||||||
mock.ANY, nw_gw_id, 'higuain')
|
mock.ANY, nw_gw_id, 'higuain')
|
||||||
@ -1485,7 +1485,7 @@ class TestNiciraNetworkGateway(NiciraPluginV2TestCase,
|
|||||||
nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw:
|
nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw:
|
||||||
with self._network_gateway(name='something') as nw_gw:
|
with self._network_gateway(name='something') as nw_gw:
|
||||||
nw_gw_id = nw_gw[self.resource]['id']
|
nw_gw_id = nw_gw[self.resource]['id']
|
||||||
self._update(nvp_networkgw.COLLECTION_NAME, nw_gw_id,
|
self._update(networkgw.COLLECTION_NAME, nw_gw_id,
|
||||||
{self.resource: {}})
|
{self.resource: {}})
|
||||||
self.assertEqual(mock_update_gw.call_count, 0)
|
self.assertEqual(mock_update_gw.call_count, 0)
|
||||||
|
|
||||||
@ -1493,9 +1493,9 @@ class TestNiciraNetworkGateway(NiciraPluginV2TestCase,
|
|||||||
new_name = 'this_is_a_gateway_whose_name_is_longer_than_40_chars'
|
new_name = 'this_is_a_gateway_whose_name_is_longer_than_40_chars'
|
||||||
with self._network_gateway(name='something') as nw_gw:
|
with self._network_gateway(name='something') as nw_gw:
|
||||||
nw_gw_id = nw_gw[self.resource]['id']
|
nw_gw_id = nw_gw[self.resource]['id']
|
||||||
self._update(nvp_networkgw.COLLECTION_NAME, nw_gw_id,
|
self._update(networkgw.COLLECTION_NAME, nw_gw_id,
|
||||||
{self.resource: {'name': new_name}})
|
{self.resource: {'name': new_name}})
|
||||||
req = self.new_show_request(nvp_networkgw.COLLECTION_NAME,
|
req = self.new_show_request(networkgw.COLLECTION_NAME,
|
||||||
nw_gw_id)
|
nw_gw_id)
|
||||||
res = self.deserialize('json', req.get_response(self.ext_api))
|
res = self.deserialize('json', req.get_response(self.ext_api))
|
||||||
# Assert Neutron name is not truncated
|
# Assert Neutron name is not truncated
|
||||||
@ -1529,7 +1529,7 @@ class TestNiciraNetworkGateway(NiciraPluginV2TestCase,
|
|||||||
def test_list_network_gateways(self):
|
def test_list_network_gateways(self):
|
||||||
with self._network_gateway(name='test-gw-1') as gw1:
|
with self._network_gateway(name='test-gw-1') as gw1:
|
||||||
with self._network_gateway(name='test_gw_2') as gw2:
|
with self._network_gateway(name='test_gw_2') as gw2:
|
||||||
req = self.new_list_request(nvp_networkgw.COLLECTION_NAME)
|
req = self.new_list_request(networkgw.COLLECTION_NAME)
|
||||||
res = self.deserialize('json', req.get_response(self.ext_api))
|
res = self.deserialize('json', req.get_response(self.ext_api))
|
||||||
# We expect the default gateway too
|
# We expect the default gateway too
|
||||||
key = self.resource + 's'
|
key = self.resource + 's'
|
||||||
@ -1551,7 +1551,7 @@ class TestNiciraNetworkGateway(NiciraPluginV2TestCase,
|
|||||||
|
|
||||||
def test_show_network_gateway_nvp_error_returns_404(self):
|
def test_show_network_gateway_nvp_error_returns_404(self):
|
||||||
invalid_id = 'b5afd4a9-eb71-4af7-a082-8fc625a35b61'
|
invalid_id = 'b5afd4a9-eb71-4af7-a082-8fc625a35b61'
|
||||||
req = self.new_show_request(nvp_networkgw.COLLECTION_NAME, invalid_id)
|
req = self.new_show_request(networkgw.COLLECTION_NAME, invalid_id)
|
||||||
res = req.get_response(self.ext_api)
|
res = req.get_response(self.ext_api)
|
||||||
self.assertEqual(webob.exc.HTTPNotFound.code, res.status_int)
|
self.assertEqual(webob.exc.HTTPNotFound.code, res.status_int)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user