Add higgins-api command
Change-Id: Ic326d7bc06577d65cbf24ac247d1ebbc9ce79ec2 Implements: blueprint higgins-api
This commit is contained in:
parent
20d1e9d251
commit
53f7ec03f2
@ -9,17 +9,57 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
from higgins import model
|
|
||||||
from pecan import make_app
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log
|
||||||
|
import pecan
|
||||||
|
|
||||||
|
from higgins.api import config as api_config
|
||||||
|
from higgins.common.i18n import _
|
||||||
|
|
||||||
|
# Register options for the service
|
||||||
|
API_SERVICE_OPTS = [
|
||||||
|
cfg.PortOpt('port',
|
||||||
|
default=9512,
|
||||||
|
help='The port for the higgins API server.'),
|
||||||
|
cfg.IPOpt('host',
|
||||||
|
default='127.0.0.1',
|
||||||
|
help='The listen IP for the higgins API server.'),
|
||||||
|
cfg.BoolOpt('enable_ssl_api',
|
||||||
|
default=False,
|
||||||
|
help=_("Enable the integrated stand-alone API to service "
|
||||||
|
"requests via HTTPS instead of HTTP. If there is a "
|
||||||
|
"front-end service performing HTTPS offloading from "
|
||||||
|
"the service, this option should be False; note, you "
|
||||||
|
"will want to change public API endpoint to represent "
|
||||||
|
"SSL termination URL with 'public_endpoint' option.")),
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
opt_group = cfg.OptGroup(name='api',
|
||||||
|
title='Options for the higgins-api service')
|
||||||
|
CONF.register_group(opt_group)
|
||||||
|
CONF.register_opts(API_SERVICE_OPTS, opt_group)
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def setup_app(config):
|
def get_pecan_config():
|
||||||
|
# Set up the pecan configuration
|
||||||
|
filename = api_config.__file__.replace('.pyc', '.py')
|
||||||
|
return pecan.configuration.conf_from_file(filename)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_app(config=None):
|
||||||
|
if not config:
|
||||||
|
config = get_pecan_config()
|
||||||
|
|
||||||
model.init_model()
|
|
||||||
app_conf = dict(config.app)
|
app_conf = dict(config.app)
|
||||||
|
|
||||||
return make_app(
|
app = pecan.make_app(
|
||||||
app_conf.pop('root'),
|
app_conf.pop('root'),
|
||||||
logging=getattr(config, 'logging', {}),
|
logging=getattr(config, 'logging', {}),
|
||||||
**app_conf
|
**app_conf
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return app
|
||||||
|
@ -16,11 +16,11 @@ from higgins.api import hooks
|
|||||||
|
|
||||||
# Pecan Application Configurations
|
# Pecan Application Configurations
|
||||||
app = {
|
app = {
|
||||||
'root': 'higgins.controllers.root.RootController',
|
'root': 'higgins.api.controllers.root.RootController',
|
||||||
'modules': ['higgins'],
|
'modules': ['higgins'],
|
||||||
'hooks': [
|
'hooks': [
|
||||||
hooks.ContextHook(),
|
hooks.ContextHook(),
|
||||||
hooks.NoExceptionTracebackHook(),
|
hooks.NoExceptionTracebackHook(),
|
||||||
],
|
],
|
||||||
'debug': True,
|
'debug': False,
|
||||||
}
|
}
|
||||||
|
0
higgins/cmd/__init__.py
Normal file
0
higgins/cmd/__init__.py
Normal file
47
higgins/cmd/api.py
Normal file
47
higgins/cmd/api.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""The Higgins Service API."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
from higgins.common import service as higgins_service
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Parse config file and command line options, then start logging
|
||||||
|
higgins_service.prepare_service(sys.argv)
|
||||||
|
|
||||||
|
# Enable object backporting via the conductor
|
||||||
|
# TODO(yuanying): Uncomment after rpc services are implemented
|
||||||
|
# base.higginsObject.indirection_api = base.higginsObjectIndirectionAPI()
|
||||||
|
|
||||||
|
# Build and start the WSGI app
|
||||||
|
launcher = higgins_service.process_launcher()
|
||||||
|
server = higgins_service.WSGIService(
|
||||||
|
'higgins_api',
|
||||||
|
CONF.api.enable_ssl_api
|
||||||
|
)
|
||||||
|
launcher.launch_service(server, workers=server.workers)
|
||||||
|
launcher.wait()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
0
higgins/common/__init__.py
Normal file
0
higgins/common/__init__.py
Normal file
31
higgins/common/config.py
Normal file
31
higgins/common/config.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Copyright 2010 United States Government as represented by the
|
||||||
|
# Administrator of the National Aeronautics and Space Administration.
|
||||||
|
# All Rights Reserved.
|
||||||
|
# Copyright 2012 Red Hat, 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.
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
# from higgins.common import rpc
|
||||||
|
from higgins import version
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args(argv, default_config_files=None):
|
||||||
|
# TODO(yuanying): Uncomment after rpc is implemented
|
||||||
|
# rpc.set_defaults(control_exchange='higgins')
|
||||||
|
cfg.CONF(argv[1:],
|
||||||
|
project='higgins',
|
||||||
|
version=version.version_info.release_string(),
|
||||||
|
default_config_files=default_config_files)
|
||||||
|
# rpc.init(cfg.CONF)
|
@ -30,9 +30,9 @@ import pecan
|
|||||||
import six
|
import six
|
||||||
import wsme
|
import wsme
|
||||||
|
|
||||||
|
from higgins.common.i18n import _
|
||||||
|
from higgins.common.i18n import _LE
|
||||||
from higgins.common import safe_utils
|
from higgins.common import safe_utils
|
||||||
from higgins.i18n import _
|
|
||||||
from higgins.i18n import _LE
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -327,3 +327,7 @@ class PatchError(Invalid):
|
|||||||
class NotAuthorized(HigginsException):
|
class NotAuthorized(HigginsException):
|
||||||
message = _("Not authorized.")
|
message = _("Not authorized.")
|
||||||
code = 403
|
code = 403
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigInvalid(HigginsException):
|
||||||
|
message = _("Invalid configuration file. %(error_msg)s")
|
||||||
|
108
higgins/common/service.py
Normal file
108
higgins/common/service.py
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright © 2012 eNovance <licensing@enovance.com>
|
||||||
|
#
|
||||||
|
# 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 socket
|
||||||
|
|
||||||
|
from oslo_concurrency import processutils
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log
|
||||||
|
from oslo_service import service
|
||||||
|
from oslo_service import wsgi
|
||||||
|
|
||||||
|
from higgins.api import app
|
||||||
|
from higgins.common import config
|
||||||
|
from higgins.common import exception
|
||||||
|
from higgins.common.i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
service_opts = [
|
||||||
|
cfg.StrOpt('host',
|
||||||
|
default=socket.getfqdn(),
|
||||||
|
help=_('Name of this node. This can be an opaque identifier. '
|
||||||
|
'It is not necessarily a hostname, FQDN, or IP address. '
|
||||||
|
'However, the node name must be valid within '
|
||||||
|
'an AMQP key, and if using ZeroMQ, a valid '
|
||||||
|
'hostname, FQDN, or IP address.')),
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
CONF.register_opts(service_opts)
|
||||||
|
|
||||||
|
|
||||||
|
def prepare_service(argv=[]):
|
||||||
|
log.register_options(CONF)
|
||||||
|
config.parse_args(argv)
|
||||||
|
log.setup(CONF, 'higgins')
|
||||||
|
# TODO(yuanying): Uncomment after objects are implemented
|
||||||
|
# objects.register_all()
|
||||||
|
|
||||||
|
|
||||||
|
def process_launcher():
|
||||||
|
return service.ProcessLauncher(CONF)
|
||||||
|
|
||||||
|
|
||||||
|
class WSGIService(service.ServiceBase):
|
||||||
|
"""Provides ability to launch Higgins API from wsgi app."""
|
||||||
|
|
||||||
|
def __init__(self, name, use_ssl=False):
|
||||||
|
"""Initialize, but do not start the WSGI server.
|
||||||
|
|
||||||
|
:param name: The name of the WSGI server given to the loader.
|
||||||
|
:param use_ssl: Wraps the socket in an SSL context if True.
|
||||||
|
:returns: None
|
||||||
|
"""
|
||||||
|
self.name = name
|
||||||
|
self.app = app.setup_app()
|
||||||
|
self.workers = (processutils.get_worker_count())
|
||||||
|
if self.workers and self.workers < 1:
|
||||||
|
raise exception.ConfigInvalid(
|
||||||
|
_("api_workers value of %d is invalid, "
|
||||||
|
"must be greater than 0.") % self.workers)
|
||||||
|
|
||||||
|
self.server = wsgi.Server(CONF, name, self.app,
|
||||||
|
host=CONF.api.host,
|
||||||
|
port=CONF.api.port,
|
||||||
|
use_ssl=use_ssl)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""Start serving this service using loaded configuration.
|
||||||
|
|
||||||
|
:returns: None
|
||||||
|
"""
|
||||||
|
self.server.start()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""Stop serving this API.
|
||||||
|
|
||||||
|
:returns: None
|
||||||
|
"""
|
||||||
|
self.server.stop()
|
||||||
|
|
||||||
|
def wait(self):
|
||||||
|
"""Wait for the service to stop serving this API.
|
||||||
|
|
||||||
|
:returns: None
|
||||||
|
"""
|
||||||
|
self.server.wait()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
"""Reset server greenpool size to default.
|
||||||
|
|
||||||
|
:returns: None
|
||||||
|
"""
|
||||||
|
self.server.reset()
|
@ -4,10 +4,15 @@
|
|||||||
|
|
||||||
PyYAML>=3.1.0 # MIT
|
PyYAML>=3.1.0 # MIT
|
||||||
eventlet!=0.18.3,>=0.18.2 # MIT
|
eventlet!=0.18.3,>=0.18.2 # MIT
|
||||||
|
keystonemiddleware!=4.1.0,>=4.0.0 # Apache-2.0
|
||||||
greenlet>=0.3.2 # MIT
|
greenlet>=0.3.2 # MIT
|
||||||
pbr>=1.6 # Apache-2.0
|
pbr>=1.6 # Apache-2.0
|
||||||
pecan>=1.0.0 # BSD
|
pecan>=1.0.0 # BSD
|
||||||
oslo.i18n>=2.1.0 # Apache-2.0
|
oslo.i18n>=2.1.0 # Apache-2.0
|
||||||
|
oslo.log>=1.14.0 # Apache-2.0
|
||||||
|
oslo.concurrency>=3.5.0 # Apache-2.0
|
||||||
oslo.config>=3.9.0 # Apache-2.0
|
oslo.config>=3.9.0 # Apache-2.0
|
||||||
|
oslo.service>=1.10.0 # Apache-2.0
|
||||||
|
oslo.versionedobjects!=1.9.0,>=1.5.0 # Apache-2.0
|
||||||
six>=1.9.0 # MIT
|
six>=1.9.0 # MIT
|
||||||
WebOb>=1.2.3 # MIT
|
WSME>=0.8 # MIT
|
||||||
|
@ -45,5 +45,8 @@ mapping_file = babel.cfg
|
|||||||
output_file = higgins/locale/higgins.pot
|
output_file = higgins/locale/higgins.pot
|
||||||
|
|
||||||
[entry_points]
|
[entry_points]
|
||||||
|
console_scripts =
|
||||||
|
higgins-api = higgins.cmd.api:main
|
||||||
|
|
||||||
oslo.config.opts =
|
oslo.config.opts =
|
||||||
higgins = higgins.opts:list_opts
|
higgins = higgins.opts:list_opts
|
||||||
|
Loading…
x
Reference in New Issue
Block a user