diff --git a/cloudkitty/openstack/__init__.py b/cloudkitty/openstack/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cloudkitty/openstack/common/__init__.py b/cloudkitty/openstack/common/__init__.py new file mode 100644 index 00000000..d1223eaf --- /dev/null +++ b/cloudkitty/openstack/common/__init__.py @@ -0,0 +1,17 @@ +# +# 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 six + + +six.add_move(six.MovedModule('mox', 'mox', 'mox3.mox')) diff --git a/cloudkitty/openstack/common/importutils.py b/cloudkitty/openstack/common/importutils.py new file mode 100644 index 00000000..c471bcf8 --- /dev/null +++ b/cloudkitty/openstack/common/importutils.py @@ -0,0 +1,73 @@ +# Copyright 2011 OpenStack Foundation. +# 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. + +""" +Import related utilities and helper functions. +""" + +import sys +import traceback + + +def import_class(import_str): + """Returns a class from a string including module and class.""" + mod_str, _sep, class_str = import_str.rpartition('.') + __import__(mod_str) + try: + return getattr(sys.modules[mod_str], class_str) + except AttributeError: + raise ImportError('Class %s cannot be found (%s)' % + (class_str, + traceback.format_exception(*sys.exc_info()))) + + +def import_object(import_str, *args, **kwargs): + """Import a class and return an instance of it.""" + return import_class(import_str)(*args, **kwargs) + + +def import_object_ns(name_space, import_str, *args, **kwargs): + """Tries to import object from default namespace. + + Imports a class and return an instance of it, first by trying + to find the class in a default namespace, then failing back to + a full path if not found in the default namespace. + """ + import_value = "%s.%s" % (name_space, import_str) + try: + return import_class(import_value)(*args, **kwargs) + except ImportError: + return import_class(import_str)(*args, **kwargs) + + +def import_module(import_str): + """Import a module.""" + __import__(import_str) + return sys.modules[import_str] + + +def import_versioned_module(version, submodule=None): + module = 'cloudkitty.v%s' % version + if submodule: + module = '.'.join((module, submodule)) + return import_module(module) + + +def try_import(import_str, default=None): + """Try to import a module and if it fails return default.""" + try: + return import_module(import_str) + except ImportError: + return default diff --git a/cloudkitty/orchestrator.py b/cloudkitty/orchestrator.py index 7af7b88a..87d93bcc 100644 --- a/cloudkitty/orchestrator.py +++ b/cloudkitty/orchestrator.py @@ -25,8 +25,8 @@ from keystoneclient.v2_0 import client as kclient from oslo.config import cfg import cloudkitty.config # NOQA +import cloudkitty.openstack.common.importutils as i_utils from cloudkitty import state -import cloudkitty.utils as utils from cloudkitty import write_orchestrator as w_orch @@ -38,11 +38,12 @@ class Orchestrator(object): # Billing settings self.billing_pipeline = [] for billing_processor in CONF.billing.pipeline: - self.billing_pipeline.append(utils.import_class(billing_processor)) + processor = i_utils.import_class(billing_processor) + self.billing_pipeline.append(processor) # Output settings self.output_pipeline = [] for writer in CONF.output.pipeline: - self.output_pipeline.append(utils.import_class(writer)) + self.output_pipeline.append(i_utils.import_class(writer)) self.keystone = kclient.Client(username=CONF.auth.username, password=CONF.auth.password, @@ -50,12 +51,12 @@ class Orchestrator(object): region_name=CONF.auth.region, auth_url=CONF.auth.url) - self.sm = state.StateManager(utils.import_class(CONF.state.backend), + self.sm = state.StateManager(i_utils.import_class(CONF.state.backend), CONF.state.basepath, self.keystone.user_id, 'osrtf') - collector = utils.import_class(CONF.collect.collector) + collector = i_utils.import_class(CONF.collect.collector) self.collector = collector(user=CONF.auth.username, password=CONF.auth.password, tenant=CONF.auth.tenant, @@ -63,8 +64,8 @@ class Orchestrator(object): keystone_url=CONF.auth.url, period=CONF.collect.period) - w_backend = utils.import_class(CONF.output.backend) - s_backend = utils.import_class(CONF.state.backend) + w_backend = i_utils.import_class(CONF.output.backend) + s_backend = i_utils.import_class(CONF.state.backend) self.wo = w_orch.WriteOrchestrator(w_backend, s_backend, self.keystone.user_id, diff --git a/cloudkitty/utils.py b/cloudkitty/utils.py index 79cbef88..36676b31 100644 --- a/cloudkitty/utils.py +++ b/cloudkitty/utils.py @@ -15,7 +15,6 @@ # # @author: Stéphane Albert # -import sys import time import iso8601 @@ -27,14 +26,3 @@ def dt2ts(orig_dt): def iso2dt(iso_date): return iso8601.parse_date(iso_date) - - -def import_class(import_str): - mod_str, _sep, class_str = import_str.rpartition('.') - if not mod_str: - mod_str = '__builtin__' - try: - __import__(mod_str) - return getattr(sys.modules[mod_str], class_str) - except (ValueError, AttributeError): - raise ImportError('Class %s cannot be found.' % class_str) diff --git a/openstack-common.conf b/openstack-common.conf new file mode 100644 index 00000000..6c350c63 --- /dev/null +++ b/openstack-common.conf @@ -0,0 +1,4 @@ +[DEFAULT] +base=cloudkitty + +module=importutils diff --git a/tox.ini b/tox.ini index 95303da6..6fed7f90 100644 --- a/tox.ini +++ b/tox.ini @@ -24,4 +24,4 @@ commands = commands = {posargs} [flake8] -exclude = .git,.venv,.tox,dist,doc,*egg,build +exclude = .git,.venv,.tox,dist,doc,*egg,build,./cloudkitty/openstack/common