Blueprint authentication-for-quantum
Modifies quantum.conf to include authN filter and pipeline with auth (optional) Removes bufferedhttp.py (not used anymore as middleware stays in keystone's tree) Change-Id: Id6410d88cd9a11c41e8813497a8af3286a88e1dc
This commit is contained in:
parent
1fcde53d0e
commit
bc4db0aa20
@ -1,165 +0,0 @@
|
||||
# Copyright (c) 2010-2011 OpenStack, LLC.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Monkey Patch httplib.HTTPResponse to buffer reads of headers. This can improve
|
||||
performance when making large numbers of small HTTP requests. This module
|
||||
also provides helper functions to make HTTP connections using
|
||||
BufferedHTTPResponse.
|
||||
|
||||
.. warning::
|
||||
|
||||
If you use this, be sure that the libraries you are using do not access
|
||||
the socket directly (xmlrpclib, I'm looking at you :/), and instead
|
||||
make all calls through httplib.
|
||||
"""
|
||||
|
||||
from urllib import quote
|
||||
import logging
|
||||
import time
|
||||
|
||||
from eventlet.green.httplib import CONTINUE, HTTPConnection, HTTPMessage, \
|
||||
HTTPResponse, HTTPSConnection, _UNKNOWN
|
||||
|
||||
|
||||
class BufferedHTTPResponse(HTTPResponse):
|
||||
"""HTTPResponse class that buffers reading of headers"""
|
||||
|
||||
def __init__(self, sock, debuglevel=0, strict=0,
|
||||
method=None): # pragma: no cover
|
||||
self.sock = sock
|
||||
self.fp = sock.makefile('rb')
|
||||
self.debuglevel = debuglevel
|
||||
self.strict = strict
|
||||
self._method = method
|
||||
|
||||
self.msg = None
|
||||
|
||||
# from the Status-Line of the response
|
||||
self.version = _UNKNOWN # HTTP-Version
|
||||
self.status = _UNKNOWN # Status-Code
|
||||
self.reason = _UNKNOWN # Reason-Phrase
|
||||
|
||||
self.chunked = _UNKNOWN # is "chunked" being used?
|
||||
self.chunk_left = _UNKNOWN # bytes left to read in current chunk
|
||||
self.length = _UNKNOWN # number of bytes left in response
|
||||
self.will_close = _UNKNOWN # conn will close at end of response
|
||||
|
||||
def expect_response(self):
|
||||
self.fp = self.sock.makefile('rb', 0)
|
||||
version, status, reason = self._read_status()
|
||||
if status != CONTINUE:
|
||||
self._read_status = lambda: (version, status, reason)
|
||||
self.begin()
|
||||
else:
|
||||
self.status = status
|
||||
self.reason = reason.strip()
|
||||
self.version = 11
|
||||
self.msg = HTTPMessage(self.fp, 0)
|
||||
self.msg.fp = None
|
||||
|
||||
|
||||
class BufferedHTTPConnection(HTTPConnection):
|
||||
"""HTTPConnection class that uses BufferedHTTPResponse"""
|
||||
response_class = BufferedHTTPResponse
|
||||
|
||||
def connect(self):
|
||||
self._connected_time = time.time()
|
||||
return HTTPConnection.connect(self)
|
||||
|
||||
def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0):
|
||||
self._method = method
|
||||
self._path = url
|
||||
return HTTPConnection.putrequest(self, method, url, skip_host,
|
||||
skip_accept_encoding)
|
||||
|
||||
def getexpect(self):
|
||||
response = BufferedHTTPResponse(self.sock, strict=self.strict,
|
||||
method=self._method)
|
||||
response.expect_response()
|
||||
return response
|
||||
|
||||
def getresponse(self):
|
||||
response = HTTPConnection.getresponse(self)
|
||||
logging.debug(("HTTP PERF: %(time).5f seconds to %(method)s "
|
||||
"%(host)s:%(port)s %(path)s)"),
|
||||
{'time': time.time() - self._connected_time, 'method': self._method,
|
||||
'host': self.host, 'port': self.port, 'path': self._path})
|
||||
return response
|
||||
|
||||
|
||||
def http_connect(ipaddr, port, device, partition, method, path,
|
||||
headers=None, query_string=None, ssl=False):
|
||||
"""
|
||||
Helper function to create an HTTPConnection object. If ssl is set True,
|
||||
HTTPSConnection will be used. However, if ssl=False, BufferedHTTPConnection
|
||||
will be used, which is buffered for backend Swift services.
|
||||
|
||||
:param ipaddr: IPv4 address to connect to
|
||||
:param port: port to connect to
|
||||
:param device: device of the node to query
|
||||
:param partition: partition on the device
|
||||
:param method: HTTP method to request ('GET', 'PUT', 'POST', etc.)
|
||||
:param path: request path
|
||||
:param headers: dictionary of headers
|
||||
:param query_string: request query string
|
||||
:param ssl: set True if SSL should be used (default: False)
|
||||
:returns: HTTPConnection object
|
||||
"""
|
||||
if ssl:
|
||||
conn = HTTPSConnection('%s:%s' % (ipaddr, port))
|
||||
else:
|
||||
conn = BufferedHTTPConnection('%s:%s' % (ipaddr, port))
|
||||
path = quote('/' + device + '/' + str(partition) + path)
|
||||
if query_string:
|
||||
path += '?' + query_string
|
||||
conn.path = path
|
||||
conn.putrequest(method, path)
|
||||
if headers:
|
||||
for header, value in headers.iteritems():
|
||||
conn.putheader(header, value)
|
||||
conn.endheaders()
|
||||
return conn
|
||||
|
||||
|
||||
def http_connect_raw(ipaddr, port, method, path, headers=None,
|
||||
query_string=None, ssl=False):
|
||||
"""
|
||||
Helper function to create an HTTPConnection object. If ssl is set True,
|
||||
HTTPSConnection will be used. However, if ssl=False, BufferedHTTPConnection
|
||||
will be used, which is buffered for backend Swift services.
|
||||
|
||||
:param ipaddr: IPv4 address to connect to
|
||||
:param port: port to connect to
|
||||
:param method: HTTP method to request ('GET', 'PUT', 'POST', etc.)
|
||||
:param path: request path
|
||||
:param headers: dictionary of headers
|
||||
:param query_string: request query string
|
||||
:param ssl: set True if SSL should be used (default: False)
|
||||
:returns: HTTPConnection object
|
||||
"""
|
||||
if ssl:
|
||||
conn = HTTPSConnection('%s:%s' % (ipaddr, port))
|
||||
else:
|
||||
conn = BufferedHTTPConnection('%s:%s' % (ipaddr, port))
|
||||
if query_string:
|
||||
path += '?' + query_string
|
||||
conn.path = path
|
||||
conn.putrequest(method, path)
|
||||
if headers:
|
||||
for header, value in headers.iteritems():
|
||||
conn.putheader(header, value)
|
||||
conn.endheaders()
|
||||
return conn
|
@ -22,7 +22,21 @@ use = egg:Paste#urlmap
|
||||
/v1.0: quantumapi
|
||||
|
||||
[pipeline:quantumapi]
|
||||
# By default, authentication is disabled.
|
||||
# To enable Keystone integration uncomment the
|
||||
# following line and comment the next one
|
||||
pipeline = extensions quantumapiapp
|
||||
#pipeline = authN extensions quantumapiapp
|
||||
|
||||
[filter:authN]
|
||||
paste.filter_factory = keystone.middleware.quantum_auth_token:filter_factory
|
||||
auth_host = 127.0.0.1
|
||||
auth_port = 35357
|
||||
auth_protocol = http
|
||||
auth_version = 2.0
|
||||
auth_admin_user = admin
|
||||
auth_admin_password = secrete
|
||||
#auth_admin_token = <token-value>
|
||||
|
||||
[filter:extensions]
|
||||
paste.filter_factory = quantum.common.extensions:plugin_aware_extension_middleware_factory
|
||||
|
Loading…
x
Reference in New Issue
Block a user