"""RequestContext: context for requests that persist through all of cinder."""
import copy
-import uuid
from oslo.utils import timeutils
from cinder.i18n import _
+from cinder.openstack.common import context
from cinder.openstack.common import local
from cinder.openstack.common import log as logging
from cinder import policy
LOG = logging.getLogger(__name__)
-def generate_request_id():
- return 'req-' + str(uuid.uuid4())
-
-
-class RequestContext(object):
+class RequestContext(context.RequestContext):
"""Security context and request information.
Represents the user taking a given action within the system.
"""
- user_idt_format = '{user} {tenant} {domain} {user_domain} {p_domain}'
-
def __init__(self, user_id, project_id, is_admin=None, read_deleted="no",
roles=None, project_name=None, remote_address=None,
timestamp=None, request_id=None, auth_token=None,
because they possibly came in from older rpc messages.
"""
- self.user_id = user_id
- self.project_id = project_id
- self.domain = domain
- self.user_domain = user_domain
- self.project_domain = project_domain
+ super(RequestContext, self).__init__(auth_token=auth_token,
+ user=user_id,
+ tenant=project_id,
+ domain=domain,
+ user_domain=user_domain,
+ project_domain=project_domain,
+ is_admin=is_admin,
+ request_id=request_id)
self.roles = roles or []
self.project_name = project_name
- self.is_admin = is_admin
if self.is_admin is None:
self.is_admin = policy.check_is_admin(self.roles)
elif self.is_admin and 'admin' not in self.roles:
if isinstance(timestamp, basestring):
timestamp = timeutils.parse_strtime(timestamp)
self.timestamp = timestamp
- if not request_id:
- request_id = generate_request_id()
- self.request_id = request_id
- self.auth_token = auth_token
self.quota_class = quota_class
if overwrite or not hasattr(local.store, 'context'):
self.update_store()
local.store.context = self
def to_dict(self):
- user_idt = (
- self.user_idt_format.format(user=self.user or '-',
- tenant=self.tenant or '-',
- domain=self.domain or '-',
- user_domain=self.user_domain or '-',
- p_domain=self.project_domain or '-'))
-
- return {'user_id': self.user_id,
- 'project_id': self.project_id,
- 'project_name': self.project_name,
- 'domain': self.domain,
- 'user_domain': self.user_domain,
- 'project_domain': self.project_domain,
- 'is_admin': self.is_admin,
- 'read_deleted': self.read_deleted,
- 'roles': self.roles,
- 'remote_address': self.remote_address,
- 'timestamp': timeutils.strtime(self.timestamp),
- 'request_id': self.request_id,
- 'auth_token': self.auth_token,
- 'quota_class': self.quota_class,
- 'service_catalog': self.service_catalog,
- 'tenant': self.tenant,
- 'user': self.user,
- 'user_identity': user_idt}
+ default = super(RequestContext, self).to_dict()
+ extra = {'user_id': self.user_id,
+ 'project_id': self.project_id,
+ 'project_name': self.project_name,
+ 'domain': self.domain,
+ 'read_deleted': self.read_deleted,
+ 'roles': self.roles,
+ 'remote_address': self.remote_address,
+ 'timestamp': timeutils.strtime(self.timestamp),
+ 'quota_class': self.quota_class,
+ 'service_catalog': self.service_catalog}
+ return dict(default.items() + extra.items())
@classmethod
def from_dict(cls, values):
return copy.deepcopy(self)
# NOTE(sirp): the openstack/common version of RequestContext uses
- # tenant/user whereas the Cinder version uses project_id/user_id. We need
- # this shim in order to use context-aware code from openstack/common, like
- # logging, until we make the switch to using openstack/common's version of
- # RequestContext.
+ # tenant/user whereas the Cinder version uses project_id/user_id.
+ # NOTE(adrienverge): The Cinder version of RequestContext now uses
+ # tenant/user internally, so it is compatible with context-aware code from
+ # openstack/common. We still need this shim for the rest of Cinder's
+ # code.
@property
- def tenant(self):
- return self.project_id
+ def project_id(self):
+ return self.tenant
+
+ @project_id.setter
+ def project_id(self, value):
+ self.tenant = value
@property
- def user(self):
- return self.user_id
+ def user_id(self):
+ return self.user
+
+ @user_id.setter
+ def user_id(self, value):
+ self.user = value
def get_admin_context(read_deleted="no"):
def generate_request_id():
- return 'req-%s' % str(uuid.uuid4())
+ return b'req-' + str(uuid.uuid4()).encode('ascii')
class RequestContext(object):
'instance_uuid': self.instance_uuid,
'user_identity': user_idt}
+ @classmethod
+ def from_dict(cls, ctx):
+ return cls(
+ auth_token=ctx.get("auth_token"),
+ user=ctx.get("user"),
+ tenant=ctx.get("tenant"),
+ domain=ctx.get("domain"),
+ user_domain=ctx.get("user_domain"),
+ project_domain=ctx.get("project_domain"),
+ is_admin=ctx.get("is_admin", False),
+ read_only=ctx.get("read_only", False),
+ show_deleted=ctx.get("show_deleted", False),
+ request_id=ctx.get("request_id"),
+ instance_uuid=ctx.get("instance_uuid"))
+
def get_admin_context(show_deleted=False):
context = RequestContext(None,
def is_user_context(context):
"""Indicates if the request context is a normal user."""
- if not context:
- return False
- if context.is_admin:
- return False
- if not context.user_id or not context.project_id:
+ if not context or context.is_admin:
return False
- return True
+ return context.user_id and context.project_id