Access control support
Change-Id: Ic842885c7bcef0e9dc7728837b6cd396ccf52fbe Implements: blueprint access-control-master-node
This commit is contained in:
parent
ff01812bb9
commit
8ffe730af6
|
@ -57,6 +57,11 @@ def load_run_parsers(subparsers):
|
|||
'--fake-tasks-tick-interval', action='store', type=int,
|
||||
help='Fake tasks tick interval in seconds'
|
||||
)
|
||||
run_parser.add_argument(
|
||||
'--authentication-method', action='store', type=str,
|
||||
help='Choose authentication type',
|
||||
choices=['none', 'fake', 'keystone'],
|
||||
)
|
||||
|
||||
|
||||
def load_db_parsers(subparsers):
|
||||
|
@ -230,6 +235,11 @@ def action_run(params):
|
|||
param = getattr(params, attr.lower())
|
||||
if param is not None:
|
||||
settings.update({attr: param})
|
||||
|
||||
if params.authentication_method:
|
||||
auth_method = params.authentication_method
|
||||
settings.AUTH.update({'AUTHENTICATION_METHOD' : auth_method})
|
||||
|
||||
if params.config_file:
|
||||
settings.update_from_file(params.config_file)
|
||||
from nailgun.app import appstart
|
||||
|
|
|
@ -32,4 +32,7 @@ class VersionHandler(BaseHandler):
|
|||
""":returns: FUEL/FUELWeb commit SHA, release version.
|
||||
:http: * 200 (OK)
|
||||
"""
|
||||
return settings.VERSION
|
||||
version = settings.VERSION
|
||||
method = settings.AUTH['AUTHENTICATION_METHOD']
|
||||
version['auth_required'] = method in ['fake', 'keystone']
|
||||
return version
|
||||
|
|
|
@ -196,3 +196,10 @@ _locals = locals()
|
|||
|
||||
def app():
|
||||
return web.application(urls, _locals)
|
||||
|
||||
|
||||
def public_urls():
|
||||
return {r'/nodes/?$': ['POST'],
|
||||
r'/nodes/agent/?$': ['PUT'],
|
||||
r'/version/?$': ['GET']
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ from nailgun.logger import HTTPLoggerMiddleware
|
|||
from nailgun.logger import logger
|
||||
from nailgun.middleware.http_method_override import \
|
||||
HTTPMethodOverrideMiddleware
|
||||
from nailgun.middleware.keystone import NailgunAuthProtocol
|
||||
from nailgun.middleware.static import StaticMiddleware
|
||||
from nailgun.settings import settings
|
||||
from nailgun.urls import urls
|
||||
|
@ -53,6 +54,9 @@ def build_middleware(app):
|
|||
if settings.DEVELOPMENT:
|
||||
middleware_list.append(StaticMiddleware)
|
||||
|
||||
if settings.AUTH['AUTHENTICATION_METHOD'] == 'keystone':
|
||||
middleware_list.append(NailgunAuthProtocol)
|
||||
|
||||
logger.debug('Initialize middleware: %s' %
|
||||
(map(lambda x: x.__name__, middleware_list)))
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2014 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 re
|
||||
|
||||
from nailgun.api.v1 import urls as api_urls
|
||||
from nailgun.settings import settings
|
||||
|
||||
from keystoneclient.middleware import auth_token
|
||||
|
||||
|
||||
def public_urls():
|
||||
urls = {}
|
||||
for url, methods in api_urls.public_urls().iteritems():
|
||||
urls['{0}{1}'.format('/api/v1', url)] = methods
|
||||
urls['{0}{1}'.format('/api', url)] = methods
|
||||
urls["/$"] = ['GET']
|
||||
urls["/static"] = ['GET']
|
||||
return urls
|
||||
|
||||
|
||||
class NailgunAuthProtocol(auth_token.AuthProtocol):
|
||||
"""A wrapper on Keystone auth_token middleware.
|
||||
|
||||
Does not perform verification of authentication tokens
|
||||
for public routes in the API.
|
||||
|
||||
"""
|
||||
def __init__(self, app):
|
||||
self.public_api_routes = {}
|
||||
try:
|
||||
for route_tpl, methods in public_urls().iteritems():
|
||||
self.public_api_routes[re.compile(route_tpl)] = methods
|
||||
except re.error as e:
|
||||
msg = 'Cannot compile public API routes: {0}'.format(e)
|
||||
|
||||
auth_token.LOG.error(msg)
|
||||
raise Exception(error_msg=msg)
|
||||
|
||||
super(NailgunAuthProtocol, self).__init__(app, settings.AUTH)
|
||||
|
||||
def __call__(self, env, start_response):
|
||||
path = env.get('PATH_INFO', '/')
|
||||
method = env.get('REQUEST_METHOD')
|
||||
|
||||
# The information whether the API call is being performed against the
|
||||
# public API may be useful. Saving it to the
|
||||
# WSGI environment is reasonable thereby.
|
||||
env['is_public_api'] = False
|
||||
for pattern, methods in self.public_api_routes.iteritems():
|
||||
if re.match(pattern, path):
|
||||
if method in methods:
|
||||
env['is_public_api'] = True
|
||||
break
|
||||
|
||||
if env['is_public_api']:
|
||||
return self.app(env, start_response)
|
||||
return super(NailgunAuthProtocol, self).__call__(env, start_response)
|
|
@ -1,6 +1,17 @@
|
|||
LISTEN_ADDRESS: "0.0.0.0"
|
||||
LISTEN_PORT: "8000"
|
||||
DEVELOPMENT: 1
|
||||
AUTH:
|
||||
# Possible options:
|
||||
# - none - authentication is disabled
|
||||
# - fake - no keystone required, credentials: admin/admin
|
||||
# - keystone - authentication enabled.
|
||||
AUTHENTICATION_METHOD: "none"
|
||||
# use only if AUTHENTICATION_METHOD is set to "keystone"
|
||||
admin_token: "ADMIN"
|
||||
auth_host: "127.0.0.1"
|
||||
auth_protocol: "http"
|
||||
auth_version: "v2.0"
|
||||
|
||||
VERSION:
|
||||
release: "5.0"
|
||||
|
|
|
@ -43,6 +43,7 @@ class TestVersionHandler(BaseIntegrationTest):
|
|||
"nailgun_sha": "12345",
|
||||
"astute_sha": "Unknown build",
|
||||
"fuellib_sha": "Unknown build",
|
||||
"ostf_sha": "Unknown build"
|
||||
"ostf_sha": "Unknown build",
|
||||
"auth_required": False
|
||||
}
|
||||
)
|
||||
|
|
|
@ -24,3 +24,4 @@ simplejson==3.3.0
|
|||
web.py==0.37
|
||||
wsgilog==0.3
|
||||
wsgiref==0.1.2
|
||||
python-keystoneclient>=0.7.1
|
||||
|
|
Loading…
Reference in New Issue