Exemplo n.º 1
0
    def _validate_ext_not_in_use_by_tenant(self,
                                           resource,
                                           event,
                                           trigger,
                                           payload=None):
        object_type = payload.metadata.get('object_type')
        policy = payload.latest_state
        context = payload.context

        if (object_type != 'network'
                or policy['action'] != 'access_as_external'):
            return
        new_project = None
        if event == events.BEFORE_UPDATE:
            new_project = payload.request_body['target_project']
            if new_project == policy['target_project']:
                # nothing to validate if the tenant didn't change
                return

        gw_ports = port_obj.Port.get_gateway_port_ids_by_network(
            context, policy['object_id'])
        if policy['target_project'] != '*':
            filters = {
                'gw_port_id': gw_ports,
                'project_id': policy['target_project']
            }
            # if there is a wildcard entry we can safely proceed without the
            # router lookup because they will have access either way
            if net_obj.NetworkRBAC.count(context,
                                         object_id=policy['object_id'],
                                         action='access_as_external',
                                         target_project='*'):
                return
            router_exist = l3_obj.Router.objects_exist(context, **filters)
        else:
            # deleting the wildcard is okay as long as the tenants with
            # attached routers have their own entries and the network is
            # not the default external network.
            if net_obj.ExternalNetwork.objects_exist(
                    context, network_id=policy['object_id'], is_default=True):
                msg = _("Default external networks must be shared to "
                        "everyone.")
                raise rbac_ext.RbacPolicyInUse(object_id=policy['object_id'],
                                               details=msg)
            projects = net_obj.NetworkRBAC.get_projects(
                context,
                object_id=policy['object_id'],
                action='access_as_external')
            projects_with_entries = [
                project for project in projects if project != '*'
            ]
            if new_project:
                projects_with_entries.append(new_project)
            router_exist = l3_obj.Router.check_routers_not_owned_by_projects(
                context, gw_ports, projects_with_entries)
        if router_exist:
            msg = _("There are routers attached to this network that "
                    "depend on this policy for access.")
            raise rbac_ext.RbacPolicyInUse(object_id=policy['object_id'],
                                           details=msg)
Exemplo n.º 2
0
 def _validate_ext_not_in_use_by_tenant(self, resource, event, trigger,
                                        context, object_type, policy,
                                        **kwargs):
     if (object_type != 'network'
             or policy['action'] != 'access_as_external'):
         return
     new_project = None
     if event == events.BEFORE_UPDATE:
         new_project = kwargs['policy_update']['target_tenant']
         if new_project == policy['target_tenant']:
             # nothing to validate if the tenant didn't change
             return
     gw_ports = context.session.query(models_v2.Port.id).filter_by(
         device_owner=constants.DEVICE_OWNER_ROUTER_GW,
         network_id=policy['object_id'])
     gw_ports = [gw_port[0] for gw_port in gw_ports]
     rbac = rbac_db.NetworkRBAC
     if policy['target_tenant'] != '*':
         filters = {
             'gw_port_id': gw_ports,
             'project_id': policy['target_tenant']
         }
         # if there is a wildcard entry we can safely proceed without the
         # router lookup because they will have access either way
         if context.session.query(rbac_db.NetworkRBAC.object_id).filter(
                 rbac.object_id == policy['object_id'],
                 rbac.action == 'access_as_external',
                 rbac.target_tenant == '*').count():
             return
         router_exist = l3_obj.Router.objects_exist(context, **filters)
     else:
         # deleting the wildcard is okay as long as the tenants with
         # attached routers have their own entries and the network is
         # not the default external network.
         if net_obj.ExternalNetwork.objects_exist(
                 context, network_id=policy['object_id'], is_default=True):
             msg = _("Default external networks must be shared to "
                     "everyone.")
             raise rbac_ext.RbacPolicyInUse(object_id=policy['object_id'],
                                            details=msg)
         projects_with_entries = (context.session.query(
             rbac.target_tenant).filter(
                 rbac.object_id == policy['object_id'],
                 rbac.action == 'access_as_external',
                 rbac.target_tenant != '*'))
         projects_with_entries = [
             projects_with_entry[0]
             for projects_with_entry in projects_with_entries
         ]
         if new_project:
             projects_with_entries.append(new_project)
         router_exist = l3_obj.Router.check_routers_not_owned_by_projects(
             context, gw_ports, projects_with_entries)
     if router_exist:
         msg = _("There are routers attached to this network that "
                 "depend on this policy for access.")
         raise rbac_ext.RbacPolicyInUse(object_id=policy['object_id'],
                                        details=msg)
Exemplo n.º 3
0
 def _validate_ext_not_in_use_by_tenant(self, resource, event, trigger,
                                        context, object_type, policy,
                                        **kwargs):
     if (object_type != 'network' or
             policy['action'] != 'access_as_external'):
         return
     new_tenant = None
     if event == events.BEFORE_UPDATE:
         new_tenant = kwargs['policy_update']['target_tenant']
         if new_tenant == policy['target_tenant']:
             # nothing to validate if the tenant didn't change
             return
     ports = context.session.query(models_v2.Port.id).filter_by(
         device_owner=DEVICE_OWNER_ROUTER_GW,
         network_id=policy['object_id'])
     router = context.session.query(l3_models.Router).filter(
         l3_models.Router.gw_port_id.in_(ports))
     rbac = rbac_db.NetworkRBAC
     if policy['target_tenant'] != '*':
         router = router.filter(
             l3_models.Router.tenant_id == policy['target_tenant'])
         # if there is a wildcard entry we can safely proceed without the
         # router lookup because they will have access either way
         if context.session.query(rbac_db.NetworkRBAC).filter(
                 rbac.object_id == policy['object_id'],
                 rbac.action == 'access_as_external',
                 rbac.target_tenant == '*').count():
             return
     else:
         # deleting the wildcard is okay as long as the tenants with
         # attached routers have their own entries and the network is
         # not the default external network.
         is_default = context.session.query(
             ext_net_models.ExternalNetwork).filter_by(
                 network_id=policy['object_id'], is_default=True).count()
         if is_default:
             msg = _("Default external networks must be shared to "
                     "everyone.")
             raise rbac_ext.RbacPolicyInUse(object_id=policy['object_id'],
                                            details=msg)
         tenants_with_entries = (
             context.session.query(rbac.target_tenant).
             filter(rbac.object_id == policy['object_id'],
                    rbac.action == 'access_as_external',
                    rbac.target_tenant != '*'))
         router = router.filter(
             ~l3_models.Router.tenant_id.in_(tenants_with_entries))
         if new_tenant:
             # if this is an update we also need to ignore any router
             # interfaces that belong to the new target.
             router = router.filter(
                 l3_models.Router.tenant_id != new_tenant)
     if router.count():
         msg = _("There are routers attached to this network that "
                 "depend on this policy for access.")
         raise rbac_ext.RbacPolicyInUse(object_id=policy['object_id'],
                                        details=msg)
Exemplo n.º 4
0
 def delete_rbac_policy(self, context, id):
     entry = self._get_rbac_policy(context, id)
     object_type = entry['object_type']
     try:
         registry.notify(resources.RBAC_POLICY,
                         events.BEFORE_DELETE,
                         self,
                         context=context,
                         object_type=object_type,
                         policy=entry)
     except c_exc.CallbackFailure as ex:
         raise ext_rbac.RbacPolicyInUse(object_id=entry['object_id'],
                                        details=ex)
     # make a dict copy because deleting the entry will nullify its
     # object_id link to network
     entry_dict = dict(entry)
     with context.session.begin(subtransactions=True):
         context.session.delete(entry)
     registry.notify(resources.RBAC_POLICY,
                     events.AFTER_DELETE,
                     self,
                     context=context,
                     object_type=object_type,
                     policy=entry_dict)
     self.object_type_cache.pop(id, None)
Exemplo n.º 5
0
 def delete_rbac_policy(self, context, id):
     entry = self._get_rbac_policy(context, id)
     object_type = entry.db_model.object_type
     try:
         registry.publish(resources.RBAC_POLICY,
                          events.BEFORE_DELETE,
                          self,
                          payload=events.DBEventPayload(
                              context,
                              states=(entry, ),
                              resource_id=id,
                              metadata={'object_type': object_type}))
     except c_exc.CallbackFailure as ex:
         raise ext_rbac.RbacPolicyInUse(object_id=entry.object_id,
                                        details=ex)
     # make a dict copy because deleting the entry will nullify its
     # object_id link to network
     entry_dict = entry.to_dict()
     entry.delete()
     registry.publish(resources.RBAC_POLICY,
                      events.AFTER_DELETE,
                      self,
                      payload=events.DBEventPayload(
                          context,
                          states=(entry_dict, ),
                          resource_id=id,
                          metadata={'object_type': object_type}))
     self.object_type_cache.pop(id, None)
Exemplo n.º 6
0
 def delete_rbac_policy(self, context, id):
     entry = self._get_rbac_policy(context, id)
     object_type = entry['object_type']
     try:
         registry.notify(RBAC_POLICY, events.BEFORE_DELETE, self,
                         context=context, object_type=object_type,
                         policy=entry)
     except c_exc.CallbackFailure as ex:
         raise ext_rbac.RbacPolicyInUse(object_id=entry['object_id'],
                                        details=ex)
     with context.session.begin(subtransactions=True):
         context.session.delete(entry)
     self.object_type_cache.pop(id, None)
Exemplo n.º 7
0
 def update_rbac_policy(self, context, id, rbac_policy):
     pol = rbac_policy['rbac_policy']
     entry = self._get_rbac_policy(context, id)
     object_type = entry['object_type']
     try:
         registry.notify(RBAC_POLICY, events.BEFORE_UPDATE, self,
                         context=context, policy=entry,
                         object_type=object_type, policy_update=pol)
     except c_exc.CallbackFailure as ex:
         raise ext_rbac.RbacPolicyInUse(object_id=entry['object_id'],
                                        details=ex)
     with context.session.begin(subtransactions=True):
         entry.update(pol)
     return self._make_rbac_policy_dict(entry)
Exemplo n.º 8
0
 def update_rbac_policy(self, context, id, rbac_policy):
     pol = rbac_policy['rbac_policy']
     entry = self._get_rbac_policy(context, id)
     object_type = entry.db_model.object_type
     try:
         registry.notify(resources.RBAC_POLICY,
                         events.BEFORE_UPDATE,
                         self,
                         context=context,
                         policy=entry,
                         object_type=object_type,
                         policy_update=pol)
     except c_exc.CallbackFailure as ex:
         raise ext_rbac.RbacPolicyInUse(object_id=entry.object_id,
                                        details=ex)
     entry.update_fields(pol)
     entry.update()
     return self._make_rbac_policy_dict(entry)
Exemplo n.º 9
0
 def update_rbac_policy(self, context, id, rbac_policy):
     pol = rbac_policy['rbac_policy']
     entry = self._get_rbac_policy(context, id)
     object_type = entry.db_model.object_type
     try:
         registry.publish(resources.RBAC_POLICY,
                          events.BEFORE_UPDATE,
                          self,
                          payload=events.DBEventPayload(
                              context,
                              request_body=pol,
                              states=(entry, ),
                              resource_id=id,
                              metadata={'object_type': object_type}))
     except c_exc.CallbackFailure as ex:
         raise ext_rbac.RbacPolicyInUse(object_id=entry.object_id,
                                        details=ex)
     entry.update_fields(pol)
     entry.update()
     return self._make_rbac_policy_dict(entry)
Exemplo n.º 10
0
 def update_rbac_policy(self, context, id, rbac_policy):
     pol = rbac_policy['rbac_policy']
     # NOTE(ralonsoh): remove this conversion when "bp/keystone-v3" is
     # widely implemented in all OpenStack projects.
     try:
         pol['target_project'] = pol.pop('target_tenant')
     except KeyError:
         pass
     entry = self._get_rbac_policy(context, id)
     object_type = entry.db_model.object_type
     try:
         registry.publish(resources.RBAC_POLICY, events.BEFORE_UPDATE, self,
                          payload=events.DBEventPayload(
                              context, request_body=pol,
                              states=(entry,), resource_id=id,
                              metadata={'object_type': object_type}))
     except c_exc.CallbackFailure as ex:
         raise ext_rbac.RbacPolicyInUse(object_id=entry.object_id,
                                        details=ex)
     entry.update_fields(pol)
     entry.update()
     return self._make_rbac_policy_dict(entry)
Exemplo n.º 11
0
 def delete_rbac_policy(self, context, id):
     entry = self._get_rbac_policy(context, id)
     object_type = entry.db_model.object_type
     try:
         registry.notify(resources.RBAC_POLICY,
                         events.BEFORE_DELETE,
                         self,
                         context=context,
                         object_type=object_type,
                         policy=entry)
     except c_exc.CallbackFailure as ex:
         raise ext_rbac.RbacPolicyInUse(object_id=entry.object_id,
                                        details=ex)
     # make a dict copy because deleting the entry will nullify its
     # object_id link to network
     entry_dict = entry.to_dict()
     entry.delete()
     registry.notify(resources.RBAC_POLICY,
                     events.AFTER_DELETE,
                     self,
                     context=context,
                     object_type=object_type,
                     policy=entry_dict)
     self.object_type_cache.pop(id, None)
Exemplo n.º 12
0
 def raise_policy_in_use():
     raise ext_rbac.RbacPolicyInUse(
         object_id=obj_id, details='tenant_id={}'.format(target_tenant))