diff options
-rwxr-xr-x | bin/skeleton-api | 64 | ||||
-rw-r--r-- | etc/skeleton-api.conf | 34 | ||||
-rw-r--r-- | openstack/common/context.py | 40 | ||||
-rw-r--r-- | openstack/common/middleware/__init__.py | 0 | ||||
-rw-r--r-- | openstack/common/middleware/context.py | 64 | ||||
-rw-r--r-- | openstack/common/utils.py | 96 | ||||
-rw-r--r-- | skeleton/version.py | 49 |
7 files changed, 347 insertions, 0 deletions
diff --git a/bin/skeleton-api b/bin/skeleton-api index e69de29..1d02055 100755 --- a/bin/skeleton-api +++ b/bin/skeleton-api @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# 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. + +""" +Simple Skeleton API Server +""" + +import optparse +import os +import sys + +# If ../skeleton/__init__.py exists, add ../ to Python search path, so that +# it will override what happens to be installed in /usr/(local/)lib/python... +possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), + os.pardir, + os.pardir)) +if os.path.exists(os.path.join(possible_topdir, 'skeleton', '__init__.py')): + sys.path.insert(0, possible_topdir) + +from openstack.common import config +from openstack.common import wsgi +from skeleton import version + + +def create_options(parser): + """ + Sets up the CLI and config-file options that may be + parsed and program commands. + + :param parser: The option parser + """ + config.add_common_options(parser) + config.add_log_options(parser) + + +if __name__ == '__main__': + oparser = optparse.OptionParser(version='%%prog %s' + % version.version_string()) + create_options(oparser) + (options, args) = config.parse_options(oparser) + + try: + conf, app = config.load_paste_app('skeleton-api', options, args) + + server = wsgi.Server() + server.start(app, int(conf['bind_port']), conf['bind_host']) + server.wait() + except RuntimeError, e: + sys.exit("ERROR: %s" % e) diff --git a/etc/skeleton-api.conf b/etc/skeleton-api.conf index e69de29..ae4c68e 100644 --- a/etc/skeleton-api.conf +++ b/etc/skeleton-api.conf @@ -0,0 +1,34 @@ +[DEFAULT] +# Show more verbose log output (sets INFO log level output) +verbose = True + +# Show debugging output in logs (sets DEBUG log level output) +debug = False + +# Address to bind the server to +bind_host = 0.0.0.0 + +# Port the bind the server to +bind_port = 80 + +# Log to this file. Make sure the user running skeleton-api has +# permissions to write to this file! +log_file = /var/log/skeleton/api.log + +[pipeline:skeleton-api] +pipeline = versionnegotiation context apiv1app + +[pipeline:versions] +pipeline = versionsapp + +[app:versionsapp] +paste.app_factory = skeleton.api.versions:app_factory + +[app:apiv1app] +paste.app_factory = skeleton.api.v1:app_factory + +[filter:versionnegotiation] +paste.filter_factory = skeleton.api.middleware.version_negotiation:filter_factory + +[filter:context] +paste.filter_factory = openstack.common.middleware.context:filter_factory diff --git a/openstack/common/context.py b/openstack/common/context.py new file mode 100644 index 0000000..a9a16f8 --- /dev/null +++ b/openstack/common/context.py @@ -0,0 +1,40 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# 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. + +""" +Simple class that stores security context information in the web request. + +Projects should subclass this class if they wish to enhance the request +context or provide additional information in their specific WSGI pipeline. +""" + + +class RequestContext(object): + + """ + Stores information about the security context under which the user + accesses the system, as well as additional request information. + """ + + def __init__(self, auth_tok=None, user=None, tenant=None, is_admin=False, + read_only=False, show_deleted=False): + self.auth_tok = auth_tok + self.user = user + self.tenant = tenant + self.is_admin = is_admin + self.read_only = read_only + self.show_deleted = show_deleted diff --git a/openstack/common/middleware/__init__.py b/openstack/common/middleware/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/openstack/common/middleware/__init__.py diff --git a/openstack/common/middleware/context.py b/openstack/common/middleware/context.py new file mode 100644 index 0000000..be7dafe --- /dev/null +++ b/openstack/common/middleware/context.py @@ -0,0 +1,64 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# 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. + +""" +Middleware that attaches a context to the WSGI request +""" + +from openstack.common import utils +from openstack.common import wsgi +from openstack.common import context + + +class ContextMiddleware(wsgi.Middleware): + def __init__(self, app, options): + self.options = options + super(ContextMiddleware, self).__init__(app) + + def make_context(self, *args, **kwargs): + """ + Create a context with the given arguments. + """ + + # Determine the context class to use + ctxcls = context.RequestContext + if 'context_class' in self.options: + ctxcls = utils.import_class(self.options['context_class']) + + return ctxcls(*args, **kwargs) + + def process_request(self, req): + """ + Extract any authentication information in the request and + construct an appropriate context from it. + """ + # Use the default empty context, with admin turned on for + # backwards compatibility + req.context = self.make_context(is_admin=True) + + +def filter_factory(global_conf, **local_conf): + """ + Factory method for paste.deploy + """ + conf = global_conf.copy() + conf.update(local_conf) + + def filter(app): + return ContextMiddleware(app, conf) + + return filter diff --git a/openstack/common/utils.py b/openstack/common/utils.py new file mode 100644 index 0000000..45c622e --- /dev/null +++ b/openstack/common/utils.py @@ -0,0 +1,96 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# 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. + +""" +System-level utilities and helper functions. +""" + +import datetime +import inspect +import logging +import os +import random +import subprocess +import socket +import sys + +from glance.common import exception +from glance.common.exception import ProcessExecutionError + + +TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" + + +def int_from_bool_as_string(subject): + """ + Interpret a string as a boolean and return either 1 or 0. + + Any string value in: + ('True', 'true', 'On', 'on', '1') + is interpreted as a boolean True. + + Useful for JSON-decoded stuff and config file parsing + """ + return bool_from_string(subject) and 1 or 0 + + +def bool_from_string(subject): + """ + Interpret a string as a boolean. + + Any string value in: + ('True', 'true', 'On', 'on', '1') + is interpreted as a boolean True. + + Useful for JSON-decoded stuff and config file parsing + """ + if type(subject) == type(bool): + return subject + if hasattr(subject, 'startswith'): # str or unicode... + if subject.strip().lower() in ('true', 'on', '1'): + return True + return False + + +def import_class(import_str): + """Returns a class from a string including module and class""" + mod_str, _sep, class_str = import_str.rpartition('.') + try: + __import__(mod_str) + return getattr(sys.modules[mod_str], class_str) + except (ImportError, ValueError, AttributeError): + raise exception.NotFound('Class %s cannot be found' % class_str) + + +def import_object(import_str): + """Returns an object including a module or module and class""" + try: + __import__(import_str) + return sys.modules[import_str] + except ImportError: + cls = import_class(import_str) + return cls() + + +def isotime(at=None): + if not at: + at = datetime.datetime.utcnow() + return at.strftime(TIME_FORMAT) + + +def parse_isotime(timestr): + return datetime.datetime.strptime(timestr, TIME_FORMAT) diff --git a/skeleton/version.py b/skeleton/version.py new file mode 100644 index 0000000..943c019 --- /dev/null +++ b/skeleton/version.py @@ -0,0 +1,49 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# All Rights Reserved. +# +# 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. + +"""Determine version of Skeleton library""" + +try: + from skeleton.vcsversion import version_info +except ImportError: + version_info = {'branch_nick': u'LOCALBRANCH', + 'revision_id': 'LOCALREVISION', + 'revno': 0} + +SKELETON_VERSION = ['2011', '3'] +YEAR, COUNT = SKELETON_VERSION + +FINAL = False # This becomes true at Release Candidate time + + +def canonical_version_string(): + return '.'.join([YEAR, COUNT]) + + +def version_string(): + if FINAL: + return canonical_version_string() + else: + return '%s-dev' % (canonical_version_string(),) + + +def vcs_version_string(): + return "%s:%s" % (version_info['branch_nick'], version_info['revision_id']) + + +def version_string_with_vcs(): + return "%s-%s" % (canonical_version_string(), vcs_version_string()) |