
Although the Climate project was renamed to Blazar in 2014, the code has still been using the climate namespace. This patch moves all code to the blazar directory and allows users and operators to use the 'blazar' command namespace. The 'climate' namespace remains O release to allow users of Blazar time to move their own code to the blazar namespace, but will be removed in P release development cycle. Change-Id: Icbe6fab1051aae4ac819982a1fa4f323cb0bf2d0 Partial-Bug: #1662734
108 lines
3.0 KiB
Python
108 lines
3.0 KiB
Python
# Copyright (c) 2013 Mirantis Inc.
|
|
#
|
|
# 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 threading
|
|
|
|
|
|
class BaseContext(object):
|
|
|
|
_elements = set()
|
|
_context_stack = threading.local()
|
|
|
|
def __init__(self, __mapping=None, **kwargs):
|
|
if __mapping is None:
|
|
self.__values = dict(**kwargs)
|
|
else:
|
|
if isinstance(__mapping, BaseContext):
|
|
__mapping = __mapping.__values
|
|
self.__values = dict(__mapping)
|
|
self.__values.update(**kwargs)
|
|
bad_keys = set(self.__values) - self._elements
|
|
if bad_keys:
|
|
raise TypeError("Only %s keys are supported. %s given" %
|
|
(tuple(self._elements), tuple(bad_keys)))
|
|
|
|
def __getattr__(self, name):
|
|
try:
|
|
return self.__values[name]
|
|
except KeyError:
|
|
if name in self._elements:
|
|
return None
|
|
else:
|
|
raise AttributeError(name)
|
|
|
|
def __setattr__(self, name, value):
|
|
# NOTE(yorik-sar): only the very first assignment for __values is
|
|
# allowed. All context arguments should be set at the time the context
|
|
# object is being created.
|
|
if not self.__dict__:
|
|
super(BaseContext, self).__setattr__(name, value)
|
|
else:
|
|
raise Exception(self.__dict__, name, value)
|
|
|
|
def __enter__(self):
|
|
try:
|
|
stack = self._context_stack.stack
|
|
except AttributeError:
|
|
stack = []
|
|
self._context_stack.stack = stack
|
|
stack.append(self)
|
|
return self
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
res = self._context_stack.stack.pop()
|
|
assert res is self, "self should be the top element of the stack"
|
|
|
|
@classmethod
|
|
def current(cls):
|
|
try:
|
|
return cls._context_stack.stack[-1]
|
|
except (AttributeError, IndexError):
|
|
raise RuntimeError("Context isn't available here")
|
|
|
|
# NOTE(yorik-sar): as long as oslo.rpc requires this
|
|
def to_dict(self):
|
|
return self.__values
|
|
|
|
|
|
class BlazarContext(BaseContext):
|
|
|
|
_elements = set([
|
|
"user_id",
|
|
"project_id",
|
|
"auth_token",
|
|
"service_catalog",
|
|
"user_name",
|
|
"project_name",
|
|
"roles",
|
|
"is_admin",
|
|
])
|
|
|
|
@classmethod
|
|
def elevated(cls):
|
|
try:
|
|
ctx = cls.current()
|
|
except RuntimeError:
|
|
ctx = None
|
|
return cls(ctx, is_admin=True)
|
|
|
|
|
|
def current():
|
|
return BlazarContext.current()
|
|
|
|
|
|
def elevated():
|
|
return BlazarContext.elevated()
|