Add QoS policy network binding OVO
Added QoS policy network binding OVO. Direct access to 'qos_network_policy_bindings' DB table is removed. Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db Change-Id: I2a2037dae5a071bd220fa04b0988bc8e7172eb59
This commit is contained in:
parent
c2e12079f6
commit
188aee25c6
|
@ -50,6 +50,11 @@ class NetworkQosBindingNotFound(e.NotFound):
|
|||
"could not be found.")
|
||||
|
||||
|
||||
class NetworkQosBindingError(e.NeutronException):
|
||||
message = _("QoS binding for network %(net_id)s and policy %(policy_id)s "
|
||||
"could not be created: %(db_error)s.")
|
||||
|
||||
|
||||
class PlacementEndpointNotFound(e.NotFound):
|
||||
message = _("Placement API endpoint not found")
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
# 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 oslo_db import exception as oslo_db_exception
|
||||
from sqlalchemy.orm import exc as orm_exc
|
||||
|
||||
from neutron.common import exceptions as n_exc
|
||||
from neutron.db import _utils as db_utils
|
||||
from neutron.db.qos import models
|
||||
|
||||
|
||||
def create_policy_network_binding(context, policy_id, network_id):
|
||||
try:
|
||||
with context.session.begin(subtransactions=True):
|
||||
db_obj = models.QosNetworkPolicyBinding(policy_id=policy_id,
|
||||
network_id=network_id)
|
||||
context.session.add(db_obj)
|
||||
except oslo_db_exception.DBReferenceError:
|
||||
raise n_exc.NetworkQosBindingNotFound(net_id=network_id,
|
||||
policy_id=policy_id)
|
||||
|
||||
|
||||
def delete_policy_network_binding(context, policy_id, network_id):
|
||||
try:
|
||||
with context.session.begin(subtransactions=True):
|
||||
db_object = (db_utils.model_query(context,
|
||||
models.QosNetworkPolicyBinding)
|
||||
.filter_by(policy_id=policy_id,
|
||||
network_id=network_id).one())
|
||||
context.session.delete(db_object)
|
||||
except orm_exc.NoResultFound:
|
||||
raise n_exc.NetworkQosBindingNotFound(net_id=network_id,
|
||||
policy_id=policy_id)
|
||||
|
||||
|
||||
def get_network_ids_by_network_policy_binding(context, policy_id):
|
||||
query = (db_utils.model_query(context, models.QosNetworkPolicyBinding)
|
||||
.filter_by(policy_id=policy_id).all())
|
||||
return [entry.network_id for entry in query]
|
|
@ -21,13 +21,12 @@ from neutron.db.models import external_net as ext_net_model
|
|||
from neutron.db.models import segment as segment_model
|
||||
from neutron.db import models_v2
|
||||
from neutron.db.port_security import models as ps_models
|
||||
from neutron.db.qos import models as qos_models
|
||||
from neutron.db import rbac_db_models
|
||||
from neutron.extensions import availability_zone as az_ext
|
||||
from neutron.objects import base
|
||||
from neutron.objects import common_types
|
||||
from neutron.objects.db import api as obj_db_api
|
||||
from neutron.objects.extensions import port_security as base_ps
|
||||
from neutron.objects.qos import binding
|
||||
from neutron.objects import rbac_db
|
||||
|
||||
|
||||
|
@ -221,18 +220,13 @@ class Network(rbac_db.NeutronRbacObject):
|
|||
self._attach_qos_policy(fields['qos_policy_id'])
|
||||
|
||||
def _attach_qos_policy(self, qos_policy_id):
|
||||
# TODO(ihrachys): introduce an object for the binding to isolate
|
||||
# database access in a single place, currently scattered between port
|
||||
# and policy objects
|
||||
obj_db_api.delete_objects(
|
||||
self.obj_context, qos_models.QosNetworkPolicyBinding,
|
||||
network_id=self.id,
|
||||
)
|
||||
binding.QosPolicyNetworkBinding.delete_objects(
|
||||
self.obj_context, network_id=self.id)
|
||||
if qos_policy_id:
|
||||
obj_db_api.create_object(
|
||||
self.obj_context, qos_models.QosNetworkPolicyBinding,
|
||||
{'network_id': self.id, 'policy_id': qos_policy_id}
|
||||
)
|
||||
net_binding_obj = binding.QosPolicyNetworkBinding(
|
||||
self.obj_context, policy_id=qos_policy_id, network_id=self.id)
|
||||
net_binding_obj.create()
|
||||
|
||||
self.qos_policy_id = qos_policy_id
|
||||
self.obj_reset_changes(['qos_policy_id'])
|
||||
|
||||
|
|
|
@ -34,3 +34,19 @@ class QosPolicyPortBinding(base.NeutronDbObject):
|
|||
|
||||
primary_keys = ['port_id']
|
||||
fields_no_update = ['policy_id', 'port_id']
|
||||
|
||||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class QosPolicyNetworkBinding(base.NeutronDbObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
db_model = qos_db_model.QosNetworkPolicyBinding
|
||||
|
||||
fields = {
|
||||
'policy_id': common_types.UUIDField(),
|
||||
'network_id': common_types.UUIDField()
|
||||
}
|
||||
|
||||
primary_keys = ['network_id']
|
||||
fields_no_update = ['policy_id', 'network_id']
|
||||
|
|
|
@ -25,7 +25,6 @@ from neutron.common import constants as n_const
|
|||
from neutron.common import exceptions
|
||||
from neutron.db import api as db_api
|
||||
from neutron.db import models_v2
|
||||
from neutron.db.qos import api as qos_db_api
|
||||
from neutron.db.qos import models as qos_db_model
|
||||
from neutron.db.rbac_db_models import QosPolicyRBAC
|
||||
from neutron.objects import base as base_db
|
||||
|
@ -69,11 +68,8 @@ class QosPolicy(rbac_db.NeutronRbacObject):
|
|||
|
||||
extra_filter_names = {'is_default'}
|
||||
|
||||
binding_models = {'network': network_binding_model}
|
||||
|
||||
#NOTE(ralonsoh): once 'network_binding_model' is converted to OVO, both
|
||||
# bindings will be in the same variable.
|
||||
binding_models2 = {'port': binding.QosPolicyPortBinding}
|
||||
binding_models = {'port': binding.QosPolicyPortBinding,
|
||||
'network': binding.QosPolicyNetworkBinding}
|
||||
|
||||
def obj_load_attr(self, attrname):
|
||||
if attrname == 'rules':
|
||||
|
@ -177,18 +173,7 @@ class QosPolicy(rbac_db.NeutronRbacObject):
|
|||
|
||||
def delete(self):
|
||||
with db_api.autonested_transaction(self.obj_context.session):
|
||||
#NOTE(ralonsoh): once 'network_binding_model' is converted to OVO,
|
||||
# this loop will be deleted.
|
||||
for object_type, model in self.binding_models.items():
|
||||
binding_db_obj = obj_db_api.get_object(self.obj_context, model,
|
||||
policy_id=self.id)
|
||||
if binding_db_obj:
|
||||
raise exceptions.QosPolicyInUse(
|
||||
policy_id=self.id,
|
||||
object_type=object_type,
|
||||
object_id=binding_db_obj['%s_id' % object_type])
|
||||
|
||||
for object_type, obj_class in self.binding_models2.items():
|
||||
for object_type, obj_class in self.binding_models.items():
|
||||
pager = base_db.Pager(limit=1)
|
||||
binding_obj = obj_class.get_objects(self.obj_context,
|
||||
policy_id=self.id,
|
||||
|
@ -202,9 +187,16 @@ class QosPolicy(rbac_db.NeutronRbacObject):
|
|||
super(QosPolicy, self).delete()
|
||||
|
||||
def attach_network(self, network_id):
|
||||
qos_db_api.create_policy_network_binding(self.obj_context,
|
||||
policy_id=self.id,
|
||||
network_id=network_id)
|
||||
network_binding = {'policy_id': self.id,
|
||||
'network_id': network_id}
|
||||
network_binding_obj = binding.QosPolicyNetworkBinding(
|
||||
self.obj_context, **network_binding)
|
||||
try:
|
||||
network_binding_obj.create()
|
||||
except db_exc.DBReferenceError as e:
|
||||
raise exceptions.NetworkQosBindingError(policy_id=self.id,
|
||||
net_id=network_id,
|
||||
db_error=e)
|
||||
|
||||
def attach_port(self, port_id):
|
||||
port_binding_obj = binding.QosPolicyPortBinding(
|
||||
|
@ -217,9 +209,11 @@ class QosPolicy(rbac_db.NeutronRbacObject):
|
|||
db_error=e)
|
||||
|
||||
def detach_network(self, network_id):
|
||||
qos_db_api.delete_policy_network_binding(self.obj_context,
|
||||
policy_id=self.id,
|
||||
network_id=network_id)
|
||||
deleted = binding.QosPolicyNetworkBinding.delete_objects(
|
||||
self.obj_context, network_id=network_id)
|
||||
if not deleted:
|
||||
raise exceptions.NetworkQosBindingNotFound(net_id=network_id,
|
||||
policy_id=self.id)
|
||||
|
||||
def detach_port(self, port_id):
|
||||
deleted = binding.QosPolicyPortBinding.delete_objects(self.obj_context,
|
||||
|
@ -251,8 +245,11 @@ class QosPolicy(rbac_db.NeutronRbacObject):
|
|||
return qos_default_policy.qos_policy_id
|
||||
|
||||
def get_bound_networks(self):
|
||||
return qos_db_api.get_network_ids_by_network_policy_binding(
|
||||
self.obj_context, self.id)
|
||||
return [
|
||||
nb.network_id
|
||||
for nb in binding.QosPolicyNetworkBinding.get_objects(
|
||||
self.obj_context, policy_id=self.id)
|
||||
]
|
||||
|
||||
def get_bound_ports(self):
|
||||
return [
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
# under the License.
|
||||
|
||||
from neutron.objects.qos import binding
|
||||
from neutron.objects.qos import policy
|
||||
from neutron.tests.unit.objects import test_base
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
||||
|
@ -26,11 +25,6 @@ class QosPolicyPortBindingDbObjectTestCase(test_base.BaseDbObjectTestCase,
|
|||
|
||||
_test_class = binding.QosPolicyPortBinding
|
||||
|
||||
def _create_test_qos_policy(self, **qos_policy_attrs):
|
||||
qos_policy = policy.QosPolicy(self.context, **qos_policy_attrs)
|
||||
qos_policy.create()
|
||||
return qos_policy
|
||||
|
||||
def setUp(self):
|
||||
super(QosPolicyPortBindingDbObjectTestCase, self).setUp()
|
||||
network_id = self._create_test_network_id()
|
||||
|
@ -38,3 +32,20 @@ class QosPolicyPortBindingDbObjectTestCase(test_base.BaseDbObjectTestCase,
|
|||
self._create_test_qos_policy(id=db_obj['policy_id'])
|
||||
self._create_test_port(network_id=network_id,
|
||||
id=db_obj['port_id'])
|
||||
|
||||
|
||||
class QosPolicyNetworkBindingObjectTestCase(test_base.BaseObjectIfaceTestCase):
|
||||
|
||||
_test_class = binding.QosPolicyNetworkBinding
|
||||
|
||||
|
||||
class QosPolicyNetworkBindingDbObjectTestCase(test_base.BaseDbObjectTestCase,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = binding.QosPolicyNetworkBinding
|
||||
|
||||
def setUp(self):
|
||||
super(QosPolicyNetworkBindingDbObjectTestCase, self).setUp()
|
||||
for db_obj in self.db_objs:
|
||||
self._create_test_qos_policy(id=db_obj['policy_id'])
|
||||
self._create_test_network(network_id=db_obj['network_id'])
|
||||
|
|
|
@ -171,8 +171,8 @@ class QosPolicyDbObjectTestCase(test_base.BaseDbObjectTestCase,
|
|||
def test_attach_network_nonexistent_network(self):
|
||||
|
||||
obj = self._create_test_policy()
|
||||
self.assertRaises(n_exc.NetworkQosBindingNotFound,
|
||||
obj.attach_network, 'non-existent-network')
|
||||
self.assertRaises(n_exc.NetworkQosBindingError,
|
||||
obj.attach_network, uuidutils.generate_uuid())
|
||||
|
||||
def test_attach_network_get_policy_network(self):
|
||||
|
||||
|
@ -209,7 +209,7 @@ class QosPolicyDbObjectTestCase(test_base.BaseDbObjectTestCase,
|
|||
def test_attach_network_nonexistent_policy(self):
|
||||
|
||||
policy_obj = self._make_object(self.obj_fields[0])
|
||||
self.assertRaises(n_exc.NetworkQosBindingNotFound,
|
||||
self.assertRaises(n_exc.NetworkQosBindingError,
|
||||
policy_obj.attach_network, self._network_id)
|
||||
|
||||
def test_attach_port_nonexistent_policy(self):
|
||||
|
|
|
@ -43,6 +43,7 @@ from neutron.objects import flavor
|
|||
from neutron.objects.logapi import event_types
|
||||
from neutron.objects import network as net_obj
|
||||
from neutron.objects import ports
|
||||
from neutron.objects.qos import policy as qos_policy
|
||||
from neutron.objects import rbac_db
|
||||
from neutron.objects import securitygroup
|
||||
from neutron.objects import subnet
|
||||
|
@ -1336,8 +1337,10 @@ class BaseDbObjectTestCase(_BaseObjectTestCase,
|
|||
objclass.db_model(**objclass_fields)
|
||||
]
|
||||
|
||||
def _create_test_network(self, name='test-network1'):
|
||||
_network = net_obj.Network(self.context, name=name)
|
||||
def _create_test_network(self, name='test-network1', network_id=None):
|
||||
network_id = (uuidutils.generate_uuid() if network_id is None
|
||||
else network_id)
|
||||
_network = net_obj.Network(self.context, name=name, id=network_id)
|
||||
_network.create()
|
||||
return _network
|
||||
|
||||
|
@ -1466,6 +1469,11 @@ class BaseDbObjectTestCase(_BaseObjectTestCase,
|
|||
service_profile_obj.create()
|
||||
return service_profile_obj.id
|
||||
|
||||
def _create_test_qos_policy(self, **qos_policy_attrs):
|
||||
_qos_policy = qos_policy.QosPolicy(self.context, **qos_policy_attrs)
|
||||
_qos_policy.create()
|
||||
return _qos_policy
|
||||
|
||||
def test_get_standard_attr_id(self):
|
||||
|
||||
if not self._test_class.has_standard_attributes():
|
||||
|
|
|
@ -14,6 +14,7 @@ import mock
|
|||
|
||||
from neutron.objects import base as obj_base
|
||||
from neutron.objects import network
|
||||
from neutron.objects.qos import binding
|
||||
from neutron.objects.qos import policy
|
||||
from neutron.tests.unit.objects import test_base as obj_test_base
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
@ -130,6 +131,10 @@ class NetworkDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
|||
|
||||
obj = network.Network.get_object(self.context, id=obj.id)
|
||||
self.assertEqual(policy_obj.id, obj.qos_policy_id)
|
||||
qos_binding_obj = binding.QosPolicyNetworkBinding.get_object(
|
||||
self.context, network_id=obj.id)
|
||||
self.assertEqual(qos_binding_obj.policy_id, obj.qos_policy_id)
|
||||
old_policy_id = policy_obj.id
|
||||
|
||||
policy_obj2 = policy.QosPolicy(self.context)
|
||||
policy_obj2.create()
|
||||
|
@ -137,6 +142,12 @@ class NetworkDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
|||
|
||||
obj = network.Network.get_object(self.context, id=obj.id)
|
||||
self.assertEqual(policy_obj2.id, obj.qos_policy_id)
|
||||
qos_binding_obj2 = binding.QosPolicyNetworkBinding.get_object(
|
||||
self.context, network_id=obj.id)
|
||||
self.assertEqual(qos_binding_obj2.policy_id, obj.qos_policy_id)
|
||||
qos_binding_obj = binding.QosPolicyNetworkBinding.get_objects(
|
||||
self.context, policy_id=old_policy_id)
|
||||
self.assertEqual(0, len(qos_binding_obj))
|
||||
|
||||
def test_dns_domain(self):
|
||||
obj = self._make_object(self.obj_fields[0])
|
||||
|
|
|
@ -69,6 +69,7 @@ object_data = {
|
|||
'QosRuleType': '1.2-e6fd08fcca152c339cbd5e9b94b1b8e7',
|
||||
'QosPolicy': '1.6-4adb0cde3102c10d8970ec9487fd7fe7',
|
||||
'QosPolicyDefault': '1.0-59e5060eedb1f06dd0935a244d27d11c',
|
||||
'QosPolicyNetworkBinding': '1.0-df53a1e0f675aab8d27a1ccfed38dc42',
|
||||
'QosPolicyPortBinding': '1.0-66cb364ac99aa64523ade07f9f868ea6',
|
||||
'Quota': '1.0-6bb6a0f1bd5d66a2134ffa1a61873097',
|
||||
'QuotaUsage': '1.0-6fbf820368681aac7c5d664662605cf9',
|
||||
|
|
Loading…
Reference in New Issue