Merge "Change RBAC relationship loading method to "joined""
This commit is contained in:
@@ -46,6 +46,6 @@ class AddressGroup(standard_attr.HasStandardAttributes,
|
||||
cascade='all, delete-orphan')
|
||||
rbac_entries = sa.orm.relationship(rbac_db_models.AddressGroupRBAC,
|
||||
backref='address_groups',
|
||||
lazy='subquery',
|
||||
lazy='joined',
|
||||
cascade='all, delete, delete-orphan')
|
||||
api_collections = [ag.ALIAS]
|
||||
|
@@ -37,5 +37,5 @@ class AddressScope(model_base.BASEV2, model_base.HasId, model_base.HasProject):
|
||||
|
||||
rbac_entries = sa.orm.relationship(rbac_db_models.AddressScopeRBAC,
|
||||
backref='address_scopes',
|
||||
lazy='subquery',
|
||||
lazy='joined',
|
||||
cascade='all, delete, delete-orphan')
|
||||
|
@@ -34,7 +34,7 @@ class SecurityGroup(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
nullable=False)
|
||||
rbac_entries = sa.orm.relationship(rbac_db_models.SecurityGroupRBAC,
|
||||
backref='security_group',
|
||||
lazy='subquery',
|
||||
lazy='joined',
|
||||
cascade='all, delete, delete-orphan')
|
||||
api_collections = [sg.SECURITYGROUPS]
|
||||
collection_resource_map = {sg.SECURITYGROUPS: 'security_group'}
|
||||
|
@@ -251,7 +251,7 @@ class Subnet(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
# subnets don't have their own rbac_entries, they just inherit from
|
||||
# the network rbac entries
|
||||
rbac_entries = orm.relationship(
|
||||
rbac_db_models.NetworkRBAC, lazy='subquery', uselist=True,
|
||||
rbac_db_models.NetworkRBAC, lazy='joined', uselist=True,
|
||||
foreign_keys='Subnet.network_id',
|
||||
primaryjoin='Subnet.network_id==NetworkRBAC.object_id',
|
||||
viewonly=True)
|
||||
@@ -306,7 +306,7 @@ class SubnetPool(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
lazy='subquery')
|
||||
rbac_entries = sa.orm.relationship(rbac_db_models.SubnetPoolRBAC,
|
||||
backref='subnetpools',
|
||||
lazy='subquery',
|
||||
lazy='joined',
|
||||
cascade='all, delete, delete-orphan')
|
||||
api_collections = [subnetpool_def.COLLECTION_NAME]
|
||||
collection_resource_map = {subnetpool_def.COLLECTION_NAME:
|
||||
@@ -328,7 +328,7 @@ class Network(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
rbac_entries = orm.relationship(rbac_db_models.NetworkRBAC,
|
||||
backref=orm.backref('network',
|
||||
load_on_pending=True),
|
||||
lazy='subquery',
|
||||
lazy='joined',
|
||||
cascade='all, delete, delete-orphan')
|
||||
availability_zone_hints = sa.Column(sa.String(255))
|
||||
mtu = sa.Column(sa.Integer, nullable=False,
|
||||
|
@@ -29,7 +29,7 @@ class QosPolicy(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
__tablename__ = 'qos_policies'
|
||||
name = sa.Column(sa.String(db_const.NAME_FIELD_SIZE))
|
||||
rbac_entries = sa.orm.relationship(rbac_db_models.QosPolicyRBAC,
|
||||
backref='qos_policy', lazy='subquery',
|
||||
backref='qos_policy', lazy='joined',
|
||||
cascade='all, delete, delete-orphan')
|
||||
api_collections = ['policies']
|
||||
collection_resource_map = {'policies': 'policy'}
|
||||
|
@@ -58,6 +58,7 @@ class AddressGroupRBACDbObjectTestCase(test_rbac.TestRBACObjectMixin,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = address_group.AddressGroupRBAC
|
||||
_parent_class = address_group.AddressGroup
|
||||
|
||||
def setUp(self):
|
||||
super(AddressGroupRBACDbObjectTestCase, self).setUp()
|
||||
|
@@ -36,6 +36,7 @@ class AddressScopeRBACDbObjectTestCase(test_rbac.TestRBACObjectMixin,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = address_scope.AddressScopeRBAC
|
||||
_parent_class = address_scope.AddressScope
|
||||
|
||||
def setUp(self):
|
||||
super(AddressScopeRBACDbObjectTestCase, self).setUp()
|
||||
|
@@ -12,6 +12,8 @@
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from neutron_lib.api.definitions import availability_zone as az_def
|
||||
|
||||
from neutron.db import rbac_db_models
|
||||
from neutron.objects import base as obj_base
|
||||
from neutron.objects import network
|
||||
@@ -27,6 +29,7 @@ class NetworkRBACDbObjectTestCase(test_rbac.TestRBACObjectMixin,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = network.NetworkRBAC
|
||||
_parent_class = network.Network
|
||||
|
||||
def setUp(self):
|
||||
self._mock_get_valid_actions = mock.patch.object(
|
||||
@@ -50,6 +53,13 @@ class NetworkRBACDbObjectTestCase(test_rbac.TestRBACObjectMixin,
|
||||
network_rbac_obj['versioned_object.data'])
|
||||
self.assertNotIn('id', network_rbac_obj['versioned_object.data'])
|
||||
|
||||
def _create_random_parent_object(self):
|
||||
objclass_fields = self.get_random_db_fields(self._parent_class)
|
||||
objclass_fields.pop(az_def.AZ_HINTS)
|
||||
_obj = self._parent_class(self.context, **objclass_fields)
|
||||
_obj.create()
|
||||
return _obj
|
||||
|
||||
|
||||
class NetworkRBACIfaceOjectTestCase(test_rbac.TestRBACObjectMixin,
|
||||
obj_test_base.BaseObjectIfaceTestCase):
|
||||
|
@@ -9,10 +9,13 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import random
|
||||
|
||||
import random
|
||||
from unittest import mock
|
||||
|
||||
from neutron_lib import context
|
||||
|
||||
from neutron.db import rbac_db_models
|
||||
from neutron.objects import address_group
|
||||
from neutron.objects import address_scope
|
||||
from neutron.objects import network
|
||||
@@ -26,6 +29,9 @@ from neutron.tests.unit.objects import test_base
|
||||
|
||||
class TestRBACObjectMixin(object):
|
||||
|
||||
_test_class = None
|
||||
_parent_class = None
|
||||
|
||||
def get_random_object_fields(self, obj_cls=None):
|
||||
fields = (super(TestRBACObjectMixin, self).
|
||||
get_random_object_fields(obj_cls))
|
||||
@@ -34,6 +40,35 @@ class TestRBACObjectMixin(object):
|
||||
fields['action'] = rnd_actions[idx]
|
||||
return fields
|
||||
|
||||
def _create_random_parent_object(self):
|
||||
objclass_fields = self.get_random_db_fields(self._parent_class)
|
||||
_obj = self._parent_class(self.context, **objclass_fields)
|
||||
_obj.create()
|
||||
return _obj
|
||||
|
||||
def test_rbac_shared_on_parent_object(self):
|
||||
if not self._test_class or not self._parent_class:
|
||||
self.skipTest('Mixin class, skipped test')
|
||||
project_id = self.objs[0].project_id
|
||||
_obj_shared = self._create_random_parent_object()
|
||||
# Create a second object that won't be shared and thus won't be
|
||||
# retrieved by the non-admin users.
|
||||
self._create_random_parent_object()
|
||||
for idx in range(3):
|
||||
project = 'project_%s' % idx
|
||||
rbac = self._test_class(
|
||||
self.context, project_id=project_id, target_project=project,
|
||||
action=rbac_db_models.ACCESS_SHARED,
|
||||
object_id=_obj_shared.id)
|
||||
rbac.create()
|
||||
|
||||
for idx in range(3):
|
||||
project = 'project_%s' % idx
|
||||
ctx_no_admin = context.Context(user_id='user', tenant_id=project,
|
||||
is_admin=False)
|
||||
objects = self._parent_class.get_objects(ctx_no_admin)
|
||||
self.assertEqual([_obj_shared.id], [_obj.id for _obj in objects])
|
||||
|
||||
|
||||
class RBACBaseObjectTestCase(neutron_test_base.BaseTestCase):
|
||||
|
||||
|
@@ -27,6 +27,7 @@ class SecurityGroupRBACDbObjectTestCase(test_rbac.TestRBACObjectMixin,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = securitygroup.SecurityGroupRBAC
|
||||
_parent_class = securitygroup.SecurityGroup
|
||||
|
||||
def setUp(self):
|
||||
super(SecurityGroupRBACDbObjectTestCase, self).setUp()
|
||||
|
@@ -195,6 +195,7 @@ class SubnetPoolRBACDbObjectTestCase(test_rbac.TestRBACObjectMixin,
|
||||
SubnetPoolTestMixin):
|
||||
|
||||
_test_class = subnetpool.SubnetPoolRBAC
|
||||
_parent_class = subnetpool.SubnetPool
|
||||
|
||||
def setUp(self):
|
||||
super(SubnetPoolRBACDbObjectTestCase, self).setUp()
|
||||
|
Reference in New Issue
Block a user