neutron/neutron/objects/rbac.py
Rodolfo Alonso Hernandez eeb918e1b9 Add the corresponding DB context to all SQL transactions
The goal of this patch is to make the Neutron code compliant
with SQLAlchemy 2.0.

All SQL transactions must be executed inside an explicit
writer/reader context. SQLAlchemy no longer will create an
implicit transaction if the session has no active transaction.

A warning message, only available in debug mode, is added. When
an ORM session calls "do_orm_execute", if there is no active
transaction, a warning message with a traceback will be logged
to help to debug the regression introduced.

Related-Bug: #1964575

Change-Id: I3da37fee205b8d67d10673075b9130147d9eab5f
2022-04-08 09:09:54 +00:00

67 lines
2.4 KiB
Python

# Copyright 2018 Red Hat, 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.
import abc
from neutron_lib.db import api as db_api
from neutron_lib.objects import common_types
from oslo_utils import versionutils
from oslo_versionedobjects import fields as obj_fields
from sqlalchemy import and_
from neutron.objects import base
class RBACBaseObject(base.NeutronDbObject, metaclass=abc.ABCMeta):
# Version 1.0: Initial version
# Version 1.1: Changed 'target_tenant' to 'target_project'
VERSION = '1.1'
fields = {
'id': common_types.UUIDField(),
'project_id': obj_fields.StringField(),
'object_id': common_types.UUIDField(),
'target_project': obj_fields.StringField(),
'action': obj_fields.StringField(),
}
fields_no_update = ['id', 'project_id', 'object_id']
@classmethod
@db_api.CONTEXT_READER
def get_projects(cls, context, object_id=None, action=None,
target_project=None):
clauses = []
if object_id:
clauses.append(cls.db_model.object_id == object_id)
if action:
clauses.append(cls.db_model.action == action)
if target_project:
clauses.append(cls.db_model.target_project == target_project)
query = context.session.query(cls.db_model.target_project)
if clauses:
query = query.filter(and_(*clauses))
return [data[0] for data in query]
@classmethod
def get_type_class_map(cls):
return {klass.db_model.object_type: klass
for klass in cls.__subclasses__()}
def obj_make_compatible(self, primitive, target_version):
_target_version = versionutils.convert_version_to_tuple(target_version)
if _target_version < (1, 1): # NOTE(ralonsoh): remove in Yoga + 4.
primitive['target_tenant'] = primitive.pop('target_project')