Merge "Replace "tenant_id" with "project_id" in OVO base"
This commit is contained in:
commit
322ed0131d
|
@ -969,7 +969,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase,
|
||||||
g.id for g in sg_objs
|
g.id for g in sg_objs
|
||||||
if (context.is_admin or not tenant_id or
|
if (context.is_admin or not tenant_id or
|
||||||
g.tenant_id == tenant_id or
|
g.tenant_id == tenant_id or
|
||||||
sg_obj.SecurityGroup.is_shared_with_tenant(
|
sg_obj.SecurityGroup.is_shared_with_project(
|
||||||
context, g.id, tenant_id))
|
context, g.id, tenant_id))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -63,10 +63,10 @@ class AddressGroup(rbac_db.NeutronRbacObject):
|
||||||
primitive.pop('shared', None)
|
primitive.pop('shared', None)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_bound_tenant_ids(cls, context, obj_id):
|
def get_bound_project_ids(cls, context, obj_id):
|
||||||
ag_objs = securitygroup.SecurityGroupRule.get_objects(
|
ag_objs = securitygroup.SecurityGroupRule.get_objects(
|
||||||
context, remote_address_group_id=[obj_id])
|
context, remote_address_group_id=[obj_id])
|
||||||
return {ag.tenant_id for ag in ag_objs}
|
return {ag.project_id for ag in ag_objs}
|
||||||
|
|
||||||
|
|
||||||
@base.NeutronObjectRegistry.register
|
@base.NeutronObjectRegistry.register
|
||||||
|
|
|
@ -69,7 +69,7 @@ class AddressScope(rbac_db.NeutronRbacObject):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_bound_tenant_ids(cls, context, obj_id):
|
def get_bound_project_ids(cls, context, obj_id):
|
||||||
snp_objs = subnetpool.SubnetPool.get_objects(
|
snp_objs = subnetpool.SubnetPool.get_objects(
|
||||||
context, address_scope_id=obj_id, fields=['project_id'])
|
context, address_scope_id=obj_id, fields=['project_id'])
|
||||||
return {snp['project_id'] for snp in snp_objs}
|
return {snp['project_id'] for snp in snp_objs}
|
||||||
|
|
|
@ -174,6 +174,7 @@ class NeutronObject(obj_base.VersionedObject,
|
||||||
# is included in self.items()
|
# is included in self.items()
|
||||||
if name in self.fields and name not in self.synthetic_fields:
|
if name in self.fields and name not in self.synthetic_fields:
|
||||||
value = self.fields[name].to_primitive(self, name, value)
|
value = self.fields[name].to_primitive(self, name, value)
|
||||||
|
# TODO(ralonsoh): remove once bp/keystone-v3 migration finishes.
|
||||||
if name == 'tenant_id':
|
if name == 'tenant_id':
|
||||||
if ('project_id' in self.fields and
|
if ('project_id' in self.fields and
|
||||||
not self.obj_attr_is_set('project_id')):
|
not self.obj_attr_is_set('project_id')):
|
||||||
|
@ -343,6 +344,7 @@ class DeclarativeObject(abc.ABCMeta):
|
||||||
|
|
||||||
def __init__(cls, name, bases, dct):
|
def __init__(cls, name, bases, dct):
|
||||||
super(DeclarativeObject, cls).__init__(name, bases, dct)
|
super(DeclarativeObject, cls).__init__(name, bases, dct)
|
||||||
|
# TODO(ralonsoh): remove once bp/keystone-v3 migration finishes.
|
||||||
if 'project_id' in cls.fields:
|
if 'project_id' in cls.fields:
|
||||||
obj_extra_fields_set = set(cls.obj_extra_fields)
|
obj_extra_fields_set = set(cls.obj_extra_fields)
|
||||||
obj_extra_fields_set.add('tenant_id')
|
obj_extra_fields_set.add('tenant_id')
|
||||||
|
@ -389,6 +391,7 @@ class DeclarativeObject(abc.ABCMeta):
|
||||||
standardattributes.add_tag_filter_names(cls)
|
standardattributes.add_tag_filter_names(cls)
|
||||||
# Instantiate extra filters per class
|
# Instantiate extra filters per class
|
||||||
cls.extra_filter_names = set(cls.extra_filter_names)
|
cls.extra_filter_names = set(cls.extra_filter_names)
|
||||||
|
# TODO(ralonsoh): remove once bp/keystone-v3 migration finishes.
|
||||||
# add tenant_id filter for objects that have project_id
|
# add tenant_id filter for objects that have project_id
|
||||||
if 'project_id' in cls.fields and 'tenant_id' not in cls.fields:
|
if 'project_id' in cls.fields and 'tenant_id' not in cls.fields:
|
||||||
cls.extra_filter_names.add('tenant_id')
|
cls.extra_filter_names.add('tenant_id')
|
||||||
|
@ -754,7 +757,7 @@ class NeutronDbObject(NeutronObject, metaclass=DeclarativeObject):
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_accessible(cls, context, db_obj):
|
def is_accessible(cls, context, db_obj):
|
||||||
return (context.is_admin or
|
return (context.is_admin or
|
||||||
context.tenant_id == db_obj.tenant_id)
|
context.project_id == db_obj.project_id)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def filter_to_str(value):
|
def filter_to_str(value):
|
||||||
|
|
|
@ -326,7 +326,7 @@ class Network(rbac_db.NeutronRbacObject):
|
||||||
self.obj_reset_changes(['qos_policy_id'])
|
self.obj_reset_changes(['qos_policy_id'])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_bound_tenant_ids(cls, context, policy_id):
|
def get_bound_project_ids(cls, context, policy_id):
|
||||||
# TODO(ihrachys): provide actual implementation
|
# TODO(ihrachys): provide actual implementation
|
||||||
return set()
|
return set()
|
||||||
|
|
||||||
|
|
|
@ -77,9 +77,8 @@ class NetworkSegmentRange(base.NeutronDbObject):
|
||||||
# fields
|
# fields
|
||||||
_dict.update({'available': self._get_available_allocation()})
|
_dict.update({'available': self._get_available_allocation()})
|
||||||
_dict.update({'used': self._get_used_allocation_mapping()})
|
_dict.update({'used': self._get_used_allocation_mapping()})
|
||||||
# NOTE(ralonsoh): this workaround should be removed once the migration
|
|
||||||
# from "tenant_id" to "project_id" is finished.
|
|
||||||
_dict = db_utils.resource_fields(_dict, fields)
|
_dict = db_utils.resource_fields(_dict, fields)
|
||||||
|
# TODO(ralonsoh): remove once bp/keystone-v3 migration finishes.
|
||||||
_dict.pop('tenant_id', None)
|
_dict.pop('tenant_id', None)
|
||||||
resource_extend.apply_funcs(nsr_def.COLLECTION_NAME, _dict,
|
resource_extend.apply_funcs(nsr_def.COLLECTION_NAME, _dict,
|
||||||
self.db_obj)
|
self.db_obj)
|
||||||
|
|
|
@ -341,18 +341,18 @@ class QosPolicy(rbac_db.NeutronRbacObject):
|
||||||
self.obj_context, policy_id=self.id)
|
self.obj_context, policy_id=self.id)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_bound_tenant_ids(cls, session, binding_db, bound_db,
|
def _get_bound_project_ids(cls, session, binding_db, bound_db,
|
||||||
binding_db_id_column, policy_id):
|
binding_db_id_column, policy_id):
|
||||||
return list(itertools.chain.from_iterable(
|
return list(itertools.chain.from_iterable(
|
||||||
session.query(bound_db.tenant_id).join(
|
session.query(bound_db.project_id).join(
|
||||||
binding_db, bound_db.id == binding_db_id_column).filter(
|
binding_db, bound_db.id == binding_db_id_column).filter(
|
||||||
binding_db.policy_id == policy_id).all()))
|
binding_db.policy_id == policy_id).all()))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_bound_tenant_ids(cls, context, policy_id):
|
def get_bound_project_ids(cls, context, policy_id):
|
||||||
"""Implements RbacNeutronObject.get_bound_tenant_ids.
|
"""Implements RbacNeutronObject.get_bound_project_ids.
|
||||||
|
|
||||||
:returns: set -- a set of tenants' ids dependent on QosPolicy.
|
:returns: set -- a set of projects' ids dependent on QosPolicy.
|
||||||
"""
|
"""
|
||||||
net = models_v2.Network
|
net = models_v2.Network
|
||||||
qosnet = qos_db_model.QosNetworkPolicyBinding
|
qosnet = qos_db_model.QosNetworkPolicyBinding
|
||||||
|
@ -362,20 +362,20 @@ class QosPolicy(rbac_db.NeutronRbacObject):
|
||||||
qosfip = qos_db_model.QosFIPPolicyBinding
|
qosfip = qos_db_model.QosFIPPolicyBinding
|
||||||
router = l3.Router
|
router = l3.Router
|
||||||
qosrouter = qos_db_model.QosRouterGatewayIPPolicyBinding
|
qosrouter = qos_db_model.QosRouterGatewayIPPolicyBinding
|
||||||
bound_tenants = []
|
bound_projects = []
|
||||||
with cls.db_context_reader(context):
|
with cls.db_context_reader(context):
|
||||||
bound_tenants.extend(cls._get_bound_tenant_ids(
|
bound_projects.extend(cls._get_bound_project_ids(
|
||||||
context.session, qosnet, net, qosnet.network_id, policy_id))
|
context.session, qosnet, net, qosnet.network_id, policy_id))
|
||||||
bound_tenants.extend(
|
bound_projects.extend(
|
||||||
cls._get_bound_tenant_ids(context.session, qosport, port,
|
cls._get_bound_project_ids(context.session, qosport, port,
|
||||||
qosport.port_id, policy_id))
|
qosport.port_id, policy_id))
|
||||||
bound_tenants.extend(
|
bound_projects.extend(
|
||||||
cls._get_bound_tenant_ids(context.session, qosfip, fip,
|
cls._get_bound_project_ids(context.session, qosfip, fip,
|
||||||
qosfip.fip_id, policy_id))
|
qosfip.fip_id, policy_id))
|
||||||
bound_tenants.extend(
|
bound_projects.extend(
|
||||||
cls._get_bound_tenant_ids(context.session, qosrouter, router,
|
cls._get_bound_project_ids(context.session, qosrouter, router,
|
||||||
qosrouter.router_id, policy_id))
|
qosrouter.router_id, policy_id))
|
||||||
return set(bound_tenants)
|
return set(bound_projects)
|
||||||
|
|
||||||
def obj_make_compatible(self, primitive, target_version):
|
def obj_make_compatible(self, primitive, target_version):
|
||||||
def filter_rules(obj_names, rules):
|
def filter_rules(obj_names, rules):
|
||||||
|
|
|
@ -27,6 +27,7 @@ class RBACBaseObject(base.NeutronDbObject, metaclass=abc.ABCMeta):
|
||||||
|
|
||||||
VERSION = '1.0'
|
VERSION = '1.0'
|
||||||
|
|
||||||
|
# TODO(ralonsoh): move 'target_tenant' to 'target_project'.
|
||||||
fields = {
|
fields = {
|
||||||
'id': common_types.UUIDField(),
|
'id': common_types.UUIDField(),
|
||||||
'project_id': obj_fields.StringField(),
|
'project_id': obj_fields.StringField(),
|
||||||
|
|
|
@ -39,23 +39,23 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def get_bound_tenant_ids(cls, context, obj_id):
|
def get_bound_project_ids(cls, context, obj_id):
|
||||||
"""Returns ids of all tenants depending on this db object.
|
"""Returns ids of all projects depending on this db object.
|
||||||
|
|
||||||
Has to be implemented by classes using RbacNeutronMetaclass.
|
Has to be implemented by classes using RbacNeutronMetaclass.
|
||||||
The tenants are the ones that need the sharing or 'visibility' of the
|
The projects are the ones that need the sharing or 'visibility' of the
|
||||||
object to them. E.g: for QosPolicy that would be the tenants using the
|
object to them. E.g: for QosPolicy that would be the projects using the
|
||||||
Networks and Ports with the shared QosPolicy applied to them.
|
Networks and Ports with the shared QosPolicy applied to them.
|
||||||
|
|
||||||
:returns: set -- a set of tenants' ids dependent on this object.
|
:returns: set -- a set of projects' ids dependent on this object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_network_shared(context, rbac_entries):
|
def is_network_shared(context, rbac_entries):
|
||||||
# NOTE(korzen) this method is copied from db_base_plugin_common.
|
# NOTE(korzen) this method is copied from db_base_plugin_common.
|
||||||
# The shared attribute for a network now reflects if the network
|
# The shared attribute for a network now reflects if the network
|
||||||
# is shared to the calling tenant via an RBAC entry.
|
# is shared to the calling project via an RBAC entry.
|
||||||
matches = ('*',) + ((context.tenant_id,) if context else ())
|
matches = ('*',) + ((context.project_id,) if context else ())
|
||||||
for entry in rbac_entries:
|
for entry in rbac_entries:
|
||||||
if (entry.action == models.ACCESS_SHARED and
|
if (entry.action == models.ACCESS_SHARED and
|
||||||
entry.target_tenant in matches):
|
entry.target_tenant in matches):
|
||||||
|
@ -63,7 +63,7 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_shared_with_tenant(context, rbac_db_cls, obj_id, tenant_id):
|
def get_shared_with_project(context, rbac_db_cls, obj_id, project_id):
|
||||||
# NOTE(korzen) This method enables to query within already started
|
# NOTE(korzen) This method enables to query within already started
|
||||||
# session
|
# session
|
||||||
rbac_db_model = rbac_db_cls.db_model
|
rbac_db_model = rbac_db_cls.db_model
|
||||||
|
@ -71,21 +71,21 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
and_(rbac_db_model.object_id == obj_id,
|
and_(rbac_db_model.object_id == obj_id,
|
||||||
rbac_db_model.action == models.ACCESS_SHARED,
|
rbac_db_model.action == models.ACCESS_SHARED,
|
||||||
rbac_db_model.target_tenant.in_(
|
rbac_db_model.target_tenant.in_(
|
||||||
['*', tenant_id]))).count() != 0)
|
['*', project_id]))).count() != 0)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_shared_with_tenant(cls, context, obj_id, tenant_id):
|
def is_shared_with_project(cls, context, obj_id, project_id):
|
||||||
ctx = context.elevated()
|
ctx = context.elevated()
|
||||||
with cls.db_context_reader(ctx):
|
with cls.db_context_reader(ctx):
|
||||||
return cls.get_shared_with_tenant(ctx, cls.rbac_db_cls,
|
return cls.get_shared_with_project(ctx, cls.rbac_db_cls,
|
||||||
obj_id, tenant_id)
|
obj_id, project_id)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_accessible(cls, context, db_obj):
|
def is_accessible(cls, context, db_obj):
|
||||||
return (super(
|
return (super(
|
||||||
RbacNeutronDbObjectMixin, cls).is_accessible(context, db_obj) or
|
RbacNeutronDbObjectMixin, cls).is_accessible(context, db_obj) or
|
||||||
cls.is_shared_with_tenant(context, db_obj.id,
|
cls.is_shared_with_project(context, db_obj.id,
|
||||||
context.tenant_id))
|
context.project_id))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_db_obj_rbac_entries(cls, context, rbac_obj_id, rbac_action):
|
def _get_db_obj_rbac_entries(cls, context, rbac_obj_id, rbac_action):
|
||||||
|
@ -95,7 +95,7 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
rbac_db_model.action == rbac_action))
|
rbac_db_model.action == rbac_action))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_tenants_with_shared_access_to_db_obj(cls, context, obj_id):
|
def _get_projects_with_shared_access_to_db_obj(cls, context, obj_id):
|
||||||
rbac_db_model = cls.rbac_db_cls.db_model
|
rbac_db_model = cls.rbac_db_cls.db_model
|
||||||
return set(itertools.chain.from_iterable(context.session.query(
|
return set(itertools.chain.from_iterable(context.session.query(
|
||||||
rbac_db_model.target_tenant).filter(
|
rbac_db_model.target_tenant).filter(
|
||||||
|
@ -107,14 +107,14 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
def _validate_rbac_policy_delete(cls, context, obj_id, target_tenant):
|
def _validate_rbac_policy_delete(cls, context, obj_id, target_tenant):
|
||||||
ctx_admin = context.elevated()
|
ctx_admin = context.elevated()
|
||||||
rb_model = cls.rbac_db_cls.db_model
|
rb_model = cls.rbac_db_cls.db_model
|
||||||
bound_tenant_ids = cls.get_bound_tenant_ids(ctx_admin, obj_id)
|
bound_project_ids = cls.get_bound_project_ids(ctx_admin, obj_id)
|
||||||
db_obj_sharing_entries = cls._get_db_obj_rbac_entries(
|
db_obj_sharing_entries = cls._get_db_obj_rbac_entries(
|
||||||
ctx_admin, obj_id, models.ACCESS_SHARED)
|
ctx_admin, obj_id, models.ACCESS_SHARED)
|
||||||
|
|
||||||
def raise_policy_in_use():
|
def raise_policy_in_use():
|
||||||
raise ext_rbac.RbacPolicyInUse(
|
raise ext_rbac.RbacPolicyInUse(
|
||||||
object_id=obj_id,
|
object_id=obj_id,
|
||||||
details='tenant_id={}'.format(target_tenant))
|
details='project_id={}'.format(target_tenant))
|
||||||
|
|
||||||
if target_tenant != '*':
|
if target_tenant != '*':
|
||||||
# if there is a wildcard rule, we can return early because it
|
# if there is a wildcard rule, we can return early because it
|
||||||
|
@ -123,15 +123,15 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
rb_model.target_tenant == '*')
|
rb_model.target_tenant == '*')
|
||||||
if wildcard_sharing_entries.count():
|
if wildcard_sharing_entries.count():
|
||||||
return
|
return
|
||||||
if target_tenant in bound_tenant_ids:
|
if target_tenant in bound_project_ids:
|
||||||
raise_policy_in_use()
|
raise_policy_in_use()
|
||||||
return
|
return
|
||||||
|
|
||||||
# for the wildcard we need to query all of the rbac entries to
|
# for the wildcard we need to query all of the rbac entries to
|
||||||
# see if any allow the object sharing
|
# see if any allow the object sharing
|
||||||
other_target_tenants = cls._get_tenants_with_shared_access_to_db_obj(
|
other_target_tenants = cls._get_projects_with_shared_access_to_db_obj(
|
||||||
ctx_admin, obj_id)
|
ctx_admin, obj_id)
|
||||||
if not bound_tenant_ids.issubset(other_target_tenants):
|
if not bound_project_ids.issubset(other_target_tenants):
|
||||||
raise_policy_in_use()
|
raise_policy_in_use()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -149,7 +149,7 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
target_tenant = policy['target_tenant']
|
target_tenant = policy['target_tenant']
|
||||||
db_obj = obj_db_api.get_object(
|
db_obj = obj_db_api.get_object(
|
||||||
cls, context.elevated(), id=policy['object_id'])
|
cls, context.elevated(), id=policy['object_id'])
|
||||||
if db_obj.tenant_id == target_tenant:
|
if db_obj.project_id == target_tenant:
|
||||||
return
|
return
|
||||||
cls._validate_rbac_policy_delete(context=context,
|
cls._validate_rbac_policy_delete(context=context,
|
||||||
obj_id=policy['object_id'],
|
obj_id=policy['object_id'],
|
||||||
|
@ -171,11 +171,11 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
"""
|
"""
|
||||||
policy = payload.latest_state
|
policy = payload.latest_state
|
||||||
|
|
||||||
prev_tenant = policy['target_tenant']
|
prev_project = policy['target_tenant']
|
||||||
new_tenant = payload.request_body['target_tenant']
|
new_project = payload.request_body['target_tenant']
|
||||||
if prev_tenant == new_tenant:
|
if prev_project == new_project:
|
||||||
return
|
return
|
||||||
if new_tenant != '*':
|
if new_project != '*':
|
||||||
return cls.validate_rbac_policy_delete(
|
return cls.validate_rbac_policy_delete(
|
||||||
resource, event, trigger, payload=payload)
|
resource, event, trigger, payload=payload)
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
cls, context.elevated(), id=policy['object_id'])
|
cls, context.elevated(), id=policy['object_id'])
|
||||||
if event in (events.BEFORE_CREATE, events.BEFORE_UPDATE):
|
if event in (events.BEFORE_CREATE, events.BEFORE_UPDATE):
|
||||||
if (not context.is_admin and
|
if (not context.is_admin and
|
||||||
db_obj['tenant_id'] != context.tenant_id):
|
db_obj['project_id'] != context.project_id):
|
||||||
msg = _("Only admins can manipulate policies on objects "
|
msg = _("Only admins can manipulate policies on objects "
|
||||||
"they do not own")
|
"they do not own")
|
||||||
raise exceptions.InvalidInput(error_message=msg)
|
raise exceptions.InvalidInput(error_message=msg)
|
||||||
|
@ -235,7 +235,7 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
|
|
||||||
# 'shared' goes False -> True
|
# 'shared' goes False -> True
|
||||||
if not is_shared_prev and is_shared_new:
|
if not is_shared_prev and is_shared_new:
|
||||||
self.attach_rbac(obj_id, self.obj_context.tenant_id)
|
self.attach_rbac(obj_id, self.obj_context.project_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
# 'shared' goes True -> False is actually an attempt to delete
|
# 'shared' goes True -> False is actually an attempt to delete
|
||||||
|
@ -265,7 +265,7 @@ class RbacNeutronDbObjectMixin(rbac_db_mixin.RbacPluginMixin,
|
||||||
# NOTE(korzen) this case is used when object was
|
# NOTE(korzen) this case is used when object was
|
||||||
# instantiated and without DB interaction (get_object(s), update,
|
# instantiated and without DB interaction (get_object(s), update,
|
||||||
# create), it should be rare case to load 'shared' by that method
|
# create), it should be rare case to load 'shared' by that method
|
||||||
shared = self.get_shared_with_tenant(
|
shared = self.get_shared_with_project(
|
||||||
self.obj_context.elevated(),
|
self.obj_context.elevated(),
|
||||||
self.rbac_db_cls,
|
self.rbac_db_cls,
|
||||||
self.id,
|
self.id,
|
||||||
|
@ -305,9 +305,8 @@ def _create_hook(self, orig_create):
|
||||||
def _to_dict_hook(self, to_dict_orig):
|
def _to_dict_hook(self, to_dict_orig):
|
||||||
dct = to_dict_orig(self)
|
dct = to_dict_orig(self)
|
||||||
if self.obj_context:
|
if self.obj_context:
|
||||||
dct['shared'] = self.is_shared_with_tenant(self.obj_context,
|
dct['shared'] = self.is_shared_with_project(
|
||||||
self.id,
|
self.obj_context, self.id, self.obj_context.project_id)
|
||||||
self.obj_context.tenant_id)
|
|
||||||
else:
|
else:
|
||||||
# most OVO objects on an agent will not have a context set on the
|
# most OVO objects on an agent will not have a context set on the
|
||||||
# object because they will be generated from obj_from_primitive.
|
# object because they will be generated from obj_from_primitive.
|
||||||
|
|
|
@ -126,10 +126,10 @@ class SecurityGroup(rbac_db.NeutronRbacObject):
|
||||||
filter_normalized_cidr_from_rules(primitive['rules'])
|
filter_normalized_cidr_from_rules(primitive['rules'])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_bound_tenant_ids(cls, context, obj_id):
|
def get_bound_project_ids(cls, context, obj_id):
|
||||||
port_objs = ports.Port.get_objects(context,
|
port_objs = ports.Port.get_objects(context,
|
||||||
security_group_ids=[obj_id])
|
security_group_ids=[obj_id])
|
||||||
return {port.tenant_id for port in port_objs}
|
return {port.project_id for port in port_objs}
|
||||||
|
|
||||||
|
|
||||||
@base.NeutronObjectRegistry.register
|
@base.NeutronObjectRegistry.register
|
||||||
|
|
|
@ -273,10 +273,10 @@ class Subnet(base.NeutronDbObject):
|
||||||
# instantiated and without DB interaction (get_object(s), update,
|
# instantiated and without DB interaction (get_object(s), update,
|
||||||
# create), it should be rare case to load 'shared' by that method
|
# create), it should be rare case to load 'shared' by that method
|
||||||
shared = (rbac_db.RbacNeutronDbObjectMixin.
|
shared = (rbac_db.RbacNeutronDbObjectMixin.
|
||||||
get_shared_with_tenant(self.obj_context.elevated(),
|
get_shared_with_project(self.obj_context.elevated(),
|
||||||
network.NetworkRBAC,
|
network.NetworkRBAC,
|
||||||
self.network_id,
|
self.network_id,
|
||||||
self.project_id))
|
self.project_id))
|
||||||
setattr(self, 'shared', shared)
|
setattr(self, 'shared', shared)
|
||||||
self.obj_reset_changes(['shared'])
|
self.obj_reset_changes(['shared'])
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ class SubnetPool(rbac_db.NeutronRbacObject):
|
||||||
self._attach_prefixes(fields['prefixes'])
|
self._attach_prefixes(fields['prefixes'])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_bound_tenant_ids(cls, context, obj_id):
|
def get_bound_project_ids(cls, context, obj_id):
|
||||||
sn_objs = subnet.Subnet.get_objects(context, subnetpool_id=obj_id)
|
sn_objs = subnet.Subnet.get_objects(context, subnetpool_id=obj_id)
|
||||||
return {snp.project_id for snp in sn_objs}
|
return {snp.project_id for snp in sn_objs}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ class SecurityGroupServerAPIShimTestCase(base.BaseTestCase):
|
||||||
self.rcache.record_resource_update(self.ctx, 'Port', p)
|
self.rcache.record_resource_update(self.ctx, 'Port', p)
|
||||||
return p
|
return p
|
||||||
|
|
||||||
@mock.patch.object(address_group.AddressGroup, 'is_shared_with_tenant',
|
@mock.patch.object(address_group.AddressGroup, 'is_shared_with_project',
|
||||||
return_value=False)
|
return_value=False)
|
||||||
def _make_address_group_ovo(self, *args, **kwargs):
|
def _make_address_group_ovo(self, *args, **kwargs):
|
||||||
id = uuidutils.generate_uuid()
|
id = uuidutils.generate_uuid()
|
||||||
|
@ -116,7 +116,7 @@ class SecurityGroupServerAPIShimTestCase(base.BaseTestCase):
|
||||||
ag)
|
ag)
|
||||||
return ag
|
return ag
|
||||||
|
|
||||||
@mock.patch.object(securitygroup.SecurityGroup, 'is_shared_with_tenant',
|
@mock.patch.object(securitygroup.SecurityGroup, 'is_shared_with_project',
|
||||||
return_value=False)
|
return_value=False)
|
||||||
def _make_security_group_ovo(self, *args, **kwargs):
|
def _make_security_group_ovo(self, *args, **kwargs):
|
||||||
attrs = {'id': uuidutils.generate_uuid(), 'revision_number': 1}
|
attrs = {'id': uuidutils.generate_uuid(), 'revision_number': 1}
|
||||||
|
|
|
@ -148,8 +148,8 @@ class QosPolicyObjectTestCase(test_base.BaseObjectIfaceTestCase):
|
||||||
self._test_class, self.context, id='fake_id')
|
self._test_class, self.context, id='fake_id')
|
||||||
|
|
||||||
def test_to_dict_makes_primitive_field_value(self):
|
def test_to_dict_makes_primitive_field_value(self):
|
||||||
# is_shared_with_tenant requires DB
|
# is_shared_with_project requires DB
|
||||||
with mock.patch.object(self._test_class, 'is_shared_with_tenant',
|
with mock.patch.object(self._test_class, 'is_shared_with_project',
|
||||||
return_value=False):
|
return_value=False):
|
||||||
(super(QosPolicyObjectTestCase, self).
|
(super(QosPolicyObjectTestCase, self).
|
||||||
test_to_dict_makes_primitive_field_value())
|
test_to_dict_makes_primitive_field_value())
|
||||||
|
@ -460,10 +460,10 @@ class QosPolicyDbObjectTestCase(test_base.BaseDbObjectTestCase,
|
||||||
policy_obj._reload_is_default()
|
policy_obj._reload_is_default()
|
||||||
self.assertTrue(policy_obj.is_default)
|
self.assertTrue(policy_obj.is_default)
|
||||||
|
|
||||||
def test_get_bound_tenant_ids_returns_set_of_tenant_ids(self):
|
def test_get_bound_project_ids_returns_set_of_project_ids(self):
|
||||||
obj = self._create_test_policy()
|
obj = self._create_test_policy()
|
||||||
obj.attach_port(self._port['id'])
|
obj.attach_port(self._port['id'])
|
||||||
ids = self._test_class.get_bound_tenant_ids(self.context, obj['id'])
|
ids = self._test_class.get_bound_project_ids(self.context, obj['id'])
|
||||||
self.assertEqual(ids.pop(), self._port.project_id)
|
self.assertEqual(ids.pop(), self._port.project_id)
|
||||||
self.assertEqual(len(ids), 0)
|
self.assertEqual(len(ids), 0)
|
||||||
|
|
||||||
|
|
|
@ -387,6 +387,8 @@ class FakeNeutronObjectWithProjectId(base.NeutronDbObject):
|
||||||
'field2': common_types.UUIDField(),
|
'field2': common_types.UUIDField(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fields_no_update = ['id', 'project_id']
|
||||||
|
|
||||||
|
|
||||||
@base.NeutronObjectRegistry.register_if(False)
|
@base.NeutronObjectRegistry.register_if(False)
|
||||||
class FakeNeutronObject(base.NeutronObject):
|
class FakeNeutronObject(base.NeutronObject):
|
||||||
|
@ -750,10 +752,10 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
|
||||||
if getattr(self._test_class.rbac_db_cls, 'db_model', None):
|
if getattr(self._test_class.rbac_db_cls, 'db_model', None):
|
||||||
mock.patch.object(
|
mock.patch.object(
|
||||||
rbac_db.RbacNeutronDbObjectMixin,
|
rbac_db.RbacNeutronDbObjectMixin,
|
||||||
'is_shared_with_tenant', return_value=False).start()
|
'is_shared_with_project', return_value=False).start()
|
||||||
mock.patch.object(
|
mock.patch.object(
|
||||||
rbac_db.RbacNeutronDbObjectMixin,
|
rbac_db.RbacNeutronDbObjectMixin,
|
||||||
'get_shared_with_tenant', return_value=False).start()
|
'get_shared_with_project', return_value=False).start()
|
||||||
|
|
||||||
def fake_get_object(self, context, model, **kwargs):
|
def fake_get_object(self, context, model, **kwargs):
|
||||||
objs = self.model_map[model]
|
objs = self.model_map[model]
|
||||||
|
@ -1189,6 +1191,7 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
|
||||||
dict_ = obj.to_dict()
|
dict_ = obj.to_dict()
|
||||||
|
|
||||||
self.assertNotIn('project_id', dict_)
|
self.assertNotIn('project_id', dict_)
|
||||||
|
# TODO(ralonsoh): remove once bp/keystone-v3 migration finishes.
|
||||||
self.assertNotIn('tenant_id', dict_)
|
self.assertNotIn('tenant_id', dict_)
|
||||||
|
|
||||||
def test_fields_no_update(self):
|
def test_fields_no_update(self):
|
||||||
|
@ -1196,13 +1199,13 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
|
||||||
for field in self._test_class.fields_no_update:
|
for field in self._test_class.fields_no_update:
|
||||||
self.assertTrue(hasattr(obj, field))
|
self.assertTrue(hasattr(obj, field))
|
||||||
|
|
||||||
def test_get_tenant_id(self):
|
def test_get_project_id(self):
|
||||||
if not hasattr(self._test_class, 'project_id'):
|
if not hasattr(self._test_class, 'project_id'):
|
||||||
self.skipTest(
|
self.skipTest(
|
||||||
'Test class %r has no project_id field' % self._test_class)
|
'Test class %r has no project_id field' % self._test_class)
|
||||||
obj = self._test_class(self.context, **self.obj_fields[0])
|
obj = self._test_class(self.context, **self.obj_fields[0])
|
||||||
project_id = self.obj_fields[0]['project_id']
|
project_id = self.obj_fields[0]['project_id']
|
||||||
self.assertEqual(project_id, obj.tenant_id)
|
self.assertEqual(project_id, obj.project_id)
|
||||||
|
|
||||||
# Adding delete_objects mock because some objects are using delete_objects
|
# Adding delete_objects mock because some objects are using delete_objects
|
||||||
# while calling update(), Port for example
|
# while calling update(), Port for example
|
||||||
|
@ -1407,22 +1410,22 @@ class BaseObjectIfaceWithProjectIdTestCase(BaseObjectIfaceTestCase):
|
||||||
|
|
||||||
_test_class = FakeNeutronObjectWithProjectId
|
_test_class = FakeNeutronObjectWithProjectId
|
||||||
|
|
||||||
def test_update_fields_using_tenant_id(self):
|
def test_update_fields_using_project_id(self):
|
||||||
obj = self._test_class(self.context, **self.obj_fields[0])
|
obj = self._test_class(self.context, **self.obj_fields[0])
|
||||||
obj.obj_reset_changes()
|
obj.obj_reset_changes()
|
||||||
|
|
||||||
tenant_id = obj['tenant_id']
|
project_id = obj['project_id']
|
||||||
new_obj_fields = dict()
|
new_obj_fields = dict()
|
||||||
new_obj_fields['tenant_id'] = uuidutils.generate_uuid()
|
new_obj_fields['project_id'] = uuidutils.generate_uuid()
|
||||||
new_obj_fields['field2'] = uuidutils.generate_uuid()
|
new_obj_fields['field2'] = uuidutils.generate_uuid()
|
||||||
|
|
||||||
obj.update_fields(new_obj_fields)
|
obj.update_fields(new_obj_fields)
|
||||||
self.assertEqual(set(['field2']), obj.obj_what_changed())
|
self.assertEqual(set(['field2']), obj.obj_what_changed())
|
||||||
self.assertEqual(tenant_id, obj.project_id)
|
self.assertEqual(project_id, obj.project_id)
|
||||||
|
|
||||||
def test_tenant_id_filter_added_when_project_id_present(self):
|
def test_project_id_filter_added_when_project_id_present(self):
|
||||||
self._test_class.get_objects(
|
self._test_class.get_objects(
|
||||||
self.context, tenant_id=self.obj_fields[0]['project_id'])
|
self.context, project_id=self.obj_fields[0]['project_id'])
|
||||||
|
|
||||||
|
|
||||||
class BaseDbObjectMultipleForeignKeysTestCase(_BaseObjectTestCase,
|
class BaseDbObjectMultipleForeignKeysTestCase(_BaseObjectTestCase,
|
||||||
|
|
|
@ -73,7 +73,7 @@ class FakeNeutronDbObject(rbac_db.NeutronRbacObject):
|
||||||
|
|
||||||
synthetic_fields = ['field2']
|
synthetic_fields = ['field2']
|
||||||
|
|
||||||
def get_bound_tenant_ids(cls, context, policy_id):
|
def get_bound_project_ids(cls, context, policy_id):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,44 +86,46 @@ class RbacNeutronDbObjectTestCase(test_rbac.RBACBaseObjectIfaceTestCase,
|
||||||
FakeNeutronDbObject.update_post = mock.Mock()
|
FakeNeutronDbObject.update_post = mock.Mock()
|
||||||
|
|
||||||
@mock.patch.object(_test_class.rbac_db_cls, 'db_model')
|
@mock.patch.object(_test_class.rbac_db_cls, 'db_model')
|
||||||
def test_get_tenants_with_shared_access_to_db_obj_return_tenant_ids(
|
def test_get_projects_with_shared_access_to_db_obj_return_project_ids(
|
||||||
self, *mocks):
|
self, *mocks):
|
||||||
ctx = mock.Mock()
|
ctx = mock.Mock()
|
||||||
fake_ids = {'tenant_id_' + str(i) for i in range(10)}
|
fake_ids = {'project_id_' + str(i) for i in range(10)}
|
||||||
ctx.session.query.return_value.filter.return_value = [
|
ctx.session.query.return_value.filter.return_value = [
|
||||||
(fake_id,) for fake_id in fake_ids]
|
(fake_id,) for fake_id in fake_ids]
|
||||||
ret_ids = self._test_class._get_tenants_with_shared_access_to_db_obj(
|
ret_ids = self._test_class._get_projects_with_shared_access_to_db_obj(
|
||||||
ctx, 'fake_db_obj_id')
|
ctx, 'fake_db_obj_id')
|
||||||
self.assertEqual(fake_ids, ret_ids)
|
self.assertEqual(fake_ids, ret_ids)
|
||||||
|
|
||||||
def test_is_accessible_for_admin(self):
|
def test_is_accessible_for_admin(self):
|
||||||
ctx = mock.Mock(is_admin=True, tenant_id='we_dont_care')
|
ctx = mock.Mock(is_admin=True, project_id='we_dont_care')
|
||||||
self.assertTrue(self._test_class.is_accessible(ctx, None))
|
self.assertTrue(self._test_class.is_accessible(ctx, None))
|
||||||
|
|
||||||
def test_is_accessible_for_db_object_owner(self):
|
def test_is_accessible_for_db_object_owner(self):
|
||||||
ctx = mock.Mock(is_admin=False, tenant_id='db_object_owner')
|
ctx = mock.Mock(is_admin=False, project_id='db_object_owner')
|
||||||
db_obj = mock.Mock(tenant_id=ctx.tenant_id)
|
db_obj = mock.Mock(project_id=ctx.project_id)
|
||||||
|
|
||||||
self.assertTrue(self._test_class.is_accessible(ctx, db_obj))
|
self.assertTrue(self._test_class.is_accessible(ctx, db_obj))
|
||||||
|
|
||||||
@mock.patch.object(_test_class, 'is_shared_with_tenant', return_value=True)
|
@mock.patch.object(_test_class, 'is_shared_with_project',
|
||||||
def test_is_accessible_if_shared_with_tenant(self, mock_is_shared):
|
return_value=True)
|
||||||
ctx = mock.Mock(is_admin=False, tenant_id='db_object_shareholder')
|
def test_is_accessible_if_shared_with_project(self, mock_is_shared):
|
||||||
db_obj = mock.Mock(tenant_id='db_object_owner')
|
ctx = mock.Mock(is_admin=False, project_id='db_object_shareholder')
|
||||||
|
db_obj = mock.Mock(project_id='db_object_owner')
|
||||||
|
|
||||||
self.assertTrue(self._test_class.is_accessible(ctx, db_obj))
|
self.assertTrue(self._test_class.is_accessible(ctx, db_obj))
|
||||||
mock_is_shared.assert_called_once_with(
|
mock_is_shared.assert_called_once_with(
|
||||||
mock.ANY, db_obj.id, ctx.tenant_id)
|
mock.ANY, db_obj.id, ctx.project_id)
|
||||||
|
|
||||||
@mock.patch.object(_test_class, 'is_shared_with_tenant',
|
@mock.patch.object(_test_class, 'is_shared_with_project',
|
||||||
return_value=False)
|
return_value=False)
|
||||||
def test_is_accessible_fails_for_unauthorized_tenant(self, mock_is_shared):
|
def test_is_accessible_fails_for_unauthorized_project(self,
|
||||||
ctx = mock.Mock(is_admin=False, tenant_id='Billy_the_kid')
|
mock_is_shared):
|
||||||
db_obj = mock.Mock(tenant_id='db_object_owner')
|
ctx = mock.Mock(is_admin=False, project_id='Billy_the_kid')
|
||||||
|
db_obj = mock.Mock(project_id='db_object_owner')
|
||||||
|
|
||||||
self.assertFalse(self._test_class.is_accessible(ctx, db_obj))
|
self.assertFalse(self._test_class.is_accessible(ctx, db_obj))
|
||||||
mock_is_shared.assert_called_once_with(
|
mock_is_shared.assert_called_once_with(
|
||||||
mock.ANY, db_obj.id, ctx.tenant_id)
|
mock.ANY, db_obj.id, ctx.project_id)
|
||||||
|
|
||||||
def _rbac_policy_generate_change_events(self, resource, trigger,
|
def _rbac_policy_generate_change_events(self, resource, trigger,
|
||||||
context, object_type, policy,
|
context, object_type, policy,
|
||||||
|
@ -151,10 +153,10 @@ class RbacNeutronDbObjectTestCase(test_rbac.RBACBaseObjectIfaceTestCase,
|
||||||
|
|
||||||
@mock.patch.object(_test_class, 'validate_rbac_policy_update')
|
@mock.patch.object(_test_class, 'validate_rbac_policy_update')
|
||||||
@mock.patch.object(obj_db_api, 'get_object',
|
@mock.patch.object(obj_db_api, 'get_object',
|
||||||
return_value={'tenant_id': 'tyrion_lannister'})
|
return_value={'project_id': 'tyrion_lannister'})
|
||||||
def test_validate_rbac_policy_change_allowed_for_admin_or_owner(
|
def test_validate_rbac_policy_change_allowed_for_admin_or_owner(
|
||||||
self, mock_get_object, mock_validate_update):
|
self, mock_get_object, mock_validate_update):
|
||||||
context = mock.Mock(is_admin=True, tenant_id='db_obj_owner_id')
|
context = mock.Mock(is_admin=True, project_id='db_obj_owner_id')
|
||||||
self._rbac_policy_generate_change_events(
|
self._rbac_policy_generate_change_events(
|
||||||
resource=None, trigger='dummy_trigger', context=context,
|
resource=None, trigger='dummy_trigger', context=context,
|
||||||
object_type=self._test_class.rbac_db_cls.db_model.object_type,
|
object_type=self._test_class.rbac_db_cls.db_model.object_type,
|
||||||
|
@ -165,10 +167,10 @@ class RbacNeutronDbObjectTestCase(test_rbac.RBACBaseObjectIfaceTestCase,
|
||||||
|
|
||||||
@mock.patch.object(_test_class, 'validate_rbac_policy_update')
|
@mock.patch.object(_test_class, 'validate_rbac_policy_update')
|
||||||
@mock.patch.object(obj_db_api, 'get_object',
|
@mock.patch.object(obj_db_api, 'get_object',
|
||||||
return_value={'tenant_id': 'king_beyond_the_wall'})
|
return_value={'project_id': 'king_beyond_the_wall'})
|
||||||
def test_validate_rbac_policy_change_forbidden_for_outsiders(
|
def test_validate_rbac_policy_change_forbidden_for_outsiders(
|
||||||
self, mock_get_object, mock_validate_update):
|
self, mock_get_object, mock_validate_update):
|
||||||
context = mock.Mock(is_admin=False, tenant_id='db_obj_owner_id')
|
context = mock.Mock(is_admin=False, project_id='db_obj_owner_id')
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
n_exc.InvalidInput,
|
n_exc.InvalidInput,
|
||||||
self._rbac_policy_generate_change_events,
|
self._rbac_policy_generate_change_events,
|
||||||
|
@ -200,20 +202,20 @@ class RbacNeutronDbObjectTestCase(test_rbac.RBACBaseObjectIfaceTestCase,
|
||||||
def test_validate_rbac_policy_delete_skips_db_object_owner(self,
|
def test_validate_rbac_policy_delete_skips_db_object_owner(self,
|
||||||
mock_get_object):
|
mock_get_object):
|
||||||
policy = {'action': rbac_db_models.ACCESS_SHARED,
|
policy = {'action': rbac_db_models.ACCESS_SHARED,
|
||||||
'target_tenant': 'fake_tenant_id',
|
'target_tenant': 'fake_project_id',
|
||||||
'object_id': 'fake_obj_id',
|
'object_id': 'fake_obj_id',
|
||||||
'tenant_id': 'fake_tenant_id'}
|
'project_id': 'fake_project_id'}
|
||||||
mock_get_object.return_value.tenant_id = policy['target_tenant']
|
mock_get_object.return_value.project_id = policy['target_tenant']
|
||||||
self._test_validate_rbac_policy_delete_handles_policy(policy)
|
self._test_validate_rbac_policy_delete_handles_policy(policy)
|
||||||
|
|
||||||
@mock.patch.object(obj_db_api, 'get_object')
|
@mock.patch.object(obj_db_api, 'get_object')
|
||||||
@mock.patch.object(_test_class, 'get_bound_tenant_ids',
|
@mock.patch.object(_test_class, 'get_bound_project_ids',
|
||||||
return_value='tenant_id_shared_with')
|
return_value='project_id_shared_with')
|
||||||
def test_validate_rbac_policy_delete_fails_single_tenant_and_in_use(
|
def test_validate_rbac_policy_delete_fails_single_project_and_in_use(
|
||||||
self, get_bound_tenant_ids_mock, mock_get_object):
|
self, get_bound_project_ids_mock, mock_get_object):
|
||||||
policy = {'action': rbac_db_models.ACCESS_SHARED,
|
policy = {'action': rbac_db_models.ACCESS_SHARED,
|
||||||
'target_tenant': 'tenant_id_shared_with',
|
'target_tenant': 'project_id_shared_with',
|
||||||
'tenant_id': 'object_owner_tenant_id',
|
'project_id': 'object_owner_project_id',
|
||||||
'object_id': 'fake_obj_id'}
|
'object_id': 'fake_obj_id'}
|
||||||
context = mock.Mock()
|
context = mock.Mock()
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
|
@ -235,16 +237,16 @@ class RbacNeutronDbObjectTestCase(test_rbac.RBACBaseObjectIfaceTestCase,
|
||||||
trigger='dummy_trigger',
|
trigger='dummy_trigger',
|
||||||
payload=payload)
|
payload=payload)
|
||||||
|
|
||||||
def test_validate_rbac_policy_delete_not_bound_tenant_success(self):
|
def test_validate_rbac_policy_delete_not_bound_project_success(self):
|
||||||
context = mock.Mock()
|
context = mock.Mock()
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
self._test_class, 'get_bound_tenant_ids',
|
self._test_class, 'get_bound_project_ids',
|
||||||
return_value={'fake_tid2', 'fake_tid3'}), \
|
return_value={'fake_tid2', 'fake_tid3'}), \
|
||||||
mock.patch.object(self._test_class,
|
mock.patch.object(self._test_class,
|
||||||
'_get_db_obj_rbac_entries') as get_rbac_entries_mock, \
|
'_get_db_obj_rbac_entries') as get_rbac_entries_mock, \
|
||||||
mock.patch.object(
|
mock.patch.object(
|
||||||
self._test_class,
|
self._test_class,
|
||||||
'_get_tenants_with_shared_access_to_db_obj') as sh_tids:
|
'_get_projects_with_shared_access_to_db_obj') as sh_tids:
|
||||||
get_rbac_entries_mock.filter.return_value.count.return_value = 0
|
get_rbac_entries_mock.filter.return_value.count.return_value = 0
|
||||||
self._test_class._validate_rbac_policy_delete(
|
self._test_class._validate_rbac_policy_delete(
|
||||||
context=context,
|
context=context,
|
||||||
|
@ -254,16 +256,16 @@ class RbacNeutronDbObjectTestCase(test_rbac.RBACBaseObjectIfaceTestCase,
|
||||||
|
|
||||||
@mock.patch.object(_test_class, '_get_db_obj_rbac_entries')
|
@mock.patch.object(_test_class, '_get_db_obj_rbac_entries')
|
||||||
@mock.patch.object(_test_class,
|
@mock.patch.object(_test_class,
|
||||||
'_get_tenants_with_shared_access_to_db_obj',
|
'_get_projects_with_shared_access_to_db_obj',
|
||||||
return_value=['some_other_tenant'])
|
return_value=['some_other_project'])
|
||||||
@mock.patch.object(_test_class, 'get_bound_tenant_ids',
|
@mock.patch.object(_test_class, 'get_bound_project_ids',
|
||||||
return_value={'fake_id1'})
|
return_value={'fake_id1'})
|
||||||
def test_validate_rbac_policy_delete_fails_single_used_wildcarded(
|
def test_validate_rbac_policy_delete_fails_single_used_wildcarded(
|
||||||
self, get_bound_tenant_ids_mock, mock_tenants_with_shared_access,
|
self, get_bound_project_ids_mock, mock_projects_with_shared_access,
|
||||||
_get_db_obj_rbac_entries_mock):
|
_get_db_obj_rbac_entries_mock):
|
||||||
policy = {'action': rbac_db_models.ACCESS_SHARED,
|
policy = {'action': rbac_db_models.ACCESS_SHARED,
|
||||||
'target_tenant': '*',
|
'target_tenant': '*',
|
||||||
'tenant_id': 'object_owner_tenant_id',
|
'project_id': 'object_owner_project_id',
|
||||||
'object_id': 'fake_obj_id'}
|
'object_id': 'fake_obj_id'}
|
||||||
context = mock.Mock()
|
context = mock.Mock()
|
||||||
payload = events.DBEventPayload(
|
payload = events.DBEventPayload(
|
||||||
|
@ -310,7 +312,7 @@ class RbacNeutronDbObjectTestCase(test_rbac.RBACBaseObjectIfaceTestCase,
|
||||||
target_tenant='*', action=rbac_db_models.ACCESS_SHARED)
|
target_tenant='*', action=rbac_db_models.ACCESS_SHARED)
|
||||||
|
|
||||||
attach_rbac_mock.assert_called_with(
|
attach_rbac_mock.assert_called_with(
|
||||||
obj_id, test_neutron_obj.obj_context.tenant_id)
|
obj_id, test_neutron_obj.obj_context.project_id)
|
||||||
|
|
||||||
def test_shared_field_false_without_context(self):
|
def test_shared_field_false_without_context(self):
|
||||||
test_neutron_obj = self._test_class()
|
test_neutron_obj = self._test_class()
|
||||||
|
@ -335,9 +337,9 @@ class RbacNeutronDbObjectTestCase(test_rbac.RBACBaseObjectIfaceTestCase,
|
||||||
@mock.patch.object(_test_class, 'create_rbac_policy')
|
@mock.patch.object(_test_class, 'create_rbac_policy')
|
||||||
def test_attach_rbac_returns_type(self, create_rbac_mock):
|
def test_attach_rbac_returns_type(self, create_rbac_mock):
|
||||||
obj_id = 'fake_obj_id'
|
obj_id = 'fake_obj_id'
|
||||||
tenant_id = 'fake_tenant_id'
|
project_id = 'fake_project_id'
|
||||||
target_tenant = 'fake_target_tenant'
|
target_tenant = 'fake_target_project'
|
||||||
self._test_class(mock.Mock()).attach_rbac(obj_id, tenant_id,
|
self._test_class(mock.Mock()).attach_rbac(obj_id, project_id,
|
||||||
target_tenant)
|
target_tenant)
|
||||||
rbac_pol = create_rbac_mock.call_args_list[0][0][1]['rbac_policy']
|
rbac_pol = create_rbac_mock.call_args_list[0][0][1]['rbac_policy']
|
||||||
self.assertEqual(rbac_pol['object_id'], obj_id)
|
self.assertEqual(rbac_pol['object_id'], obj_id)
|
||||||
|
|
|
@ -138,10 +138,10 @@ class SubnetObjectIfaceTestCase(obj_test_base.BaseObjectIfaceTestCase):
|
||||||
# which is not allowed in 'Iface' test classes.
|
# which is not allowed in 'Iface' test classes.
|
||||||
mock.patch.object(
|
mock.patch.object(
|
||||||
rbac_db.RbacNeutronDbObjectMixin,
|
rbac_db.RbacNeutronDbObjectMixin,
|
||||||
'is_shared_with_tenant', return_value=False).start()
|
'is_shared_with_project', return_value=False).start()
|
||||||
mock.patch.object(
|
mock.patch.object(
|
||||||
rbac_db.RbacNeutronDbObjectMixin,
|
rbac_db.RbacNeutronDbObjectMixin,
|
||||||
'get_shared_with_tenant').start()
|
'get_shared_with_project').start()
|
||||||
|
|
||||||
|
|
||||||
class SubnetDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
class SubnetDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||||
|
@ -192,7 +192,7 @@ class SubnetDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||||
|
|
||||||
obj = self._make_object(subnet_data)
|
obj = self._make_object(subnet_data)
|
||||||
# check if shared will be load by 'obj_load_attr' and using extra query
|
# check if shared will be load by 'obj_load_attr' and using extra query
|
||||||
# by RbacNeutronDbObjectMixin get_shared_with_tenant
|
# by RbacNeutronDbObjectMixin get_shared_with_project
|
||||||
self.assertTrue(obj.shared)
|
self.assertTrue(obj.shared)
|
||||||
obj.create()
|
obj.create()
|
||||||
# here the shared should be load by is_network_shared
|
# here the shared should be load by is_network_shared
|
||||||
|
|
|
@ -84,7 +84,7 @@ class SubnetPoolDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||||
@mock.patch.object(obj_db_api, 'get_object')
|
@mock.patch.object(obj_db_api, 'get_object')
|
||||||
def test_rbac_policy_create_no_address_scope(self, mock_get_object,
|
def test_rbac_policy_create_no_address_scope(self, mock_get_object,
|
||||||
mock_query_with_hooks):
|
mock_query_with_hooks):
|
||||||
context = mock.Mock(is_admin=False, tenant_id='db_obj_owner_id')
|
context = mock.Mock(is_admin=False, project_id='db_obj_owner_id')
|
||||||
payload = mock.Mock(
|
payload = mock.Mock(
|
||||||
context=context, request_body=dict(object_id="fake_id")
|
context=context, request_body=dict(object_id="fake_id")
|
||||||
)
|
)
|
||||||
|
@ -114,8 +114,8 @@ class SubnetPoolDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||||
@mock.patch.object(obj_db_api, 'get_object')
|
@mock.patch.object(obj_db_api, 'get_object')
|
||||||
def test_rbac_policy_create_no_matching_policies(self, mock_get_object,
|
def test_rbac_policy_create_no_matching_policies(self, mock_get_object,
|
||||||
mock_query_with_hooks):
|
mock_query_with_hooks):
|
||||||
context = mock.Mock(is_admin=False, tenant_id='db_obj_owner_id')
|
context = mock.Mock(is_admin=False, project_id='db_obj_owner_id')
|
||||||
fake_project_id = "fake_target_tenant_id"
|
fake_project_id = "fake_target_project_id"
|
||||||
payload = mock.Mock(
|
payload = mock.Mock(
|
||||||
context=context, request_body=dict(
|
context=context, request_body=dict(
|
||||||
object_id="fake_id",
|
object_id="fake_id",
|
||||||
|
@ -146,8 +146,8 @@ class SubnetPoolDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||||
@mock.patch.object(obj_db_api, 'get_object')
|
@mock.patch.object(obj_db_api, 'get_object')
|
||||||
def test_rbac_policy_create_valid(self, mock_get_object,
|
def test_rbac_policy_create_valid(self, mock_get_object,
|
||||||
mock_query_with_hooks):
|
mock_query_with_hooks):
|
||||||
context = mock.Mock(is_admin=False, tenant_id='db_obj_owner_id')
|
context = mock.Mock(is_admin=False, project_id='db_obj_owner_id')
|
||||||
fake_project_id = "fake_target_tenant_id"
|
fake_project_id = "fake_target_project_id"
|
||||||
payload = mock.Mock(
|
payload = mock.Mock(
|
||||||
context=context, request_body=dict(
|
context=context, request_body=dict(
|
||||||
object_id="fake_id",
|
object_id="fake_id",
|
||||||
|
|
Loading…
Reference in New Issue