Load cyborg-api app with paste_deploy

Change-Id: I3976d05f737e09ceb88c40f65b445bad0b096516
Story: 2002121
Task: 19800
This commit is contained in:
wangzh21 2018-05-29 20:46:00 +08:00
parent 07a273e70d
commit cc9da9a944
8 changed files with 66 additions and 29 deletions

View File

@ -13,13 +13,21 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
import pecan
from oslo_config import cfg
from oslo_log import log
from paste import deploy
from cyborg.api import config
from cyborg.api import hooks
from cyborg.api import middleware
import cyborg.conf
CONF = cyborg.conf.CONF
LOG = log.getLogger(__name__)
def get_pecan_config():
@ -29,6 +37,9 @@ def get_pecan_config():
def setup_app(pecan_config=None, extra_hooks=None):
if not pecan_config:
pecan_config = get_pecan_config()
app_hooks = [hooks.ConfigHook(),
hooks.ConductorAPIHook(),
hooks.ContextHook(pecan_config.app.acl_public_routes),
@ -36,31 +47,31 @@ def setup_app(pecan_config=None, extra_hooks=None):
if extra_hooks:
app_hooks.extend(extra_hooks)
if not pecan_config:
pecan_config = get_pecan_config()
pecan.configuration.set_config(dict(pecan_config), overwrite=True)
app_conf = dict(pecan_config.app)
app = pecan.make_app(
pecan_config.app.root,
static_root=pecan_config.app.static_root,
debug=False,
app_conf.pop('root'),
force_canonical=getattr(pecan_config.app, 'force_canonical', True),
hooks=app_hooks,
wrap_app=middleware.ParsableErrorMiddleware
wrap_app=middleware.ParsableErrorMiddleware,
**app_conf
)
app = middleware.AuthTokenMiddleware(
app, dict(cfg.CONF),
public_api_routes=pecan_config.app.acl_public_routes)
return app
class VersionSelectorApplication(object):
def __init__(self):
pc = get_pecan_config()
self.v1 = setup_app(pecan_config=pc)
def load_app():
cfg_file = None
cfg_path = CONF.api.api_paste_config
if not os.path.isabs(cfg_path):
cfg_file = CONF.find_file(cfg_path)
elif os.path.exists(cfg_path):
cfg_file = cfg_path
def __call__(self, environ, start_response):
return self.v1(environ, start_response)
if not cfg_file:
raise cfg.ConfigFilesNotFoundError([CONF.api.api_paste_config])
LOG.info("Full WSGI config used: %s", cfg_file)
return deploy.loadapp("config:" + cfg_file)
def app_factory(global_config, **local_conf):
return setup_app()

View File

@ -92,12 +92,3 @@ class ContextHook(hooks.PecanHook):
is_admin = policy.authorize('is_admin', creds, creds)
state.request.context = context.RequestContext(
is_admin=is_admin, **creds)
def after(self, state):
if state.request.context == {}:
# An incorrect url path will not create RequestContext
return
# RequestContext will generate a request_id if no one
# passing outside, so it always contain a request_id.
request_id = state.request.context.request_id
state.response.headers['Openstack-Request-Id'] = request_id

View File

@ -62,3 +62,13 @@ class AuthTokenMiddleware(auth_token.AuthProtocol):
return self.app(env, start_response)
return super(AuthTokenMiddleware, self).__call__(env, start_response)
@classmethod
def factory(cls, global_config, **local_conf):
public_routes = local_conf.get('acl_public_routes', '')
public_api_routes = [path.strip() for path in public_routes.split(',')]
def _factory(app):
return cls(app, global_config, public_api_routes=public_api_routes)
return _factory

View File

@ -103,7 +103,7 @@ class WSGIService(service.ServiceBase):
:returns: None
"""
self.name = name
self.app = app.VersionSelectorApplication()
self.app = app.load_app()
self.workers = (CONF.api.api_workers or
processutils.get_worker_count())
if self.workers and self.workers < 1:

View File

@ -45,6 +45,9 @@ opts = [
"host URL. If the API is operating behind a proxy, you "
"will want to change this to represent the proxy's URL. "
"Defaults to None.")),
cfg.StrOpt('api_paste_config',
default="api-paste.ini",
help="Configuration file for WSGI definition of API."),
]
opt_group = cfg.OptGroup(name='api',

View File

@ -37,6 +37,7 @@ CYBORG_STATE_PATH=/var/lib/cyborg
CYBORG_AUTH_CACHE_DIR=${CYBORG_AUTH_CACHE_DIR:-/var/cache/cyborg}
CYBORG_CONF_DIR=${CYBORG_CONF_DIR:-/etc/cyborg}
CYBORG_CONF_FILE=$CYBORG_CONF_DIR/cyborg.conf
CYBORG_API_PASTE_INI=$CYBORG_CONF_DIR/api-paste.ini
CYBORG_ROOTWRAP_CONF=$CYBORG_CONF_DIR/rootwrap.conf
CYBORG_POLICY_JSON=$CYBORG_CONF_DIR/policy.json
CYBORG_SERVICE_HOST=${CYBORG_SERVICE_HOST:-$SERVICE_HOST}
@ -173,6 +174,7 @@ function configure_cyborg_conductor {
sudo cp $CYBORG_DIR/etc/cyborg/rootwrap.conf $CYBORG_ROOTWRAP_CONF
sudo cp -r $CYBORG_DIR/etc/cyborg/rootwrap.d $CYBORG_CONF_DIR
sudo cp -p $CYBORG_DIR/etc/cyborg/api-paste.ini $CYBORG_API_PASTE_INI
local cyborg_rootwrap
cyborg_rootwrap=$(get_rootwrap_location cyborg)
local rootwrap_isudoer_cmd="$cyborg_rootwrap $CYBORG_CONF_DIR/rootwrap.conf *"

19
etc/cyborg/api-paste.ini Normal file
View File

@ -0,0 +1,19 @@
[pipeline:main]
pipeline = cors request_id authtoken api_v1
[app:api_v1]
paste.app_factory = cyborg.api.app:app_factory
[filter:authtoken]
acl_public_routes = /, /v1
paste.filter_factory = cyborg.api.middleware.auth_token:AuthTokenMiddleware.factory
[filter:osprofiler]
paste.filter_factory = cyborg.common.profiler:WsgiMiddleware.factory
[filter:request_id]
paste.filter_factory = oslo_middleware:RequestId.factory
[filter:cors]
paste.filter_factory = oslo_middleware.cors:filter_factory
oslo_config_project = cyborg

View File

@ -26,6 +26,7 @@ data_files =
etc/cyborg =
etc/cyborg/rootwrap.conf
etc/cyborg/policy.json
etc/cyborg/api-paste.ini
etc/cyborg/rootwrap.d =
etc/cyborg/rootwrap.d/*