termie all the things
Change-Id: Ib7b5fab2a09de8a9dcad8d8b0cf71c529e944f8c
This commit is contained in:
parent
3364905041
commit
51eda0155f
|
@ -317,7 +317,7 @@ class DictWrapper(dict):
|
||||||
|
|
||||||
def print_commands(cmds):
|
def print_commands(cmds):
|
||||||
print
|
print
|
||||||
print "Available commands:"
|
print 'Available commands:'
|
||||||
o = []
|
o = []
|
||||||
max_length = max([len(k) for k in cmds]) + 2
|
max_length = max([len(k) for k in cmds]) + 2
|
||||||
for k, cmd in sorted(cmds.iteritems()):
|
for k, cmd in sorted(cmds.iteritems()):
|
||||||
|
|
|
@ -95,8 +95,8 @@ class BufferedHTTPConnection(HTTPConnection):
|
||||||
|
|
||||||
def getresponse(self):
|
def getresponse(self):
|
||||||
response = HTTPConnection.getresponse(self)
|
response = HTTPConnection.getresponse(self)
|
||||||
logging.debug(("HTTP PERF: %(time).5f seconds to %(method)s "
|
logging.debug(('HTTP PERF: %(time).5f seconds to %(method)s '
|
||||||
"%(host)s:%(port)s %(path)s)"),
|
'%(host)s:%(port)s %(path)s)'),
|
||||||
{'time': time.time() - self._connected_time, 'method': self._method,
|
{'time': time.time() - self._connected_time, 'method': self._method,
|
||||||
'host': self.host, 'port': self.port, 'path': self._path})
|
'host': self.host, 'port': self.port, 'path': self._path})
|
||||||
return response
|
return response
|
||||||
|
|
|
@ -223,9 +223,9 @@ class ArgsAlreadyParsedError(Error):
|
||||||
"""Raised if a CLI opt is registered after parsing."""
|
"""Raised if a CLI opt is registered after parsing."""
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
ret = "arguments already parsed"
|
ret = 'arguments already parsed'
|
||||||
if self.msg:
|
if self.msg:
|
||||||
ret += ": " + self.msg
|
ret += ': ' + self.msg
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,9 +238,9 @@ class NoSuchOptError(Error):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.group is None:
|
if self.group is None:
|
||||||
return "no such option: %s" % self.opt_name
|
return 'no such option: %s' % self.opt_name
|
||||||
else:
|
else:
|
||||||
return "no such option in group %s: %s" % (self.group.name,
|
return 'no such option in group %s: %s' % (self.group.name,
|
||||||
self.opt_name)
|
self.opt_name)
|
||||||
|
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ class NoSuchGroupError(Error):
|
||||||
self.group_name = group_name
|
self.group_name = group_name
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "no such group: %s" % self.group_name
|
return 'no such group: %s' % self.group_name
|
||||||
|
|
||||||
|
|
||||||
class DuplicateOptError(Error):
|
class DuplicateOptError(Error):
|
||||||
|
@ -261,14 +261,14 @@ class DuplicateOptError(Error):
|
||||||
self.opt_name = opt_name
|
self.opt_name = opt_name
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "duplicate option: %s" % self.opt_name
|
return 'duplicate option: %s' % self.opt_name
|
||||||
|
|
||||||
|
|
||||||
class TemplateSubstitutionError(Error):
|
class TemplateSubstitutionError(Error):
|
||||||
"""Raised if an error occurs substituting a variable in an opt value."""
|
"""Raised if an error occurs substituting a variable in an opt value."""
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "template substitution error: %s" % self.msg
|
return 'template substitution error: %s' % self.msg
|
||||||
|
|
||||||
|
|
||||||
class ConfigFilesNotFoundError(Error):
|
class ConfigFilesNotFoundError(Error):
|
||||||
|
|
|
@ -102,12 +102,12 @@ class Base(object):
|
||||||
"""Return a SQLAlchemy engine."""
|
"""Return a SQLAlchemy engine."""
|
||||||
connection_dict = sqlalchemy.engine.url.make_url(CONF.sql.connection)
|
connection_dict = sqlalchemy.engine.url.make_url(CONF.sql.connection)
|
||||||
|
|
||||||
engine_args = {"pool_recycle": CONF.sql.idle_timeout,
|
engine_args = {'pool_recycle': CONF.sql.idle_timeout,
|
||||||
"echo": False,
|
'echo': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
if "sqlite" in connection_dict.drivername:
|
if 'sqlite' in connection_dict.drivername:
|
||||||
engine_args["poolclass"] = sqlalchemy.pool.NullPool
|
engine_args['poolclass'] = sqlalchemy.pool.NullPool
|
||||||
|
|
||||||
return sql.create_engine(CONF.sql.connection, **engine_args)
|
return sql.create_engine(CONF.sql.connection, **engine_args)
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ except ImportError:
|
||||||
# See LP Bug #717467
|
# See LP Bug #717467
|
||||||
from migrate import exceptions as versioning_exceptions
|
from migrate import exceptions as versioning_exceptions
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.exit("python-migrate is not installed. Exiting.")
|
sys.exit('python-migrate is not installed. Exiting.')
|
||||||
|
|
||||||
|
|
||||||
def db_sync(version=None):
|
def db_sync(version=None):
|
||||||
|
@ -44,7 +44,7 @@ def db_sync(version=None):
|
||||||
try:
|
try:
|
||||||
version = int(version)
|
version = int(version)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise Exception("version should be an integer")
|
raise Exception('version should be an integer')
|
||||||
|
|
||||||
current_version = db_version()
|
current_version = db_version()
|
||||||
repo_path = _find_migrate_repo()
|
repo_path = _find_migrate_repo()
|
||||||
|
|
|
@ -169,14 +169,14 @@ def check_output(*popenargs, **kwargs):
|
||||||
|
|
||||||
The arguments are the same as for the Popen constructor. Example:
|
The arguments are the same as for the Popen constructor. Example:
|
||||||
|
|
||||||
>>> check_output(["ls", "-l", "/dev/null"])
|
>>> check_output(['ls', '-l', '/dev/null'])
|
||||||
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
|
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
|
||||||
|
|
||||||
The stdout argument is not allowed as it is used internally.
|
The stdout argument is not allowed as it is used internally.
|
||||||
To capture standard error in the result, use stderr=STDOUT.
|
To capture standard error in the result, use stderr=STDOUT.
|
||||||
|
|
||||||
>>> check_output(["/bin/sh", "-c",
|
>>> check_output(['/bin/sh', '-c',
|
||||||
... "ls -l non_existent_file ; exit 0"],
|
... 'ls -l non_existent_file ; exit 0'],
|
||||||
... stderr=STDOUT)
|
... stderr=STDOUT)
|
||||||
'ls: non_existent_file: No such file or directory\n'
|
'ls: non_existent_file: No such file or directory\n'
|
||||||
"""
|
"""
|
||||||
|
@ -187,7 +187,7 @@ def check_output(*popenargs, **kwargs):
|
||||||
output, unused_err = process.communicate()
|
output, unused_err = process.communicate()
|
||||||
retcode = process.poll()
|
retcode = process.poll()
|
||||||
if retcode:
|
if retcode:
|
||||||
cmd = kwargs.get("args")
|
cmd = kwargs.get('args')
|
||||||
if cmd is None:
|
if cmd is None:
|
||||||
cmd = popenargs[0]
|
cmd = popenargs[0]
|
||||||
raise subprocess.CalledProcessError(retcode, cmd)
|
raise subprocess.CalledProcessError(retcode, cmd)
|
||||||
|
|
|
@ -57,8 +57,8 @@ def setup_logging(conf):
|
||||||
logging.config.fileConfig(conf.log_config)
|
logging.config.fileConfig(conf.log_config)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unable to locate specified logging "
|
raise RuntimeError('Unable to locate specified logging '
|
||||||
"config file: %s" % conf.log_config)
|
'config file: %s' % conf.log_config)
|
||||||
|
|
||||||
root_logger = logging.root
|
root_logger = logging.root
|
||||||
if conf.debug:
|
if conf.debug:
|
||||||
|
@ -75,7 +75,7 @@ def setup_logging(conf):
|
||||||
facility = getattr(logging.SysLogHandler,
|
facility = getattr(logging.SysLogHandler,
|
||||||
conf.syslog_log_facility)
|
conf.syslog_log_facility)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise ValueError(_("Invalid syslog facility"))
|
raise ValueError(_('Invalid syslog facility'))
|
||||||
|
|
||||||
handler = logging.SysLogHandler(address='/dev/log',
|
handler = logging.SysLogHandler(address='/dev/log',
|
||||||
facility=facility)
|
facility=facility)
|
||||||
|
|
|
@ -19,132 +19,132 @@ class CrudExtension(wsgi.ExtensionRouter):
|
||||||
service_controller = catalog.ServiceController()
|
service_controller = catalog.ServiceController()
|
||||||
|
|
||||||
# Tenant Operations
|
# Tenant Operations
|
||||||
mapper.connect("/tenants", controller=tenant_controller,
|
mapper.connect('/tenants', controller=tenant_controller,
|
||||||
action="create_tenant",
|
action='create_tenant',
|
||||||
conditions=dict(method=["POST"]))
|
conditions=dict(method=['POST']))
|
||||||
mapper.connect("/tenants/{tenant_id}",
|
mapper.connect('/tenants/{tenant_id}',
|
||||||
controller=tenant_controller,
|
controller=tenant_controller,
|
||||||
action="update_tenant",
|
action='update_tenant',
|
||||||
conditions=dict(method=["PUT", "POST"]))
|
conditions=dict(method=['PUT', 'POST']))
|
||||||
mapper.connect("/tenants/{tenant_id}",
|
mapper.connect('/tenants/{tenant_id}',
|
||||||
controller=tenant_controller,
|
controller=tenant_controller,
|
||||||
action="delete_tenant",
|
action='delete_tenant',
|
||||||
conditions=dict(method=["DELETE"]))
|
conditions=dict(method=['DELETE']))
|
||||||
mapper.connect("/tenants/{tenant_id}/users",
|
mapper.connect('/tenants/{tenant_id}/users',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="get_tenant_users",
|
action='get_tenant_users',
|
||||||
conditions=dict(method=["GET"]))
|
conditions=dict(method=['GET']))
|
||||||
|
|
||||||
# User Operations
|
# User Operations
|
||||||
mapper.connect("/users",
|
mapper.connect('/users',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="get_users",
|
action='get_users',
|
||||||
conditions=dict(method=["GET"]))
|
conditions=dict(method=['GET']))
|
||||||
mapper.connect("/users",
|
mapper.connect('/users',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="create_user",
|
action='create_user',
|
||||||
conditions=dict(method=["POST"]))
|
conditions=dict(method=['POST']))
|
||||||
# NOTE(termie): not in diablo
|
# NOTE(termie): not in diablo
|
||||||
mapper.connect("/users/{user_id}",
|
mapper.connect('/users/{user_id}',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="update_user",
|
action='update_user',
|
||||||
conditions=dict(method=["PUT"]))
|
conditions=dict(method=['PUT']))
|
||||||
mapper.connect("/users/{user_id}",
|
mapper.connect('/users/{user_id}',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="delete_user",
|
action='delete_user',
|
||||||
conditions=dict(method=["DELETE"]))
|
conditions=dict(method=['DELETE']))
|
||||||
|
|
||||||
# COMPAT(diablo): the copy with no OS-KSADM is from diablo
|
# COMPAT(diablo): the copy with no OS-KSADM is from diablo
|
||||||
mapper.connect("/users/{user_id}/password",
|
mapper.connect('/users/{user_id}/password',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="set_user_password",
|
action='set_user_password',
|
||||||
conditions=dict(method=["PUT"]))
|
conditions=dict(method=['PUT']))
|
||||||
mapper.connect("/users/{user_id}/OS-KSADM/password",
|
mapper.connect('/users/{user_id}/OS-KSADM/password',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="set_user_password",
|
action='set_user_password',
|
||||||
conditions=dict(method=["PUT"]))
|
conditions=dict(method=['PUT']))
|
||||||
|
|
||||||
# COMPAT(diablo): the copy with no OS-KSADM is from diablo
|
# COMPAT(diablo): the copy with no OS-KSADM is from diablo
|
||||||
mapper.connect("/users/{user_id}/tenant",
|
mapper.connect('/users/{user_id}/tenant',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="update_user_tenant",
|
action='update_user_tenant',
|
||||||
conditions=dict(method=["PUT"]))
|
conditions=dict(method=['PUT']))
|
||||||
mapper.connect("/users/{user_id}/OS-KSADM/tenant",
|
mapper.connect('/users/{user_id}/OS-KSADM/tenant',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="update_user_tenant",
|
action='update_user_tenant',
|
||||||
conditions=dict(method=["PUT"]))
|
conditions=dict(method=['PUT']))
|
||||||
|
|
||||||
# COMPAT(diablo): the copy with no OS-KSADM is from diablo
|
# COMPAT(diablo): the copy with no OS-KSADM is from diablo
|
||||||
mapper.connect("/users/{user_id}/enabled",
|
mapper.connect('/users/{user_id}/enabled',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="set_user_enabled",
|
action='set_user_enabled',
|
||||||
conditions=dict(method=["PUT"]))
|
conditions=dict(method=['PUT']))
|
||||||
mapper.connect("/users/{user_id}/OS-KSADM/enabled",
|
mapper.connect('/users/{user_id}/OS-KSADM/enabled',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action="set_user_enabled",
|
action='set_user_enabled',
|
||||||
conditions=dict(method=["PUT"]))
|
conditions=dict(method=['PUT']))
|
||||||
|
|
||||||
# User Roles
|
# User Roles
|
||||||
mapper.connect("/users/{user_id}/roles/OS-KSADM/{role_id}",
|
mapper.connect('/users/{user_id}/roles/OS-KSADM/{role_id}',
|
||||||
controller=role_controller, action="add_role_to_user",
|
controller=role_controller, action='add_role_to_user',
|
||||||
conditions=dict(method=["PUT"]))
|
conditions=dict(method=['PUT']))
|
||||||
mapper.connect("/users/{user_id}/roles/OS-KSADM/{role_id}",
|
mapper.connect('/users/{user_id}/roles/OS-KSADM/{role_id}',
|
||||||
controller=role_controller, action="delete_role_from_user",
|
controller=role_controller, action='delete_role_from_user',
|
||||||
conditions=dict(method=["DELETE"]))
|
conditions=dict(method=['DELETE']))
|
||||||
|
|
||||||
# COMPAT(diablo): User Roles
|
# COMPAT(diablo): User Roles
|
||||||
mapper.connect("/users/{user_id}/roleRefs",
|
mapper.connect('/users/{user_id}/roleRefs',
|
||||||
controller=role_controller, action="get_role_refs",
|
controller=role_controller, action='get_role_refs',
|
||||||
conditions=dict(method=["GET"]))
|
conditions=dict(method=['GET']))
|
||||||
mapper.connect("/users/{user_id}/roleRefs",
|
mapper.connect('/users/{user_id}/roleRefs',
|
||||||
controller=role_controller, action="create_role_ref",
|
controller=role_controller, action='create_role_ref',
|
||||||
conditions=dict(method=["POST"]))
|
conditions=dict(method=['POST']))
|
||||||
mapper.connect("/users/{user_id}/roleRefs/{role_ref_id}",
|
mapper.connect('/users/{user_id}/roleRefs/{role_ref_id}',
|
||||||
controller=role_controller, action="delete_role_ref",
|
controller=role_controller, action='delete_role_ref',
|
||||||
conditions=dict(method=["DELETE"]))
|
conditions=dict(method=['DELETE']))
|
||||||
|
|
||||||
# User-Tenant Roles
|
# User-Tenant Roles
|
||||||
mapper.connect(
|
mapper.connect(
|
||||||
"/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}",
|
'/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}',
|
||||||
controller=role_controller, action="add_role_to_user",
|
controller=role_controller, action='add_role_to_user',
|
||||||
conditions=dict(method=["PUT"]))
|
conditions=dict(method=['PUT']))
|
||||||
mapper.connect(
|
mapper.connect(
|
||||||
"/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}",
|
'/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}',
|
||||||
controller=role_controller, action="remove_role_from_user",
|
controller=role_controller, action='remove_role_from_user',
|
||||||
conditions=dict(method=["DELETE"]))
|
conditions=dict(method=['DELETE']))
|
||||||
|
|
||||||
# Service Operations
|
# Service Operations
|
||||||
mapper.connect("/OS-KSADM/services",
|
mapper.connect('/OS-KSADM/services',
|
||||||
controller=service_controller,
|
controller=service_controller,
|
||||||
action="get_services",
|
action='get_services',
|
||||||
conditions=dict(method=["GET"]))
|
conditions=dict(method=['GET']))
|
||||||
mapper.connect("/OS-KSADM/services",
|
mapper.connect('/OS-KSADM/services',
|
||||||
controller=service_controller,
|
controller=service_controller,
|
||||||
action="create_service",
|
action='create_service',
|
||||||
conditions=dict(method=["POST"]))
|
conditions=dict(method=['POST']))
|
||||||
mapper.connect("/OS-KSADM/services/{service_id}",
|
mapper.connect('/OS-KSADM/services/{service_id}',
|
||||||
controller=service_controller,
|
controller=service_controller,
|
||||||
action="delete_service",
|
action='delete_service',
|
||||||
conditions=dict(method=["DELETE"]))
|
conditions=dict(method=['DELETE']))
|
||||||
mapper.connect("/OS-KSADM/services/{service_id}",
|
mapper.connect('/OS-KSADM/services/{service_id}',
|
||||||
controller=service_controller,
|
controller=service_controller,
|
||||||
action="get_service",
|
action='get_service',
|
||||||
conditions=dict(method=["GET"]))
|
conditions=dict(method=['GET']))
|
||||||
|
|
||||||
# Role Operations
|
# Role Operations
|
||||||
mapper.connect("/OS-KSADM/roles",
|
mapper.connect('/OS-KSADM/roles',
|
||||||
controller=role_controller,
|
controller=role_controller,
|
||||||
action="create_role",
|
action='create_role',
|
||||||
conditions=dict(method=["POST"]))
|
conditions=dict(method=['POST']))
|
||||||
mapper.connect("/OS-KSADM/roles",
|
mapper.connect('/OS-KSADM/roles',
|
||||||
controller=role_controller,
|
controller=role_controller,
|
||||||
action="get_roles",
|
action='get_roles',
|
||||||
conditions=dict(method=["GET"]))
|
conditions=dict(method=['GET']))
|
||||||
mapper.connect("/OS-KSADM/roles/{role_id}",
|
mapper.connect('/OS-KSADM/roles/{role_id}',
|
||||||
controller=role_controller,
|
controller=role_controller,
|
||||||
action="get_role",
|
action='get_role',
|
||||||
conditions=dict(method=["GET"]))
|
conditions=dict(method=['GET']))
|
||||||
mapper.connect("/OS-KSADM/roles/{role_id}",
|
mapper.connect('/OS-KSADM/roles/{role_id}',
|
||||||
controller=role_controller,
|
controller=role_controller,
|
||||||
action="delete_role",
|
action='delete_role',
|
||||||
conditions=dict(method=["DELETE"]))
|
conditions=dict(method=['DELETE']))
|
||||||
|
|
|
@ -95,15 +95,15 @@ class Ec2Controller(wsgi.Application):
|
||||||
# NOTE(vish): Some libraries don't use the port when signing
|
# NOTE(vish): Some libraries don't use the port when signing
|
||||||
# requests, so try again without port.
|
# requests, so try again without port.
|
||||||
elif ':' in credentials['signature']:
|
elif ':' in credentials['signature']:
|
||||||
hostname, _port = credentials['host'].split(":")
|
hostname, _port = credentials['host'].split(':')
|
||||||
credentials['host'] = hostname
|
credentials['host'] = hostname
|
||||||
signature = signer.generate(credentials)
|
signature = signer.generate(credentials)
|
||||||
if signature != credentials.signature:
|
if signature != credentials.signature:
|
||||||
# TODO(termie): proper exception
|
# TODO(termie): proper exception
|
||||||
msg = "Invalid signature"
|
msg = 'Invalid signature'
|
||||||
raise webob.exc.HTTPUnauthorized(explanation=msg)
|
raise webob.exc.HTTPUnauthorized(explanation=msg)
|
||||||
else:
|
else:
|
||||||
msg = "Signature not supplied"
|
msg = 'Signature not supplied'
|
||||||
raise webob.exc.HTTPUnauthorized(explanation=msg)
|
raise webob.exc.HTTPUnauthorized(explanation=msg)
|
||||||
|
|
||||||
def authenticate(self, context, credentials=None,
|
def authenticate(self, context, credentials=None,
|
||||||
|
@ -137,7 +137,7 @@ class Ec2Controller(wsgi.Application):
|
||||||
creds_ref = self.ec2_api.get_credential(context,
|
creds_ref = self.ec2_api.get_credential(context,
|
||||||
credentials['access'])
|
credentials['access'])
|
||||||
if not creds_ref:
|
if not creds_ref:
|
||||||
msg = "Access key not found"
|
msg = 'Access key not found'
|
||||||
raise webob.exc.HTTPUnauthorized(explanation=msg)
|
raise webob.exc.HTTPUnauthorized(explanation=msg)
|
||||||
|
|
||||||
self.check_signature(creds_ref, credentials)
|
self.check_signature(creds_ref, credentials)
|
||||||
|
|
|
@ -34,4 +34,4 @@ class S3Controller(ec2.Ec2Controller):
|
||||||
signed = base64.encodestring(hmac.new(key, msg, sha1).digest()).strip()
|
signed = base64.encodestring(hmac.new(key, msg, sha1).digest()).strip()
|
||||||
|
|
||||||
if credentials['signature'] != signed:
|
if credentials['signature'] != signed:
|
||||||
raise Exception("Not Authorized")
|
raise Exception('Not Authorized')
|
||||||
|
|
|
@ -78,7 +78,7 @@ from webob.exc import HTTPUnauthorized
|
||||||
|
|
||||||
from keystone.common.bufferedhttp import http_connect_raw as http_connect
|
from keystone.common.bufferedhttp import http_connect_raw as http_connect
|
||||||
|
|
||||||
PROTOCOL_NAME = "Token Authentication"
|
PROTOCOL_NAME = 'Token Authentication'
|
||||||
|
|
||||||
|
|
||||||
class AuthProtocol(object):
|
class AuthProtocol(object):
|
||||||
|
@ -86,7 +86,7 @@ class AuthProtocol(object):
|
||||||
|
|
||||||
def _init_protocol_common(self, app, conf):
|
def _init_protocol_common(self, app, conf):
|
||||||
""" Common initialization code"""
|
""" Common initialization code"""
|
||||||
print "Starting the %s component" % PROTOCOL_NAME
|
print 'Starting the %s component' % PROTOCOL_NAME
|
||||||
|
|
||||||
self.conf = conf
|
self.conf = conf
|
||||||
self.app = app
|
self.app = app
|
||||||
|
@ -120,7 +120,7 @@ class AuthProtocol(object):
|
||||||
# where to tell clients to find the auth service (default to url
|
# where to tell clients to find the auth service (default to url
|
||||||
# constructed based on endpoint we have for the service to use)
|
# constructed based on endpoint we have for the service to use)
|
||||||
self.auth_location = conf.get('auth_uri',
|
self.auth_location = conf.get('auth_uri',
|
||||||
"%s://%s:%s" % (self.auth_protocol,
|
'%s://%s:%s' % (self.auth_protocol,
|
||||||
self.auth_host,
|
self.auth_host,
|
||||||
self.auth_port))
|
self.auth_port))
|
||||||
|
|
||||||
|
@ -152,8 +152,8 @@ class AuthProtocol(object):
|
||||||
if self.delay_auth_decision:
|
if self.delay_auth_decision:
|
||||||
#Configured to allow downstream service to make final decision.
|
#Configured to allow downstream service to make final decision.
|
||||||
#So mark status as Invalid and forward the request downstream
|
#So mark status as Invalid and forward the request downstream
|
||||||
self._decorate_request("X_IDENTITY_STATUS",
|
self._decorate_request('X_IDENTITY_STATUS',
|
||||||
"Invalid", env, proxy_headers)
|
'Invalid', env, proxy_headers)
|
||||||
else:
|
else:
|
||||||
#Respond to client as appropriate for this auth protocol
|
#Respond to client as appropriate for this auth protocol
|
||||||
return self._reject_request(env, start_response)
|
return self._reject_request(env, start_response)
|
||||||
|
@ -164,14 +164,14 @@ class AuthProtocol(object):
|
||||||
# Keystone rejected claim
|
# Keystone rejected claim
|
||||||
if self.delay_auth_decision:
|
if self.delay_auth_decision:
|
||||||
# Downstream service will receive call still and decide
|
# Downstream service will receive call still and decide
|
||||||
self._decorate_request("X_IDENTITY_STATUS",
|
self._decorate_request('X_IDENTITY_STATUS',
|
||||||
"Invalid", env, proxy_headers)
|
'Invalid', env, proxy_headers)
|
||||||
else:
|
else:
|
||||||
#Respond to client as appropriate for this auth protocol
|
#Respond to client as appropriate for this auth protocol
|
||||||
return self._reject_claims(env, start_response)
|
return self._reject_claims(env, start_response)
|
||||||
else:
|
else:
|
||||||
self._decorate_request("X_IDENTITY_STATUS",
|
self._decorate_request('X_IDENTITY_STATUS',
|
||||||
"Confirmed", env, proxy_headers)
|
'Confirmed', env, proxy_headers)
|
||||||
|
|
||||||
#Collect information about valid claims
|
#Collect information about valid claims
|
||||||
if valid:
|
if valid:
|
||||||
|
@ -179,7 +179,7 @@ class AuthProtocol(object):
|
||||||
|
|
||||||
# Store authentication data
|
# Store authentication data
|
||||||
if claims:
|
if claims:
|
||||||
self._decorate_request('X_AUTHORIZATION', "Proxy %s" %
|
self._decorate_request('X_AUTHORIZATION', 'Proxy %s' %
|
||||||
claims['user'], env, proxy_headers)
|
claims['user'], env, proxy_headers)
|
||||||
|
|
||||||
# For legacy compatibility before we had ID and Name
|
# For legacy compatibility before we had ID and Name
|
||||||
|
@ -218,14 +218,14 @@ class AuthProtocol(object):
|
||||||
validate a user's token. Validate_token is a priviledged call so
|
validate a user's token. Validate_token is a priviledged call so
|
||||||
it needs to be authenticated by a service that is calling it
|
it needs to be authenticated by a service that is calling it
|
||||||
"""
|
"""
|
||||||
headers = {"Content-type": "application/json",
|
headers = {'Content-type': 'application/json',
|
||||||
"Accept": "application/json"}
|
'Accept': 'application/json'}
|
||||||
params = {"passwordCredentials": {"username": username,
|
params = {'passwordCredentials': {'username': username,
|
||||||
"password": password,
|
'password': password,
|
||||||
"tenantId": "1"}}
|
'tenantId': '1'}}
|
||||||
conn = httplib.HTTPConnection("%s:%s" \
|
conn = httplib.HTTPConnection('%s:%s' \
|
||||||
% (self.auth_host, self.auth_port))
|
% (self.auth_host, self.auth_port))
|
||||||
conn.request("POST", "/v2.0/tokens", json.dumps(params), \
|
conn.request('POST', '/v2.0/tokens', json.dumps(params), \
|
||||||
headers=headers)
|
headers=headers)
|
||||||
response = conn.getresponse()
|
response = conn.getresponse()
|
||||||
data = response.read()
|
data = response.read()
|
||||||
|
@ -238,8 +238,8 @@ class AuthProtocol(object):
|
||||||
|
|
||||||
def _reject_request(self, env, start_response):
|
def _reject_request(self, env, start_response):
|
||||||
"""Redirect client to auth server"""
|
"""Redirect client to auth server"""
|
||||||
return webob.exc.HTTPUnauthorized("Authentication required",
|
return webob.exc.HTTPUnauthorized('Authentication required',
|
||||||
[("WWW-Authenticate",
|
[('WWW-Authenticate',
|
||||||
"Keystone uri='%s'" % self.auth_location)])(env,
|
"Keystone uri='%s'" % self.auth_location)])(env,
|
||||||
start_response)
|
start_response)
|
||||||
|
|
||||||
|
@ -255,19 +255,19 @@ class AuthProtocol(object):
|
||||||
# admin token
|
# admin token
|
||||||
#TODO(ziad): Need to properly implement this, where to store creds
|
#TODO(ziad): Need to properly implement this, where to store creds
|
||||||
# for now using token from ini
|
# for now using token from ini
|
||||||
#auth = self.get_admin_auth_token("admin", "secrete", "1")
|
#auth = self.get_admin_auth_token('admin', 'secrete', '1')
|
||||||
#admin_token = json.loads(auth)["auth"]["token"]["id"]
|
#admin_token = json.loads(auth)['auth']['token']['id']
|
||||||
|
|
||||||
# Step 2: validate the user's token with the auth service
|
# Step 2: validate the user's token with the auth service
|
||||||
# since this is a priviledged op,m we need to auth ourselves
|
# since this is a priviledged op,m we need to auth ourselves
|
||||||
# by using an admin token
|
# by using an admin token
|
||||||
headers = {"Content-type": "application/json",
|
headers = {'Content-type': 'application/json',
|
||||||
"Accept": "application/json",
|
'Accept': 'application/json',
|
||||||
"X-Auth-Token": self.admin_token}
|
'X-Auth-Token': self.admin_token}
|
||||||
##TODO(ziad):we need to figure out how to auth to keystone
|
##TODO(ziad):we need to figure out how to auth to keystone
|
||||||
#since validate_token is a priviledged call
|
#since validate_token is a priviledged call
|
||||||
#Khaled's version uses creds to get a token
|
#Khaled's version uses creds to get a token
|
||||||
# "X-Auth-Token": admin_token}
|
# 'X-Auth-Token': admin_token}
|
||||||
# we're using a test token from the ini file for now
|
# we're using a test token from the ini file for now
|
||||||
conn = http_connect(self.auth_host, self.auth_port, 'GET',
|
conn = http_connect(self.auth_host, self.auth_port, 'GET',
|
||||||
'/v2.0/tokens/%s' % claims, headers=headers)
|
'/v2.0/tokens/%s' % claims, headers=headers)
|
||||||
|
@ -287,13 +287,13 @@ class AuthProtocol(object):
|
||||||
def _expound_claims(self, claims):
|
def _expound_claims(self, claims):
|
||||||
# Valid token. Get user data and put it in to the call
|
# Valid token. Get user data and put it in to the call
|
||||||
# so the downstream service can use it
|
# so the downstream service can use it
|
||||||
headers = {"Content-type": "application/json",
|
headers = {'Content-type': 'application/json',
|
||||||
"Accept": "application/json",
|
'Accept': 'application/json',
|
||||||
"X-Auth-Token": self.admin_token}
|
'X-Auth-Token': self.admin_token}
|
||||||
##TODO(ziad):we need to figure out how to auth to keystone
|
##TODO(ziad):we need to figure out how to auth to keystone
|
||||||
#since validate_token is a priviledged call
|
#since validate_token is a priviledged call
|
||||||
#Khaled's version uses creds to get a token
|
#Khaled's version uses creds to get a token
|
||||||
# "X-Auth-Token": admin_token}
|
# 'X-Auth-Token': admin_token}
|
||||||
# we're using a test token from the ini file for now
|
# we're using a test token from the ini file for now
|
||||||
conn = http_connect(self.auth_host, self.auth_port, 'GET',
|
conn = http_connect(self.auth_host, self.auth_port, 'GET',
|
||||||
'/v2.0/tokens/%s' % claims, headers=headers)
|
'/v2.0/tokens/%s' % claims, headers=headers)
|
||||||
|
@ -306,12 +306,12 @@ class AuthProtocol(object):
|
||||||
|
|
||||||
token_info = json.loads(data)
|
token_info = json.loads(data)
|
||||||
roles = []
|
roles = []
|
||||||
role_refs = token_info["access"]["user"]["roles"]
|
role_refs = token_info['access']['user']['roles']
|
||||||
if role_refs != None:
|
if role_refs != None:
|
||||||
for role_ref in role_refs:
|
for role_ref in role_refs:
|
||||||
# Nova looks for the non case-sensitive role 'Admin'
|
# Nova looks for the non case-sensitive role 'Admin'
|
||||||
# to determine admin-ness
|
# to determine admin-ness
|
||||||
roles.append(role_ref["name"])
|
roles.append(role_ref['name'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tenant = token_info['access']['token']['tenant']['id']
|
tenant = token_info['access']['token']['tenant']['id']
|
||||||
|
@ -332,12 +332,12 @@ class AuthProtocol(object):
|
||||||
def _decorate_request(self, index, value, env, proxy_headers):
|
def _decorate_request(self, index, value, env, proxy_headers):
|
||||||
"""Add headers to request"""
|
"""Add headers to request"""
|
||||||
proxy_headers[index] = value
|
proxy_headers[index] = value
|
||||||
env["HTTP_%s" % index] = value
|
env['HTTP_%s' % index] = value
|
||||||
|
|
||||||
def _forward_request(self, env, start_response, proxy_headers):
|
def _forward_request(self, env, start_response, proxy_headers):
|
||||||
"""Token/Auth processed & claims added to headers"""
|
"""Token/Auth processed & claims added to headers"""
|
||||||
self._decorate_request('AUTHORIZATION',
|
self._decorate_request('AUTHORIZATION',
|
||||||
"Basic %s" % self.service_pass, env, proxy_headers)
|
'Basic %s' % self.service_pass, env, proxy_headers)
|
||||||
#now decide how to pass on the call
|
#now decide how to pass on the call
|
||||||
if self.app:
|
if self.app:
|
||||||
# Pass to downstream WSGI component
|
# Pass to downstream WSGI component
|
||||||
|
@ -362,7 +362,7 @@ class AuthProtocol(object):
|
||||||
|
|
||||||
if resp.status == 401 or resp.status == 305:
|
if resp.status == 401 or resp.status == 305:
|
||||||
# Add our own headers to the list
|
# Add our own headers to the list
|
||||||
headers = [("WWW_AUTHENTICATE",
|
headers = [('WWW_AUTHENTICATE',
|
||||||
"Keystone uri='%s'" % self.auth_location)]
|
"Keystone uri='%s'" % self.auth_location)]
|
||||||
return webob.Response(status=resp.status,
|
return webob.Response(status=resp.status,
|
||||||
body=data,
|
body=data,
|
||||||
|
@ -387,11 +387,11 @@ def app_factory(global_conf, **local_conf):
|
||||||
conf.update(local_conf)
|
conf.update(local_conf)
|
||||||
return AuthProtocol(None, conf)
|
return AuthProtocol(None, conf)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
app = deploy.loadapp("config:" + \
|
app = deploy.loadapp('config:' + \
|
||||||
os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
||||||
os.pardir,
|
os.pardir,
|
||||||
os.pardir,
|
os.pardir,
|
||||||
"examples/paste/auth_token.ini"),
|
'examples/paste/auth_token.ini'),
|
||||||
global_conf={"log_name": "auth_token.log"})
|
global_conf={'log_name': 'auth_token.log'})
|
||||||
wsgi.server(eventlet.listen(('', 8090)), app)
|
wsgi.server(eventlet.listen(('', 8090)), app)
|
||||||
|
|
|
@ -115,15 +115,15 @@ class Debug(wsgi.Middleware):
|
||||||
|
|
||||||
@webob.dec.wsgify
|
@webob.dec.wsgify
|
||||||
def __call__(self, req):
|
def __call__(self, req):
|
||||||
print ("*" * 40) + " REQUEST ENVIRON"
|
print ('*' * 40) + ' REQUEST ENVIRON'
|
||||||
for key, value in req.environ.items():
|
for key, value in req.environ.items():
|
||||||
print key, "=", value
|
print key, '=', value
|
||||||
print
|
print
|
||||||
resp = req.get_response(self.application)
|
resp = req.get_response(self.application)
|
||||||
|
|
||||||
print ("*" * 40) + " RESPONSE HEADERS"
|
print ('*' * 40) + ' RESPONSE HEADERS'
|
||||||
for (key, value) in resp.headers.iteritems():
|
for (key, value) in resp.headers.iteritems():
|
||||||
print key, "=", value
|
print key, '=', value
|
||||||
print
|
print
|
||||||
|
|
||||||
resp.app_iter = self.print_generator(resp.app_iter)
|
resp.app_iter = self.print_generator(resp.app_iter)
|
||||||
|
@ -136,7 +136,7 @@ class Debug(wsgi.Middleware):
|
||||||
Iterator that prints the contents of a wrapper string iterator
|
Iterator that prints the contents of a wrapper string iterator
|
||||||
when iterated.
|
when iterated.
|
||||||
"""
|
"""
|
||||||
print ("*" * 40) + " BODY"
|
print ('*' * 40) + ' BODY'
|
||||||
for part in app_iter:
|
for part in app_iter:
|
||||||
sys.stdout.write(part)
|
sys.stdout.write(part)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
|
@ -65,11 +65,11 @@ class EC2Token(wsgi.Middleware):
|
||||||
creds_json = utils.dumps(creds)
|
creds_json = utils.dumps(creds)
|
||||||
headers = {'Content-Type': 'application/json'}
|
headers = {'Content-Type': 'application/json'}
|
||||||
|
|
||||||
# Disable "has no x member" pylint error
|
# Disable 'has no x member' pylint error
|
||||||
# for httplib and urlparse
|
# for httplib and urlparse
|
||||||
# pylint: disable-msg=E1101
|
# pylint: disable-msg=E1101
|
||||||
o = urlparse(FLAGS.keystone_ec2_url)
|
o = urlparse(FLAGS.keystone_ec2_url)
|
||||||
if o.scheme == "http":
|
if o.scheme == 'http':
|
||||||
conn = httplib.HTTPConnection(o.netloc)
|
conn = httplib.HTTPConnection(o.netloc)
|
||||||
else:
|
else:
|
||||||
conn = httplib.HTTPSConnection(o.netloc)
|
conn = httplib.HTTPSConnection(o.netloc)
|
||||||
|
|
|
@ -49,7 +49,7 @@ from swift.common.middleware.acl import clean_acl, parse_acl, referrer_allowed
|
||||||
from swift.common.utils import get_logger, split_path
|
from swift.common.utils import get_logger, split_path
|
||||||
|
|
||||||
|
|
||||||
PROTOCOL_NAME = "Swift Token Authentication"
|
PROTOCOL_NAME = 'Swift Token Authentication'
|
||||||
|
|
||||||
|
|
||||||
class AuthProtocol(object):
|
class AuthProtocol(object):
|
||||||
|
@ -195,9 +195,9 @@ class AuthProtocol(object):
|
||||||
# TODO(todd): cache
|
# TODO(todd): cache
|
||||||
|
|
||||||
self.log.debug('Asking keystone to validate token')
|
self.log.debug('Asking keystone to validate token')
|
||||||
headers = {"Content-type": "application/json",
|
headers = {'Content-type': 'application/json',
|
||||||
"Accept": "application/json",
|
'Accept': 'application/json',
|
||||||
"X-Auth-Token": self.admin_token}
|
'X-Auth-Token': self.admin_token}
|
||||||
self.log.debug('headers: %r', headers)
|
self.log.debug('headers: %r', headers)
|
||||||
self.log.debug('url: %s', self.keystone_url)
|
self.log.debug('url: %s', self.keystone_url)
|
||||||
conn = http_connect(self.keystone_url.hostname, self.keystone_url.port,
|
conn = http_connect(self.keystone_url.hostname, self.keystone_url.port,
|
||||||
|
@ -206,17 +206,17 @@ class AuthProtocol(object):
|
||||||
data = resp.read()
|
data = resp.read()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
# Check http status code for the "OK" family of responses
|
# Check http status code for the 'OK' family of responses
|
||||||
if not str(resp.status).startswith('20'):
|
if not str(resp.status).startswith('20'):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
identity_info = json.loads(data)
|
identity_info = json.loads(data)
|
||||||
roles = []
|
roles = []
|
||||||
role_refs = identity_info["access"]["user"]["roles"]
|
role_refs = identity_info['access']['user']['roles']
|
||||||
|
|
||||||
if role_refs is not None:
|
if role_refs is not None:
|
||||||
for role_ref in role_refs:
|
for role_ref in role_refs:
|
||||||
roles.append(role_ref["id"])
|
roles.append(role_ref['id'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tenant = identity_info['access']['token']['tenantId']
|
tenant = identity_info['access']['token']['tenantId']
|
||||||
|
|
|
@ -227,12 +227,12 @@ class TestCase(unittest.TestCase):
|
||||||
def assertDictEquals(self, actual, expected):
|
def assertDictEquals(self, actual, expected):
|
||||||
for k in expected:
|
for k in expected:
|
||||||
self.assertTrue(k in actual,
|
self.assertTrue(k in actual,
|
||||||
"Expected key %s not in %s." % (k, actual))
|
'Expected key %s not in %s.' % (k, actual))
|
||||||
self.assertDeepEquals(expected[k], actual[k])
|
self.assertDeepEquals(expected[k], actual[k])
|
||||||
|
|
||||||
for k in actual:
|
for k in actual:
|
||||||
self.assertTrue(k in expected,
|
self.assertTrue(k in expected,
|
||||||
"Unexpected key %s in %s." % (k, actual))
|
'Unexpected key %s in %s.' % (k, actual))
|
||||||
|
|
||||||
def assertDeepEquals(self, actual, expected):
|
def assertDeepEquals(self, actual, expected):
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue