Add keystone authentication of token

Closes-Bug: #1532075
Change-Id: Id45a0babc8e128d02bf648fedb7b66099bc3c7ae
Co-Authored-By: Lubosz "diltram" Kosnik <lubosz.kosnik@intel.com>
Depends-On: Id0deee2714040d271f43a537c27f410e2f4e3ef2
This commit is contained in:
Brandon Logan 2016-01-07 22:11:15 -06:00 committed by Lubosz "diltram" Kosnik
parent 61d8da7d46
commit 1ace351fd8
9 changed files with 57 additions and 9 deletions

View File

@ -7,6 +7,9 @@
# bind_port = 9876
# api_handler = queue_producer
#
# How should authentication be handled (keystone, noauth)
# auth_strategy = noauth
#
# Plugin options are hot_plug_plugin (Hot-pluggable controller plugin)
#
# octavia_plugins = hot_plug_plugin

View File

@ -12,10 +12,14 @@
# License for the specific language governing permissions and limitations
# under the License.
from keystonemiddleware import auth_token
from oslo_config import cfg
from oslo_middleware import cors
from oslo_middleware import request_id
import pecan
from octavia.api import config as app_config
from octavia.api.v1 import hooks
from octavia.common import constants
from octavia.common import service as octavia_service
@ -29,15 +33,35 @@ def setup_app(pecan_config=None, debug=False, argv=None):
"""Creates and returns a pecan wsgi app."""
octavia_service.prepare_service(argv)
app_hooks = [hooks.ContextHook()]
if not pecan_config:
pecan_config = get_pecan_config()
pecan.configuration.set_config(dict(pecan_config), overwrite=True)
return pecan.make_app(
pecan_config.app.root,
wrap_app=_wrap_app,
debug=debug,
hooks=app_hooks,
hooks=pecan_config.app.hooks,
wsme=pecan_config.wsme
)
def _wrap_app(app):
"""Wraps wsgi app with additional middlewares."""
app = request_id.RequestId(app)
if cfg.CONF.auth_strategy == constants.KEYSTONE:
app = auth_token.AuthProtocol(app, {})
# This should be the last middleware in the list (which results in
# it being the first in the middleware chain). This is to ensure
# that any errors thrown by other middleware, such as an auth
# middleware - are annotated with CORS headers, and thus accessible
# by the browser.
app = cors.CORS(app, cfg.CONF)
app.set_latent(
allow_headers=['X-Auth-Token', 'X-Openstack-Request-Id'],
allow_methods=['GET', 'PUT', 'POST', 'DELETE'],
expose_headers=['X-Auth-Token', 'X-Openstack-Request-Id']
)
return app

View File

@ -12,11 +12,14 @@
# License for the specific language governing permissions and limitations
# under the License.
from octavia.api.v1 import hooks
# Pecan Application Configurations
# See https://pecan.readthedocs.org/en/latest/configuration.html#application-configuration # noqa
app = {
'root': 'octavia.api.root_controller.RootController',
'modules': ['octavia.api'],
'hooks': [hooks.ContextHook()],
'debug': False
}

View File

@ -18,6 +18,7 @@ from octavia.common import context
class ContextHook(hooks.PecanHook):
"""Configures a request context and attaches it to the request."""
def on_route(self, state):
context_obj = context.Context.from_environ(state.request.environ)

View File

@ -35,15 +35,15 @@ core_opts = [
help=_("The host IP to bind to")),
cfg.PortOpt('bind_port', default=9876,
help=_("The port to bind to")),
cfg.StrOpt('auth_strategy', default=constants.NOAUTH,
choices=[constants.NOAUTH, constants.KEYSTONE],
help=_("The auth strategy for API requests.")),
cfg.StrOpt('api_handler', default='queue_producer',
help=_("The handler that the API communicates with")),
cfg.StrOpt('api_paste_config', default="api-paste.ini",
help=_("The API paste config file to use")),
cfg.StrOpt('api_extensions_path', default="",
help=_("The path for API extensions")),
cfg.StrOpt('auth_strategy', default='keystone',
choices=('noauth', 'keystone'),
help=_("The type of authentication to use")),
cfg.BoolOpt('allow_bulk', default=True,
help=_("Allow the usage of the bulk API")),
cfg.BoolOpt('allow_pagination', default=False,

View File

@ -358,3 +358,7 @@ INIT_PROC_COMM_PATH = '/proc/1/comm'
KEEPALIVED_SYSTEMD = 'octavia-keepalived.service'
KEEPALIVED_SYSVINIT = 'octavia-keepalived'
KEEPALIVED_UPSTART = 'octavia-keepalived.conf'
# Authentication
KEYSTONE = 'keystone'
NOAUTH = 'noauth'

View File

@ -25,6 +25,7 @@ class KeystoneSession:
def __init__(self, section=constants.SERVICE_AUTH):
self._session = None
self.section = section
ks_loading.register_auth_conf_options(cfg.CONF, self.section)
ks_loading.register_session_conf_options(cfg.CONF, self.section)

View File

@ -56,6 +56,7 @@ class BaseAPITest(base_db_test.OctaviaDBTestBase):
conf.config(api_handler='simulated_handler')
conf.config(group="controller_worker",
network_driver='network_noop_driver')
conf.config(auth_strategy='noauth')
self.lb_repo = repositories.LoadBalancerRepository()
self.listener_repo = repositories.ListenerRepository()
self.listener_stats_repo = repositories.ListenerStatisticsRepository()
@ -74,8 +75,8 @@ class BaseAPITest(base_db_test.OctaviaDBTestBase):
self.addCleanup(reset_pecan)
def _make_app(self):
return pecan.testing.load_test_app({'app': pconfig.app,
'wsme': pconfig.wsme})
return pecan.testing.load_test_app(
{'app': pconfig.app, 'wsme': pconfig.wsme})
def _get_full_path(self, path):
return ''.join([self.BASE_PATH, path])

View File

@ -0,0 +1,11 @@
---
prelude: >
Support for Keystone token authentication on frontend Octavia API.
features:
- After setting "auth_strategy = keystone" all incoming requests to Octavia
API will be verified using Keystone are they send by authenticated person.
By default that option is disabled because Neutron LBaaS v2 is not
supporting that functionality properly.
upgrade:
- This feature add new configuration value "auth_strategy" which by default
is set for "noauth".