from neutron.plugins.nicira.common import sync
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 networkgw_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 import dhcpmeta_modes
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 nvp_qos as ext_qos
+from neutron.plugins.nicira.extensions import networkgw
+from neutron.plugins.nicira.extensions import qos
from neutron.plugins.nicira.nsxlib import l2gateway as l2gwlib
from neutron.plugins.nicira.nsxlib import queue as queuelib
from neutron.plugins.nicira.nsxlib import router as routerlib
"nvp-qos",
"port-security",
"provider",
+ "qos-queue",
"quotas",
"external-net",
"router",
port_data['fixed_ips'],
port_data[psec.PORTSECURITY],
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(addr_pair.ADDRESS_PAIRS))
# DB Operations for setting the network as external
self._process_l3_create(context, new_net, net_data)
# 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:
# Raises if not found
self.get_qos_queue(context, net_queue_id)
if psec.PORTSECURITY in network['network']:
self._process_network_port_security_update(
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:
self._delete_network_queue_mapping(context, id)
self._process_network_queue_mapping(context, net, net_queue_id)
if nsx_port_id:
try:
switchlib.update_port(
- self.cluster,
- nsx_switch_id, nsx_port_id, id, tenant_id,
+ self.cluster, nsx_switch_id, nsx_port_id,
+ id, tenant_id,
ret_port['name'],
ret_port['device_id'],
ret_port['admin_state_up'],
ret_port['fixed_ips'],
ret_port[psec.PORTSECURITY],
ret_port[ext_sg.SECURITYGROUPS],
- ret_port[ext_qos.QUEUE],
+ ret_port[qos.QUEUE],
ret_port.get(mac_ext.MAC_LEARNING),
ret_port.get(addr_pair.ADDRESS_PAIRS))
queues = self._get_port_queue_bindings(context, filters)
if queues:
if raise_in_use:
- raise ext_qos.QueueInUseByPort()
+ raise qos.QueueInUseByPort()
else:
return
queuelib.delete_lqueue(self.cluster, queue_id)
from neutron.db import models_v2
from neutron.openstack.common import log as logging
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__)
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):
try:
import neutron.db.api as db
from neutron.openstack.common.db import exception as d_exc
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_networkgw_db
LOG = logging.getLogger(__name__)
def unset_default_network_gateways(session):
with session.begin(subtransactions=True):
- session.query(nicira_networkgw_db.NetworkGateway).update(
- {nicira_networkgw_db.NetworkGateway.default: False})
+ session.query(networkgw_db.NetworkGateway).update(
+ {networkgw_db.NetworkGateway.default: False})
def set_default_network_gateway(session, gw_id):
with session.begin(subtransactions=True):
- gw = (session.query(nicira_networkgw_db.NetworkGateway).
+ gw = (session.query(networkgw_db.NetworkGateway).
filter_by(id=gw_id).one())
gw['default'] = True
from neutron.db import models_v2
from neutron.openstack.common import log
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__)
cascade='delete', lazy='joined'))
-class NVPQoSDbMixin(ext_qos.QueuePluginBase):
+class NVPQoSDbMixin(qos.QueuePluginBase):
"""Mixin class to add queues."""
def create_qos_queue(self, context, qos_queue):
try:
return self._get_by_id(context, QoSQueue, queue_id)
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):
return self._get_collection(context, QoSQueue,
context.session.delete(qos_queue)
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:
return
with context.session.begin(subtransactions=True):
context.session.delete(binding)
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:
return
with context.session.begin(subtransactions=True):
def _extend_dict_qos_queue(self, obj_res, obj_db):
queue_mapping = obj_db['qos_queue']
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
def _extend_port_dict_qos_queue(self, port_res, port_db):
# create the queue
tenant_id = self._get_tenant_id_for_create(context, port)
- if port.get(ext_qos.RXTX_FACTOR) and queue_to_create.get('max'):
- queue_to_create['max'] *= int(port[ext_qos.RXTX_FACTOR])
+ if port.get(qos.RXTX_FACTOR) and queue_to_create.get('max'):
+ queue_to_create['max'] *= int(port[qos.RXTX_FACTOR])
queue = {'qos_queue': {'name': queue_to_create.get('name'),
'min': queue_to_create.get('min'),
'max': queue_to_create.get('max'),
if qos_queue.get('default'):
if context.is_admin:
if self.get_qos_queues(context, filters={'default': [True]}):
- raise ext_qos.DefaultQueueAlreadyExists()
+ raise qos.DefaultQueueAlreadyExists()
else:
- raise ext_qos.DefaultQueueCreateNotAdmin()
+ raise qos.DefaultQueueCreateNotAdmin()
if qos_queue.get('qos_marking') == 'trusted':
dscp = qos_queue.pop('dscp')
LOG.info(_("DSCP value (%s) will be ignored with 'trusted' "
min = qos_queue.get('min')
# Max can be None
if max and min > max:
- raise ext_qos.QueueMinGreaterMax()
+ raise qos.QueueMinGreaterMax()
-# 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.
# 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
# not use this file except in compliance with the License. You may obtain
@classmethod
def get_description(cls):
- return "Enables configuration of NSX Distributed routers"
+ return "Enables configuration of NSX Distributed routers."
@classmethod
def get_namespace(cls):
# 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
# not use this file except in compliance with the License. You may obtain
@classmethod
def get_description(cls):
- return "Provides mac learning capabilities"
+ return "Provides MAC learning capabilities."
@classmethod
def get_namespace(cls):
--- /dev/null
+# 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
# 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
# not use this file except in compliance with the License. You may obtain
# License for the specific language governing permissions and limitations
# under the License.
#
-# @author: Salvatore Orlando, VMware
-
-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}
- }
-}
+# TODO(armando-migliaccio): This is deprecated in Icehouse, and
+# to be removed in Juno.
+from neutron.plugins.nicira.extensions import networkgw
-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.
- """
+class Nvp_networkgw(networkgw.Networkgw):
+ """(Deprecated) API extension for Layer-2 Gateway support."""
@classmethod
def get_name(cls):
@classmethod
def get_alias(cls):
- return EXT_ALIAS
+ return "network-gateway"
@classmethod
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
def get_namespace(cls):
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
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2013 Nicira, Inc.
+# Copyright 2013 VMware, Inc.
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# License for the specific language governing permissions and limitations
# 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
-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."""
+class Nvp_qos(qos.Qos):
+ """(Deprecated) Port Queue extension."""
@classmethod
def get_name(cls):
@classmethod
def get_description(cls):
- return "NVP QoS extension."
+ return "NVP QoS extension (deprecated)."
@classmethod
def get_namespace(cls):
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
--- /dev/null
+# 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
# License for the specific language governing permissions and limitations
# under the License.
#
-# @author: Kaiwei Fan, VMware, Inc
-
from neutron.api import extensions
from neutron.api.v2 import attributes
@classmethod
def get_description(cls):
- return "Provides service router"
+ return "Provides service router."
@classmethod
def get_namespace(cls):
- return ""
+ return "http://docs.openstack.org/ext/service-router/api/v1.0"
@classmethod
def get_updated(cls):
# 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
# not use this file except in compliance with the License. You may obtain
from neutron.db import api as db_api
from neutron.db import db_base_plugin_v2
from neutron import manager
-from neutron.plugins.nicira.dbexts import nicira_networkgw_db
-from neutron.plugins.nicira.extensions import nvp_networkgw as networkgw
+from neutron.plugins.nicira.dbexts import networkgw_db
+from neutron.plugins.nicira.extensions import networkgw
from neutron.plugins.nicira.NeutronPlugin import NVP_EXT_PATH
from neutron import quota
from neutron.tests import base
# the global attribute map
attributes.RESOURCE_ATTRIBUTE_MAP.update(
networkgw.RESOURCE_ATTRIBUTE_MAP)
- return networkgw.Nvp_networkgw.get_resources()
+ return networkgw.Networkgw.get_resources()
def get_actions(self):
return []
pass
# Verify nothing left on db
session = db_api.get_session()
- gw_query = session.query(nicira_networkgw_db.NetworkGateway)
- dev_query = session.query(nicira_networkgw_db.NetworkGatewayDevice)
+ gw_query = session.query(networkgw_db.NetworkGateway)
+ dev_query = session.query(networkgw_db.NetworkGatewayDevice)
self.assertEqual(exp_gw_count, gw_query.count())
self.assertEqual(0, dev_query.count())
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."""
supported_extension_aliases = ["network-gateway"]
from neutron.plugins.nicira.dbexts import nicira_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 nvp_networkgw
-from neutron.plugins.nicira.extensions import nvp_qos as ext_qos
+from neutron.plugins.nicira.extensions import networkgw
+from neutron.plugins.nicira.extensions import qos
from neutron.plugins.nicira import NeutronPlugin
from neutron.plugins.nicira import nsxlib
from neutron.plugins.nicira import NvpApiClient
class NvpQoSTestExtensionManager(object):
def get_resources(self):
- return ext_qos.Nvp_qos.get_resources()
+ return qos.Qos.get_resources()
def get_actions(self):
return []
def test_create_port_with_queue(self):
with self.qos_queue(default=True) as q1:
res = self._create_network('json', 'net1', True,
- arg_list=(ext_qos.QUEUE,),
+ arg_list=(qos.QUEUE,),
queue_id=q1['qos_queue']['id'])
net1 = self.deserialize('json', res)
- self.assertEqual(net1['network'][ext_qos.QUEUE],
+ self.assertEqual(net1['network'][qos.QUEUE],
q1['qos_queue']['id'])
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
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):
with self.qos_queue(default=True, no_delete=True) as q1:
res = self._create_network('json', 'net1', True,
- arg_list=(ext_qos.QUEUE,),
+ arg_list=(qos.QUEUE,),
queue_id=q1['qos_queue']['id'])
net1 = self.deserialize('json', res)
- self.assertEqual(net1['network'][ext_qos.QUEUE],
+ self.assertEqual(net1['network'][qos.QUEUE],
q1['qos_queue']['id'])
res = self._create_network('json', 'net2', True,
- arg_list=(ext_qos.QUEUE,),
+ arg_list=(qos.QUEUE,),
queue_id=q1['qos_queue']['id'])
net2 = self.deserialize('json', res)
- self.assertEqual(net1['network'][ext_qos.QUEUE],
+ self.assertEqual(net1['network'][qos.QUEUE],
q1['qos_queue']['id'])
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
res = self._create_port('json', net1['network']['id'],
res = self._create_port('json', net2['network']['id'],
device_id=device_id)
port2 = self.deserialize('json', res)
- self.assertEqual(port1['port'][ext_qos.QUEUE],
- port2['port'][ext_qos.QUEUE])
+ self.assertEqual(port1['port'][qos.QUEUE],
+ port2['port'][qos.QUEUE])
self._delete('ports', port1['port']['id'])
self._delete('ports', port2['port']['id'])
def test_remove_queue_in_use_fail(self):
with self.qos_queue(no_delete=True) as q1:
res = self._create_network('json', 'net1', True,
- arg_list=(ext_qos.QUEUE,),
+ arg_list=(qos.QUEUE,),
queue_id=q1['qos_queue']['id'])
net1 = self.deserialize('json', res)
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
res = self._create_port('json', net1['network']['id'],
device_id=device_id)
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):
with self.qos_queue() as q1:
res = self._create_network('json', 'net1', True,
- arg_list=(ext_qos.QUEUE,),
+ arg_list=(qos.QUEUE,),
queue_id=q1['qos_queue']['id'])
net1 = self.deserialize('json', res)
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,
net1['network']['id'])
res = req.get_response(self.api)
net1 = self.deserialize('json', res)
- self.assertEqual(net1['network'][ext_qos.QUEUE],
+ self.assertEqual(net1['network'][qos.QUEUE],
new_q['qos_queue']['id'])
def test_update_port_adding_device_id(self):
with self.qos_queue(no_delete=True) as q1:
res = self._create_network('json', 'net1', True,
- arg_list=(ext_qos.QUEUE,),
+ arg_list=(qos.QUEUE,),
queue_id=q1['qos_queue']['id'])
net1 = self.deserialize('json', res)
device_id = "00fff4d0-e4a8-4a3a-8906-4c4cdafb59f1"
res = self._create_port('json', net1['network']['id'])
port = self.deserialize('json', res)
- self.assertIsNone(port['port'][ext_qos.QUEUE])
+ self.assertIsNone(port['port'][qos.QUEUE])
data = {'port': {'device_id': device_id}}
req = self.new_update_request('ports', data,
res = req.get_response(self.api)
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):
body = {'qos_queue': {'tenant_id': 'not_admin',
res = self._create_qos_queue('json', body, tenant_id='not_admin')
q1 = self.deserialize('json', res)
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'],
tenant_id="not_admin")
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'],
tenant_id='not_admin', set_context=True)
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):
body = {'qos_queue': {'tenant_id': 'admin', 'dscp': '64',
res = self._create_qos_queue('json', body, tenant_id='not_admin')
q1 = self.deserialize('json', res)
res = self._create_network('json', 'net1', True,
- arg_list=(ext_qos.QUEUE,),
+ arg_list=(qos.QUEUE,),
tenant_id='not_admin',
queue_id=q1['qos_queue']['id'])
neutron_context = context.Context('', 'not_admin')
port = self._update('ports', port['port']['id'], data,
neutron_context=neutron_context)
- self.assertNotIn(ext_qos.QUEUE, port['port'])
+ self.assertNotIn(qos.QUEUE, port['port'])
def test_rxtx_factor(self):
with self.qos_queue(max=10) as q1:
res = self._create_network('json', 'net1', True,
- arg_list=(ext_qos.QUEUE,),
+ arg_list=(qos.QUEUE,),
queue_id=q1['qos_queue']['id'])
net1 = self.deserialize('json', res)
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')
port = self.deserialize('json', res)
req = self.new_show_request('qos-queues',
- port['port'][ext_qos.QUEUE])
+ port['port'][qos.QUEUE])
res = req.get_response(self.ext_api)
queue = self.deserialize('json', res)
self.assertEqual(queue['qos_queue']['max'], 20)
nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw:
with self._network_gateway(name='cavani') as nw_gw:
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'}})
mock_update_gw.assert_called_once_with(
mock.ANY, nw_gw_id, 'higuain')
nsxlib.l2gateway, 'update_l2_gw_service') as mock_update_gw:
with self._network_gateway(name='something') as nw_gw:
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.assertEqual(mock_update_gw.call_count, 0)
new_name = 'this_is_a_gateway_whose_name_is_longer_than_40_chars'
with self._network_gateway(name='something') as nw_gw:
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}})
- req = self.new_show_request(nvp_networkgw.COLLECTION_NAME,
+ req = self.new_show_request(networkgw.COLLECTION_NAME,
nw_gw_id)
res = self.deserialize('json', req.get_response(self.ext_api))
# Assert Neutron name is not truncated
def test_list_network_gateways(self):
with self._network_gateway(name='test-gw-1') as gw1:
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))
# We expect the default gateway too
key = self.resource + 's'
def test_show_network_gateway_nvp_error_returns_404(self):
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)
self.assertEqual(webob.exc.HTTPNotFound.code, res.status_int)