115 lines
3.7 KiB
Python
115 lines
3.7 KiB
Python
# Copyright (c) 2015 Huawei Tech. Co., Ltd.
|
|
# Copyright (c) 2017-2022 Wind River Systems, 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 pecan import expose
|
|
from pecan import request
|
|
import six
|
|
|
|
import dcmanager.common.context as k_context
|
|
|
|
|
|
def extract_context_from_environ():
|
|
context_paras = {'auth_token': 'HTTP_X_AUTH_TOKEN',
|
|
'user': 'HTTP_X_USER_ID',
|
|
'project': 'HTTP_X_TENANT_ID',
|
|
'user_name': 'HTTP_X_USER_NAME',
|
|
'tenant_name': 'HTTP_X_PROJECT_NAME',
|
|
'domain': 'HTTP_X_DOMAIN_ID',
|
|
'roles': 'HTTP_X_ROLE',
|
|
'user_domain': 'HTTP_X_USER_DOMAIN_ID',
|
|
'project_domain': 'HTTP_X_PROJECT_DOMAIN_ID',
|
|
'request_id': 'openstack.request_id'}
|
|
|
|
environ = request.environ
|
|
|
|
for key, val in context_paras.items():
|
|
context_paras[key] = environ.get(val)
|
|
role = environ.get('HTTP_X_ROLE')
|
|
|
|
context_paras['is_admin'] = 'admin' in role.split(',')
|
|
return k_context.RequestContext(**context_paras)
|
|
|
|
|
|
def extract_credentials_for_policy():
|
|
context_paras = {'project_name': 'HTTP_X_PROJECT_NAME',
|
|
'roles': 'HTTP_X_ROLE'}
|
|
environ = request.environ
|
|
for key, val in context_paras.items():
|
|
context_paras[key] = environ.get(val)
|
|
context_paras['roles'] = context_paras['roles'].split(',')
|
|
return context_paras
|
|
|
|
|
|
def _get_pecan_data(obj):
|
|
return getattr(obj, "_pecan", {})
|
|
|
|
|
|
def _is_exposed(obj):
|
|
return getattr(obj, "exposed", False)
|
|
|
|
|
|
def _is_generic(obj):
|
|
data = _get_pecan_data(obj)
|
|
return "generic" in data.keys()
|
|
|
|
|
|
def _is_generic_handler(obj):
|
|
data = _get_pecan_data(obj)
|
|
return "generic_handler" in data.keys()
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class GenericPathController(object):
|
|
"""A controller that allows path parameters to be equal to handler names.
|
|
|
|
The _route method provides a custom route resolution that checks if the
|
|
next object is marked as generic or a generic handler, pointing to the
|
|
generic index method in case it is. Pecan will properly handle the rest
|
|
of the routing process by redirecting it to the proper method function
|
|
handler (GET, POST, PATCH, DELETE, etc.).
|
|
|
|
Useful when part of the URL contains path parameters that might have
|
|
the same name as an already defined exposed controller method.
|
|
|
|
Requires the definition of an index method with the generator:
|
|
@expose(generic=True, ...)
|
|
|
|
Does not support nested subcontrollers.
|
|
"""
|
|
|
|
RESERVED_NAMES = ("_route", "_default", "_lookup")
|
|
|
|
@abc.abstractmethod
|
|
def index(self):
|
|
pass
|
|
|
|
@expose()
|
|
def _route(self, remainder, request):
|
|
next_url_part, rest = remainder[0], remainder[1:]
|
|
next_obj = getattr(self, next_url_part, None)
|
|
|
|
is_generic = _is_generic(next_obj) or _is_generic_handler(next_obj)
|
|
is_reserved_name = next_url_part in self.__class__.RESERVED_NAMES
|
|
|
|
if _is_exposed(next_obj) and not is_generic and not is_reserved_name:
|
|
# A non-generic exposed method with a non-reserved name
|
|
return next_obj, rest
|
|
else:
|
|
return self.index, remainder
|