summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/keystone81
-rwxr-xr-xbin/keystone-admin35
-rwxr-xr-xbin/keystone-auth35
-rw-r--r--keystone/__init__.py131
-rw-r--r--keystone/test/__init__.py75
5 files changed, 176 insertions, 181 deletions
diff --git a/bin/keystone b/bin/keystone
index db4d1dca..d79189db 100755
--- a/bin/keystone
+++ b/bin/keystone
@@ -36,16 +36,18 @@ if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
import keystone.tools.tracer # @UnusedImport # module runs on import
import keystone
-from keystone.common import config, wsgi
+from keystone.common import config
if __name__ == '__main__':
+
# Initialize a parser for our configuration paramaters
+ # since we have special handling for --admin-port argument
parser = optparse.OptionParser(version='%%prog %s' % keystone.version)
common_group = config.add_common_options(parser)
config.add_log_options(parser)
# Handle a special argument to support starting two endpoints
- common_group.add_option(
+ option = common_group.add_option(
'-a', '--admin-port', dest="admin_port", metavar="PORT",
help="specifies port for Admin API to listen on (default is 35357)")
@@ -54,67 +56,22 @@ if __name__ == '__main__':
# Start services
try:
- # Load Service API server
- conf, app = config.load_paste_app(
- 'keystone-legacy-auth', options, args)
- admin_conf, admin_app = config.load_paste_app(
- 'admin', options, args)
-
- debug = options.get('debug') or conf.get('debug', False)
- debug = debug in [True, "True", "1"]
- verbose = options.get('verbose') or conf.get('verbose', False)
- verbose = verbose in [True, "True", "1"]
-
- # Safely get SSL options
- service_ssl = conf.get('service_ssl', False)
- service_ssl = service_ssl in [True, "True", "1"]
- admin_ssl = conf.get('admin_ssl', False)
- admin_ssl = admin_ssl in [True, "True", "1"]
- cert_required = conf.get('cert_required', False)
- cert_required = cert_required in [True, "True", "1"]
- certfile = conf.get('certfile')
- keyfile = conf.get('keyfile')
- ca_certs = conf.get('ca_certs')
-
- if debug or verbose:
- config_file = config.find_config_file(options, args)
- print "Using config file:", config_file
-
- port = int(options.get('bind_port') or conf.get('service_port', 5000))
- host = options.get('bind_host', conf.get('service_host', '0.0.0.0'))
-
- # Load Service API server
- if service_ssl:
- server = wsgi.SslServer()
- server.start(app, port, host,
- certfile=certfile, keyfile=keyfile,
- ca_certs=ca_certs,
- cert_required=cert_required)
- else:
- server = wsgi.Server()
- server.start(app, port, host)
-
- print "Service API (ssl=%s) listening on %s:%s" % (
- service_ssl, host, port)
+ # Load Service API Server
+ service = keystone.Server(name="Service API",
+ config_name='keystone-legacy-auth',
+ options=options, args=args)
+ service.start(wait=False)
+ except RuntimeError, e:
+ sys.exit("ERROR: %s" % e)
+ try:
# Load Admin API server
- port = int(options.get('admin_port') or conf.get('admin_port', 35357))
- host = options.get('bind_host', conf.get('admin_host', '0.0.0.0'))
-
- if admin_ssl:
- admin_server = wsgi.SslServer()
- admin_server.start(admin_app, port, host,
- certfile=certfile, keyfile=keyfile,
- ca_certs=ca_certs,
- cert_required=cert_required)
- else:
- admin_server = wsgi.Server()
- admin_server.start(admin_app, port, host)
-
- print "Admin API (ssl=%s) listening on %s:%s" % (
- admin_ssl, host, port)
-
- # Wait until done
- server.wait()
+ port = options.get('admin_port', None)
+ host = options.get('bind_host', None)
+ admin = keystone.Server(name='Admin API', config_name='admin',
+ options=options, args=args)
+ admin.start(host=host, port=port, wait=True)
except RuntimeError, e:
sys.exit("ERROR: %s" % e)
+ finally:
+ service.stop()
diff --git a/bin/keystone-admin b/bin/keystone-admin
index fd5c6ef9..68549303 100755
--- a/bin/keystone-admin
+++ b/bin/keystone-admin
@@ -19,7 +19,7 @@
# under the License.
"""
-Keystone Identity Server - Admin API
+Keystone Identity Server - Admin API
"""
import optparse
@@ -36,40 +36,11 @@ if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
import keystone.tools.tracer # @UnusedImport # module runs on import
import keystone
-from keystone.common import config, wsgi
-
if __name__ == '__main__':
- # Initialize a parser for our configuration paramaters
- parser = optparse.OptionParser(version='%%prog %s' % keystone.version)
- common_group = config.add_common_options(parser)
- config.add_log_options(parser)
-
- # Parse arguments and load config
- (options, args) = config.parse_options(parser)
- config_file = config.find_config_file(options, args)
-
- # Start services
try:
# Load Admin API server
- conf, app = config.load_paste_app('admin', options, args)
-
- debug = options.get('debug') or conf.get('debug', False)
- debug = debug in [True, "True", "1"]
- verbose = options.get('verbose') or conf.get('verbose', False)
- verbose = verbose in [True, "True", "1"]
- if debug or verbose:
- print "Using config file:", config_file
-
- server = wsgi.Server()
-
- port = int(options['bind_port'] or conf['admin_port'] or 35357)
- host = options['bind_host'] or conf['admin_host']
-
- server.start(app, port, host)
-
- print "Admin API listening on %s:%s" % (host, port)
-
- server.wait()
+ admin = keystone.Server(name='Admin API', config_name='admin')
+ admin.start(wait=True)
except RuntimeError, e:
sys.exit("ERROR: %s" % e)
diff --git a/bin/keystone-auth b/bin/keystone-auth
index 73d43863..287482a0 100755
--- a/bin/keystone-auth
+++ b/bin/keystone-auth
@@ -36,41 +36,12 @@ if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
import keystone.tools.tracer # @UnusedImport # module runs on import
import keystone
-from keystone.common import config, wsgi
-
if __name__ == '__main__':
- # Initialize a parser for our configuration paramaters
- parser = optparse.OptionParser(version='%%prog %s' % keystone.version)
- common_group = config.add_common_options(parser)
- config.add_log_options(parser)
-
- # Parse arguments and load config
- (options, args) = config.parse_options(parser)
-
- # Start services
try:
# Load Service API server
- conf, app = config.load_paste_app('keystone-legacy-auth',
- options, args)
-
- debug = options.get('debug') or conf.get('debug', False)
- debug = debug in [True, "True", "1"]
- verbose = options.get('verbose') or conf.get('verbose', False)
- verbose = verbose in [True, "True", "1"]
- if debug or verbose:
- config_file = config.find_config_file(options, args)
- print "Using config file:", config_file
-
- server = wsgi.Server()
-
- port = int(options['bind_port'] or conf['service_port'] or 5000)
- host = options['bind_host'] or conf['service_host']
-
- server.start(app, port, host)
-
- print "Service API listening on %s:%s" % (host, port)
-
- server.wait()
+ admin = keystone.Server(name='Service API',
+ config_name='keystone-legacy-auth')
+ admin.start(wait=True)
except RuntimeError, e:
sys.exit("ERROR: %s" % e)
diff --git a/keystone/__init__.py b/keystone/__init__.py
index 226b09ae..30ee337f 100644
--- a/keystone/__init__.py
+++ b/keystone/__init__.py
@@ -13,6 +13,10 @@
# limitations under the License.
import gettext
+import optparse
+import sys
+
+from keystone.common import config, wsgi
API_VERSION = "2.0"
@@ -37,3 +41,130 @@ def version():
# This installs the _(...) function as a built-in so all other modules
# don't need to.
gettext.install('keystone')
+
+
+class Server():
+ """Used to start and stop Keystone servers
+
+ This class is called from shell and command-line scripts and is the
+ entry-point for starting and stopping Keystone servers.
+
+ The initializer can take option and argument overrides, but otherwise will
+ parse arguments and configuration files itself to determine how to start
+ the server.
+ """
+
+ def __init__(self, name='admin', config_name=None,
+ options=None, args=None):
+ """Initizalizer which takes the following paramaters:
+
+ :param name: A cosmetic name for the server (ex. Admin API)
+ :param config: the paste config name to look for when starting the
+ server
+ :param options: a mapping of option key/str(value) pairs passed to
+ config.load_paste_app
+ :param args: override for sys.argv (otherwise sys.argv is used)
+ """
+ self.options = options
+ if args:
+ self.args = args
+ else:
+ self.args = sys.argv
+
+ if options is None or args is None:
+ # Initialize a parser for our configuration paramaters
+ parser = optparse.OptionParser(version='%%prog %s' %
+ version)
+ common_group = config.add_common_options(parser)
+ config.add_log_options(parser)
+
+ # Parse arguments and load config
+ (poptions, pargs) = config.parse_options(parser)
+
+ if options is None:
+ self.options = poptions
+ else:
+ self.options = options
+
+ if args is None:
+ self.args = pargs
+ else:
+ self.args = args
+
+ self.name = name
+ self.config = config_name or self.name
+
+ def start(self, host=None, port=None, wait=True):
+ """Starts the Keystone server
+
+ :param host: the IP address to listen on
+ :param port: the TCP/IP port to listen on
+ :param wait: whether to wait (block) for the server to terminate or
+ return to the caller without waiting
+ """
+ # Load Service API server
+ conf, app = config.load_paste_app(
+ self.config, self.options, self.args)
+
+ debug = self.options.get('debug') or conf.get('debug', False)
+ debug = debug in [True, "True", "1"]
+ verbose = self.options.get('verbose') or conf.get('verbose', False)
+ verbose = verbose in [True, "True", "1"]
+
+ if debug or verbose:
+ config_file = config.find_config_file(self.options, self.args)
+ print "Starting '%s' with config: %s" % (self.config, config_file)
+
+ if port is None:
+ if self.config == 'admin':
+ # Legacy
+ port = int(self.options.get('bind_port') or
+ conf.get('admin_port', 35357))
+ else:
+ port = int(self.options.get('bind_port') or
+ conf.get('service_port', 5000))
+ if host is None:
+ host = self.options.get('bind_host',
+ conf.get('service_host', '0.0.0.0'))
+
+ self.key = "%s-%s:%s" % (self.name, host, port)
+
+ # Safely get SSL options
+ service_ssl = conf.get('service_ssl', False)
+ service_ssl = service_ssl in [True, "True", "1"]
+
+ # Load the server
+ if service_ssl:
+ cert_required = conf.get('cert_required', False)
+ cert_required = cert_required in [True, "True", "1"]
+ certfile = conf.get('certfile')
+ keyfile = conf.get('keyfile')
+ ca_certs = conf.get('ca_certs')
+
+ self.server = wsgi.SslServer()
+ self.server.start(app, port, host,
+ certfile=certfile, keyfile=keyfile,
+ ca_certs=ca_certs,
+ cert_required=cert_required,
+ key=self.key)
+ else:
+ self.server = wsgi.Server()
+ self.server.start(app, port, host,
+ key="%s-%s:%s" % (self.config, host, port))
+
+ print "%s listening on %s://%s:%s" % (
+ self.name, ['http', 'https'][service_ssl], host, port)
+
+ # Wait until done
+ if wait:
+ self.server.wait()
+
+ def stop(self):
+ """Stops the Keystone server
+
+ This should be called always to release the network socket
+ """
+ if self.server is not None:
+ if self.key in self.server.threads:
+ self.server.threads[self.key].kill()
+ self.server = None
diff --git a/keystone/test/__init__.py b/keystone/test/__init__.py
index 915eaf15..3765bfba 100644
--- a/keystone/test/__init__.py
+++ b/keystone/test/__init__.py
@@ -65,7 +65,7 @@ cgitb.enable(format="text")
from functional.common import HttpTestCase
import keystone
from keystone.common import config, wsgi
-from keystone import backends
+from keystone import backends, Server
TEST_DIR = os.path.abspath(os.path.dirname(__file__))
BASE_DIR = os.path.abspath(os.path.join(TEST_DIR, os.pardir, os.pardir))
@@ -399,61 +399,28 @@ class KeystoneTest(object):
(options, args) = config.parse_options(parser)
options['config_file'] = self.conf_fp.name
- # Start services
try:
- # Load Service API server
- conf, app = config.load_paste_app(
- 'keystone-legacy-auth', options, args)
- admin_conf, admin_app = config.load_paste_app(
- 'admin', options, args)
-
- port = int(options['bind_port'] or conf['service_port'] or 5000)
- host = options['bind_host'] or conf['service_host']
-
- if (self.isSsl == True):
- server = wsgi.SslServer()
- server.start(app, port, host,
- certfile=conf['certfile'],
- keyfile=conf['keyfile'],
- ca_certs=conf['ca_certs'],
- cert_required=conf['cert_required'])
- # Load Admin API server
- port = int(options['admin_port'] or conf['admin_port']
- or 35357)
- host = options['bind_host'] or conf['admin_host']
-
- admin_server = wsgi.SslServer()
- admin_server.start(admin_app,
- port, host,
- certfile=conf['certfile'],
- keyfile=conf['keyfile'],
- ca_certs=conf['ca_certs'],
- cert_required=conf['cert_required'])
-
- else:
- server = wsgi.Server()
- server.start(app, port, host, key="Test")
-
- print "Service API (ssl=%s) listening on %s:%s" % (
- conf['service_ssl'], host, port)
-
- # Load Admin API server
- port = int(options['admin_port'] or conf['admin_port']
- or 35357)
- host = options['bind_host'] or conf['admin_host']
-
- admin_server = wsgi.Server()
- admin_server.start(admin_app, port, host, key="Test")
-
- print "Admin API (ssl=%s) listening on %s:%s" % (
- conf['admin_ssl'], host, port)
+ # Load Service API Server
+ service = keystone.Server(name="Service API",
+ config_name='keystone-legacy-auth',
+ options=options, args=args)
+ service.start(wait=False)
+ except RuntimeError, e:
+ sys.exit("ERROR: %s" % e)
+ try:
+ # Load Admin API server
+ port = options.get('admin_port', None)
+ host = options.get('bind_host', None)
+ admin = keystone.Server(name='Admin API', config_name='admin',
+ options=options, args=args)
+ admin.start(host=host, port=port, wait=False)
except RuntimeError, e:
- print e
+ service.stop()
sys.exit("ERROR: %s" % e)
- self.server = server
- self.admin_server = admin_server
+ self.server = service
+ self.admin_server = admin
# Load sample data
from keystone.test import sampledata
@@ -465,12 +432,10 @@ class KeystoneTest(object):
print "Stopping the keystone server..."
try:
if self.server is not None:
- if 'Test' in self.server.threads:
- self.server.threads['Test'].kill()
+ self.server.stop()
self.server = None
if self.admin_server is not None:
- if 'Test' in self.admin_server.threads:
- self.admin_server.threads['Test'].kill()
+ self.admin_server.stop()
self.admin_server = None
self.conf_fp.close()
self.conf_fp = None